From 5c3b69fe966f8c764874f6842ed5fb0d07992ad6 Mon Sep 17 00:00:00 2001 From: Paul Fultz II Date: Sat, 25 Sep 2021 04:55:49 -0500 Subject: [PATCH] Fix 10496: crash: endless recursion (symbolDatabaseCreateExprId => isSameExpr => isSameExpr ...) (#3467) --- lib/astutils.cpp | 8 +++++--- test/testtokenize.cpp | 9 +++++++++ 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/lib/astutils.cpp b/lib/astutils.cpp index cdf5e9d26..f2f0f10d1 100644 --- a/lib/astutils.cpp +++ b/lib/astutils.cpp @@ -169,9 +169,9 @@ bool astHasToken(const Token* root, const Token * tok) { if (!root) return false; - if (root == tok) - return true; - return astHasToken(root->astOperand1(), tok) || astHasToken(root->astOperand2(), tok); + while (tok->astParent() && tok != root) + tok = tok->astParent(); + return root == tok; } bool astHasVar(const Token * tok, nonneg int varid) @@ -833,6 +833,8 @@ std::vector followAllReferences(const Token* tok, errors.emplace_back(var->declEndToken(), "Passed to reference."); return {{tok, std::move(errors)}}; } else if (Token::simpleMatch(var->declEndToken(), "=")) { + if (astHasToken(var->declEndToken(), tok)) + return std::vector{}; errors.emplace_back(var->declEndToken(), "Assigned to reference."); const Token *vartok = var->declEndToken()->astOperand2(); if (vartok == tok || (!temporary && isTemporary(true, vartok, nullptr, true) && diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index ed3e89f9a..7dde244b1 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -409,6 +409,7 @@ private: TEST_CASE(checkIfCppCast); TEST_CASE(checkRefQualifiers); TEST_CASE(checkConditionBlock); + TEST_CASE(checkUnknownCircularVar); // #9052 TEST_CASE(noCrash1); @@ -6845,6 +6846,14 @@ private: "}\n")); } + void checkUnknownCircularVar() + { + ASSERT_NO_THROW(tokenizeAndStringify("void execute() {\n" + " const auto &bias = GEMM_CTX_ARG_STORAGE(bias);\n" + " auto &c = GEMM_CTX_ARG_STORAGE(c);\n" + "}\n")); + } + void noCrash1() { ASSERT_NO_THROW(tokenizeAndStringify( "struct A {\n"