summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
Diffstat (limited to 'clang')
-rw-r--r--clang/lib/AST/Stmt.cpp22
-rw-r--r--clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp39
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()))));
OpenPOWER on IntegriCloud