From c547c9a108bcd68dfe0dec501bc76f920d6975f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Tue, 14 Jan 2014 17:57:50 +0100 Subject: [PATCH] value flow: fixed fp when variable is used in for-loop condition --- lib/valueflow.cpp | 12 +++++++++--- test/testvalueflow.cpp | 13 +++++++++++++ 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index a8a2e5326..51a70bd3b 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -162,8 +162,9 @@ static void valueFlowBeforeCondition(TokenList *tokenlist, ErrorLogger *errorLog for (const Token *tok2 = tok; tok2; tok2 = tok2->previous()) { if (tok2->str() == ")") tok2 = tok2->link(); - else if (tok2->str() == "(") { - if (Token::Match(tok2->previous(), "for|while (") && Token::Match(tok2->link(), ") {")) { + + else if (tok2->str() == "(" && Token::simpleMatch(tok2->link(), ") {")) { + if (Token::Match(tok2->previous(), "for|while (")) { const Token *start = tok2->link()->next(); const Token *end = start->link(); if (Token::findmatch(start,"++|--| %varid% ++|--|=",end,varid)) { @@ -172,14 +173,19 @@ static void valueFlowBeforeCondition(TokenList *tokenlist, ErrorLogger *errorLog bailout(tokenlist, errorLogger, tok, "variable " + var->nameToken()->str() + " used in loop"); } } - // bailout.. + + // if,macro => bailout else if (Token::simpleMatch(tok2->previous(), "if (") && tok2->previous()->isExpandedMacro()) { varid = 0U; if (settings->debugwarnings) bailout(tokenlist, errorLogger, tok, "variable " + var->nameToken()->str() + ", condition is defined in macro"); } + break; } + + else if (Token::Match(tok2, "[{}]")) + break; } if (varid == 0U) continue; diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index d06f476ac..537101621 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -177,6 +177,19 @@ private: "}"; ASSERT_EQUALS(false, testValueOfX(code, 2U, 37)); + code = "void f(menu *x) {\n" + " a = x->parent;\n" + " for (i=0;(i<10) && (x!=0); i++) { x = x->next; }\n" + "}"; + ASSERT_EQUALS(false, testValueOfX(code, 2U, 0)); + + code = "void f() {\n" // loop condition, x is assigned inside loop => dont use condition + " vimmenu_T *x = pMenu->parent;\n" + " for (index = 1; (index != itemIndex) && (pMenu != NULL); index++)\n" + " pMenu = pMenu->next;\n" + "}"; + ASSERT_EQUALS(false, testValueOfX(code, 2U, 0)); + code = "void f(int x) {\n" // condition inside loop, x is NOT assigned inside loop => use condition " a = x;\n" " do {\n"