diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index f824826c0..e61ab45c0 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -8085,6 +8085,15 @@ static std::vector getContainerSizeFromConstructorArgs(const s return {}; } +static bool valueFlowIsSameContainerType(const ValueType& contType, const Token* tok, const Settings* settings) +{ + if (!tok || !tok->valueType() || !tok->valueType()->containerTypeToken) + return false; + + const ValueType tokType = ValueType::parseDecl(tok->valueType()->containerTypeToken, settings, true); + return contType.isTypeEqual(&tokType); +} + static std::vector getInitListSize(const Token* tok, const ValueType* valueType, const Settings* settings, @@ -8108,6 +8117,8 @@ static std::vector getInitListSize(const Token* tok, initList = true; else if (vt.isIntegral() && astIsIntegral(args[0], false)) initList = true; + else if (args.size() == 1 && valueFlowIsSameContainerType(vt, tok->astOperand2(), settings)) + initList = false; // copy ctor } } if (!initList) diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index fe872ff2b..5b2cb58e4 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -6317,6 +6317,22 @@ private: " return x;\n" "}\n"; ASSERT_EQUALS(false, testValueOfX(code, 5U, 0)); + + code = "std::vector g();\n" // #11417 + "int f() {\n" + " std::vector v{ g() };\n" + " auto x = v.size();\n" + " return x;\n" + "}\n"; + ASSERT_EQUALS(false, testValueOfXKnown(code, 5U, 1)); + + code = "std::vector g();\n" + "int f() {\n" + " std::vector> v{ g() };\n" + " auto x = v.size();\n" + " return x;\n" + "}\n"; + ASSERT_EQUALS(true, testValueOfXKnown(code, 5U, 1)); } void valueFlowContainerElement()