diff --git a/lib/astutils.cpp b/lib/astutils.cpp index 7fd1ba3c3..f6dcccf5e 100644 --- a/lib/astutils.cpp +++ b/lib/astutils.cpp @@ -174,10 +174,7 @@ static const Token * followVariableExpression(const Token * tok, bool cpp, const if (tok->astParent() && tok->isUnaryOp("*")) return tok; // Skip following variables if it is used in an assignment - if (Token::Match(tok->astTop(), "%assign%") || Token::Match(tok->next(), "%assign%")) - return tok; - // Skip references - if (Token::Match(tok->astTop(), "& %var% ;") && Token::Match(tok->astTop()->astOperand1(), "%type%")) + if (Token::Match(tok->next(), "%assign%")) return tok; const Variable * var = tok->variable(); const Token * varTok = getVariableInitExpression(var); @@ -197,7 +194,7 @@ static const Token * followVariableExpression(const Token * tok, bool cpp, const const Token * lastTok = precedes(tok, end) ? end : tok; // If this is in a loop then check if variables are modified in the entire scope const Token * endToken = (isInLoopCondition(tok) || isInLoopCondition(varTok) || var->scope() != tok->scope()) ? var->scope()->bodyEnd : lastTok; - if (!var->isConst() && isVariableChanged(varTok, endToken, tok->varId(), false, nullptr, cpp)) + if (!var->isConst() && (!precedes(varTok, endToken) || isVariableChanged(varTok, endToken, tok->varId(), false, nullptr, cpp))) return tok; // Start at beginning of initialization const Token * startToken = varTok; @@ -223,7 +220,7 @@ static const Token * followVariableExpression(const Token * tok, bool cpp, const return tok; if (var2->isStatic() && !var2->isConst()) return tok; - if (!var2->isConst() && isVariableChanged(tok2, endToken2, tok2->varId(), false, nullptr, cpp)) + if (!var2->isConst() && (!precedes(tok2, endToken2) || isVariableChanged(tok2, endToken2, tok2->varId(), false, nullptr, cpp))) return tok; // Recognized as a variable but the declaration is unknown } else if (tok2->varId() > 0) { diff --git a/test/testgarbage.cpp b/test/testgarbage.cpp index e7ff80dcd..3b8da0507 100644 --- a/test/testgarbage.cpp +++ b/test/testgarbage.cpp @@ -229,6 +229,7 @@ private: TEST_CASE(garbageCode196); // #8265 TEST_CASE(garbageCode197); // #8385 TEST_CASE(garbageCode198); // #8383 + TEST_CASE(garbageCode199); // #8752 TEST_CASE(garbageCodeFuzzerClientMode1); // test cases created with the fuzzer client, mode 1 @@ -1540,6 +1541,11 @@ private: "}"), InternalError); } + // #8752 + void garbageCode199() { + checkCode("d f(){e n00e0[]n00e0&""0+f=0}"); + } + void syntaxErrorFirstToken() { ASSERT_THROW(checkCode("&operator(){[]};"), InternalError); // #7818 ASSERT_THROW(checkCode("*(*const<> (size_t); foo) { } *(*const (size_t)() ; foo) { }"), InternalError); // #6858