[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