diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 4d93771e7..16dfc2725 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -7924,10 +7924,24 @@ static Token* findStartToken(const Variable* var, Token* start, const Library* l Token* first = uses.front(); if (Token::findmatch(start, "goto|asm|setjmp|longjmp", first)) return start; - const Scope* scope = first->scope(); - // If there is only one usage or the first usage is in the same scope - if (uses.size() == 1 || scope == var->scope()) + // If there is only one usage + if (uses.size() == 1) return first->previous(); + const Scope* scope = first->scope(); + // If first usage is in variable scope + if (scope == var->scope()) { + bool isLoopExpression = false; + for (const Token* parent = first; parent; parent = parent->astParent()) { + if (Token::simpleMatch(parent->astParent(), ";") && + Token::simpleMatch(parent->astParent()->astParent(), ";") && + Token::simpleMatch(parent->astParent()->astParent()->astParent(), "(") && + Token::simpleMatch(parent->astParent()->astParent()->astParent()->astOperand1(), "for (") && + parent == parent->astParent()->astParent()->astParent()->astOperand2()->astOperand2()->astOperand2()) { + isLoopExpression = true; + } + } + return isLoopExpression ? start : first->previous(); + } // If all uses are in the same scope if (std::all_of(uses.begin() + 1, uses.end(), [&](const Token* tok) { return tok->scope() == scope; diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index 6c1535558..17e4278d9 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -5392,7 +5392,7 @@ private: " int c;\n" " if (d)\n" " c = 0;\n" - " else if (e)\n" + " else if (e)\n" " c = 0;\n" " c++;\n" "}\n"; @@ -5406,7 +5406,7 @@ private: " int c;\n" " if (d)\n" " c = 0;\n" - " else if (!d)\n" + " else if (!d)\n" " c = 0;\n" " c++;\n" "}\n"; @@ -5510,6 +5510,15 @@ private: "}\n"; values = tokenValues(code, "i ++", ValueFlow::Value::ValueType::UNINIT); ASSERT_EQUALS(0, values.size()); + + // #11688 + code = "void f() {\n" + " int n;\n" + " for (int i = 0; i < 4; i = n)\n" // <- n is initialized in the loop body + " n = 10;\n" + "}"; + values = tokenValues(code, "n )", ValueFlow::Value::ValueType::UNINIT); + ASSERT_EQUALS(0, values.size()); } void valueFlowConditionExpressions() {