This revision was automatically updated to reflect the committed changes. Closed by commit rL339730: Fix Stmt::ignoreImplicit (authored by steveire, committed by ). Herald added a subscriber: llvm-commits.
Repository: rL LLVM https://reviews.llvm.org/D50666 Files: cfe/trunk/lib/AST/Stmt.cpp cfe/trunk/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp Index: cfe/trunk/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp =================================================================== --- cfe/trunk/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp +++ cfe/trunk/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp @@ -1321,6 +1321,45 @@ 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())))); Index: cfe/trunk/lib/AST/Stmt.cpp =================================================================== --- cfe/trunk/lib/AST/Stmt.cpp +++ cfe/trunk/lib/AST/Stmt.cpp @@ -113,17 +113,23 @@ 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; }
Index: cfe/trunk/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp =================================================================== --- cfe/trunk/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp +++ cfe/trunk/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp @@ -1321,6 +1321,45 @@ 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())))); Index: cfe/trunk/lib/AST/Stmt.cpp =================================================================== --- cfe/trunk/lib/AST/Stmt.cpp +++ cfe/trunk/lib/AST/Stmt.cpp @@ -113,17 +113,23 @@ 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; }
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits