]> granicus.if.org Git - clang/commitdiff
[analyzer] Treat @throw as a sink (stop processing).
authorJordan Rose <jordan_rose@apple.com>
Sat, 18 Aug 2012 00:30:20 +0000 (00:30 +0000)
committerJordan Rose <jordan_rose@apple.com>
Sat, 18 Aug 2012 00:30:20 +0000 (00:30 +0000)
The CFG approximates @throw as a return statement, but that's not good
enough in inlined functions. Moreover, since Objective-C exceptions are
usually considered fatal, we should be suppressing leak warnings like we
do for calls to noreturn functions (like abort()).

The comments indicate that we were probably intending to do this all along;
it may have been inadvertantly changed during a refactor at one point.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@162156 91177308-0d34-0410-b5e6-96231b3b80d8

lib/StaticAnalyzer/Core/ExprEngine.cpp
test/Analysis/exceptions.mm [new file with mode: 0644]

index b0435fb562e3b31a94ec955f539f8aa6f7215438..e7b009a176ef68b3c2a5d940d444d9577bf76a9f 100644 (file)
@@ -889,7 +889,7 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred,
     case Stmt::ObjCAtThrowStmtClass: {
       // FIXME: This is not complete.  We basically treat @throw as
       // an abort.
-      Bldr.generateNode(S, Pred, Pred->getState());
+      Bldr.generateNode(S, Pred, Pred->getState(), /*IsSink=*/true);
       break;
     }
 
diff --git a/test/Analysis/exceptions.mm b/test/Analysis/exceptions.mm
new file mode 100644 (file)
index 0000000..7306038
--- /dev/null
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -analyze -fexceptions -fobjc-exceptions -fcxx-exceptions -analyzer-ipa=inlining -analyzer-checker=core,unix.Malloc,debug.ExprInspection -verify %s
+
+void clang_analyzer_checkInlined(bool);
+
+typedef typeof(sizeof(int)) size_t;
+void *malloc(size_t);
+void free(void *);
+
+
+id getException();
+void inlinedObjC() {
+  clang_analyzer_checkInlined(true); // expected-warning{{TRUE}}
+  @throw getException();
+}
+
+int testObjC() {
+  int a; // uninitialized
+  void *mem = malloc(4); // no-warning (ObjC exceptions are usually fatal)
+  inlinedObjC();
+  free(mem);
+  return a; // no-warning
+}
+