Skip to content

Commit

Permalink
[clang][AST][ASTImporter] improve AST comparasion on VarDecl & GotoSt…
Browse files Browse the repository at this point in the history
…mt (#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 <836744285@qq.com>
  • Loading branch information
jcsxky committed Sep 21, 2023
1 parent 1a78444 commit b8f056d
Show file tree
Hide file tree
Showing 2 changed files with 102 additions and 2 deletions.
27 changes: 27 additions & 0 deletions clang/lib/AST/ASTStructuralEquivalence.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,17 @@ class StmtComparer {

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

bool IsStmtEquivalent(const GotoStmt *S1, const GotoStmt *S2) {
LabelDecl *L1 = S1->getLabel();
LabelDecl *L2 = S2->getLabel();
if (!L1 || !L2)
return L1 == L2;

IdentifierInfo *Name1 = L1->getIdentifier();
IdentifierInfo *Name2 = L2->getIdentifier();
return ::IsStructurallyEquivalent(Name1, Name2);
}

bool IsStmtEquivalent(const SourceLocExpr *E1, const SourceLocExpr *E2) {
return E1->getIdentKind() == E2->getIdentKind();
}
Expand Down Expand Up @@ -1295,6 +1306,22 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
return true;
}

static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
VarDecl *D1, VarDecl *D2) {
if (D1->getStorageClass() != D2->getStorageClass())
return false;

IdentifierInfo *Name1 = D1->getIdentifier();
IdentifierInfo *Name2 = D2->getIdentifier();
if (!::IsStructurallyEquivalent(Name1, Name2))
return false;

if (!IsStructurallyEquivalent(Context, D1->getType(), D2->getType()))
return false;

return IsStructurallyEquivalent(Context, D1->getInit(), D2->getInit());
}

static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
FieldDecl *Field1, FieldDecl *Field2,
QualType Owner2Type) {
Expand Down
77 changes: 75 additions & 2 deletions clang/unittests/AST/StructuralEquivalenceTest.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "clang/AST/ASTContext.h"
#include "clang/AST/ASTStructuralEquivalence.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/ASTMatchers/ASTMatchers.h"
#include "clang/Frontend/ASTUnit.h"
Expand Down Expand Up @@ -1801,10 +1802,10 @@ TEST_F(StructuralEquivalenceCacheTest, SimpleNonEq) {
TEST_F(StructuralEquivalenceCacheTest, ReturnStmtNonEq) {
auto TU = makeTuDecls(
R"(
bool x(){ return true; }
bool x() { return true; }
)",
R"(
bool x(){ return false; }
bool x() { return false; }
)",
Lang_CXX03);

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

}

TEST_F(StructuralEquivalenceCacheTest, VarDeclNoEq) {
auto TU = makeTuDecls(
R"(
int p;
)",
R"(
int q;
)",
Lang_CXX03);

StructuralEquivalenceContext Ctx(
get<0>(TU)->getASTContext(), get<1>(TU)->getASTContext(),
NonEquivalentDecls, StructuralEquivalenceKind::Default, false, false);

auto Var = findDeclPair<VarDecl>(TU, varDecl());
EXPECT_FALSE(Ctx.IsEquivalent(Var.first, Var.second));
}

TEST_F(StructuralEquivalenceCacheTest, VarDeclWithDifferentStorageClassNoEq) {
auto TU = makeTuDecls(
R"(
int p;
)",
R"(
static int p;
)",
Lang_CXX03);

StructuralEquivalenceContext Ctx(
get<0>(TU)->getASTContext(), get<1>(TU)->getASTContext(),
NonEquivalentDecls, StructuralEquivalenceKind::Default, false, false);

auto Var = findDeclPair<VarDecl>(TU, varDecl());
EXPECT_FALSE(Ctx.IsEquivalent(Var.first, Var.second));
}

TEST_F(StructuralEquivalenceCacheTest, VarDeclWithInitNoEq) {
auto TU = makeTuDecls(
R"(
int p = 1;
)",
R"(
int p = 2;
)",
Lang_CXX03);

StructuralEquivalenceContext Ctx(
get<0>(TU)->getASTContext(), get<1>(TU)->getASTContext(),
NonEquivalentDecls, StructuralEquivalenceKind::Default, false, false);

auto Var = findDeclPair<VarDecl>(TU, varDecl());
EXPECT_FALSE(Ctx.IsEquivalent(Var.first, Var.second));
}

TEST_F(StructuralEquivalenceCacheTest, SpecialNonEq) {
auto TU = makeTuDecls(
R"(
Expand Down Expand Up @@ -2320,5 +2375,23 @@ TEST_F(StructuralEquivalenceStmtTest, UnresolvedLookup) {
EXPECT_TRUE(testStructuralMatch(t));
}

TEST_F(StructuralEquivalenceCacheTest, GotoStmtNoEq) {
auto S = makeStmts(
R"(
void foo() {
goto L1;
L1: foo();
}
)",
R"(
void foo() {
goto L2;
L2: foo();
}
)",
Lang_CXX03, gotoStmt());
EXPECT_FALSE(testStructuralMatch(S));
}

} // end namespace ast_matchers
} // end namespace clang

0 comments on commit b8f056d

Please sign in to comment.