Fixed #5752 (FP (error) Possible null pointer dereference)
This commit is contained in:
parent
45ac1db175
commit
fadc27092e
@ -28,6 +28,11 @@
|
|||||||
#include <stack>
|
#include <stack>
|
||||||
|
|
||||||
|
|
||||||
|
static void execute(const Token *expr,
|
||||||
|
std::map<unsigned int, MathLib::bigint> * const programMemory,
|
||||||
|
MathLib::bigint *result,
|
||||||
|
bool *error);
|
||||||
|
|
||||||
//static void printvalues(const Token *tok)
|
//static void printvalues(const Token *tok)
|
||||||
//{
|
//{
|
||||||
// if (tok->values.empty())
|
// if (tok->values.empty())
|
||||||
@ -100,6 +105,29 @@ static bool bailoutFunctionPar(const Token *tok, const ValueFlow::Value &value,
|
|||||||
return arg && !arg->isConst() && arg->isReference();
|
return arg && !arg->isConst() && arg->isReference();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is condition always false when variable has given value?
|
||||||
|
* \param condition top ast token in condition
|
||||||
|
* \param varid variable id for variable
|
||||||
|
* \param value value of variable
|
||||||
|
*/
|
||||||
|
static bool conditionIsFalse(const Token *condition, unsigned int varid, const ValueFlow::Value &value)
|
||||||
|
{
|
||||||
|
if (!condition)
|
||||||
|
return false;
|
||||||
|
if (condition->str() == "&&") {
|
||||||
|
bool result1 = conditionIsFalse(condition->astOperand1(), varid, value);
|
||||||
|
bool result2 = result1 ? true : conditionIsFalse(condition->astOperand2(), varid, value);
|
||||||
|
return result2;
|
||||||
|
}
|
||||||
|
std::map<unsigned int, MathLib::bigint> programMemory;
|
||||||
|
programMemory[varid] = value.intvalue;
|
||||||
|
MathLib::bigint result = 0;
|
||||||
|
bool error = false;
|
||||||
|
execute(condition, &programMemory, &result, &error);
|
||||||
|
return !error && result == 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Should value be skipped because it's hidden inside && || or ?: expression.
|
* Should value be skipped because it's hidden inside && || or ?: expression.
|
||||||
* Example: ((x!=NULL) && (*x == 123))
|
* Example: ((x!=NULL) && (*x == 123))
|
||||||
@ -552,6 +580,22 @@ static void valueFlowAfterAssign(TokenList *tokenlist, ErrorLogger *errorLogger,
|
|||||||
|
|
||||||
// conditional block of code that assigns variable..
|
// conditional block of code that assigns variable..
|
||||||
else if (Token::Match(tok2, "%var% (") && Token::simpleMatch(tok2->linkAt(1), ") {")) {
|
else if (Token::Match(tok2, "%var% (") && Token::simpleMatch(tok2->linkAt(1), ") {")) {
|
||||||
|
// Should scope be skipped because variable value is checked?
|
||||||
|
bool skip = false;
|
||||||
|
for (std::list<ValueFlow::Value>::iterator it = values.begin(); it != values.end(); ++it) {
|
||||||
|
if (conditionIsFalse(tok2->next()->astOperand2(), varid, *it)) {
|
||||||
|
skip = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (skip) {
|
||||||
|
// goto '{'
|
||||||
|
tok2 = tok2->linkAt(1)->next();
|
||||||
|
// goto '}'
|
||||||
|
tok2 = tok2->link();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
Token * const start = tok2->linkAt(1)->next();
|
Token * const start = tok2->linkAt(1)->next();
|
||||||
Token * const end = start->link();
|
Token * const end = start->link();
|
||||||
bool varusage = (indentlevel >= 0 && constValue && number_of_if == 0U) ?
|
bool varusage = (indentlevel >= 0 && constValue && number_of_if == 0U) ?
|
||||||
|
@ -655,6 +655,14 @@ private:
|
|||||||
"}";
|
"}";
|
||||||
ASSERT_EQUALS(false, testValueOfX(code, 7U, 0));
|
ASSERT_EQUALS(false, testValueOfX(code, 7U, 0));
|
||||||
|
|
||||||
|
code = "void f() {\n" // #5752 - FP
|
||||||
|
" int *x = 0;\n"
|
||||||
|
" if (x && *x == 123) {\n"
|
||||||
|
" getx(*x);\n"
|
||||||
|
" }\n"
|
||||||
|
"}";
|
||||||
|
ASSERT_EQUALS(false, testValueOfX(code, 4U, 0));
|
||||||
|
|
||||||
// multivariables
|
// multivariables
|
||||||
code = "void f(int a) {\n"
|
code = "void f(int a) {\n"
|
||||||
" int x = a;\n"
|
" int x = a;\n"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user