summaryrefslogtreecommitdiffstats
path: root/clang/lib/StaticAnalyzer/Core/BugReporter.cpp
diff options
context:
space:
mode:
authorArtem Dergachev <artem.dergachev@gmail.com>2017-07-25 09:44:02 +0000
committerArtem Dergachev <artem.dergachev@gmail.com>2017-07-25 09:44:02 +0000
commite235bd1d03234873047357656f32659b84f1c62f (patch)
treeb9bca91feba5d669eec9ee4e2588f5e33a0aca75 /clang/lib/StaticAnalyzer/Core/BugReporter.cpp
parent82bf3de606311a82c54cf1cab064076a0675b213 (diff)
downloadbcm5719-llvm-e235bd1d03234873047357656f32659b84f1c62f.tar.gz
bcm5719-llvm-e235bd1d03234873047357656f32659b84f1c62f.zip
[analyzer] Treat throws as sinks for suppress-on-sink purposes.
Because since r308957 the suppress-on-sink feature contains its own mini-analysis, it also needs to become aware that C++ unhandled exceptions cause sinks. Unfortunately, for now we treat all exceptions as unhandled in the analyzer, so suppress-on-sink needs to do the same. rdar://problem/28157554 Differential Revision: https://reviews.llvm.org/D35674 llvm-svn: 308961
Diffstat (limited to 'clang/lib/StaticAnalyzer/Core/BugReporter.cpp')
-rw-r--r--clang/lib/StaticAnalyzer/Core/BugReporter.cpp25
1 files changed, 23 insertions, 2 deletions
diff --git a/clang/lib/StaticAnalyzer/Core/BugReporter.cpp b/clang/lib/StaticAnalyzer/Core/BugReporter.cpp
index a306462605f..9a30bca6f91 100644
--- a/clang/lib/StaticAnalyzer/Core/BugReporter.cpp
+++ b/clang/lib/StaticAnalyzer/Core/BugReporter.cpp
@@ -3310,13 +3310,34 @@ static const CFGBlock *findBlockForNode(const ExplodedNode *N) {
return nullptr;
}
+static bool isNoReturnBlock(const CFGBlock *Blk) {
+ if (Blk->hasNoReturnElement())
+ return true;
+
+ // FIXME: Throw-expressions are currently generating sinks during analysis:
+ // 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, but once we have better support for exceptions,
+ // we'd need to carefully handle the case when the throw is being
+ // immediately caught.
+ 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;
+ }))
+ return true;
+
+ return false;
+}
+
static bool isDominatedByNoReturnBlocks(const ExplodedNode *N) {
const CFG &Cfg = N->getCFG();
const CFGBlock *StartBlk = findBlockForNode(N);
if (!StartBlk)
return false;
- if (StartBlk->hasNoReturnElement())
+ if (isNoReturnBlock(StartBlk))
return true;
llvm::SmallVector<const CFGBlock *, 32> DFSWorkList;
@@ -3336,7 +3357,7 @@ static bool isDominatedByNoReturnBlocks(const ExplodedNode *N) {
return false;
}
- if (!SuccBlk->hasNoReturnElement() && !Visited.count(SuccBlk)) {
+ if (!isNoReturnBlock(SuccBlk) && !Visited.count(SuccBlk)) {
// If the block has reachable child blocks that aren't no-return,
// add them to the worklist.
DFSWorkList.push_back(SuccBlk);
OpenPOWER on IntegriCloud