diff --git a/lib/vf_analyzers.cpp b/lib/vf_analyzers.cpp index 9dc01477515..54aeeab3034 100644 --- a/lib/vf_analyzers.cpp +++ b/lib/vf_analyzers.cpp @@ -1489,7 +1489,12 @@ struct ContainerExpressionAnalyzer : ExpressionAnalyzer { const Library::Container::Action action = container->getAction(tok->astParent()->strAt(1)); if (action == Library::Container::Action::PUSH || action == Library::Container::Action::POP || action == Library::Container::Action::APPEND) { // TODO: handle more actions? std::vector args = getArguments(tok->tokAt(3)); - if (args.size() < 2 || action == Library::Container::Action::APPEND) + bool isVariadic = false; + if (const Library::Function* libFunc = settings.library.getFunction(tok->tokAt(2))) { + const auto& argChecks = libFunc->argumentChecks; + isVariadic = argChecks.find(-1) != argChecks.end() && argChecks.at(-1).variadic; + } + if (args.size() < 2 || action == Library::Container::Action::APPEND || isVariadic) return Action::Read | Action::Write | Action::Incremental; } } diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index 7a19a92786b..c0fc9867df2 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -7172,6 +7172,15 @@ class TestValueFlow : public TestFixture { "}\n"; ASSERT_EQUALS(true, tokenValues(code, "a . size", ValueFlow::Value::ValueType::CONTAINER_SIZE).empty()); + code = "void f() {\n" // #14060 + " std::stack> s;\n" + " s.emplace(0, 0);\n" + " s.pop();\n" + " bool x = s.empty();\n" + " return x;\n" + "}\n"; + ASSERT_EQUALS(true, testValueOfXKnown(code, 6U, 1)); + code = "std::vector g();\n" "std::vector f() {\n" " std::vector v = g();\n"