From 222ed6d375f9e0f70739bc72a22fa044e527dc8d Mon Sep 17 00:00:00 2001 From: Robert Reif Date: Sat, 6 Aug 2011 19:10:15 -0400 Subject: [PATCH] fix #2971 (Wrong warning generated) --- lib/checkmemoryleak.cpp | 27 +++++++++++++++------------ lib/tokenize.cpp | 7 +++++++ test/testmemleak.cpp | 30 ++++++++++++++++++++++++++++++ 3 files changed, 52 insertions(+), 12 deletions(-) diff --git a/lib/checkmemoryleak.cpp b/lib/checkmemoryleak.cpp index ca6471d0d..638f8291a 100644 --- a/lib/checkmemoryleak.cpp +++ b/lib/checkmemoryleak.cpp @@ -159,14 +159,14 @@ CheckMemoryLeak::AllocType CheckMemoryLeak::getAllocationType(const Token *tok2, return gMalloc; } - if (Token::Match(tok2, "new %type% [;()]") || - Token::Match(tok2, "new ( std :: nothrow ) %type% [;()]") || - Token::Match(tok2, "new ( nothrow ) %type% [;()]")) + if (Token::Match(tok2, "new struct| %type% [;()]") || + Token::Match(tok2, "new ( std :: nothrow ) struct| %type% [;()]") || + Token::Match(tok2, "new ( nothrow ) struct| %type% [;()]")) return New; - if (Token::Match(tok2, "new %type% [") || - Token::Match(tok2, "new ( std :: nothrow ) %type% [") || - Token::Match(tok2, "new ( nothrow ) %type% [")) + if (Token::Match(tok2, "new struct| %type% [") || + Token::Match(tok2, "new ( std :: nothrow ) struct| %type% [") || + Token::Match(tok2, "new ( nothrow ) struct| %type% [")) return NewArray; if (Token::Match(tok2, "fopen|tmpfile|g_fopen (")) @@ -1035,23 +1035,26 @@ Token *CheckMemoryLeakInFunction::getcode(const Token *tok, std::listtokAt(2), "new %type% [(;]")) + if (Token::Match(tok->tokAt(2), "new struct| %type% [(;]")) { - if (isclass(_tokenizer, tok->tokAt(3), varid)) + const int offset = tok->strAt(3) == "struct" ? 1 : 0; + if (isclass(_tokenizer, tok->tokAt(3 + offset), varid)) { alloc = No; } } - else if (Token::Match(tok->tokAt(2), "new ( nothrow ) %type%")) + else if (Token::Match(tok->tokAt(2), "new ( nothrow ) struct| %type%")) { - if (isclass(_tokenizer, tok->tokAt(6), varid)) + const int offset = tok->strAt(6) == "struct" ? 1 : 0; + if (isclass(_tokenizer, tok->tokAt(6 + offset), varid)) { alloc = No; } } - else if (Token::Match(tok->tokAt(2), "new ( std :: nothrow ) %type%")) + else if (Token::Match(tok->tokAt(2), "new ( std :: nothrow ) struct| %type%")) { - if (isclass(_tokenizer, tok->tokAt(8), varid)) + const int offset = tok->strAt(8) == "struct" ? 1 : 0; + if (isclass(_tokenizer, tok->tokAt(8 + offset), varid)) { alloc = No; } diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 9f2535e32..30e33de53 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -2510,6 +2510,13 @@ bool Tokenizer::tokenize(std::istream &code, } } + // convert Microsoft DEBUG_NEW macro to new + for (Token *tok = _tokens; tok; tok = tok->next()) + { + if (tok->str() == "DEBUG_NEW") + tok->str("new"); + } + // typedef.. simplifyTypedef(); diff --git a/test/testmemleak.cpp b/test/testmemleak.cpp index 2b87d7f15..42f85b4eb 100644 --- a/test/testmemleak.cpp +++ b/test/testmemleak.cpp @@ -971,6 +971,21 @@ private: " Fred *f = new(std::nothrow) Fred;\n" "}\n"); ASSERT_EQUALS("", errout.str()); + + // ticket #2971 + check("void f()\n" + "{\n" + " Fred *f = new(std::nothrow) Fred[10];\n" + " delete f;\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:4]: (error) Mismatching allocation and deallocation: f\n", errout.str()); + + check("void f()\n" + "{\n" + " struct Fred *f = new(std::nothrow) struct Fred[10];\n" + " delete f;\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:4]: (error) Mismatching allocation and deallocation: f\n", errout.str()); } @@ -1388,6 +1403,21 @@ private: " free(a);\n" "}\n", true); ASSERT_EQUALS("[test.cpp:4]: (error) Mismatching allocation and deallocation: a\n", errout.str()); + + // ticket #2971 + check("void f()\n" + "{\n" + " Fred *a = new Fred[10];\n" + " free(a);\n" + "}\n", true); + ASSERT_EQUALS("[test.cpp:4]: (error) Mismatching allocation and deallocation: a\n", errout.str()); + + check("void f()\n" + "{\n" + " struct Fred *a = new struct Fred[10];\n" + " free(a);\n" + "}\n", true); + ASSERT_EQUALS("[test.cpp:4]: (error) Mismatching allocation and deallocation: a\n", errout.str()); } void mismatch2()