diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index edd6634a0ea..86b49c0b137 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -6504,10 +6504,12 @@ static std::vector getContainerSizeFromConstructorArgs(const s return {}; } -static bool valueFlowIsSameContainerType(const ValueType& contType, const Token* tok, const Settings& settings) +static bool valueFlowIsSameContainerType(const ValueType& contType, const Token* tok, bool isView, const Settings& settings) { - if (!tok || !tok->valueType() || !tok->valueType()->containerTypeToken) + if (!tok || !tok->valueType()) return true; + if (!tok->valueType()->containerTypeToken) + return !isView; const ValueType tokType = ValueType::parseDecl(tok->valueType()->containerTypeToken, settings); return contType.isTypeEqual(&tokType) || tokType.type == ValueType::Type::UNKNOWN_TYPE; @@ -6536,7 +6538,7 @@ 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)) + else if (args.size() == 1 && valueFlowIsSameContainerType(vt, tok->astOperand2(), valueType->container->view, settings)) initList = false; // copy ctor else if (args.size() == 2 && (!args[0]->valueType() || !args[1]->valueType())) // might be unknown iterators initList = false; diff --git a/test/teststl.cpp b/test/teststl.cpp index 2c4669dbeca..636fd36b1d0 100644 --- a/test/teststl.cpp +++ b/test/teststl.cpp @@ -972,6 +972,14 @@ class TestStl : public TestFixture { "bool g() { return f(\" \"); }\n"); ASSERT_EQUALS("[test.cpp:1:44]: error: Out of bounds access in 's[500]', if 's' size is 1 and '500' is 500 [containerOutOfBounds]\n", errout_str()); + + checkNormal("int main() {\n" // #14342 + " const int a[] = { 1, 2, 3 };\n" + " std::span x{ a };\n" + " return x[3];\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:4:13]: error: Out of bounds access in 'x[3]', if 'x' size is 1 and '3' is 3 [containerOutOfBounds]\n", + errout_str()); } void outOfBoundsSymbolic()