diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 1cbf76877..ca49fa001 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -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::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()) diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index 60a9cae16..751a83bb7 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -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"