Fix 10678: FP nullPointerArithmeticRedundantCheck in while loop (#3674)

This commit is contained in:
Paul Fultz II 2022-01-04 14:19:45 -06:00 committed by GitHub
parent fe077fc141
commit 1682344a80
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 23 additions and 2 deletions

View File

@ -354,9 +354,8 @@ void ProgramMemoryState::replace(const ProgramMemory &pm, const Token* origin)
state.replace(pm); state.replace(pm);
} }
void ProgramMemoryState::addState(const Token* tok, const ProgramMemory::Map& vars) static void addVars(ProgramMemory& pm, const ProgramMemory::Map& vars)
{ {
ProgramMemory pm = state;
for (const auto& p:vars) { for (const auto& p:vars) {
nonneg int exprid = p.first; nonneg int exprid = p.first;
const ValueFlow::Value &value = p.second; const ValueFlow::Value &value = p.second;
@ -364,9 +363,16 @@ void ProgramMemoryState::addState(const Token* tok, const ProgramMemory::Map& va
if (value.varId) if (value.varId)
pm.setIntValue(value.varId, value.varvalue); pm.setIntValue(value.varId, value.varvalue);
} }
}
void ProgramMemoryState::addState(const Token* tok, const ProgramMemory::Map& vars)
{
ProgramMemory pm = state;
addVars(pm, vars);
fillProgramMemoryFromConditions(pm, tok, settings); fillProgramMemoryFromConditions(pm, tok, settings);
ProgramMemory local = pm; ProgramMemory local = pm;
fillProgramMemoryFromAssignments(pm, tok, local, vars); fillProgramMemoryFromAssignments(pm, tok, local, vars);
addVars(pm, vars);
replace(pm, tok); replace(pm, tok);
} }

View File

@ -133,6 +133,8 @@ struct ReverseTraversal {
} }
if (tok != parent->astOperand2()) if (tok != parent->astOperand2())
continue; continue;
if (Token::simpleMatch(parent, ":"))
parent = parent->astParent();
if (!Token::Match(parent, "%oror%|&&|?")) if (!Token::Match(parent, "%oror%|&&|?"))
continue; continue;
Token* condTok = parent->astOperand1(); Token* condTok = parent->astOperand1();

View File

@ -130,6 +130,7 @@ private:
TEST_CASE(nullpointer88); // #9949 TEST_CASE(nullpointer88); // #9949
TEST_CASE(nullpointer89); // #10640 TEST_CASE(nullpointer89); // #10640
TEST_CASE(nullpointer90); // #6098 TEST_CASE(nullpointer90); // #6098
TEST_CASE(nullpointer91); // #10678
TEST_CASE(nullpointer_addressOf); // address of TEST_CASE(nullpointer_addressOf); // address of
TEST_CASE(nullpointerSwitch); // #2626 TEST_CASE(nullpointerSwitch); // #2626
TEST_CASE(nullpointer_cast); // #4692 TEST_CASE(nullpointer_cast); // #4692
@ -2666,6 +2667,18 @@ private:
errout.str()); errout.str());
} }
void nullpointer91() // #10678
{
check("void f(const char* PBeg, const char* PEnd) {\n"
" while (PEnd != nullptr) {\n"
" const int N = h(PEnd);\n"
" PEnd = g();\n"
" const int Length = PEnd == nullptr ? 0 : PEnd - PBeg;\n"
" };\n"
"}\n");
ASSERT_EQUALS("", errout.str());
}
void nullpointer_addressOf() { // address of void nullpointer_addressOf() { // address of
check("void f() {\n" check("void f() {\n"
" struct X *x = 0;\n" " struct X *x = 0;\n"