ValueFlow: Improved analysis in the valueFlowAfterAssign
This commit is contained in:
parent
2c3807f089
commit
fe80f858d1
|
@ -527,17 +527,30 @@ static void valueFlowAfterAssign(TokenList *tokenlist, ErrorLogger *errorLogger,
|
|||
continue;
|
||||
std::list<ValueFlow::Value> values = tok->astOperand2()->values;
|
||||
|
||||
const bool constValue = tok->astOperand2()->isNumber();
|
||||
int indentlevel = 0;
|
||||
unsigned int number_of_if = 0;
|
||||
int varusagelevel = -1;
|
||||
|
||||
for (Token *tok2 = tok; tok2 && tok2 != endToken; tok2 = tok2->next()) {
|
||||
if (indentlevel >= 0 && tok2->str() == "{")
|
||||
++indentlevel;
|
||||
else if (indentlevel >= 0 && tok2->str() == "}")
|
||||
--indentlevel;
|
||||
|
||||
if (Token::Match(tok2, "sizeof|typeof|typeid ("))
|
||||
tok2 = tok2->linkAt(1);
|
||||
|
||||
// conditional block of code that assigns variable..
|
||||
if (Token::Match(tok2, "%var% (") && Token::simpleMatch(tok2->linkAt(1), ") {")) {
|
||||
else if (Token::Match(tok2, "%var% (") && Token::simpleMatch(tok2->linkAt(1), ") {")) {
|
||||
Token * const start = tok2->linkAt(1)->next();
|
||||
Token * const end = start->link();
|
||||
if (Token::findmatch(start, "%varid%", end, varid)) {
|
||||
bool varusage = (indentlevel >= 0 && constValue && number_of_if == 0U) ?
|
||||
isVariableChanged(start,end,varid) :
|
||||
(nullptr != Token::findmatch(start, "%varid%", end, varid));
|
||||
if (varusage) {
|
||||
varusagelevel = indentlevel;
|
||||
|
||||
// TODO: don't check noreturn scopes
|
||||
if (number_of_if > 0U || Token::findmatch(tok2, "%varid%", start, varid)) {
|
||||
if (settings->debugwarnings)
|
||||
|
@ -586,7 +599,7 @@ static void valueFlowAfterAssign(TokenList *tokenlist, ErrorLogger *errorLogger,
|
|||
}
|
||||
}
|
||||
|
||||
else if (tok2->str() == "}") {
|
||||
else if (tok2->str() == "}" && indentlevel == varusagelevel) {
|
||||
++number_of_if;
|
||||
|
||||
// Set "conditional" flag for all values
|
||||
|
|
|
@ -594,6 +594,16 @@ private:
|
|||
"}";
|
||||
TODO_ASSERT_EQUALS(true, false, testValueOfX(code, 4U, 32));
|
||||
|
||||
code = "void f() {\n"
|
||||
" int x = 32;\n"
|
||||
" if (a==1) { z=x+12; }\n"
|
||||
" if (a==2) { z=x+32; }\n"
|
||||
" z = x;\n"
|
||||
"}";
|
||||
ASSERT_EQUALS(true, testValueOfX(code, 3U, 32));
|
||||
ASSERT_EQUALS(true, testValueOfX(code, 4U, 32));
|
||||
ASSERT_EQUALS(true, testValueOfX(code, 5U, 32));
|
||||
|
||||
code = "void f() {\n" // #5656 - FP
|
||||
" int x = 0;\n"
|
||||
" if (!x) {\n"
|
||||
|
|
Loading…
Reference in New Issue