[clang] [clang] fix lack comparison of declRefExpr in ASTStructuralEquivalence (PR #66041)

via cfe-commits cfe-commits at lists.llvm.org
Fri Sep 15 03:47:56 PDT 2023


https://github.com/mzyKi updated https://github.com/llvm/llvm-project/pull/66041

>From f74271d018d413832290e9d021ad6f25209a35fd Mon Sep 17 00:00:00 2001
From: miaozhiyuan <miaozhiyuan at feysh.com>
Date: Tue, 12 Sep 2023 10:51:35 +0800
Subject: [PATCH] [clang][AST] fix lack comparison of declRefExpr in
 ASTStructuralEquivalence

---
 clang/docs/ReleaseNotes.rst                   |  2 +
 clang/lib/AST/ASTStructuralEquivalence.cpp    | 54 +++++++++++--------
 .../AST/StructuralEquivalenceTest.cpp         |  9 ++++
 3 files changed, 43 insertions(+), 22 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 3cdad2f7b9f0e5a..58b8622ed42236d 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -218,6 +218,8 @@ Bug Fixes in This Version
   (`#65156 <https://github.com/llvm/llvm-project/issues/65156>`_)
 - Clang no longer considers the loss of ``__unaligned`` qualifier from objects as
   an invalid conversion during method function overload resolution.
+- Fix lack of comparison of declRefExpr in ASTStructuralEquivalence
+  (`#66047 <https://github.com/llvm/llvm-project/issues/66047>`_`)
 - Fix parser crash when dealing with ill-formed objective C++ header code. Fixes
   (`#64836 <https://github.com/llvm/llvm-project/issues/64836>`_)
 
diff --git a/clang/lib/AST/ASTStructuralEquivalence.cpp b/clang/lib/AST/ASTStructuralEquivalence.cpp
index 544420234ef0eb0..0f132b73c23b80b 100644
--- a/clang/lib/AST/ASTStructuralEquivalence.cpp
+++ b/clang/lib/AST/ASTStructuralEquivalence.cpp
@@ -214,6 +214,15 @@ class StmtComparer {
     return E1->size() == E2->size();
   }
 
+  bool IsStmtEquivalent(const DeclRefExpr *DRE1, const DeclRefExpr *DRE2) {
+    const ValueDecl *Decl1 = DRE1->getDecl();
+    const ValueDecl *Decl2 = DRE2->getDecl();
+    if (!Decl1 || !Decl2)
+      return false;
+    return IsStructurallyEquivalent(Context, const_cast<ValueDecl *>(Decl1),
+                                    const_cast<ValueDecl *>(Decl2));
+  }
+
   bool IsStmtEquivalent(const DependentScopeDeclRefExpr *DE1,
                         const DependentScopeDeclRefExpr *DE2) {
     if (!IsStructurallyEquivalent(Context, DE1->getDeclName(),
@@ -366,7 +375,8 @@ class StmtComparer {
     return true;
   }
 
-  bool IsStmtEquivalent(const CXXBoolLiteralExpr *E1, const CXXBoolLiteralExpr *E2) {
+  bool IsStmtEquivalent(const CXXBoolLiteralExpr *E1,
+                        const CXXBoolLiteralExpr *E2) {
     return E1->getValue() == E2->getValue();
   }
 
@@ -551,13 +561,12 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
            P1->getIndex() == P2->getIndex();
   }
 
-   case TemplateName::Template:
-   case TemplateName::QualifiedTemplate:
-   case TemplateName::SubstTemplateTemplateParm:
-   case TemplateName::UsingTemplate:
-     // It is sufficient to check value of getAsTemplateDecl.
-     break;
-
+  case TemplateName::Template:
+  case TemplateName::QualifiedTemplate:
+  case TemplateName::SubstTemplateTemplateParm:
+  case TemplateName::UsingTemplate:
+    // It is sufficient to check value of getAsTemplateDecl.
+    break;
   }
 
   return true;
@@ -579,18 +588,20 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
     return true;
 
   case TemplateArgument::Type:
-    return IsStructurallyEquivalent(Context, Arg1.getAsType(), Arg2.getAsType());
+    return IsStructurallyEquivalent(Context, Arg1.getAsType(),
+                                    Arg2.getAsType());
 
   case TemplateArgument::Integral:
     if (!IsStructurallyEquivalent(Context, Arg1.getIntegralType(),
-                                          Arg2.getIntegralType()))
+                                  Arg2.getIntegralType()))
       return false;
 
     return llvm::APSInt::isSameValue(Arg1.getAsIntegral(),
                                      Arg2.getAsIntegral());
 
   case TemplateArgument::Declaration:
-    return IsStructurallyEquivalent(Context, Arg1.getAsDecl(), Arg2.getAsDecl());
+    return IsStructurallyEquivalent(Context, Arg1.getAsDecl(),
+                                    Arg2.getAsDecl());
 
   case TemplateArgument::NullPtr:
     return true; // FIXME: Is this correct?
@@ -1402,8 +1413,8 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
   }
 
   // Check the prototypes.
-  if (!::IsStructurallyEquivalent(Context,
-                                  Method1->getType(), Method2->getType()))
+  if (!::IsStructurallyEquivalent(Context, Method1->getType(),
+                                  Method2->getType()))
     return false;
 
   return true;
@@ -1902,8 +1913,9 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
                                   D2->getTemplateParameters());
 }
 
-static bool IsTemplateDeclCommonStructurallyEquivalent(
-    StructuralEquivalenceContext &Ctx, TemplateDecl *D1, TemplateDecl *D2) {
+static bool
+IsTemplateDeclCommonStructurallyEquivalent(StructuralEquivalenceContext &Ctx,
+                                           TemplateDecl *D1, TemplateDecl *D2) {
   if (!IsStructurallyEquivalent(D1->getIdentifier(), D2->getIdentifier()))
     return false;
   if (!D1->getIdentifier()) // Special name
@@ -1938,8 +1950,7 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
 }
 
 static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
-                                     ConceptDecl *D1,
-                                     ConceptDecl *D2) {
+                                     ConceptDecl *D1, ConceptDecl *D2) {
   // Check template parameters.
   if (!IsTemplateDeclCommonStructurallyEquivalent(Context, D1, D2))
     return false;
@@ -1953,11 +1964,10 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
                                      FriendDecl *D1, FriendDecl *D2) {
   if ((D1->getFriendType() && D2->getFriendDecl()) ||
       (D1->getFriendDecl() && D2->getFriendType())) {
-      return false;
+    return false;
   }
   if (D1->getFriendType() && D2->getFriendType())
-    return IsStructurallyEquivalent(Context,
-                                    D1->getFriendType()->getType(),
+    return IsStructurallyEquivalent(Context, D1->getFriendType()->getType(),
                                     D2->getFriendType()->getType());
   if (D1->getFriendDecl() && D2->getFriendDecl())
     return IsStructurallyEquivalent(Context, D1->getFriendDecl(),
@@ -2303,8 +2313,8 @@ bool StructuralEquivalenceContext::CheckCommonEquivalence(Decl *D1, Decl *D2) {
   return true;
 }
 
-bool StructuralEquivalenceContext::CheckKindSpecificEquivalence(
-    Decl *D1, Decl *D2) {
+bool StructuralEquivalenceContext::CheckKindSpecificEquivalence(Decl *D1,
+                                                                Decl *D2) {
 
   // Kind mismatch.
   if (D1->getKind() != D2->getKind())
diff --git a/clang/unittests/AST/StructuralEquivalenceTest.cpp b/clang/unittests/AST/StructuralEquivalenceTest.cpp
index 4e9f476659b9ee6..5787fc5a6566617 100644
--- a/clang/unittests/AST/StructuralEquivalenceTest.cpp
+++ b/clang/unittests/AST/StructuralEquivalenceTest.cpp
@@ -2320,5 +2320,14 @@ TEST_F(StructuralEquivalenceStmtTest, UnresolvedLookup) {
   EXPECT_TRUE(testStructuralMatch(t));
 }
 
+TEST_F(StructuralEquivalenceStmtTest, DeclRefENoEq) {
+  std::string Prefix = "enum Test { AAA, BBB };";
+  auto t = makeStmts(
+      Prefix + "void foo(int i) {if (i > 0) {i = AAA;} else {i = BBB;}}",
+      Prefix + "void foo(int i) {if (i > 0) {i = BBB;} else {i = AAA;}}",
+      Lang_CXX03, ifStmt());
+  EXPECT_FALSE(testStructuralMatch(t));
+}
+
 } // end namespace ast_matchers
 } // end namespace clang



More information about the cfe-commits mailing list