From 54959d1932186d44abe29251bc12df62c9dba405 Mon Sep 17 00:00:00 2001 From: PKEuS Date: Sun, 9 Oct 2016 10:28:19 +0200 Subject: [PATCH] CheckLeakAutoVar: Distinguish between new and new[] (#888) --- lib/checkleakautovar.cpp | 9 ++++++--- test/testleakautovar.cpp | 20 ++++++++++++++++++-- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/lib/checkleakautovar.cpp b/lib/checkleakautovar.cpp index 6420b2188..987a0717a 100644 --- a/lib/checkleakautovar.cpp +++ b/lib/checkleakautovar.cpp @@ -285,7 +285,9 @@ void CheckLeakAutoVar::checkScope(const Token * const startToken, alloctype[varTok->varId()].status = VarInfo::ALLOC; } } else if (_tokenizer->isCPP() && varTok->strAt(2) == "new") { - alloctype[varTok->varId()].type = -1; + const Token* tok2 = varTok->tokAt(2)->astOperand1(); + bool arrayNew = (tok2 && (tok2->str() == "[" || (tok2->str() == "(" && tok2->astOperand1() && tok2->astOperand1()->str() == "["))); + alloctype[varTok->varId()].type = arrayNew ? -2 : -1; alloctype[varTok->varId()].status = VarInfo::ALLOC; } @@ -469,14 +471,15 @@ void CheckLeakAutoVar::checkScope(const Token * const startToken, // delete else if (_tokenizer->isCPP() && tok->str() == "delete") { - if (tok->strAt(1) == "[") + bool arrayDelete = (tok->strAt(1) == "["); + if (arrayDelete) tok = tok->tokAt(3); else tok = tok->next(); while (Token::Match(tok, "%name% ::|.")) tok = tok->tokAt(2); if (tok->varId() && tok->strAt(1) != "[") { - VarInfo::AllocInfo allocation(-1, VarInfo::DEALLOC); + VarInfo::AllocInfo allocation(arrayDelete ? -2 : -1, VarInfo::DEALLOC); changeAllocStatus(varInfo, allocation, tok, tok); } } diff --git a/test/testleakautovar.cpp b/test/testleakautovar.cpp index dc143a286..c1da4118c 100644 --- a/test/testleakautovar.cpp +++ b/test/testleakautovar.cpp @@ -92,7 +92,7 @@ private: TEST_CASE(loop1); // mismatching allocation/deallocation - TEST_CASE(mismatch_fopen_free); + TEST_CASE(mismatchAllocDealloc); // Execution reaches a 'return' TEST_CASE(return1); @@ -994,12 +994,28 @@ private: ASSERT_EQUALS("", errout.str()); } - void mismatch_fopen_free() { + void mismatchAllocDealloc() { check("void f() {\n" " FILE*f=fopen(fname,a);\n" " free(f);\n" "}"); ASSERT_EQUALS("[test.c:3]: (error) Mismatching allocation and deallocation: f\n", errout.str()); + + check("void f() {\n" + " char *cPtr = new char[100];\n" + " delete[] cPtr;\n" + " cPtr = new char[100]('x');\n" + " delete[] cPtr;\n" + " cPtr = new char[100];\n" + " delete cPtr;\n" + "}", true); + ASSERT_EQUALS("[test.cpp:7]: (error) Mismatching allocation and deallocation: cPtr\n", errout.str()); + + check("void f() {\n" + " char *cPtr = new char[100];\n" + " free(cPtr);\n" + "}", true); + ASSERT_EQUALS("[test.cpp:3]: (error) Mismatching allocation and deallocation: cPtr\n", errout.str()); } void return1() {