ValueFlow: Fixed valueFlowForward, when condition is false and else-block returns dont set values below the else-code
This commit is contained in:
parent
39fde3c8c7
commit
1f698ca493
|
@ -690,8 +690,15 @@ 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::simpleMatch(tok2->link()->previous(), ") {")) {
|
if (indentlevel == 0 && isReturn(tok2) && Token::Match(tok2->link()->previous(), "else|) {")) {
|
||||||
const Token *condition = tok2->link()->linkAt(-1)->astOperand2();
|
const Token *condition = tok2->link();
|
||||||
|
const bool iselse = Token::simpleMatch(condition->tokAt(-2), "} else {");
|
||||||
|
if (iselse)
|
||||||
|
condition = condition->linkAt(-2);
|
||||||
|
if (condition && Token::simpleMatch(condition->previous(), ") {"))
|
||||||
|
condition = condition->linkAt(-1)->astOperand2();
|
||||||
|
else
|
||||||
|
condition = nullptr;
|
||||||
if (!condition) {
|
if (!condition) {
|
||||||
if (settings->debugwarnings)
|
if (settings->debugwarnings)
|
||||||
bailout(tokenlist, errorLogger, tok2, "variable " + var->name() + " valueFlowForward, bailing out since it's unknown if conditional return is executed");
|
bailout(tokenlist, errorLogger, tok2, "variable " + var->name() + " valueFlowForward, bailing out since it's unknown if conditional return is executed");
|
||||||
|
@ -700,7 +707,11 @@ static bool valueFlowForward(Token * const startToken,
|
||||||
|
|
||||||
bool bailoutflag = false;
|
bool bailoutflag = false;
|
||||||
for (std::list<ValueFlow::Value>::const_iterator it = values.begin(); it != values.end(); ++it) {
|
for (std::list<ValueFlow::Value>::const_iterator it = values.begin(); it != values.end(); ++it) {
|
||||||
if (conditionIsTrue(condition, getProgramMemory(condition->astParent(), varid, *it))) {
|
if (!iselse && conditionIsTrue(condition, getProgramMemory(condition->astParent(), varid, *it))) {
|
||||||
|
bailoutflag = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (iselse && conditionIsFalse(condition, getProgramMemory(condition->astParent(), varid, *it))) {
|
||||||
bailoutflag = true;
|
bailoutflag = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1295,10 +1295,19 @@ private:
|
||||||
" if (x == 5) {\n"
|
" if (x == 5) {\n"
|
||||||
" panic();\n"
|
" panic();\n"
|
||||||
" }\n"
|
" }\n"
|
||||||
" a = x;\n"
|
" a = x;\n" // <- x can't be 5
|
||||||
"}";
|
"}";
|
||||||
ASSERT_EQUALS(false, testValueOfX(code, 7U, 5));
|
ASSERT_EQUALS(false, testValueOfX(code, 7U, 5));
|
||||||
|
|
||||||
|
code = "void f() {\n"
|
||||||
|
" int x;\n"
|
||||||
|
" for (x = 0; x < 5; x++) {}\n"
|
||||||
|
" if (x < 5) {}\n"
|
||||||
|
" else return;\n"
|
||||||
|
" a = x;\n" // <- x can't be 5
|
||||||
|
"}";
|
||||||
|
ASSERT_EQUALS(false, testValueOfX(code, 6U, 5));
|
||||||
|
|
||||||
// hang
|
// hang
|
||||||
code = "void f() {\n"
|
code = "void f() {\n"
|
||||||
" for(int i = 0; i < 20; i++)\n"
|
" for(int i = 0; i < 20; i++)\n"
|
||||||
|
|
Loading…
Reference in New Issue