summaryrefslogtreecommitdiffstats
path: root/clang/lib/StaticAnalyzer/Checkers
diff options
context:
space:
mode:
authorPavel Labath <labath@google.com>2013-07-03 08:23:49 +0000
committerPavel Labath <labath@google.com>2013-07-03 08:23:49 +0000
commitf77e7368444cc5de3e2e19eed4283ded2ef70db7 (patch)
treecfa00f84b9b825bda923c62ccb9dcd3b588b625e /clang/lib/StaticAnalyzer/Checkers
parent18c67a158b1a0b58fc843ca47f0d7aa417732d2f (diff)
downloadbcm5719-llvm-f77e7368444cc5de3e2e19eed4283ded2ef70db7.tar.gz
bcm5719-llvm-f77e7368444cc5de3e2e19eed4283ded2ef70db7.zip
[analyzer] Improve handling of noreturn destructors
Summary: The analyzer incorrectly handled noreturn destructors which were hidden inside function calls. This happened because NoReturnFunctionChecker only listened for PostStmt events, which are not executed for destructor calls. I've changed it to listen to PostCall events, which should catch both cases. Reviewers: jordan_rose CC: cfe-commits Differential Revision: http://llvm-reviews.chandlerc.com/D1056 llvm-svn: 185522
Diffstat (limited to 'clang/lib/StaticAnalyzer/Checkers')
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/NoReturnFunctionChecker.cpp24
1 files changed, 11 insertions, 13 deletions
diff --git a/clang/lib/StaticAnalyzer/Checkers/NoReturnFunctionChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/NoReturnFunctionChecker.cpp
index 0009e1b7cf4..d7a880c6604 100644
--- a/clang/lib/StaticAnalyzer/Checkers/NoReturnFunctionChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/NoReturnFunctionChecker.cpp
@@ -26,31 +26,29 @@ using namespace ento;
namespace {
-class NoReturnFunctionChecker : public Checker< check::PostStmt<CallExpr>,
+class NoReturnFunctionChecker : public Checker< check::PostCall,
check::PostObjCMessage > {
public:
- void checkPostStmt(const CallExpr *CE, CheckerContext &C) const;
+ void checkPostCall(const CallEvent &CE, CheckerContext &C) const;
void checkPostObjCMessage(const ObjCMethodCall &msg, CheckerContext &C) const;
};
}
-void NoReturnFunctionChecker::checkPostStmt(const CallExpr *CE,
+void NoReturnFunctionChecker::checkPostCall(const CallEvent &CE,
CheckerContext &C) const {
ProgramStateRef state = C.getState();
- const Expr *Callee = CE->getCallee();
+ bool BuildSinks = false;
- bool BuildSinks = getFunctionExtInfo(Callee->getType()).getNoReturn();
+ if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(CE.getDecl()))
+ BuildSinks = FD->getAttr<AnalyzerNoReturnAttr>() || FD->isNoReturn();
- if (!BuildSinks) {
- SVal L = state->getSVal(Callee, C.getLocationContext());
- const FunctionDecl *FD = L.getAsFunctionDecl();
- if (!FD)
- return;
+ const Expr *Callee = CE.getOriginExpr();
+ if (!BuildSinks && Callee)
+ BuildSinks = getFunctionExtInfo(Callee->getType()).getNoReturn();
- if (FD->getAttr<AnalyzerNoReturnAttr>() || FD->isNoReturn())
- BuildSinks = true;
- else if (const IdentifierInfo *II = FD->getIdentifier()) {
+ if (!BuildSinks && CE.isGlobalCFunction()) {
+ if (const IdentifierInfo *II = CE.getCalleeIdentifier()) {
// HACK: Some functions are not marked noreturn, and don't return.
// Here are a few hardwired ones. If this takes too long, we can
// potentially cache these results.
OpenPOWER on IntegriCloud