diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index f9c8a54c0..e0a560726 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -1981,8 +1981,9 @@ void Variable::evaluate(const Settings* settings) const Library * const lib = &settings->library; + bool isContainer = false; if (mNameToken) - setFlag(fIsArray, arrayDimensions(settings)); + setFlag(fIsArray, arrayDimensions(settings, &isContainer)); if (mTypeStartToken) setValueType(ValueType::parseDecl(mTypeStartToken,settings)); @@ -2008,7 +2009,7 @@ void Variable::evaluate(const Settings* settings) setFlag(fIsConst, true); setFlag(fIsStatic, true); } else if (tok->str() == "*") { - setFlag(fIsPointer, !isArray() || Token::Match(tok->previous(), "( * %name% )")); + setFlag(fIsPointer, !isArray() || (isContainer && !Token::Match(tok->next(), "%name% [")) || Token::Match(tok->previous(), "( * %name% )")); setFlag(fIsConst, false); // Points to const, isn't necessarily const itself } else if (tok->str() == "&") { if (isReference()) @@ -2053,7 +2054,7 @@ void Variable::evaluate(const Settings* settings) tok = tok->link()->previous(); // add array dimensions if present if (tok && tok->next()->str() == "[") - setFlag(fIsArray, arrayDimensions(settings)); + setFlag(fIsArray, arrayDimensions(settings, &isContainer)); } if (!tok) return; @@ -3243,12 +3244,14 @@ bool Type::isDerivedFrom(const std::string & ancestor) const return false; } -bool Variable::arrayDimensions(const Settings* settings) +bool Variable::arrayDimensions(const Settings* settings, bool* isContainer) { + *isContainer = false; const Library::Container* container = settings->library.detectContainer(mTypeStartToken); if (container && container->arrayLike_indexOp && container->size_templateArgNo > 0) { const Token* tok = Token::findsimplematch(mTypeStartToken, "<"); if (tok) { + *isContainer = true; Dimension dimension_; tok = tok->next(); for (int i = 0; i < container->size_templateArgNo && tok; i++) { diff --git a/lib/symboldatabase.h b/lib/symboldatabase.h index 73b95ef24..904a3698f 100644 --- a/lib/symboldatabase.h +++ b/lib/symboldatabase.h @@ -215,9 +215,10 @@ class CPPCHECKLIB Variable { /** * @brief parse and save array dimension information * @param settings Platform settings and library + * @param isContainer Is the array container-like? * @return true if array, false if not */ - bool arrayDimensions(const Settings* settings); + bool arrayDimensions(const Settings* settings, bool* isContainer); public: Variable(const Token *name_, const Token *start_, const Token *end_, diff --git a/test/testautovariables.cpp b/test/testautovariables.cpp index 52961a64a..8e584232c 100644 --- a/test/testautovariables.cpp +++ b/test/testautovariables.cpp @@ -746,6 +746,14 @@ private: " free((char **)args2);\n" "}"); ASSERT_EQUALS("", errout.str()); + + // #10097 + check("struct Array {\n" + " ~Array() { delete m_Arr; }\n" + " std::array* m_Arr{};\n" + "};\n" + "Array arr;\n"); + ASSERT_EQUALS("", errout.str()); } void testinvaliddealloc_C() { diff --git a/test/testuninitvar.cpp b/test/testuninitvar.cpp index 8fb3e1387..58c7fe28a 100644 --- a/test/testuninitvar.cpp +++ b/test/testuninitvar.cpp @@ -1792,6 +1792,13 @@ private: "}"); ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: vertices\n", errout.str()); + + checkUninitVar("void f() {\n" + " std::array *PArr[2] = { p0, p1 };\n" + " (*PArr[0])[2] = 0;\n" + " (*PArr[1])[2] = 0;\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); } void uninitvar_cpp11ArrayInit() { // #7010