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;
|
continue;
|
||||||
std::list<ValueFlow::Value> values = tok->astOperand2()->values;
|
std::list<ValueFlow::Value> values = tok->astOperand2()->values;
|
||||||
|
|
||||||
|
const bool constValue = tok->astOperand2()->isNumber();
|
||||||
|
int indentlevel = 0;
|
||||||
unsigned int number_of_if = 0;
|
unsigned int number_of_if = 0;
|
||||||
|
int varusagelevel = -1;
|
||||||
|
|
||||||
for (Token *tok2 = tok; tok2 && tok2 != endToken; tok2 = tok2->next()) {
|
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 ("))
|
if (Token::Match(tok2, "sizeof|typeof|typeid ("))
|
||||||
tok2 = tok2->linkAt(1);
|
tok2 = tok2->linkAt(1);
|
||||||
|
|
||||||
// conditional block of code that assigns variable..
|
// 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 start = tok2->linkAt(1)->next();
|
||||||
Token * const end = start->link();
|
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
|
// TODO: don't check noreturn scopes
|
||||||
if (number_of_if > 0U || Token::findmatch(tok2, "%varid%", start, varid)) {
|
if (number_of_if > 0U || Token::findmatch(tok2, "%varid%", start, varid)) {
|
||||||
if (settings->debugwarnings)
|
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;
|
++number_of_if;
|
||||||
|
|
||||||
// Set "conditional" flag for all values
|
// Set "conditional" flag for all values
|
||||||
|
@ -594,6 +594,16 @@ private:
|
|||||||
"}";
|
"}";
|
||||||
TODO_ASSERT_EQUALS(true, false, testValueOfX(code, 4U, 32));
|
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
|
code = "void f() {\n" // #5656 - FP
|
||||||
" int x = 0;\n"
|
" int x = 0;\n"
|
||||||
" if (!x) {\n"
|
" if (!x) {\n"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user