Skip to content

Commit c547c9a

Browse files
committed
value flow: fixed fp when variable is used in for-loop condition
1 parent e45a2e2 commit c547c9a

2 files changed

Lines changed: 22 additions & 3 deletions

File tree

lib/valueflow.cpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -162,8 +162,9 @@ static void valueFlowBeforeCondition(TokenList *tokenlist, ErrorLogger *errorLog
162162
for (const Token *tok2 = tok; tok2; tok2 = tok2->previous()) {
163163
if (tok2->str() == ")")
164164
tok2 = tok2->link();
165-
else if (tok2->str() == "(") {
166-
if (Token::Match(tok2->previous(), "for|while (") && Token::Match(tok2->link(), ") {")) {
165+
166+
else if (tok2->str() == "(" && Token::simpleMatch(tok2->link(), ") {")) {
167+
if (Token::Match(tok2->previous(), "for|while (")) {
167168
const Token *start = tok2->link()->next();
168169
const Token *end = start->link();
169170
if (Token::findmatch(start,"++|--| %varid% ++|--|=",end,varid)) {
@@ -172,14 +173,19 @@ static void valueFlowBeforeCondition(TokenList *tokenlist, ErrorLogger *errorLog
172173
bailout(tokenlist, errorLogger, tok, "variable " + var->nameToken()->str() + " used in loop");
173174
}
174175
}
175-
// bailout..
176+
177+
// if,macro => bailout
176178
else if (Token::simpleMatch(tok2->previous(), "if (") && tok2->previous()->isExpandedMacro()) {
177179
varid = 0U;
178180
if (settings->debugwarnings)
179181
bailout(tokenlist, errorLogger, tok, "variable " + var->nameToken()->str() + ", condition is defined in macro");
180182
}
183+
181184
break;
182185
}
186+
187+
else if (Token::Match(tok2, "[{}]"))
188+
break;
183189
}
184190
if (varid == 0U)
185191
continue;

test/testvalueflow.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,19 @@ class TestValueFlow : public TestFixture {
177177
"}";
178178
ASSERT_EQUALS(false, testValueOfX(code, 2U, 37));
179179

180+
code = "void f(menu *x) {\n"
181+
" a = x->parent;\n"
182+
" for (i=0;(i<10) && (x!=0); i++) { x = x->next; }\n"
183+
"}";
184+
ASSERT_EQUALS(false, testValueOfX(code, 2U, 0));
185+
186+
code = "void f() {\n" // loop condition, x is assigned inside loop => dont use condition
187+
" vimmenu_T *x = pMenu->parent;\n"
188+
" for (index = 1; (index != itemIndex) && (pMenu != NULL); index++)\n"
189+
" pMenu = pMenu->next;\n"
190+
"}";
191+
ASSERT_EQUALS(false, testValueOfX(code, 2U, 0));
192+
180193
code = "void f(int x) {\n" // condition inside loop, x is NOT assigned inside loop => use condition
181194
" a = x;\n"
182195
" do {\n"

0 commit comments

Comments
 (0)