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;
|
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)
|
void programMemoryParseCondition(ProgramMemory& pm, const Token* tok, const Token* endTok, const Settings* settings, bool then)
|
||||||
{
|
{
|
||||||
auto eval = [&](const Token* t) -> std::vector<MathLib::bigint> {
|
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 (tok2->str() == "{") {
|
||||||
if (indentlevel <= 0) {
|
if (indentlevel <= 0) {
|
||||||
// Keep progressing with anonymous/do scopes
|
const Token* cond = getCondTokFromEnd(tok2->link());
|
||||||
if (!Token::Match(tok2->previous(), "do|; {"))
|
// Keep progressing with anonymous/do scopes and always true branches
|
||||||
|
if (!Token::Match(tok2->previous(), "do|; {") && !conditionIsTrue(cond, state) &&
|
||||||
|
(cond || !isBasicForLoop(tok2)))
|
||||||
break;
|
break;
|
||||||
} else
|
} else
|
||||||
--indentlevel;
|
--indentlevel;
|
||||||
|
|
|
@ -104,6 +104,7 @@ private:
|
||||||
TEST_CASE(valueFlowForwardTryCatch);
|
TEST_CASE(valueFlowForwardTryCatch);
|
||||||
TEST_CASE(valueFlowForwardInconclusiveImpossible);
|
TEST_CASE(valueFlowForwardInconclusiveImpossible);
|
||||||
TEST_CASE(valueFlowForwardConst);
|
TEST_CASE(valueFlowForwardConst);
|
||||||
|
TEST_CASE(valueFlowForwardAfterCondition);
|
||||||
|
|
||||||
TEST_CASE(valueFlowFwdAnalysis);
|
TEST_CASE(valueFlowFwdAnalysis);
|
||||||
|
|
||||||
|
@ -3685,6 +3686,56 @@ private:
|
||||||
ASSERT_EQUALS(true, testValueOfXKnown(code, 8U, 3));
|
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() {
|
void valueFlowRightShift() {
|
||||||
const char *code;
|
const char *code;
|
||||||
/* Set some temporary fixed values to simplify testing */
|
/* Set some temporary fixed values to simplify testing */
|
||||||
|
|
Loading…
Reference in New Issue