Fix 11056: FP uninitvar with known condition in loop (#4107)
* Fix 11056: FP uninitvar with known condition in loop * Format
This commit is contained in:
parent
6d3208ecb0
commit
5f9bee9b91
|
@ -232,6 +232,25 @@ static bool frontIs(const std::vector<MathLib::bigint>& v, bool i)
|
|||
return !i;
|
||||
}
|
||||
|
||||
// If the scope is a non-range for loop
|
||||
static bool isBasicForLoop(const Token* tok)
|
||||
{
|
||||
if (!tok)
|
||||
return false;
|
||||
if (Token::simpleMatch(tok, "}"))
|
||||
return isBasicForLoop(tok->link());
|
||||
if (!Token::simpleMatch(tok->previous(), ") {"))
|
||||
return false;
|
||||
const Token* start = tok->linkAt(-1);
|
||||
if (!start)
|
||||
return false;
|
||||
if (!Token::simpleMatch(start->previous(), "for ("))
|
||||
return false;
|
||||
if (!Token::simpleMatch(start->astOperand2(), ";"))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void programMemoryParseCondition(ProgramMemory& pm, const Token* tok, const Token* endTok, const Settings* settings, bool then)
|
||||
{
|
||||
auto eval = [&](const Token* t) -> std::vector<MathLib::bigint> {
|
||||
|
@ -343,8 +362,10 @@ static void fillProgramMemoryFromAssignments(ProgramMemory& pm, const Token* tok
|
|||
|
||||
if (tok2->str() == "{") {
|
||||
if (indentlevel <= 0) {
|
||||
// Keep progressing with anonymous/do scopes
|
||||
if (!Token::Match(tok2->previous(), "do|; {"))
|
||||
const Token* cond = getCondTokFromEnd(tok2->link());
|
||||
// Keep progressing with anonymous/do scopes and always true branches
|
||||
if (!Token::Match(tok2->previous(), "do|; {") && !conditionIsTrue(cond, state) &&
|
||||
(cond || !isBasicForLoop(tok2)))
|
||||
break;
|
||||
} else
|
||||
--indentlevel;
|
||||
|
|
|
@ -104,6 +104,7 @@ private:
|
|||
TEST_CASE(valueFlowForwardTryCatch);
|
||||
TEST_CASE(valueFlowForwardInconclusiveImpossible);
|
||||
TEST_CASE(valueFlowForwardConst);
|
||||
TEST_CASE(valueFlowForwardAfterCondition);
|
||||
|
||||
TEST_CASE(valueFlowFwdAnalysis);
|
||||
|
||||
|
@ -3685,6 +3686,56 @@ private:
|
|||
ASSERT_EQUALS(true, testValueOfXKnown(code, 8U, 3));
|
||||
}
|
||||
|
||||
void valueFlowForwardAfterCondition()
|
||||
{
|
||||
const char* code;
|
||||
|
||||
code = "int g();\n"
|
||||
"void f() {\n"
|
||||
" int x = 3;\n"
|
||||
" int kk = 11;\n"
|
||||
" for (;;) {\n"
|
||||
" if (kk > 10) {\n"
|
||||
" kk = 0;\n"
|
||||
" x = g();\n"
|
||||
" }\n"
|
||||
" kk++;\n"
|
||||
" int a = x;\n"
|
||||
" }\n"
|
||||
"}\n";
|
||||
ASSERT_EQUALS(false, testValueOfX(code, 11U, 3));
|
||||
|
||||
code = "int g();\n"
|
||||
"void f() {\n"
|
||||
" int x = 3;\n"
|
||||
" int kk = 11;\n"
|
||||
" while (true) {\n"
|
||||
" if (kk > 10) {\n"
|
||||
" kk = 0;\n"
|
||||
" x = g();\n"
|
||||
" }\n"
|
||||
" kk++;\n"
|
||||
" int a = x;\n"
|
||||
" }\n"
|
||||
"}\n";
|
||||
ASSERT_EQUALS(false, testValueOfX(code, 11U, 3));
|
||||
|
||||
code = "int g();\n"
|
||||
"void f() {\n"
|
||||
" int x = 3;\n"
|
||||
" int kk = 11;\n"
|
||||
" if (true) {\n"
|
||||
" if (kk > 10) {\n"
|
||||
" kk = 0;\n"
|
||||
" x = g();\n"
|
||||
" }\n"
|
||||
" kk++;\n"
|
||||
" int a = x;\n"
|
||||
" }\n"
|
||||
"}\n";
|
||||
ASSERT_EQUALS(false, testValueOfX(code, 11U, 3));
|
||||
}
|
||||
|
||||
void valueFlowRightShift() {
|
||||
const char *code;
|
||||
/* Set some temporary fixed values to simplify testing */
|
||||
|
|
Loading…
Reference in New Issue