Fix #11688 (FP uninitvar in for loop iteration expression) (#5140)

This commit is contained in:
Daniel Marjamäki 2023-06-10 09:58:08 +02:00 committed by GitHub
parent 7e0f64688f
commit 3c8caac772
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 28 additions and 5 deletions

View File

@ -7924,10 +7924,24 @@ static Token* findStartToken(const Variable* var, Token* start, const Library* l
Token* first = uses.front(); Token* first = uses.front();
if (Token::findmatch(start, "goto|asm|setjmp|longjmp", first)) if (Token::findmatch(start, "goto|asm|setjmp|longjmp", first))
return start; return start;
const Scope* scope = first->scope(); // If there is only one usage
// If there is only one usage or the first usage is in the same scope if (uses.size() == 1)
if (uses.size() == 1 || scope == var->scope())
return first->previous(); 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 all uses are in the same scope
if (std::all_of(uses.begin() + 1, uses.end(), [&](const Token* tok) { if (std::all_of(uses.begin() + 1, uses.end(), [&](const Token* tok) {
return tok->scope() == scope; return tok->scope() == scope;

View File

@ -5510,6 +5510,15 @@ private:
"}\n"; "}\n";
values = tokenValues(code, "i ++", ValueFlow::Value::ValueType::UNINIT); values = tokenValues(code, "i ++", ValueFlow::Value::ValueType::UNINIT);
ASSERT_EQUALS(0, values.size()); 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() { void valueFlowConditionExpressions() {