Fix 10409: FP 'Condition 's.size()<3' is always false' (#3396)

This commit is contained in:
Paul Fultz II 2021-08-13 23:48:38 -05:00 committed by GitHub
parent 4f8b1b2f20
commit b9ac48c90a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 22 additions and 4 deletions

View File

@ -4500,8 +4500,10 @@ struct ConditionHandler {
std::list<ValueFlow::Value> true_values; std::list<ValueFlow::Value> true_values;
std::list<ValueFlow::Value> false_values; std::list<ValueFlow::Value> false_values;
bool inverted = false; bool inverted = false;
// Whether to insert impossible values for the condition or only use possible values
bool impossible = true;
Condition() : vartok(nullptr), true_values(), false_values(), inverted(false) {} Condition() : vartok(nullptr), true_values(), false_values(), inverted(false), impossible(true) {}
}; };
virtual Analyzer::Result forward(Token* start, virtual Analyzer::Result forward(Token* start,
@ -4680,12 +4682,12 @@ struct ConditionHandler {
if (!Token::Match(tok, "!=|=|(|.") && tok != cond.vartok) { if (!Token::Match(tok, "!=|=|(|.") && tok != cond.vartok) {
thenValues.insert(thenValues.end(), cond.true_values.begin(), cond.true_values.end()); thenValues.insert(thenValues.end(), cond.true_values.begin(), cond.true_values.end());
if (isConditionKnown(tok, false)) if (cond.impossible && isConditionKnown(tok, false))
insertImpossible(elseValues, cond.false_values); insertImpossible(elseValues, cond.false_values);
} }
if (!Token::Match(tok, "==|!")) { if (!Token::Match(tok, "==|!")) {
elseValues.insert(elseValues.end(), cond.false_values.begin(), cond.false_values.end()); elseValues.insert(elseValues.end(), cond.false_values.begin(), cond.false_values.end());
if (isConditionKnown(tok, true)) { if (cond.impossible && isConditionKnown(tok, true)) {
insertImpossible(thenValues, cond.true_values); insertImpossible(thenValues, cond.true_values);
if (tok == cond.vartok && astIsBool(tok)) if (tok == cond.vartok && astIsBool(tok))
insertNegateKnown(thenValues, cond.true_values); insertNegateKnown(thenValues, cond.true_values);
@ -6734,6 +6736,7 @@ struct ContainerConditionHandler : ConditionHandler {
cond.false_values.emplace_back(value); cond.false_values.emplace_back(value);
cond.true_values.emplace_back(std::move(value)); cond.true_values.emplace_back(std::move(value));
cond.vartok = vartok; cond.vartok = vartok;
cond.impossible = false;
return {cond}; return {cond};
} }
return {}; return {};

View File

@ -3969,6 +3969,21 @@ private:
" }\n" " }\n"
"};\n"); "};\n");
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
// #10409
check("void foo(const std::string& s) {\n"
" if( s.size() < 2 ) return;\n"
" if( s == \"ab\" ) return;\n"
" if( s.size() < 3 ) return;\n"
"}\n");
ASSERT_EQUALS("", errout.str());
check("void foo(const std::string& s) {\n"
" if( s.size() < 2 ) return;\n"
" if( s != \"ab\" )\n"
" if( s.size() < 3 ) return;\n"
"}\n");
ASSERT_EQUALS("", errout.str());
} }
void multiConditionAlwaysTrue() { void multiConditionAlwaysTrue() {

View File

@ -4990,7 +4990,7 @@ private:
" if (s != \"hello\")\n" " if (s != \"hello\")\n"
" s[40] = c;\n" " s[40] = c;\n"
"}"; "}";
ASSERT_EQUALS("", isImpossibleContainerSizeValue(tokenValues(code, "s ["), 5)); ASSERT(!isImpossibleContainerSizeValue(tokenValues(code, "s ["), 5).empty());
code = "void f() {\n" code = "void f() {\n"
" static std::string s;\n" " static std::string s;\n"