Skip to content

Commit b8f056d

Browse files
authored
[clang][AST][ASTImporter] improve AST comparasion on VarDecl & GotoStmt (#66976)
improve AST comparasion on VarDecl & GotoStmt: 1. VarDecl should not be ignored, 2. GotoStmt has no children, it should be handle explicitly. Reviewed By: donat.nagy Differential Revision: https://reviews.llvm.org/D159519 Co-authored-by: huqizhi <[email protected]>
1 parent 1a78444 commit b8f056d

File tree

2 files changed

+102
-2
lines changed

2 files changed

+102
-2
lines changed

clang/lib/AST/ASTStructuralEquivalence.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,17 @@ class StmtComparer {
277277

278278
bool IsStmtEquivalent(const Stmt *S1, const Stmt *S2) { return true; }
279279

280+
bool IsStmtEquivalent(const GotoStmt *S1, const GotoStmt *S2) {
281+
LabelDecl *L1 = S1->getLabel();
282+
LabelDecl *L2 = S2->getLabel();
283+
if (!L1 || !L2)
284+
return L1 == L2;
285+
286+
IdentifierInfo *Name1 = L1->getIdentifier();
287+
IdentifierInfo *Name2 = L2->getIdentifier();
288+
return ::IsStructurallyEquivalent(Name1, Name2);
289+
}
290+
280291
bool IsStmtEquivalent(const SourceLocExpr *E1, const SourceLocExpr *E2) {
281292
return E1->getIdentKind() == E2->getIdentKind();
282293
}
@@ -1295,6 +1306,22 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
12951306
return true;
12961307
}
12971308

1309+
static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
1310+
VarDecl *D1, VarDecl *D2) {
1311+
if (D1->getStorageClass() != D2->getStorageClass())
1312+
return false;
1313+
1314+
IdentifierInfo *Name1 = D1->getIdentifier();
1315+
IdentifierInfo *Name2 = D2->getIdentifier();
1316+
if (!::IsStructurallyEquivalent(Name1, Name2))
1317+
return false;
1318+
1319+
if (!IsStructurallyEquivalent(Context, D1->getType(), D2->getType()))
1320+
return false;
1321+
1322+
return IsStructurallyEquivalent(Context, D1->getInit(), D2->getInit());
1323+
}
1324+
12981325
static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
12991326
FieldDecl *Field1, FieldDecl *Field2,
13001327
QualType Owner2Type) {

clang/unittests/AST/StructuralEquivalenceTest.cpp

Lines changed: 75 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include "clang/AST/ASTContext.h"
22
#include "clang/AST/ASTStructuralEquivalence.h"
3+
#include "clang/AST/Decl.h"
34
#include "clang/AST/DeclTemplate.h"
45
#include "clang/ASTMatchers/ASTMatchers.h"
56
#include "clang/Frontend/ASTUnit.h"
@@ -1801,10 +1802,10 @@ TEST_F(StructuralEquivalenceCacheTest, SimpleNonEq) {
18011802
TEST_F(StructuralEquivalenceCacheTest, ReturnStmtNonEq) {
18021803
auto TU = makeTuDecls(
18031804
R"(
1804-
bool x(){ return true; }
1805+
bool x() { return true; }
18051806
)",
18061807
R"(
1807-
bool x(){ return false; }
1808+
bool x() { return false; }
18081809
)",
18091810
Lang_CXX03);
18101811

@@ -1817,6 +1818,60 @@ TEST_F(StructuralEquivalenceCacheTest, ReturnStmtNonEq) {
18171818

18181819
}
18191820

1821+
TEST_F(StructuralEquivalenceCacheTest, VarDeclNoEq) {
1822+
auto TU = makeTuDecls(
1823+
R"(
1824+
int p;
1825+
)",
1826+
R"(
1827+
int q;
1828+
)",
1829+
Lang_CXX03);
1830+
1831+
StructuralEquivalenceContext Ctx(
1832+
get<0>(TU)->getASTContext(), get<1>(TU)->getASTContext(),
1833+
NonEquivalentDecls, StructuralEquivalenceKind::Default, false, false);
1834+
1835+
auto Var = findDeclPair<VarDecl>(TU, varDecl());
1836+
EXPECT_FALSE(Ctx.IsEquivalent(Var.first, Var.second));
1837+
}
1838+
1839+
TEST_F(StructuralEquivalenceCacheTest, VarDeclWithDifferentStorageClassNoEq) {
1840+
auto TU = makeTuDecls(
1841+
R"(
1842+
int p;
1843+
)",
1844+
R"(
1845+
static int p;
1846+
)",
1847+
Lang_CXX03);
1848+
1849+
StructuralEquivalenceContext Ctx(
1850+
get<0>(TU)->getASTContext(), get<1>(TU)->getASTContext(),
1851+
NonEquivalentDecls, StructuralEquivalenceKind::Default, false, false);
1852+
1853+
auto Var = findDeclPair<VarDecl>(TU, varDecl());
1854+
EXPECT_FALSE(Ctx.IsEquivalent(Var.first, Var.second));
1855+
}
1856+
1857+
TEST_F(StructuralEquivalenceCacheTest, VarDeclWithInitNoEq) {
1858+
auto TU = makeTuDecls(
1859+
R"(
1860+
int p = 1;
1861+
)",
1862+
R"(
1863+
int p = 2;
1864+
)",
1865+
Lang_CXX03);
1866+
1867+
StructuralEquivalenceContext Ctx(
1868+
get<0>(TU)->getASTContext(), get<1>(TU)->getASTContext(),
1869+
NonEquivalentDecls, StructuralEquivalenceKind::Default, false, false);
1870+
1871+
auto Var = findDeclPair<VarDecl>(TU, varDecl());
1872+
EXPECT_FALSE(Ctx.IsEquivalent(Var.first, Var.second));
1873+
}
1874+
18201875
TEST_F(StructuralEquivalenceCacheTest, SpecialNonEq) {
18211876
auto TU = makeTuDecls(
18221877
R"(
@@ -2320,5 +2375,23 @@ TEST_F(StructuralEquivalenceStmtTest, UnresolvedLookup) {
23202375
EXPECT_TRUE(testStructuralMatch(t));
23212376
}
23222377

2378+
TEST_F(StructuralEquivalenceCacheTest, GotoStmtNoEq) {
2379+
auto S = makeStmts(
2380+
R"(
2381+
void foo() {
2382+
goto L1;
2383+
L1: foo();
2384+
}
2385+
)",
2386+
R"(
2387+
void foo() {
2388+
goto L2;
2389+
L2: foo();
2390+
}
2391+
)",
2392+
Lang_CXX03, gotoStmt());
2393+
EXPECT_FALSE(testStructuralMatch(S));
2394+
}
2395+
23232396
} // end namespace ast_matchers
23242397
} // end namespace clang

0 commit comments

Comments
 (0)