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
|
// start token of conditional code
|
||||||
Token* startTokens[] = {nullptr, nullptr};
|
Token* startTokens[] = {nullptr, nullptr};
|
||||||
|
|
||||||
bool inverted = false;
|
|
||||||
// if astParent is "!" we need to invert codeblock
|
// if astParent is "!" we need to invert codeblock
|
||||||
{
|
{
|
||||||
const Token* tok2 = tok;
|
const Token* tok2 = tok;
|
||||||
|
@ -4484,10 +4483,8 @@ struct ConditionHandler {
|
||||||
const Token* parent = tok2->astParent();
|
const Token* parent = tok2->astParent();
|
||||||
while (parent && parent->str() == "&&")
|
while (parent && parent->str() == "&&")
|
||||||
parent = parent->astParent();
|
parent = parent->astParent();
|
||||||
if (parent && (parent->str() == "!" || Token::simpleMatch(parent, "== false"))) {
|
if (parent && (parent->str() == "!" || Token::simpleMatch(parent, "== false")))
|
||||||
inverted = true;
|
|
||||||
std::swap(thenValues, elseValues);
|
std::swap(thenValues, elseValues);
|
||||||
}
|
|
||||||
tok2 = parent;
|
tok2 = parent;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4569,8 +4566,25 @@ struct ConditionHandler {
|
||||||
std::mem_fn(&ValueFlow::Value::isPossible));
|
std::mem_fn(&ValueFlow::Value::isPossible));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (values.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
if (dead_if || dead_else) {
|
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));
|
values.remove_if(std::mem_fn(&ValueFlow::Value::isImpossible));
|
||||||
changeKnownToPossible(values);
|
changeKnownToPossible(values);
|
||||||
} else {
|
} else {
|
||||||
|
@ -4578,7 +4592,8 @@ struct ConditionHandler {
|
||||||
valueFlowSetConditionToKnown(tok, values, false);
|
valueFlowSetConditionToKnown(tok, values, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!values.empty())
|
if (values.empty())
|
||||||
|
return;
|
||||||
forward(after, scope->bodyEnd, cond.vartok, values, tokenlist, settings);
|
forward(after, scope->bodyEnd, cond.vartok, values, tokenlist, settings);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5063,6 +5063,22 @@ private:
|
||||||
ASSERT_EQUALS("",
|
ASSERT_EQUALS("",
|
||||||
isKnownContainerSizeValue(tokenValues(code, "a . front", ValueFlow::Value::ValueType::CONTAINER_SIZE), 10));
|
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"
|
code = "void f(std::string str) {\n"
|
||||||
" if (str == \"123\") {\n"
|
" if (str == \"123\") {\n"
|
||||||
" bool x = (str == \"\");\n"
|
" bool x = (str == \"\");\n"
|
||||||
|
|
Loading…
Reference in New Issue