From 13761927ffadc77c16afec11812ab3e6d05cf338 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Wed, 18 Jun 2014 06:57:48 +0200 Subject: [PATCH] ValueFlow: better analysis in valueFlowAfterCondition of 'if|while ( %var% )' etc --- lib/valueflow.cpp | 13 +++++++++++-- test/testvalueflow.cpp | 10 ++++++++++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 7bcb1fff5..e0946d304 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -780,14 +780,23 @@ static void valueFlowAfterCondition(TokenList *tokenlist, ErrorLogger *errorLogg } if (!vartok->isName() || !numtok->isNumber()) continue; + } else if (tok->str() == "!") { vartok = tok->astOperand1(); numtok = nullptr; if (!vartok || !vartok->isName()) continue; + + } else if (tok->isName() && + (Token::Match(tok->astParent(), "%oror%|&&") || + Token::Match(tok->tokAt(-2), "if|while ( %var% )"))) { + vartok = tok; + numtok = nullptr; + } else { continue; } + const unsigned int varid = vartok->varId(); if (varid == 0U) continue; @@ -821,11 +830,11 @@ static void valueFlowAfterCondition(TokenList *tokenlist, ErrorLogger *errorLogg Token *startToken = nullptr; if (Token::Match(tok, "==|>=|<=|!") && Token::simpleMatch(top->link(), ") {")) startToken = top->link()->next(); - else if (tok->str() == "!=" && Token::simpleMatch(top->link()->linkAt(1), "} else {")) + else if (Token::Match(tok, "%var%|!=") && Token::simpleMatch(top->link()->linkAt(1), "} else {")) startToken = top->link()->linkAt(1)->tokAt(2); bool ok = true; if (startToken) - ok &= valueFlowForward(startToken->next(), startToken->link(), var, varid, values, true, tokenlist, errorLogger, settings); + ok = valueFlowForward(startToken->next(), startToken->link(), var, varid, values, true, tokenlist, errorLogger, settings); // After conditional code.. if (ok && !scopeEnd.empty() && Token::simpleMatch(top->link(), ") {")) { diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index 7d3e31802..59de3827c 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -761,6 +761,16 @@ private: "}"; ASSERT_EQUALS(true, testValueOfX(code, 2U, 0)); + // if (var) + code = "void f(int x) {\n" + " if (x) { a = x; }\n" // <- x is not 0 + " else { b = x; }\n" // <- x is 0 + " c = x;\n" // <- x might be 0 + "}"; + ASSERT_EQUALS(false, testValueOfX(code, 2U, 0)); + ASSERT_EQUALS(true, testValueOfX(code, 3U, 0)); + ASSERT_EQUALS(true, testValueOfX(code, 4U, 0)); + // After while code = "void f(int x) {\n" " while (x != 3) {}\n"