From 7481fbb028008948638b70a1bb2f4a20b5a4d711 Mon Sep 17 00:00:00 2001 From: Simon Martin Date: Sat, 20 Jun 2015 21:00:54 +0200 Subject: [PATCH] Fixed #6506 (Properly detect calls to the deallocating free() function) --- lib/checkautovariables.cpp | 6 ++++-- test/testautovariables.cpp | 21 +++++++++++++++++++++ 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/lib/checkautovariables.cpp b/lib/checkautovariables.cpp index 55f05e7b1..81ad3c65e 100644 --- a/lib/checkautovariables.cpp +++ b/lib/checkautovariables.cpp @@ -202,11 +202,13 @@ void CheckAutoVariables::autoVariables() errorReturnAddressOfFunctionParameter(tok, tok->strAt(2)); } // Invalid pointer deallocation - else if (Token::Match(tok, "free ( %var% ) ;") || (_tokenizer->isCPP() && Token::Match(tok, "delete [| ]| (| %var% !!["))) { + else if ((Token::Match(tok, "%name% ( %var% ) ;") && _settings->library.dealloc(tok)) || + (_tokenizer->isCPP() && Token::Match(tok, "delete [| ]| (| %var% !!["))) { tok = Token::findmatch(tok->next(), "%var%"); if (isAutoVarArray(tok)) errorInvalidDeallocation(tok); - } else if (Token::Match(tok, "free ( & %var% ) ;") || (_tokenizer->isCPP() && Token::Match(tok, "delete [| ]| (| & %var% !!["))) { + } else if ((Token::Match(tok, "%name% ( & %var% ) ;") && _settings->library.dealloc(tok)) || + (_tokenizer->isCPP() && Token::Match(tok, "delete [| ]| (| & %var% !!["))) { tok = Token::findmatch(tok->next(), "%var%"); if (isAutoVar(tok)) errorInvalidDeallocation(tok); diff --git a/test/testautovariables.cpp b/test/testautovariables.cpp index b9b4ab013..985c2b01f 100644 --- a/test/testautovariables.cpp +++ b/test/testautovariables.cpp @@ -34,6 +34,7 @@ private: errout.str(""); Settings settings; + LOAD_LIB_2(settings.library, "std.cfg"); settings.inconclusive = inconclusive; settings.addEnabled("warning"); settings.addEnabled("style"); @@ -559,6 +560,26 @@ private: "}"); ASSERT_EQUALS("", errout.str()); + // #6506 + check("struct F {\n" + " void free(void*) {}\n" + "};\n" + "void foo() {\n" + " char c1[1];\n" + " F().free(c1);\n" + " char *c2 = 0;\n" + " F().free(&c2);\n" + "}"); + ASSERT_EQUALS("", errout.str()); + + check("class foo {\n" + " void free(void* );\n" + " void someMethod() {\n" + " char **dst_copy = NULL;\n" + " free(&dst_copy);\n" + " }\n" + "};"); + ASSERT_EQUALS("", errout.str()); } void testinvaliddealloc_C() {