From c4fa3bb137bd230020d45dd1ddaa9ff9690c29aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Mon, 6 Jan 2014 07:44:58 +0100 Subject: [PATCH] value flow: added bailouts for global variables and assignments --- lib/valueflow.cpp | 22 ++++++++++++++++++++++ test/testvalueflow.cpp | 29 +++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 257f9c077..99db24499 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -24,6 +24,14 @@ #include "token.h" #include "tokenlist.h" +static void bailout(TokenList *tokenlist, ErrorLogger *errorLogger, const Token *tok, const std::string &what) +{ + std::list callstack; + callstack.push_back(ErrorLogger::ErrorMessage::FileLocation(tok,tokenlist)); + ErrorLogger::ErrorMessage errmsg(callstack, Severity::debug, "ValueFlow bailout: " + what, "valueFlowBailout", false); + errorLogger->reportErr(errmsg); +} + static void valueFlowBeforeCondition(TokenList *tokenlist, ErrorLogger *errorLogger, const Settings *settings) { for (Token *tok = tokenlist->front(); tok; tok = tok->next()) { @@ -58,6 +66,13 @@ static void valueFlowBeforeCondition(TokenList *tokenlist, ErrorLogger *errorLog if (varid == 0U) continue; + // bailout: global variables + if (var && var->isGlobal()) { + if (settings->debugwarnings) + bailout(tokenlist, errorLogger, tok, "global variable " + var->nameToken()->str()); + continue; + } + struct ValueFlow::Value val; val.condition = tok; val.intvalue = num; @@ -74,6 +89,13 @@ static void valueFlowBeforeCondition(TokenList *tokenlist, ErrorLogger *errorLog } if (tok2->varId() == varid) { + // bailout: assignment + if (Token::Match(tok2, "%var% =")) { + if (settings->debugwarnings) + bailout(tokenlist, errorLogger, tok2, "assignment of " + tok2->str()); + continue; + } + tok2->values.push_back(val); if (var && tok2 == var->nameToken()) break; diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index b12e4eefd..06eb58da1 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -60,12 +60,41 @@ private: return false; } + + void bailout(const char code[]) { + Settings settings; + settings.valueFlow = true; // temporary flag + settings.debugwarnings = true; + + // Tokenize.. + Tokenizer tokenizer(&settings, this); + std::istringstream istr(code); + errout.str(""); + tokenizer.tokenize(istr, "test.cpp"); + } + + void valueFlowBeforeCondition() { const char code[] = "void f(int x) {\n" " int a = x;\n" " if (x == 123) {}\n" "}"; ASSERT_EQUALS(true, testValueOfX(code, 2U, 123)); + + // bailout: assignment + bailout("void f(int x) {\n" + " x = y;\n" + " if (x == 123) {}\n" + "}"); + ASSERT_EQUALS("[test.cpp:2]: (debug) ValueFlow bailout: assignment of x\n", errout.str()); + + // bailout: global variables + bailout("int x;\n" + "void f() {\n" + " int a = x;\n" + " if (x == 123) {}\n" + "}"); + ASSERT_EQUALS("[test.cpp:4]: (debug) ValueFlow bailout: global variable x\n", errout.str()); } };