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

llvm-svn: 339730
This commit is contained in:
Stephen Kelly 2018-08-14 21:33:28 +00:00
parent 1f65600873
commit 0945c8b942
2 changed files with 53 additions and 8 deletions

View File

@ -113,17 +113,23 @@ void Stmt::EnableStatistics() {
Stmt *Stmt::IgnoreImplicit() { Stmt *Stmt::IgnoreImplicit() {
Stmt *s = this; Stmt *s = this;
if (auto *ewc = dyn_cast<ExprWithCleanups>(s)) Stmt *lasts = nullptr;
s = ewc->getSubExpr();
if (auto *mte = dyn_cast<MaterializeTemporaryExpr>(s)) while (s != lasts) {
s = mte->GetTemporaryExpr(); lasts = s;
if (auto *bte = dyn_cast<CXXBindTemporaryExpr>(s)) if (auto *ewc = dyn_cast<ExprWithCleanups>(s))
s = bte->getSubExpr(); s = ewc->getSubExpr();
while (auto *ice = dyn_cast<ImplicitCastExpr>(s)) if (auto *mte = dyn_cast<MaterializeTemporaryExpr>(s))
s = ice->getSubExpr(); 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; return s;
} }

View File

@ -1321,6 +1321,45 @@ TEST(IgnoringImplicit, MatchesImplicit) {
varDecl(has(ignoringImplicit(cxxConstructExpr()))))); 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) { TEST(IgnoringImplicit, DoesNotMatchIncorrectly) {
EXPECT_TRUE( EXPECT_TRUE(
notMatches("class C {}; C a = C();", varDecl(has(cxxConstructExpr())))); notMatches("class C {}; C a = C();", varDecl(has(cxxConstructExpr()))));