Skip to content

Commit 629f883

Browse files
Fix #10097: autovarInvalidDeallocation with pointer to std::array (#3529)
1 parent b456122 commit 629f883

4 files changed

Lines changed: 24 additions & 5 deletions

File tree

lib/symboldatabase.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1981,8 +1981,9 @@ void Variable::evaluate(const Settings* settings)
19811981

19821982
const Library * const lib = &settings->library;
19831983

1984+
bool isContainer = false;
19841985
if (mNameToken)
1985-
setFlag(fIsArray, arrayDimensions(settings));
1986+
setFlag(fIsArray, arrayDimensions(settings, &isContainer));
19861987

19871988
if (mTypeStartToken)
19881989
setValueType(ValueType::parseDecl(mTypeStartToken,settings));
@@ -2008,7 +2009,7 @@ void Variable::evaluate(const Settings* settings)
20082009
setFlag(fIsConst, true);
20092010
setFlag(fIsStatic, true);
20102011
} else if (tok->str() == "*") {
2011-
setFlag(fIsPointer, !isArray() || Token::Match(tok->previous(), "( * %name% )"));
2012+
setFlag(fIsPointer, !isArray() || (isContainer && !Token::Match(tok->next(), "%name% [")) || Token::Match(tok->previous(), "( * %name% )"));
20122013
setFlag(fIsConst, false); // Points to const, isn't necessarily const itself
20132014
} else if (tok->str() == "&") {
20142015
if (isReference())
@@ -2053,7 +2054,7 @@ void Variable::evaluate(const Settings* settings)
20532054
tok = tok->link()->previous();
20542055
// add array dimensions if present
20552056
if (tok && tok->next()->str() == "[")
2056-
setFlag(fIsArray, arrayDimensions(settings));
2057+
setFlag(fIsArray, arrayDimensions(settings, &isContainer));
20572058
}
20582059
if (!tok)
20592060
return;
@@ -3243,12 +3244,14 @@ bool Type::isDerivedFrom(const std::string & ancestor) const
32433244
return false;
32443245
}
32453246

3246-
bool Variable::arrayDimensions(const Settings* settings)
3247+
bool Variable::arrayDimensions(const Settings* settings, bool* isContainer)
32473248
{
3249+
*isContainer = false;
32483250
const Library::Container* container = settings->library.detectContainer(mTypeStartToken);
32493251
if (container && container->arrayLike_indexOp && container->size_templateArgNo > 0) {
32503252
const Token* tok = Token::findsimplematch(mTypeStartToken, "<");
32513253
if (tok) {
3254+
*isContainer = true;
32523255
Dimension dimension_;
32533256
tok = tok->next();
32543257
for (int i = 0; i < container->size_templateArgNo && tok; i++) {

lib/symboldatabase.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,9 +215,10 @@ class CPPCHECKLIB Variable {
215215
/**
216216
* @brief parse and save array dimension information
217217
* @param settings Platform settings and library
218+
* @param isContainer Is the array container-like?
218219
* @return true if array, false if not
219220
*/
220-
bool arrayDimensions(const Settings* settings);
221+
bool arrayDimensions(const Settings* settings, bool* isContainer);
221222

222223
public:
223224
Variable(const Token *name_, const Token *start_, const Token *end_,

test/testautovariables.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -746,6 +746,14 @@ class TestAutoVariables : public TestFixture {
746746
" free((char **)args2);\n"
747747
"}");
748748
ASSERT_EQUALS("", errout.str());
749+
750+
// #10097
751+
check("struct Array {\n"
752+
" ~Array() { delete m_Arr; }\n"
753+
" std::array<long, 256>* m_Arr{};\n"
754+
"};\n"
755+
"Array arr;\n");
756+
ASSERT_EQUALS("", errout.str());
749757
}
750758

751759
void testinvaliddealloc_C() {

test/testuninitvar.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1792,6 +1792,13 @@ class TestUninitVar : public TestFixture {
17921792
"}");
17931793
ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: vertices\n",
17941794
errout.str());
1795+
1796+
checkUninitVar("void f() {\n"
1797+
" std::array<int, 3> *PArr[2] = { p0, p1 };\n"
1798+
" (*PArr[0])[2] = 0;\n"
1799+
" (*PArr[1])[2] = 0;\n"
1800+
"}\n");
1801+
ASSERT_EQUALS("", errout.str());
17951802
}
17961803

17971804
void uninitvar_cpp11ArrayInit() { // #7010

0 commit comments

Comments
 (0)