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 *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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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()))));
|
||||||
|
|
Loading…
Reference in New Issue