value flow: added bailouts for global variables and assignments

This commit is contained in:
Daniel Marjamäki 2014-01-06 07:44:58 +01:00
parent d618730c96
commit c4fa3bb137
2 changed files with 51 additions and 0 deletions

View File

@ -24,6 +24,14 @@
#include "token.h" #include "token.h"
#include "tokenlist.h" #include "tokenlist.h"
static void bailout(TokenList *tokenlist, ErrorLogger *errorLogger, const Token *tok, const std::string &what)
{
std::list<ErrorLogger::ErrorMessage::FileLocation> 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) static void valueFlowBeforeCondition(TokenList *tokenlist, ErrorLogger *errorLogger, const Settings *settings)
{ {
for (Token *tok = tokenlist->front(); tok; tok = tok->next()) { for (Token *tok = tokenlist->front(); tok; tok = tok->next()) {
@ -58,6 +66,13 @@ static void valueFlowBeforeCondition(TokenList *tokenlist, ErrorLogger *errorLog
if (varid == 0U) if (varid == 0U)
continue; 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; struct ValueFlow::Value val;
val.condition = tok; val.condition = tok;
val.intvalue = num; val.intvalue = num;
@ -74,6 +89,13 @@ static void valueFlowBeforeCondition(TokenList *tokenlist, ErrorLogger *errorLog
} }
if (tok2->varId() == varid) { 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); tok2->values.push_back(val);
if (var && tok2 == var->nameToken()) if (var && tok2 == var->nameToken())
break; break;

View File

@ -60,12 +60,41 @@ private:
return false; 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() { void valueFlowBeforeCondition() {
const char code[] = "void f(int x) {\n" const char code[] = "void f(int x) {\n"
" int a = x;\n" " int a = x;\n"
" if (x == 123) {}\n" " if (x == 123) {}\n"
"}"; "}";
ASSERT_EQUALS(true, testValueOfX(code, 2U, 123)); 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());
} }
}; };