value flow: added bailouts for global variables and assignments
This commit is contained in:
parent
d618730c96
commit
c4fa3bb137
|
@ -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;
|
||||||
|
|
|
@ -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());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue