Fix 10373: ValueFlow: container in struct assumed empty (#3355)

This commit is contained in:
Paul Fultz II 2021-07-25 11:13:55 -05:00 committed by GitHub
parent 8e416a7255
commit 5be3f700bb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 19 additions and 7 deletions

View File

@ -6408,19 +6408,20 @@ static void valueFlowContainerSize(TokenList *tokenlist, SymbolDatabase* symbold
for (const ValueFlow::Value& value : values) for (const ValueFlow::Value& value : values)
valueFlowContainerForward(containerTok->next(), containerTok, value, tokenlist); valueFlowContainerForward(containerTok->next(), containerTok, value, tokenlist);
} }
} else if (Token::Match(tok, "%var% . %name% (") && tok->valueType() && tok->valueType()->container) { } else if (Token::Match(tok, ". %name% (") && tok->astOperand1() && tok->astOperand1()->valueType() && tok->astOperand1()->valueType()->container) {
Library::Container::Action action = tok->valueType()->container->getAction(tok->strAt(2)); const Token* containerTok = tok->astOperand1();
Library::Container::Action action = containerTok->valueType()->container->getAction(tok->strAt(1));
if (action == Library::Container::Action::CLEAR) { if (action == Library::Container::Action::CLEAR) {
ValueFlow::Value value(0); ValueFlow::Value value(0);
value.valueType = ValueFlow::Value::ValueType::CONTAINER_SIZE; value.valueType = ValueFlow::Value::ValueType::CONTAINER_SIZE;
value.setKnown(); value.setKnown();
valueFlowContainerForward(tok->next(), tok, value, tokenlist); valueFlowContainerForward(tok->next(), containerTok, value, tokenlist);
} else if (action == Library::Container::Action::RESIZE && tok->tokAt(3)->astOperand2() && } else if (action == Library::Container::Action::RESIZE && tok->tokAt(2)->astOperand2() &&
tok->tokAt(3)->astOperand2()->hasKnownIntValue()) { tok->tokAt(2)->astOperand2()->hasKnownIntValue()) {
ValueFlow::Value value(tok->tokAt(3)->astOperand2()->values().front()); ValueFlow::Value value(tok->tokAt(2)->astOperand2()->values().front());
value.valueType = ValueFlow::Value::ValueType::CONTAINER_SIZE; value.valueType = ValueFlow::Value::ValueType::CONTAINER_SIZE;
value.setKnown(); value.setKnown();
valueFlowContainerForward(tok->next(), tok, value, tokenlist); valueFlowContainerForward(tok->next(), containerTok, value, tokenlist);
} }
} }
} }

View File

@ -5085,6 +5085,17 @@ private:
"}", "}",
true); true);
ASSERT_EQUALS("[test.cpp:7]: (style) Iterating over container 'arr' that is always empty.\n", errout.str()); ASSERT_EQUALS("[test.cpp:7]: (style) Iterating over container 'arr' that is always empty.\n", errout.str());
check("struct S {\n"
" std::vector<int> v;\n"
"};\n"
"void foo(S& s) {\n"
" s.v.clear();\n"
" bar(s);\n"
" std::sort(s.v.begin(), s.v.end());\n"
"}\n",
true);
ASSERT_EQUALS("", errout.str());
} }
void checkMutexes() { void checkMutexes() {