From 2d92f1ff6a48ce0a8645ba691c9e80199754a2be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Mon, 10 Jan 2011 19:35:06 +0100 Subject: [PATCH] Fixed #2442 (False positive: Memory leak when function returns in 'if' instead of 'else if') --- lib/checkmemoryleak.cpp | 22 +++++++++++++++++++++- test/testmemleak.cpp | 4 ++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/lib/checkmemoryleak.cpp b/lib/checkmemoryleak.cpp index c004edc05..278653877 100644 --- a/lib/checkmemoryleak.cpp +++ b/lib/checkmemoryleak.cpp @@ -838,6 +838,10 @@ Token *CheckMemoryLeakInFunction::getcode(const Token *tok, std::list extravar; + // The first token should be ";" rethead = new Token(0); rethead->str(";"); @@ -1084,10 +1088,22 @@ Token *CheckMemoryLeakInFunction::getcode(const Token *tok, std::listtokAt(2), varid, true)) { addtoken(&rettail, tok, "if(!var)"); + + // parse the if-body. + // if a variable is assigned then add variable to "extravar". + for (const Token *tok2 = tok->next()->link()->tokAt(2); tok2; tok2 = tok2->next()) + { + if (tok2->str() == "{") + tok2 = tok2->link(); + else if (tok2->str() == "}") + break; + else if (Token::Match(tok2, "%var% =")) + extravar.insert(tok2->varId()); + } } else { - // Check if the condition depends on var somehow.. + // Check if the condition depends on var or extravar somehow.. bool dep = false; int innerParlevel = 0; for (const Token *tok2 = tok->next(); tok2; tok2 = tok2->next()) @@ -1138,6 +1154,10 @@ Token *CheckMemoryLeakInFunction::getcode(const Token *tok, std::listvarId() && extravar.find(tok2->varId()) != extravar.end()) + { + dep = true; + } } if (Token::Match(tok, "if ( ! %varid% &&", varid)) diff --git a/test/testmemleak.cpp b/test/testmemleak.cpp index 05b04e3c4..ef900c103 100644 --- a/test/testmemleak.cpp +++ b/test/testmemleak.cpp @@ -425,6 +425,10 @@ private: ASSERT_EQUALS(";;use;if{}", getcode("char *s; if (x(&s)) { }", "s")); ASSERT_EQUALS(";;use;if{}", getcode("char *s; if (!s || x(&s)) { }", "s")); + // if (ticket #2442) + ASSERT_EQUALS(";;;;if(!var){;}ifv{}", getcode("char *s; int x = 0; if (!s) { x = 2; } if (x) { }", "s")); + ASSERT_EQUALS(";;;;if(!var){;}if{}", getcode("char *s; int x = 0; if (!s) { x = 2; } if (y) { }", "s")); + // switch.. ASSERT_EQUALS(";;switch{case;;break;};", getcode("char *s; switch(a){case 1: break;};", "s"));