[cfe-commits] r163264 - in /cfe/trunk: include/clang/Analysis/ include/clang/Driver/ include/clang/StaticAnalyzer/Core/ lib/Analysis/ lib/Frontend/ lib/StaticAnalyzer/Core/ test/Analysis/

Jordan Rose jordan_rose at apple.com
Wed Sep 5 15:55:23 PDT 2012


Author: jrose
Date: Wed Sep  5 17:55:23 2012
New Revision: 163264

URL: http://llvm.org/viewvc/llvm-project?rev=163264&view=rev
Log:
[analyzer] Always include destructors in the analysis CFG.

While destructors will continue to not be inlined (unless the analyzer
config option 'c++-inlining' is set to 'destructors'), leaving them out
of the CFG is an incomplete model of the behavior of an object, and
can cause false positive warnings (like PR13751, now working).

Destructors for temporaries are still not on by default, since
(a) we haven't actually checked this code to be sure it's fully correct
    (in particular, we probably need to be very careful with regard to
    lifetime-extension when a temporary is bound to a reference,
    C++11 [class.temporary]p5), and
(b) ExprEngine doesn't actually do anything when it sees a temporary
    destructor in the CFG -- not even invalidate the object region.

To enable temporary destructors, set the 'cfg-temporary-dtors' analyzer
config option to '1'. The old -cfg-add-implicit-dtors cc1 option, which
controlled all implicit destructors, has been removed.

Modified:
    cfe/trunk/include/clang/Analysis/AnalysisContext.h
    cfe/trunk/include/clang/Analysis/CFG.h
    cfe/trunk/include/clang/Driver/CC1Options.td
    cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
    cfe/trunk/lib/Analysis/AnalysisDeclContext.cpp
    cfe/trunk/lib/Analysis/CFG.cpp
    cfe/trunk/lib/Frontend/CompilerInvocation.cpp
    cfe/trunk/lib/StaticAnalyzer/Core/AnalysisManager.cpp
    cfe/trunk/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp
    cfe/trunk/test/Analysis/auto-obj-dtors-cfg-output.cpp
    cfe/trunk/test/Analysis/dtor.cpp
    cfe/trunk/test/Analysis/dtors-in-dtor-cfg-output.cpp
    cfe/trunk/test/Analysis/malloc.cpp
    cfe/trunk/test/Analysis/temp-obj-dtors-cfg-output.cpp

Modified: cfe/trunk/include/clang/Analysis/AnalysisContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/AnalysisContext.h?rev=163264&r1=163263&r2=163264&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/AnalysisContext.h (original)
+++ cfe/trunk/include/clang/Analysis/AnalysisContext.h Wed Sep  5 17:55:23 2012
@@ -382,8 +382,9 @@
 
 public:
   AnalysisDeclContextManager(bool useUnoptimizedCFG = false,
-                         bool addImplicitDtors = false,
-                         bool addInitializers = false);
+                             bool addImplicitDtors = false,
+                             bool addInitializers = false,
+                             bool addTemporaryDtors = false);
 
   ~AnalysisDeclContextManager();
 

Modified: cfe/trunk/include/clang/Analysis/CFG.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/CFG.h?rev=163264&r1=163263&r2=163264&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/CFG.h (original)
+++ cfe/trunk/include/clang/Analysis/CFG.h Wed Sep  5 17:55:23 2012
@@ -568,6 +568,7 @@
     bool AddEHEdges;
     bool AddInitializers;
     bool AddImplicitDtors;
+    bool AddTemporaryDtors;
 
     bool alwaysAdd(const Stmt *stmt) const {
       return alwaysAddMask[stmt->getStmtClass()];
@@ -587,7 +588,8 @@
     : forcedBlkExprs(0), PruneTriviallyFalseEdges(true)
       ,AddEHEdges(false)
       ,AddInitializers(false)
-      ,AddImplicitDtors(false) {}
+      ,AddImplicitDtors(false)
+      ,AddTemporaryDtors(false) {}
   };
 
   /// \brief Provides a custom implementation of the iterator class to have the

Modified: cfe/trunk/include/clang/Driver/CC1Options.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/CC1Options.td?rev=163264&r1=163263&r2=163264&view=diff
==============================================================================
--- cfe/trunk/include/clang/Driver/CC1Options.td (original)
+++ cfe/trunk/include/clang/Driver/CC1Options.td Wed Sep  5 17:55:23 2012
@@ -37,8 +37,6 @@
 
 def analysis_UnoptimizedCFG : Flag<"-unoptimized-cfg">,
   HelpText<"Generate unoptimized CFGs for all analyses">;
-def analysis_CFGAddImplicitDtors : Flag<"-cfg-add-implicit-dtors">,
-  HelpText<"Add C++ implicit destructors to CFGs for all analyses">;
 
 def analyzer_store : Separate<"-analyzer-store">,
   HelpText<"Source Code Analysis - Abstract Memory Store Models">;

Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h?rev=163264&r1=163263&r2=163264&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h Wed Sep  5 17:55:23 2012
@@ -147,7 +147,6 @@
   unsigned visualizeExplodedGraphWithGraphViz : 1;
   unsigned visualizeExplodedGraphWithUbiGraph : 1;
   unsigned UnoptimizedCFG : 1;
-  unsigned CFGAddImplicitDtors : 1;
   unsigned eagerlyTrimExplodedGraph : 1;
   unsigned PrintStats : 1;
   
@@ -172,9 +171,18 @@
   /// Returns the option controlling which C++ member functions will be
   /// considered for inlining.
   ///
+  /// This is controlled by the 'c++-inlining' config option.
+  ///
   /// \sa CXXMemberInliningMode
   bool mayInlineCXXMemberFunction(CXXInlineableMemberKind K) const;
 
+  /// Returns whether or not the destructors for C++ temporary objects should
+  /// be included in the CFG.
+  ///
+  /// This is controlled by the 'cfg-temporary-dtors' config option. Any
+  /// non-empty value is considered to be 'true'.
+  bool includeTemporaryDtorsInCFG() const;
+
 public:
   AnalyzerOptions() : CXXMemberInliningMode() {
     AnalysisStoreOpt = RegionStoreModel;
@@ -191,7 +199,6 @@
     visualizeExplodedGraphWithGraphViz = 0;
     visualizeExplodedGraphWithUbiGraph = 0;
     UnoptimizedCFG = 0;
-    CFGAddImplicitDtors = 0;
     eagerlyTrimExplodedGraph = 0;
     PrintStats = 0;
     NoRetryExhausted = 0;

Modified: cfe/trunk/lib/Analysis/AnalysisDeclContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/AnalysisDeclContext.cpp?rev=163264&r1=163263&r2=163264&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/AnalysisDeclContext.cpp (original)
+++ cfe/trunk/lib/Analysis/AnalysisDeclContext.cpp Wed Sep  5 17:55:23 2012
@@ -62,11 +62,13 @@
 }
 
 AnalysisDeclContextManager::AnalysisDeclContextManager(bool useUnoptimizedCFG,
-                                               bool addImplicitDtors,
-                                               bool addInitializers) {
+                                                       bool addImplicitDtors,
+                                                       bool addInitializers,
+                                                       bool addTemporaryDtors) {
   cfgBuildOptions.PruneTriviallyFalseEdges = !useUnoptimizedCFG;
   cfgBuildOptions.AddImplicitDtors = addImplicitDtors;
   cfgBuildOptions.AddInitializers = addInitializers;
+  cfgBuildOptions.AddTemporaryDtors = addTemporaryDtors;
 }
 
 void AnalysisDeclContextManager::clear() {

Modified: cfe/trunk/lib/Analysis/CFG.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/CFG.cpp?rev=163264&r1=163263&r2=163264&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/CFG.cpp (original)
+++ cfe/trunk/lib/Analysis/CFG.cpp Wed Sep  5 17:55:23 2012
@@ -706,7 +706,7 @@
       IsReference = FD->getType()->isReferenceType();
     HasTemporaries = isa<ExprWithCleanups>(Init);
 
-    if (BuildOpts.AddImplicitDtors && HasTemporaries) {
+    if (BuildOpts.AddTemporaryDtors && HasTemporaries) {
       // Generate destructors for temporaries in initialization expression.
       VisitForTemporaryDtors(cast<ExprWithCleanups>(Init)->getSubExpr(),
           IsReference);
@@ -1617,7 +1617,7 @@
     IsReference = VD->getType()->isReferenceType();
     HasTemporaries = isa<ExprWithCleanups>(Init);
 
-    if (BuildOpts.AddImplicitDtors && HasTemporaries) {
+    if (BuildOpts.AddTemporaryDtors && HasTemporaries) {
       // Generate destructors for temporaries in initialization expression.
       VisitForTemporaryDtors(cast<ExprWithCleanups>(Init)->getSubExpr(),
           IsReference);
@@ -2972,7 +2972,7 @@
 
 CFGBlock *CFGBuilder::VisitExprWithCleanups(ExprWithCleanups *E,
     AddStmtChoice asc) {
-  if (BuildOpts.AddImplicitDtors) {
+  if (BuildOpts.AddTemporaryDtors) {
     // If adding implicit destructors visit the full expression for adding
     // destructors of temporaries.
     VisitForTemporaryDtors(E->getSubExpr());
@@ -3052,6 +3052,8 @@
 }
 
 CFGBlock *CFGBuilder::VisitForTemporaryDtors(Stmt *E, bool BindToTemporary) {
+  assert(BuildOpts.AddImplicitDtors && BuildOpts.AddTemporaryDtors);
+
 tryAgain:
   if (!E) {
     badCFG = true;

Modified: cfe/trunk/lib/Frontend/CompilerInvocation.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CompilerInvocation.cpp?rev=163264&r1=163263&r2=163264&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/CompilerInvocation.cpp (original)
+++ cfe/trunk/lib/Frontend/CompilerInvocation.cpp Wed Sep  5 17:55:23 2012
@@ -1130,7 +1130,6 @@
   Opts.eagerlyAssumeBinOpBifurcation = Args.hasArg(OPT_analyzer_eagerly_assume);
   Opts.AnalyzeSpecificFunction = Args.getLastArgValue(OPT_analyze_function);
   Opts.UnoptimizedCFG = Args.hasArg(OPT_analysis_UnoptimizedCFG);
-  Opts.CFGAddImplicitDtors = Args.hasArg(OPT_analysis_CFGAddImplicitDtors);
   Opts.TrimGraph = Args.hasArg(OPT_trim_egraph);
   Opts.MaxNodes = Args.getLastArgIntValue(OPT_analyzer_max_nodes, 150000,Diags);
   Opts.maxBlockVisitOnPath = Args.getLastArgIntValue(OPT_analyzer_max_loop, 4, Diags);

Modified: cfe/trunk/lib/StaticAnalyzer/Core/AnalysisManager.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/AnalysisManager.cpp?rev=163264&r1=163263&r2=163264&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/AnalysisManager.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/AnalysisManager.cpp Wed Sep  5 17:55:23 2012
@@ -22,8 +22,9 @@
                                  CheckerManager *checkerMgr,
                                  const AnalyzerOptions &Options)
   : AnaCtxMgr(Options.UnoptimizedCFG,
-              Options.CFGAddImplicitDtors,
-              /*addInitializers=*/true),
+              /*AddImplicitDtors=*/true,
+              /*AddInitializers=*/true,
+              Options.includeTemporaryDtorsInCFG()),
     Ctx(ctx),
     Diags(diags),
     LangOpts(lang),

Modified: cfe/trunk/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp?rev=163264&r1=163263&r2=163264&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp Wed Sep  5 17:55:23 2012
@@ -46,3 +46,7 @@
 
   return CXXMemberInliningMode >= K;
 }
+
+bool AnalyzerOptions::includeTemporaryDtorsInCFG() const {
+  return !Config.lookup("cfg-temporary-dtors").empty();
+}

Modified: cfe/trunk/test/Analysis/auto-obj-dtors-cfg-output.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/auto-obj-dtors-cfg-output.cpp?rev=163264&r1=163263&r2=163264&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/auto-obj-dtors-cfg-output.cpp (original)
+++ cfe/trunk/test/Analysis/auto-obj-dtors-cfg-output.cpp Wed Sep  5 17:55:23 2012
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -analyze -analyzer-checker=debug.DumpCFG -cfg-add-implicit-dtors %s > %t 2>&1
+// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -analyze -analyzer-checker=debug.DumpCFG %s > %t 2>&1
 // RUN: FileCheck --input-file=%t %s
 // XPASS: *
 

Modified: cfe/trunk/test/Analysis/dtor.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/dtor.cpp?rev=163264&r1=163263&r2=163264&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/dtor.cpp (original)
+++ cfe/trunk/test/Analysis/dtor.cpp Wed Sep  5 17:55:23 2012
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-ipa=inlining  -analyzer-config c++-inlining=destructors -cfg-add-implicit-dtors -Wno-null-dereference -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-ipa=inlining  -analyzer-config c++-inlining=destructors -Wno-null-dereference -verify %s
 
 void clang_analyzer_eval(bool);
 void clang_analyzer_checkInlined(bool);

Modified: cfe/trunk/test/Analysis/dtors-in-dtor-cfg-output.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/dtors-in-dtor-cfg-output.cpp?rev=163264&r1=163263&r2=163264&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/dtors-in-dtor-cfg-output.cpp (original)
+++ cfe/trunk/test/Analysis/dtors-in-dtor-cfg-output.cpp Wed Sep  5 17:55:23 2012
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=debug.DumpCFG -cfg-add-implicit-dtors %s 2>&1 | FileCheck %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=debug.DumpCFG %s 2>&1 | FileCheck %s
 // XPASS: *
 
 class A {

Modified: cfe/trunk/test/Analysis/malloc.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/malloc.cpp?rev=163264&r1=163263&r2=163264&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/malloc.cpp (original)
+++ cfe/trunk/test/Analysis/malloc.cpp Wed Sep  5 17:55:23 2012
@@ -6,6 +6,11 @@
 void *realloc(void *ptr, size_t size);
 void *calloc(size_t nmemb, size_t size);
 
+
+void checkThatMallocCheckerIsRunning() {
+  malloc(4); // expected-warning{{leak}}
+}
+
 // Test for radar://11110132.
 struct Foo {
     mutable void* m_data;
@@ -35,3 +40,23 @@
   const_ptr_and_callback_def_param(0, x, 12, p->myFree);
 }
 
+
+namespace PR13751 {
+  class OwningVector {
+    void **storage;
+    size_t length;
+  public:
+    OwningVector();
+    ~OwningVector();
+    void push_back(void *Item) {
+      storage[length++] = Item;
+    }
+  };
+
+  void testDestructors() {
+    OwningVector v;
+    v.push_back(malloc(4));
+    // no leak warning; freed in destructor
+  }
+}
+

Modified: cfe/trunk/test/Analysis/temp-obj-dtors-cfg-output.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/temp-obj-dtors-cfg-output.cpp?rev=163264&r1=163263&r2=163264&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/temp-obj-dtors-cfg-output.cpp (original)
+++ cfe/trunk/test/Analysis/temp-obj-dtors-cfg-output.cpp Wed Sep  5 17:55:23 2012
@@ -1,5 +1,5 @@
 // RUN: rm -f %t
-// RUN: %clang_cc1 -analyze -analyzer-checker=debug.DumpCFG -cfg-add-implicit-dtors %s > %t 2>&1
+// RUN: %clang_cc1 -analyze -analyzer-checker=debug.DumpCFG -analyzer-config cfg-temporary-dtors=1 %s > %t 2>&1
 // RUN: FileCheck --input-file=%t %s
 // XPASS: *
 





More information about the cfe-commits mailing list