Skip to content

Commit 3c8caac

Browse files
authored
Fix #11688 (FP uninitvar in for loop iteration expression) (danmar#5140)
1 parent 7e0f646 commit 3c8caac

2 files changed

Lines changed: 28 additions & 5 deletions

File tree

lib/valueflow.cpp

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7924,10 +7924,24 @@ static Token* findStartToken(const Variable* var, Token* start, const Library* l
79247924
Token* first = uses.front();
79257925
if (Token::findmatch(start, "goto|asm|setjmp|longjmp", first))
79267926
return start;
7927-
const Scope* scope = first->scope();
7928-
// If there is only one usage or the first usage is in the same scope
7929-
if (uses.size() == 1 || scope == var->scope())
7927+
// If there is only one usage
7928+
if (uses.size() == 1)
79307929
return first->previous();
7930+
const Scope* scope = first->scope();
7931+
// If first usage is in variable scope
7932+
if (scope == var->scope()) {
7933+
bool isLoopExpression = false;
7934+
for (const Token* parent = first; parent; parent = parent->astParent()) {
7935+
if (Token::simpleMatch(parent->astParent(), ";") &&
7936+
Token::simpleMatch(parent->astParent()->astParent(), ";") &&
7937+
Token::simpleMatch(parent->astParent()->astParent()->astParent(), "(") &&
7938+
Token::simpleMatch(parent->astParent()->astParent()->astParent()->astOperand1(), "for (") &&
7939+
parent == parent->astParent()->astParent()->astParent()->astOperand2()->astOperand2()->astOperand2()) {
7940+
isLoopExpression = true;
7941+
}
7942+
}
7943+
return isLoopExpression ? start : first->previous();
7944+
}
79317945
// If all uses are in the same scope
79327946
if (std::all_of(uses.begin() + 1, uses.end(), [&](const Token* tok) {
79337947
return tok->scope() == scope;

test/testvalueflow.cpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5392,7 +5392,7 @@ class TestValueFlow : public TestFixture {
53925392
" int c;\n"
53935393
" if (d)\n"
53945394
" c = 0;\n"
5395-
" else if (e)\n"
5395+
" else if (e)\n"
53965396
" c = 0;\n"
53975397
" c++;\n"
53985398
"}\n";
@@ -5406,7 +5406,7 @@ class TestValueFlow : public TestFixture {
54065406
" int c;\n"
54075407
" if (d)\n"
54085408
" c = 0;\n"
5409-
" else if (!d)\n"
5409+
" else if (!d)\n"
54105410
" c = 0;\n"
54115411
" c++;\n"
54125412
"}\n";
@@ -5510,6 +5510,15 @@ class TestValueFlow : public TestFixture {
55105510
"}\n";
55115511
values = tokenValues(code, "i ++", ValueFlow::Value::ValueType::UNINIT);
55125512
ASSERT_EQUALS(0, values.size());
5513+
5514+
// #11688
5515+
code = "void f() {\n"
5516+
" int n;\n"
5517+
" for (int i = 0; i < 4; i = n)\n" // <- n is initialized in the loop body
5518+
" n = 10;\n"
5519+
"}";
5520+
values = tokenValues(code, "n )", ValueFlow::Value::ValueType::UNINIT);
5521+
ASSERT_EQUALS(0, values.size());
55135522
}
55145523

55155524
void valueFlowConditionExpressions() {

0 commit comments

Comments
 (0)