From e2348560e44bbaf48617c7a18097e511223decf2 Mon Sep 17 00:00:00 2001 From: Zachary Blair Date: Sun, 10 Jun 2012 17:38:31 -0700 Subject: [PATCH] Fixed Ticket #3876 (Error (double free) detected that can't possibly happen) --- lib/checkother.cpp | 7 +++++++ test/testother.cpp | 45 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+) diff --git a/lib/checkother.cpp b/lib/checkother.cpp index 9f35c0128..d516d0189 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -2292,6 +2292,13 @@ void CheckOther::checkDoubleFree() closeDirVariables.clear(); } + // If this scope is a "for" or "while" loop, give up on trying to figure + // out the flow of execution and just clear the set of previously freed variables + else if (tok->str() == "}" && tok->link() && tok->link()->previous() && tok->link()->previous()->link() && + Token::Match(tok->link()->previous()->link()->previous(), "while|for")) { + freedVariables.clear(); + closeDirVariables.clear(); + } // If a variable is passed to a function, remove it from the set of previously freed variables else if (Token::Match(tok, "%var% (") && !Token::Match(tok, "printf|sprintf|snprintf|fprintf")) { diff --git a/test/testother.cpp b/test/testother.cpp index 40b354d81..95d5848a8 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -5087,6 +5087,51 @@ private: "}" ); ASSERT_EQUALS("", errout.str()); + + check( + "void foo(int y)\n" + "{\n" + " char * x = NULL;\n" + " while(1) {\n" + " x = new char[100];\n" + " if (y++ > 100)\n" + " break;\n" + " delete[] x;\n" + " }\n" + " delete[] x;\n" + "}" + ); + ASSERT_EQUALS("", errout.str()); + + check( + "void foo(int y)\n" + "{\n" + " char * x = NULL;\n" + " for (;;) {\n" + " x = new char[100];\n" + " if (y++ > 100)\n" + " break;\n" + " delete[] x;\n" + " }\n" + " delete[] x;\n" + "}" + ); + ASSERT_EQUALS("", errout.str()); + + check( + "void foo(int y)\n" + "{\n" + " char * x = NULL;\n" + " do {\n" + " x = new char[100];\n" + " if (y++ > 100)\n" + " break;\n" + " delete[] x;\n" + " } while (1);\n" + " delete[] x;\n" + "}" + ); + ASSERT_EQUALS("", errout.str()); } };