diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 8eb5735c986..8da6695eb3e 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -6884,6 +6884,26 @@ static void valueFlowContainerSize(const TokenList& tokenlist, } for (const ValueFlow::Value& value : values) setTokenValue(tok, value, settings); + } + else if (Token::Match(tok->previous(), ",|( {")) { + int nArg{}; + if (const Token* funcTok = getTokenArgumentFunction(tok, nArg)) { + if (const Function* func = funcTok->function()) { + if (const Variable* var = func->getArgumentVar(nArg)) { + if (var->valueType() && var->valueType()->container && var->valueType()->container->size_templateArgNo < 0) { + std::vector values = getInitListSize(tok, var->valueType(), settings, true); + ValueFlow::Value tokValue; + tokValue.valueType = ValueFlow::Value::ValueType::TOK; + tokValue.tokvalue = tok; + tokValue.setKnown(); + values.push_back(std::move(tokValue)); + + for (const ValueFlow::Value &value : values) + setTokenValue(tok, value, settings); + } + } + } + } } else if (Token::Match(tok, ";|{|} %var% =") && Token::Match(tok->tokAt(2)->astOperand2(), "[({]") && // init list ((tok->tokAt(2) == tok->tokAt(2)->astOperand2()->astParent() && !tok->tokAt(2)->astOperand2()->astOperand2() && tok->tokAt(2)->astOperand2()->str() == "{") || diff --git a/test/teststl.cpp b/test/teststl.cpp index 43f5ca2eda5..9f3ddba54de 100644 --- a/test/teststl.cpp +++ b/test/teststl.cpp @@ -945,6 +945,28 @@ class TestStl : public TestFixture { " (void)v[0];\n" "}\n"); ASSERT_EQUALS("", errout_str()); + + checkNormal("int f(const std::vector& v) {\n" // #8983 + " return v[2];\n" + "}\n" + "int g() {\n" + " return f({});\n" + "}\n" + "int h() {\n" + " return f({ 1, 2 });\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:2:13]: error: Out of bounds access in 'v[2]', if 'v' size is 2 and '2' is 2 [containerOutOfBounds]\n" + "[test.cpp:2:13]: error: Out of bounds access in expression 'v[2]' because 'v' is empty. [containerOutOfBounds]\n", + errout_str()); + + checkNormal("int f(int x, const std::vector& v) {\n" + " return x + v[0];\n" + "}\n" + "int g() {\n" + " return f(1, {});\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:2:17]: error: Out of bounds access in expression 'v[0]' because 'v' is empty. [containerOutOfBounds]\n", + errout_str()); } void outOfBoundsSymbolic()