[cfe-commits] r162157 - in /cfe/trunk: lib/StaticAnalyzer/Core/ExprEngine.cpp test/Analysis/exceptions.mm test/Analysis/misc-ps-region-store.cpp

Jordan Rose jordan_rose at apple.com
Fri Aug 17 17:30:23 PDT 2012


Author: jrose
Date: Fri Aug 17 19:30:23 2012
New Revision: 162157

URL: http://llvm.org/viewvc/llvm-project?rev=162157&view=rev
Log:
[analyzer] Treat C++ 'throw' as a sink.

Our current handling of 'throw' is all CFG-based: it jumps to a 'catch' block
if there is one and the function exit block if not. But this doesn't really
get the right behavior when a function is inlined: execution will continue on
the caller's side, which is always the wrong thing to do.

Even within a single function, 'throw' completely skips any destructors that
are to be run. This is essentially the same problem as @finally -- a CFGBlock
that can have multiple entry points, whose exit points depend on whether it
was entered normally or exceptionally.

Representing 'throw' as a sink matches our current (non-)handling of @throw.
It's not a perfect solution, but it's better than continuing analysis in an
inconsistent or even impossible state.

<rdar://problem/12113713>

Modified:
    cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
    cfe/trunk/test/Analysis/exceptions.mm
    cfe/trunk/test/Analysis/misc-ps-region-store.cpp

Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp?rev=162157&r1=162156&r2=162157&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp Fri Aug 17 19:30:23 2012
@@ -607,11 +607,6 @@
     case Stmt::AtomicExprClass:
       // Fall through.
 
-    // Currently all handling of 'throw' just falls to the CFG.  We
-    // can consider doing more if necessary.
-    case Stmt::CXXThrowExprClass:
-      // Fall through.
-      
     // Cases we intentionally don't evaluate, since they don't need
     // to be explicitly evaluated.
     case Stmt::AddrLabelExprClass:
@@ -886,12 +881,12 @@
       Bldr.addNodes(Dst);
       break;
 
-    case Stmt::ObjCAtThrowStmtClass: {
+    case Stmt::ObjCAtThrowStmtClass:
+    case Stmt::CXXThrowExprClass:
       // FIXME: This is not complete.  We basically treat @throw as
       // an abort.
       Bldr.generateNode(S, Pred, Pred->getState(), /*IsSink=*/true);
       break;
-    }
 
     case Stmt::ReturnStmtClass:
       Bldr.takeNodes(Pred);

Modified: cfe/trunk/test/Analysis/exceptions.mm
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/exceptions.mm?rev=162157&r1=162156&r2=162157&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/exceptions.mm (original)
+++ cfe/trunk/test/Analysis/exceptions.mm Fri Aug 17 19:30:23 2012
@@ -21,3 +21,18 @@
   return a; // no-warning
 }
 
+
+void inlinedCXX() {
+  clang_analyzer_checkInlined(true); // expected-warning{{TRUE}}
+  throw -1;
+}
+
+int testCXX() {
+  int a; // uninitialized
+  // FIXME: this should be reported as a leak, because C++ exceptions are
+  // often not fatal.
+  void *mem = malloc(4);
+  inlinedCXX();
+  free(mem);
+  return a; // no-warning
+}

Modified: cfe/trunk/test/Analysis/misc-ps-region-store.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/misc-ps-region-store.cpp?rev=162157&r1=162156&r2=162157&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/misc-ps-region-store.cpp (original)
+++ cfe/trunk/test/Analysis/misc-ps-region-store.cpp Fri Aug 17 19:30:23 2012
@@ -537,7 +537,8 @@
     throw MyEnumValue;
   } catch (MyEnum e) {
     int *p = 0;
-    *p = 0xDEADBEEF; // expected-warning {{null}}
+    // FALSE NEGATIVE
+    *p = 0xDEADBEEF; // {{null}}
     return e;
   }
   return MyEnumValue;
@@ -562,7 +563,8 @@
   catch (...)
   {
     int *p = 0;
-    *p = 0xDEADBEEF; // expected-warning {{null}}
+    // FALSE NEGATIVE
+    *p = 0xDEADBEEF; // {{null}}
   }
 }
 





More information about the cfe-commits mailing list