Fix 11850: false negative: knownConditionTrueFalse with std::string::empty() after modification (#5307)

This commit is contained in:
Paul Fultz II 2023-08-09 13:33:44 -05:00 committed by GitHub
parent 4e8c240129
commit 24479c60f9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 33 additions and 0 deletions

View File

@ -8806,6 +8806,29 @@ static void valueFlowContainerSize(TokenList& tokenlist,
value.setImpossible(); value.setImpossible();
valueFlowForward(tok->linkAt(2), containerTok, value, tokenlist, settings); valueFlowForward(tok->linkAt(2), containerTok, value, tokenlist, settings);
} }
} else if (Token::simpleMatch(tok, "+=") && astIsContainer(tok->astOperand1())) {
const Token* containerTok = tok->astOperand1();
const Token* valueTok = tok->astOperand2();
MathLib::bigint size = 0;
if (valueTok->tokType() == Token::eString)
size = Token::getStrLength(valueTok);
else if (astIsGenericChar(tok) || valueTok->tokType() == Token::eChar)
size = 1;
else if (const ValueFlow::Value* v1 = valueTok->getKnownValue(ValueFlow::Value::ValueType::TOK))
size = Token::getStrLength(v1->tokvalue);
else if (const ValueFlow::Value* v2 =
valueTok->getKnownValue(ValueFlow::Value::ValueType::CONTAINER_SIZE))
size = v2->intvalue;
if (size == 0)
continue;
ValueFlow::Value value(size - 1);
value.valueType = ValueFlow::Value::ValueType::CONTAINER_SIZE;
value.bound = ValueFlow::Value::Bound::Lower;
value.setImpossible();
Token* next = nextAfterAstRightmostLeaf(tok);
if (!next)
next = tok->next();
valueFlowForward(next, containerTok, value, tokenlist, settings);
} }
} }
} }

View File

@ -5013,6 +5013,16 @@ private:
" if(!s.empty()) {}\n" " if(!s.empty()) {}\n"
"}\n"); "}\n");
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
check("int f(std::string s) {\n"
" if (s.empty())\n"
" return -1;\n"
" s += '\\n';\n"
" if (s.empty())\n"
" return -1;\n"
" return -1;\n"
"}\n");
ASSERT_EQUALS("[test.cpp:5]: (style) Condition 's.empty()' is always false\n", errout.str());
} }
void alwaysTrueLoop() void alwaysTrueLoop()