ValueFlow: improved handling of conditional noreturn scope in valueFlowForward
This commit is contained in:
parent
d952c3d74d
commit
eee9183406
|
@ -690,7 +690,7 @@ static bool valueFlowForward(Token * const startToken,
|
||||||
++indentlevel;
|
++indentlevel;
|
||||||
else if (indentlevel >= 0 && tok2->str() == "}") {
|
else if (indentlevel >= 0 && tok2->str() == "}") {
|
||||||
--indentlevel;
|
--indentlevel;
|
||||||
if (indentlevel == 0 && isReturn(tok2) && Token::Match(tok2->link()->previous(), "else|) {")) {
|
if (indentlevel <= 0 && isReturn(tok2) && Token::Match(tok2->link()->previous(), "else|) {")) {
|
||||||
const Token *condition = tok2->link();
|
const Token *condition = tok2->link();
|
||||||
const bool iselse = Token::simpleMatch(condition->tokAt(-2), "} else {");
|
const bool iselse = Token::simpleMatch(condition->tokAt(-2), "} else {");
|
||||||
if (iselse)
|
if (iselse)
|
||||||
|
@ -830,6 +830,19 @@ static bool valueFlowForward(Token * const startToken,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// stop after conditional noreturn scopes that are executed
|
||||||
|
if (isReturn(end)) {
|
||||||
|
std::list<ValueFlow::Value>::iterator it;
|
||||||
|
for (it = values.begin(); it != values.end();) {
|
||||||
|
if (conditionIsTrue(tok2->next()->astOperand2(), getProgramMemory(tok2, varid, *it)))
|
||||||
|
values.erase(it++);
|
||||||
|
else
|
||||||
|
it++;
|
||||||
|
}
|
||||||
|
if (values.empty())
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// noreturn scopes..
|
// noreturn scopes..
|
||||||
if ((number_of_if > 0 || Token::findmatch(tok2, "%varid%", start, varid)) &&
|
if ((number_of_if > 0 || Token::findmatch(tok2, "%varid%", start, varid)) &&
|
||||||
(Token::findmatch(start, "return|continue|break|throw", end) ||
|
(Token::findmatch(start, "return|continue|break|throw", end) ||
|
||||||
|
|
|
@ -816,6 +816,18 @@ private:
|
||||||
"}";
|
"}";
|
||||||
ASSERT_EQUALS(true, testValueOfX(code, 5U, 2));
|
ASSERT_EQUALS(true, testValueOfX(code, 5U, 2));
|
||||||
|
|
||||||
|
code = "void f(int mode) {\n"
|
||||||
|
" struct ABC *x;\n"
|
||||||
|
"\n"
|
||||||
|
" if (mode) { x = &y; }\n"
|
||||||
|
" else { x = NULL; }\n"
|
||||||
|
"\n"
|
||||||
|
" if (!x) exit(1);\n"
|
||||||
|
"\n"
|
||||||
|
" a = x->a;\n" // <- x can't be 0
|
||||||
|
"}";
|
||||||
|
ASSERT_EQUALS(false, testValueOfX(code, 9U, 0));
|
||||||
|
|
||||||
// multivariables
|
// multivariables
|
||||||
code = "void f(int a) {\n"
|
code = "void f(int a) {\n"
|
||||||
" int x = a;\n"
|
" int x = a;\n"
|
||||||
|
|
Loading…
Reference in New Issue