[clang] improve ast comparation (PR #66110)

Qizhi Hu via cfe-commits cfe-commits at lists.llvm.org
Tue Sep 12 09:45:26 PDT 2023


https://github.com/jcsxky created https://github.com/llvm/llvm-project/pull/66110:

    1.VarDecl should not be ignored.
    2.GotoStmt has no children, it should be handle explicitly.

>From ab11dd019685d714a4d697cc021cb313a5b30b95 Mon Sep 17 00:00:00 2001
From: huqizhi <huqizhi at feysh.com>
Date: Wed, 13 Sep 2023 00:03:27 +0800
Subject: [PATCH] improve ast comparation     1.VarDecl should not be ignored. 
    2.GotoStmt has no children, it should be handle explicitly.

---
 clang/lib/AST/ASTStructuralEquivalence.cpp    | 26 ++++++++++++++
 .../AST/StructuralEquivalenceTest.cpp         | 36 +++++++++++++++++--
 2 files changed, 60 insertions(+), 2 deletions(-)

diff --git a/clang/lib/AST/ASTStructuralEquivalence.cpp b/clang/lib/AST/ASTStructuralEquivalence.cpp
index 544420234ef0eb0..241afce88985ae7 100644
--- a/clang/lib/AST/ASTStructuralEquivalence.cpp
+++ b/clang/lib/AST/ASTStructuralEquivalence.cpp
@@ -277,6 +277,17 @@ class StmtComparer {
 
   bool IsStmtEquivalent(const Stmt *S1, const Stmt *S2) { return true; }
 
+  bool IsStmtEquivalent(const GotoStmt *S1, const GotoStmt *S2) {
+    auto *L1 = S1->getLabel();
+    auto *L2 = S2->getLabel();
+    if (!L1 || !L2) {
+      return false;
+    }
+    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();
   }
@@ -1295,6 +1306,21 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
   return true;
 }
 
+static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
+                                     VarDecl *D1, VarDecl *D2) {
+  IdentifierInfo *Name1 = D1->getIdentifier();
+  IdentifierInfo *Name2 = D2->getIdentifier();
+  if (!::IsStructurallyEquivalent(Name1, Name2)) {
+    return false;
+  }
+
+  if (!IsStructurallyEquivalent(Context, D1->getType(), D2->getType())) {
+    return false;
+  }
+
+  return true;
+}
+
 static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
                                      FieldDecl *Field1, FieldDecl *Field2,
                                      QualType Owner2Type) {
diff --git a/clang/unittests/AST/StructuralEquivalenceTest.cpp b/clang/unittests/AST/StructuralEquivalenceTest.cpp
index 4e9f476659b9ee6..b4f3c606c576ab4 100644
--- a/clang/unittests/AST/StructuralEquivalenceTest.cpp
+++ b/clang/unittests/AST/StructuralEquivalenceTest.cpp
@@ -1801,10 +1801,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);
 
@@ -2320,5 +2320,37 @@ TEST_F(StructuralEquivalenceStmtTest, UnresolvedLookup) {
   EXPECT_TRUE(testStructuralMatch(t));
 }
 
+TEST_F(StructuralEquivalenceCacheTest, UnaryOperatorNoEq) {
+  auto t = makeStmts(
+      R"(
+      int *p;
+      void foo() { p++; }
+      )",
+      R"(
+      int *q;
+      void foo() { q++; }
+      )",
+      Lang_CXX03, unaryOperator());
+  EXPECT_FALSE(testStructuralMatch(t));
+}
+
+TEST_F(StructuralEquivalenceCacheTest, GotoStmtNoEq) {
+  auto t = makeStmts(
+      R"(
+      void foo() {
+        goto L1;
+        L1: foo();
+      }
+      )",
+      R"(
+      void foo() {
+        goto L2;
+        L2: foo();
+      }
+      )",
+      Lang_CXX03, gotoStmt());
+  EXPECT_FALSE(testStructuralMatch(t));
+}
+
 } // end namespace ast_matchers
 } // end namespace clang



More information about the cfe-commits mailing list