forked from OSchip/llvm-project
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:
parent
1f65600873
commit
0945c8b942
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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()))));
|
||||
|
|
Loading…
Reference in New Issue