[PATCH] D35674: [analyzer] Treat C++ throw as sink during CFG-based suppress-on-sink.

Artem Dergachev via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Thu Jul 20 03:47:16 PDT 2017


NoQ created this revision.

Because throws produce sinks during symbolic execution, we need to treat them as noreturn during our suppress-on-sink analysis as well. This would get a lot less conservative when CFG actually supports exceptions.


https://reviews.llvm.org/D35674

Files:
  lib/StaticAnalyzer/Core/BugReporter.cpp
  test/Analysis/max-nodes-suppress-on-sink.cpp


Index: test/Analysis/max-nodes-suppress-on-sink.cpp
===================================================================
--- /dev/null
+++ test/Analysis/max-nodes-suppress-on-sink.cpp
@@ -0,0 +1,35 @@
+// RUN: %clang_analyze_cc1 -x c++ -fcxx-exceptions -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-config max-nodes=12 -verify %s
+
+// Here we test how "suppress on sink" feature of certain bugtypes interacts
+// with reaching analysis limits. See comments in max-nodes-suppress-on-sink.c
+// for more discussion.
+
+typedef __typeof(sizeof(int)) size_t;
+void *malloc(size_t);
+
+void clang_analyzer_warnIfReached(void);
+
+// Because we don't have a better approach, we currently treat throw as
+// noreturn.
+void test_throw_treated_as_noreturn() {
+  void *p = malloc(1); // no-warning
+
+  clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
+  clang_analyzer_warnIfReached(); // no-warning
+
+  throw 0;
+}
+
+// FIXME: Handled throws shouldn't be suppressing us!
+void test_handled_throw_treated_as_noreturn() {
+  void *p = malloc(1); // no-warning
+
+  clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
+  clang_analyzer_warnIfReached(); // no-warning
+
+  try {
+    throw 0;
+  } catch (int i) {
+  }
+}
+
Index: lib/StaticAnalyzer/Core/BugReporter.cpp
===================================================================
--- lib/StaticAnalyzer/Core/BugReporter.cpp
+++ lib/StaticAnalyzer/Core/BugReporter.cpp
@@ -3324,6 +3324,19 @@
       continue;
     }
 
+    if (std::any_of(Blk->begin(), Blk->end(), [](const CFGElement &Elm) {
+          if (Optional<CFGStmt> StmtElm = Elm.getAs<CFGStmt>())
+            if (isa<CXXThrowExpr>(StmtElm->getStmt()))
+              return true;
+          return false;
+        })) {
+      // Throw-expressions are currently generating sinks during symbolic
+      // execution: they're not supported yet, and also often used for
+      // actually terminating the program. So we should treat them as sinks
+      // in this analysis as well, at least for now.
+      continue;
+    }
+
     if (Blk == &Cfg.getExit()) {
       // We're leaving the current CFG. We're no longer sure what happens next.
       return false;


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D35674.107478.patch
Type: text/x-patch
Size: 2221 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20170720/a30ac98e/attachment.bin>


More information about the cfe-commits mailing list