Fix issue 10088: ValueFlow: Array size, wrong known value (#3204)
This commit is contained in:
parent
1e9687aa8b
commit
255f273c46
|
@ -4476,7 +4476,6 @@ struct ConditionHandler {
|
|||
// start token of conditional code
|
||||
Token* startTokens[] = {nullptr, nullptr};
|
||||
|
||||
bool inverted = false;
|
||||
// if astParent is "!" we need to invert codeblock
|
||||
{
|
||||
const Token* tok2 = tok;
|
||||
|
@ -4484,10 +4483,8 @@ struct ConditionHandler {
|
|||
const Token* parent = tok2->astParent();
|
||||
while (parent && parent->str() == "&&")
|
||||
parent = parent->astParent();
|
||||
if (parent && (parent->str() == "!" || Token::simpleMatch(parent, "== false"))) {
|
||||
inverted = true;
|
||||
if (parent && (parent->str() == "!" || Token::simpleMatch(parent, "== false")))
|
||||
std::swap(thenValues, elseValues);
|
||||
}
|
||||
tok2 = parent;
|
||||
}
|
||||
}
|
||||
|
@ -4569,8 +4566,25 @@ struct ConditionHandler {
|
|||
std::mem_fn(&ValueFlow::Value::isPossible));
|
||||
}
|
||||
|
||||
if (values.empty())
|
||||
return;
|
||||
|
||||
if (dead_if || dead_else) {
|
||||
if (!inverted && Token::Match(tok->astParent(), "&&|&")) {
|
||||
const Token* parent = tok->astParent();
|
||||
// Skip the not operator
|
||||
while (Token::simpleMatch(parent, "!"))
|
||||
parent = parent->astParent();
|
||||
bool possible = false;
|
||||
if (Token::Match(parent, "&&|%oror%")) {
|
||||
std::string op = parent->str();
|
||||
while (parent && parent->str() == op)
|
||||
parent = parent->astParent();
|
||||
if (Token::simpleMatch(parent, "!") || Token::simpleMatch(parent, "== false"))
|
||||
possible = op == "||";
|
||||
else
|
||||
possible = op == "&&";
|
||||
}
|
||||
if (possible) {
|
||||
values.remove_if(std::mem_fn(&ValueFlow::Value::isImpossible));
|
||||
changeKnownToPossible(values);
|
||||
} else {
|
||||
|
@ -4578,7 +4592,8 @@ struct ConditionHandler {
|
|||
valueFlowSetConditionToKnown(tok, values, false);
|
||||
}
|
||||
}
|
||||
if (!values.empty())
|
||||
if (values.empty())
|
||||
return;
|
||||
forward(after, scope->bodyEnd, cond.vartok, values, tokenlist, settings);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5063,6 +5063,22 @@ private:
|
|||
ASSERT_EQUALS("",
|
||||
isKnownContainerSizeValue(tokenValues(code, "a . front", ValueFlow::Value::ValueType::CONTAINER_SIZE), 10));
|
||||
|
||||
code = "int f(const std::vector<int>& x) {\n"
|
||||
" if (!x.empty() && x[0] == 0)\n"
|
||||
" return 2;\n"
|
||||
" return x.front();\n"
|
||||
"}\n";
|
||||
ASSERT_EQUALS("",
|
||||
isPossibleContainerSizeValue(tokenValues(code, "x . front", ValueFlow::Value::ValueType::CONTAINER_SIZE), 0));
|
||||
|
||||
code = "int f(const std::vector<int>& x) {\n"
|
||||
" if (!(x.empty() || x[0] != 0))\n"
|
||||
" return 2;\n"
|
||||
" return x.front();\n"
|
||||
"}\n";
|
||||
ASSERT_EQUALS("",
|
||||
isPossibleContainerSizeValue(tokenValues(code, "x . front", ValueFlow::Value::ValueType::CONTAINER_SIZE), 0));
|
||||
|
||||
code = "void f(std::string str) {\n"
|
||||
" if (str == \"123\") {\n"
|
||||
" bool x = (str == \"\");\n"
|
||||
|
|
Loading…
Reference in New Issue