Fixed #6973 (ValueFlow: dont set possible tokvalues in unreachable code)

This commit is contained in:
Daniel Marjamäki 2015-12-01 07:49:19 +01:00
parent f762affea0
commit 508b06abaa
2 changed files with 33 additions and 7 deletions

View File

@ -1727,6 +1727,10 @@ static void execute(const Token *expr,
if (!expr)
*error = true;
else if (expr->values.size() == 1U && expr->values.front().isKnown() && !expr->values.front().tokvalue) {
*result = expr->values.front().intvalue;
}
else if (expr->isNumber()) {
*result = MathLib::toLongNumber(expr->str());
if (MathLib::isFloat(expr->str()))
@ -1838,16 +1842,22 @@ static void execute(const Token *expr,
}
else if (expr->str() == "[" && expr->astOperand1() && expr->astOperand2()) {
if (expr->astOperand1()->values.size() != 1U) {
const Token *tokvalue = nullptr;
std::map<unsigned int, const Token *>::iterator var = programMemory->tokvalues.find(expr->astOperand1()->varId());
if (var != programMemory->tokvalues.end()) {
tokvalue = var->second;
} else {
if (expr->astOperand1()->values.size() != 1U) {
*error = true;
return;
}
tokvalue = expr->astOperand1()->values.front().tokvalue;
}
if (!tokvalue || !tokvalue->isLiteral()) {
*error = true;
return;
}
const ValueFlow::Value val = expr->astOperand1()->values.front();
if (!val.tokvalue || !val.tokvalue->isLiteral()) {
*error = true;
return;
}
const std::string strValue = val.tokvalue->strValue();
const std::string strValue = tokvalue->strValue();
MathLib::bigint index = 0;
execute(expr->astOperand2(), programMemory, &index, error);
if (index >= 0 && index < strValue.size())

View File

@ -820,6 +820,22 @@ private:
"}";
ASSERT_EQUALS(false, testValueOfX(code, 4U, "\"\""));
code = "void f() {\n" // #6973
" char *x = getenv (\"LC_ALL\");\n"
" if (x == NULL)\n"
" x = \"\";\n"
"\n"
" if ( (x[0] == 'U') &&\n" // x can be ""
" (x[1] ?\n" // x can't be ""
" x[3] :\n" // x can't be ""
" x[2] ))\n" // x can't be ""
" {}\n"
"}\n";
ASSERT_EQUALS(true, testValueOfX(code, 6U, "\"\""));
ASSERT_EQUALS(false, testValueOfX(code, 7U, "\"\""));
ASSERT_EQUALS(false, testValueOfX(code, 8U, "\"\""));
ASSERT_EQUALS(false, testValueOfX(code, 9U, "\"\""));
// if/else
code = "void f() {\n"
" int x = 123;\n"