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) {
|
||||
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);
|
||||
|
||||
// possible value after condition
|
||||
const Token *after = scope.bodyEnd;
|
||||
if (Token::simpleMatch(after, "} else {"))
|
||||
after = after->linkAt(2);
|
||||
valueFlowContainerForward(after, tok->varId(), value, settings);
|
||||
if (!isEscapeScope(scope.bodyStart, tokenlist)) {
|
||||
const Token *after = scope.bodyEnd;
|
||||
if (Token::simpleMatch(after, "} else {"))
|
||||
after = isEscapeScope(after->tokAt(2), tokenlist) ? nullptr : after->linkAt(2);
|
||||
if (after)
|
||||
valueFlowContainerForward(after, tok->varId(), value, settings);
|
||||
}
|
||||
|
||||
// known value in conditional code
|
||||
if (conditionToken->str() == "==" || conditionToken->str() == "(") {
|
||||
|
|
|
@ -3276,26 +3276,26 @@ private:
|
|||
|
||||
// valueFlowContainerReverse
|
||||
code = "void f(const std::list<int> &ints) {\n"
|
||||
" ints.front();\n"
|
||||
" ints.front();\n" // <- container can be empty
|
||||
" if (ints.empty()) {}\n"
|
||||
"}";
|
||||
ASSERT_EQUALS("", isPossibleContainerSizeValue(tokenValues(code, "ints . front"), 0));
|
||||
|
||||
code = "void f(const std::list<int> &ints) {\n"
|
||||
" ints.front();\n"
|
||||
" ints.front();\n" // <- container can be empty
|
||||
" if (ints.size()==0) {}\n"
|
||||
"}";
|
||||
ASSERT_EQUALS("", isPossibleContainerSizeValue(tokenValues(code, "ints . front"), 0));
|
||||
|
||||
code = "void f(std::list<int> ints) {\n"
|
||||
" ints.front();\n"
|
||||
" ints.front();\n" // <- no container size
|
||||
" ints.pop_back();\n"
|
||||
" if (ints.empty()) {}\n"
|
||||
"}";
|
||||
ASSERT(tokenValues(code, "ints . front").empty());
|
||||
|
||||
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"
|
||||
"}";
|
||||
ASSERT_EQUALS("", isPossibleContainerSizeValue(tokenValues(code, "v ["), 10));
|
||||
|
@ -3303,13 +3303,19 @@ private:
|
|||
// valueFlowContainerForward
|
||||
code = "void f(const std::list<int> &ints) {\n"
|
||||
" if (ints.empty()) {}\n"
|
||||
" ints.front();\n"
|
||||
" ints.front();\n" // <- container can be empty
|
||||
"}";
|
||||
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"
|
||||
" if (ints.empty()) {\n"
|
||||
" ints.front();\n"
|
||||
" ints.front();\n" // <- container is empty
|
||||
" }\n"
|
||||
"}";
|
||||
ASSERT_EQUALS("", isKnownContainerSizeValue(tokenValues(code, "ints . front"), 0));
|
||||
|
|
Loading…
Reference in New Issue