diff options
Diffstat (limited to 'clang')
| -rw-r--r-- | clang/lib/AST/Stmt.cpp | 22 | ||||
| -rw-r--r-- | clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp | 39 |
2 files changed, 53 insertions, 8 deletions
diff --git a/clang/lib/AST/Stmt.cpp b/clang/lib/AST/Stmt.cpp index 5fce6332af6..6ed71fd6733 100644 --- a/clang/lib/AST/Stmt.cpp +++ b/clang/lib/AST/Stmt.cpp @@ -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; } diff --git a/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp index 443b0588ca7..52ab54467e5 100644 --- a/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp +++ b/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp @@ -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())))); |

