valueFlowContainerSize: Fix wrong value after condition if conditional code escapes
This commit is contained in:
parent
1f427eda8f
commit
6008bbdfb4
|
@ -3465,7 +3465,7 @@ static void valueFlowContainerForward(const Token *tok, unsigned int containerId
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void valueFlowContainerSize(TokenList * /*tokenlist*/, SymbolDatabase* symboldatabase, ErrorLogger * /*errorLogger*/, const Settings *settings)
|
static void valueFlowContainerSize(TokenList *tokenlist, SymbolDatabase* symboldatabase, ErrorLogger * /*errorLogger*/, const Settings *settings)
|
||||||
{
|
{
|
||||||
for (const Scope &scope : symboldatabase->scopeList) {
|
for (const Scope &scope : symboldatabase->scopeList) {
|
||||||
if (scope.type != Scope::ScopeType::eIf) // TODO: while
|
if (scope.type != Scope::ScopeType::eIf) // TODO: while
|
||||||
|
@ -3504,10 +3504,13 @@ static void valueFlowContainerSize(TokenList * /*tokenlist*/, SymbolDatabase* sy
|
||||||
valueFlowContainerReverse(scope.classDef, tok->varId(), value, settings);
|
valueFlowContainerReverse(scope.classDef, tok->varId(), value, settings);
|
||||||
|
|
||||||
// possible value after condition
|
// possible value after condition
|
||||||
const Token *after = scope.bodyEnd;
|
if (!isEscapeScope(scope.bodyStart, tokenlist)) {
|
||||||
if (Token::simpleMatch(after, "} else {"))
|
const Token *after = scope.bodyEnd;
|
||||||
after = after->linkAt(2);
|
if (Token::simpleMatch(after, "} else {"))
|
||||||
valueFlowContainerForward(after, tok->varId(), value, settings);
|
after = isEscapeScope(after->tokAt(2), tokenlist) ? nullptr : after->linkAt(2);
|
||||||
|
if (after)
|
||||||
|
valueFlowContainerForward(after, tok->varId(), value, settings);
|
||||||
|
}
|
||||||
|
|
||||||
// known value in conditional code
|
// known value in conditional code
|
||||||
if (conditionToken->str() == "==" || conditionToken->str() == "(") {
|
if (conditionToken->str() == "==" || conditionToken->str() == "(") {
|
||||||
|
|
|
@ -3276,26 +3276,26 @@ private:
|
||||||
|
|
||||||
// valueFlowContainerReverse
|
// valueFlowContainerReverse
|
||||||
code = "void f(const std::list<int> &ints) {\n"
|
code = "void f(const std::list<int> &ints) {\n"
|
||||||
" ints.front();\n"
|
" ints.front();\n" // <- container can be empty
|
||||||
" if (ints.empty()) {}\n"
|
" if (ints.empty()) {}\n"
|
||||||
"}";
|
"}";
|
||||||
ASSERT_EQUALS("", isPossibleContainerSizeValue(tokenValues(code, "ints . front"), 0));
|
ASSERT_EQUALS("", isPossibleContainerSizeValue(tokenValues(code, "ints . front"), 0));
|
||||||
|
|
||||||
code = "void f(const std::list<int> &ints) {\n"
|
code = "void f(const std::list<int> &ints) {\n"
|
||||||
" ints.front();\n"
|
" ints.front();\n" // <- container can be empty
|
||||||
" if (ints.size()==0) {}\n"
|
" if (ints.size()==0) {}\n"
|
||||||
"}";
|
"}";
|
||||||
ASSERT_EQUALS("", isPossibleContainerSizeValue(tokenValues(code, "ints . front"), 0));
|
ASSERT_EQUALS("", isPossibleContainerSizeValue(tokenValues(code, "ints . front"), 0));
|
||||||
|
|
||||||
code = "void f(std::list<int> ints) {\n"
|
code = "void f(std::list<int> ints) {\n"
|
||||||
" ints.front();\n"
|
" ints.front();\n" // <- no container size
|
||||||
" ints.pop_back();\n"
|
" ints.pop_back();\n"
|
||||||
" if (ints.empty()) {}\n"
|
" if (ints.empty()) {}\n"
|
||||||
"}";
|
"}";
|
||||||
ASSERT(tokenValues(code, "ints . front").empty());
|
ASSERT(tokenValues(code, "ints . front").empty());
|
||||||
|
|
||||||
code = "void f(std::vector<int> v) {\n"
|
code = "void f(std::vector<int> v) {\n"
|
||||||
" v[10] = 0;\n"
|
" v[10] = 0;\n" // <- container size can be 10
|
||||||
" if (v.size() == 10) {}\n"
|
" if (v.size() == 10) {}\n"
|
||||||
"}";
|
"}";
|
||||||
ASSERT_EQUALS("", isPossibleContainerSizeValue(tokenValues(code, "v ["), 10));
|
ASSERT_EQUALS("", isPossibleContainerSizeValue(tokenValues(code, "v ["), 10));
|
||||||
|
@ -3303,13 +3303,19 @@ private:
|
||||||
// valueFlowContainerForward
|
// valueFlowContainerForward
|
||||||
code = "void f(const std::list<int> &ints) {\n"
|
code = "void f(const std::list<int> &ints) {\n"
|
||||||
" if (ints.empty()) {}\n"
|
" if (ints.empty()) {}\n"
|
||||||
" ints.front();\n"
|
" ints.front();\n" // <- container can be empty
|
||||||
"}";
|
"}";
|
||||||
ASSERT_EQUALS("", isPossibleContainerSizeValue(tokenValues(code, "ints . front"), 0));
|
ASSERT_EQUALS("", isPossibleContainerSizeValue(tokenValues(code, "ints . front"), 0));
|
||||||
|
|
||||||
|
code = "void f(const std::list<int> &ints) {\n"
|
||||||
|
" if (ints.empty()) { continue; }\n"
|
||||||
|
" ints.front();\n" // <- no container size
|
||||||
|
"}";
|
||||||
|
ASSERT(tokenValues(code, "ints . front").empty());
|
||||||
|
|
||||||
code = "void f(const std::list<int> &ints) {\n"
|
code = "void f(const std::list<int> &ints) {\n"
|
||||||
" if (ints.empty()) {\n"
|
" if (ints.empty()) {\n"
|
||||||
" ints.front();\n"
|
" ints.front();\n" // <- container is empty
|
||||||
" }\n"
|
" }\n"
|
||||||
"}";
|
"}";
|
||||||
ASSERT_EQUALS("", isKnownContainerSizeValue(tokenValues(code, "ints . front"), 0));
|
ASSERT_EQUALS("", isKnownContainerSizeValue(tokenValues(code, "ints . front"), 0));
|
||||||
|
|
Loading…
Reference in New Issue