Fixed #6239 (Possible null pointer dereference after pointer is modified by a function template)

This commit is contained in:
Daniel Marjamäki 2015-10-27 12:33:46 +01:00
parent b775603e93
commit 4b0625c570
2 changed files with 17 additions and 3 deletions

View File

@ -1146,13 +1146,16 @@ static bool valueFlowForward(Token * const startToken,
} }
} }
const Token * const condTok = tok2->next()->astOperand2();
const bool condAlwaysTrue = (condTok && condTok->values.size() == 1U && condTok->values.front().isKnown() && condTok->values.front().intvalue != 0);
// Should scope be skipped because variable value is checked? // Should scope be skipped because variable value is checked?
std::list<ValueFlow::Value> truevalues; std::list<ValueFlow::Value> truevalues;
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 (!conditionIsFalse(tok2->next()->astOperand2(), getProgramMemory(tok2, varid, *it))) if (condAlwaysTrue || !conditionIsFalse(condTok, getProgramMemory(tok2, varid, *it)))
truevalues.push_back(*it); truevalues.push_back(*it);
} }
if (truevalues.size() != values.size()) { if (truevalues.size() != values.size() || condAlwaysTrue) {
// '{' // '{'
Token * const startToken1 = tok2->linkAt(1)->next(); Token * const startToken1 = tok2->linkAt(1)->next();
@ -1171,6 +1174,10 @@ static bool valueFlowForward(Token * const startToken,
// goto '}' // goto '}'
tok2 = startToken1->link(); tok2 = startToken1->link();
if (condAlwaysTrue && isReturn(tok2))
return false;
continue; continue;
} }

View File

@ -829,11 +829,18 @@ private:
code = "void f() {\n" code = "void f() {\n"
" X *x = getx();\n" " X *x = getx();\n"
" if(false) { x = 0; }\n" " if(0) { x = 0; }\n"
" else { x->y = 1; }\n" " else { x->y = 1; }\n"
"}"; "}";
ASSERT_EQUALS(false, testValueOfX(code, 4U, 0)); ASSERT_EQUALS(false, testValueOfX(code, 4U, 0));
code = "void f() {\n" // #6239
" int x = 4;\n"
" if(1) { x = 0; }\n"
" a = x;\n"
"}";
ASSERT_EQUALS(false, testValueOfX(code, 4U, 4));
code = "void f() {\n" code = "void f() {\n"
" int x = 32;\n" " int x = 32;\n"
" if (x>=32) return;\n" " if (x>=32) return;\n"