mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-02-03 16:03:21 +00:00
[ASTMatchers] Avoid pathological traversal over nested lambdas
Differential Revision: https://reviews.llvm.org/D95573
This commit is contained in:
parent
39ecfe6143
commit
6f0df3cddb
@ -186,6 +186,9 @@ public:
|
||||
/// code, e.g., implicit constructors and destructors.
|
||||
bool shouldVisitImplicitCode() const { return false; }
|
||||
|
||||
/// Return whether this visitor should recurse into lambda body
|
||||
bool shouldVisitLambdaBody() const { return true; }
|
||||
|
||||
/// Return whether this visitor should traverse post-order.
|
||||
bool shouldTraversePostOrder() const { return false; }
|
||||
|
||||
@ -2057,6 +2060,14 @@ bool RecursiveASTVisitor<Derived>::TraverseFunctionHelper(FunctionDecl *D) {
|
||||
// by clang.
|
||||
(!D->isDefaulted() || getDerived().shouldVisitImplicitCode());
|
||||
|
||||
if (const auto *MD = dyn_cast<CXXMethodDecl>(D)) {
|
||||
if (const CXXRecordDecl *RD = MD->getParent()) {
|
||||
if (RD->isLambda()) {
|
||||
VisitBody = VisitBody && getDerived().shouldVisitLambdaBody();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (VisitBody) {
|
||||
TRY_TO(TraverseStmt(D->getBody())); // Function body.
|
||||
}
|
||||
|
@ -556,9 +556,9 @@ public:
|
||||
if (LE->hasExplicitResultType())
|
||||
TraverseTypeLoc(Proto.getReturnLoc());
|
||||
TraverseStmt(LE->getTrailingRequiresClause());
|
||||
|
||||
TraverseStmt(LE->getBody());
|
||||
}
|
||||
|
||||
TraverseStmt(LE->getBody());
|
||||
return true;
|
||||
}
|
||||
return RecursiveASTVisitor<MatchASTVisitor>::dataTraverseNode(S, Queue);
|
||||
@ -697,6 +697,10 @@ public:
|
||||
bool shouldVisitTemplateInstantiations() const { return true; }
|
||||
bool shouldVisitImplicitCode() const { return true; }
|
||||
|
||||
// We visit the lambda body explicitly, so instruct the RAV
|
||||
// to not visit it on our behalf too.
|
||||
bool shouldVisitLambdaBody() const { return false; }
|
||||
|
||||
bool IsMatchingInASTNodeNotSpelledInSource() const override {
|
||||
return TraversingASTNodeNotSpelledInSource;
|
||||
}
|
||||
|
@ -3853,6 +3853,78 @@ void binop()
|
||||
}
|
||||
}
|
||||
|
||||
TEST(IgnoringImpCasts, PathologicalLambda) {
|
||||
|
||||
// Test that deeply nested lambdas are not a performance penalty
|
||||
StringRef Code = R"cpp(
|
||||
void f() {
|
||||
[] {
|
||||
[] {
|
||||
[] {
|
||||
[] {
|
||||
[] {
|
||||
[] {
|
||||
[] {
|
||||
[] {
|
||||
[] {
|
||||
[] {
|
||||
[] {
|
||||
[] {
|
||||
[] {
|
||||
[] {
|
||||
[] {
|
||||
[] {
|
||||
[] {
|
||||
[] {
|
||||
[] {
|
||||
[] {
|
||||
[] {
|
||||
[] {
|
||||
[] {
|
||||
[] {
|
||||
[] {
|
||||
[] {
|
||||
[] {
|
||||
[] {
|
||||
[] {
|
||||
int i = 42;
|
||||
(void)i;
|
||||
}();
|
||||
}();
|
||||
}();
|
||||
}();
|
||||
}();
|
||||
}();
|
||||
}();
|
||||
}();
|
||||
}();
|
||||
}();
|
||||
}();
|
||||
}();
|
||||
}();
|
||||
}();
|
||||
}();
|
||||
}();
|
||||
}();
|
||||
}();
|
||||
}();
|
||||
}();
|
||||
}();
|
||||
}();
|
||||
}();
|
||||
}();
|
||||
}();
|
||||
}();
|
||||
}();
|
||||
}();
|
||||
}();
|
||||
}
|
||||
)cpp";
|
||||
|
||||
EXPECT_TRUE(matches(Code, integerLiteral(equals(42))));
|
||||
EXPECT_TRUE(matches(Code, functionDecl(hasDescendant(integerLiteral(equals(42))))));
|
||||
}
|
||||
|
||||
TEST(IgnoringImpCasts, MatchesImpCasts) {
|
||||
// This test checks that ignoringImpCasts matches when implicit casts are
|
||||
// present and its inner matcher alone does not match.
|
||||
|
Loading…
x
Reference in New Issue
Block a user