r339730 - Fix Stmt::ignoreImplicit

Stephen Kelly via cfe-commits cfe-commits at lists.llvm.org
Tue Aug 14 14:33:28 PDT 2018


Author: steveire
Date: Tue Aug 14 14:33:28 2018
New Revision: 339730

URL: http://llvm.org/viewvc/llvm-project?rev=339730&view=rev
Log:
Fix Stmt::ignoreImplicit

Summary:
A CXXBindTemporaryExpr can appear inside an ImplicitCastExpr, and was
not ignored previously.

Fixes the case reported in PR37327.

Reviewers: rsmith, dblaikie, klimek

Subscribers: cfe-commits

Differential Revision: https://reviews.llvm.org/D50666

Modified:
    cfe/trunk/lib/AST/Stmt.cpp
    cfe/trunk/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp

Modified: cfe/trunk/lib/AST/Stmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Stmt.cpp?rev=339730&r1=339729&r2=339730&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Stmt.cpp (original)
+++ cfe/trunk/lib/AST/Stmt.cpp Tue Aug 14 14:33:28 2018
@@ -113,17 +113,23 @@ void Stmt::EnableStatistics() {
 Stmt *Stmt::IgnoreImplicit() {
   Stmt *s = this;
 
-  if (auto *ewc = dyn_cast<ExprWithCleanups>(s))
-    s = ewc->getSubExpr();
+  Stmt *lasts = nullptr;
 
-  if (auto *mte = dyn_cast<MaterializeTemporaryExpr>(s))
-    s = mte->GetTemporaryExpr();
+  while (s != lasts) {
+    lasts = s;
 
-  if (auto *bte = dyn_cast<CXXBindTemporaryExpr>(s))
-    s = bte->getSubExpr();
+    if (auto *ewc = dyn_cast<ExprWithCleanups>(s))
+      s = ewc->getSubExpr();
 
-  while (auto *ice = dyn_cast<ImplicitCastExpr>(s))
-    s = ice->getSubExpr();
+    if (auto *mte = dyn_cast<MaterializeTemporaryExpr>(s))
+      s = mte->GetTemporaryExpr();
+
+    if (auto *bte = dyn_cast<CXXBindTemporaryExpr>(s))
+      s = bte->getSubExpr();
+
+    if (auto *ice = dyn_cast<ImplicitCastExpr>(s))
+      s = ice->getSubExpr();
+  }
 
   return s;
 }

Modified: cfe/trunk/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp?rev=339730&r1=339729&r2=339730&view=diff
==============================================================================
--- cfe/trunk/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp (original)
+++ cfe/trunk/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp Tue Aug 14 14:33:28 2018
@@ -1321,6 +1321,45 @@ TEST(IgnoringImplicit, MatchesImplicit)
                       varDecl(has(ignoringImplicit(cxxConstructExpr())))));
 }
 
+TEST(IgnoringImplicit, MatchesNestedImplicit) {
+  EXPECT_TRUE(matches(R"(
+
+struct OtherType;
+
+struct SomeType
+{
+    SomeType() {}
+    SomeType(const OtherType&) {}
+    SomeType& operator=(OtherType const&) { return *this; }
+};
+
+struct OtherType
+{
+    OtherType() {}
+    ~OtherType() {}
+};
+
+OtherType something()
+{
+    return {};
+}
+
+int main()
+{
+    SomeType i = something();
+}
+)"
+  , varDecl(
+      hasName("i"),
+      hasInitializer(exprWithCleanups(has(
+        cxxConstructExpr(has(expr(ignoringImplicit(cxxConstructExpr(
+          has(expr(ignoringImplicit(callExpr())))
+          )))))
+        )))
+      )
+  ));
+}
+
 TEST(IgnoringImplicit, DoesNotMatchIncorrectly) {
   EXPECT_TRUE(
       notMatches("class C {}; C a = C();", varDecl(has(cxxConstructExpr()))));




More information about the cfe-commits mailing list