From 5be3f700bb383fe30ba67f0b83ea99269d63dc65 Mon Sep 17 00:00:00 2001 From: Paul Fultz II Date: Sun, 25 Jul 2021 11:13:55 -0500 Subject: [PATCH] Fix 10373: ValueFlow: container in struct assumed empty (#3355) --- lib/valueflow.cpp | 15 ++++++++------- test/teststl.cpp | 11 +++++++++++ 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index c939577d2..452941062 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -6408,19 +6408,20 @@ static void valueFlowContainerSize(TokenList *tokenlist, SymbolDatabase* symbold for (const ValueFlow::Value& value : values) valueFlowContainerForward(containerTok->next(), containerTok, value, tokenlist); } - } else if (Token::Match(tok, "%var% . %name% (") && tok->valueType() && tok->valueType()->container) { - Library::Container::Action action = tok->valueType()->container->getAction(tok->strAt(2)); + } else if (Token::Match(tok, ". %name% (") && tok->astOperand1() && tok->astOperand1()->valueType() && tok->astOperand1()->valueType()->container) { + const Token* containerTok = tok->astOperand1(); + Library::Container::Action action = containerTok->valueType()->container->getAction(tok->strAt(1)); if (action == Library::Container::Action::CLEAR) { ValueFlow::Value value(0); value.valueType = ValueFlow::Value::ValueType::CONTAINER_SIZE; value.setKnown(); - valueFlowContainerForward(tok->next(), tok, value, tokenlist); - } else if (action == Library::Container::Action::RESIZE && tok->tokAt(3)->astOperand2() && - tok->tokAt(3)->astOperand2()->hasKnownIntValue()) { - ValueFlow::Value value(tok->tokAt(3)->astOperand2()->values().front()); + valueFlowContainerForward(tok->next(), containerTok, value, tokenlist); + } else if (action == Library::Container::Action::RESIZE && tok->tokAt(2)->astOperand2() && + tok->tokAt(2)->astOperand2()->hasKnownIntValue()) { + ValueFlow::Value value(tok->tokAt(2)->astOperand2()->values().front()); value.valueType = ValueFlow::Value::ValueType::CONTAINER_SIZE; value.setKnown(); - valueFlowContainerForward(tok->next(), tok, value, tokenlist); + valueFlowContainerForward(tok->next(), containerTok, value, tokenlist); } } } diff --git a/test/teststl.cpp b/test/teststl.cpp index ee5983cca..e395e0dc1 100644 --- a/test/teststl.cpp +++ b/test/teststl.cpp @@ -5085,6 +5085,17 @@ private: "}", true); ASSERT_EQUALS("[test.cpp:7]: (style) Iterating over container 'arr' that is always empty.\n", errout.str()); + + check("struct S {\n" + " std::vector 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() {