From: Anton Yartsev Date: Fri, 28 Feb 2014 22:29:48 +0000 (+0000) Subject: [analyzer] Fix for PR18394. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=efeac4d14e06b0c6279189a060d626fe4e04a521;p=clang [analyzer] Fix for PR18394. Additional conditions that prevent useful nodes before call from being reclaimed. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@202553 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/StaticAnalyzer/Core/ExplodedGraph.cpp b/lib/StaticAnalyzer/Core/ExplodedGraph.cpp index e9c4a35de6..7812c96f86 100644 --- a/lib/StaticAnalyzer/Core/ExplodedGraph.cpp +++ b/lib/StaticAnalyzer/Core/ExplodedGraph.cpp @@ -90,8 +90,9 @@ bool ExplodedGraph::shouldCollect(const ExplodedNode *node) { // (7) The LocationContext is the same as the predecessor. // (8) Expressions that are *not* lvalue expressions. // (9) The PostStmt isn't for a non-consumed Stmt or Expr. - // (10) The successor is not a CallExpr StmtPoint (so that we would - // be able to find it when retrying a call with no inlining). + // (10) The successor is neither a CallExpr StmtPoint nor a CallEnter or + // PreImplicitCall (so that we would be able to find it when retrying a + // call with no inlining). // FIXME: It may be safe to reclaim PreCall and PostCall nodes as well. // Conditions 1 and 2. @@ -153,6 +154,10 @@ bool ExplodedGraph::shouldCollect(const ExplodedNode *node) { if (CallEvent::isCallStmt(SP->getStmt())) return false; + // Condition 10, continuation. + if (SuccLoc.getAs() || SuccLoc.getAs()) + return false; + return true; } diff --git a/test/Analysis/NewDeleteLeaks-PR18394.cpp b/test/Analysis/NewDeleteLeaks-PR18394.cpp new file mode 100644 index 0000000000..452781d07a --- /dev/null +++ b/test/Analysis/NewDeleteLeaks-PR18394.cpp @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 -analyzer-config graph-trim-interval=1 -analyzer-max-loop 1 -analyze -analyzer-checker=core,alpha.cplusplus.NewDeleteLeaks -verify %s +// expected-no-diagnostics + +class A { +public: + void f() {}; + ~A() { + for (int i=0; i<3; i++) + f(); + } +}; + +void error() { + A *a = new A(); + delete a; +}