r185522 - [analyzer] Improve handling of noreturn destructors

Pavel Labath labath at google.com
Wed Jul 3 01:23:50 PDT 2013


Author: labath
Date: Wed Jul  3 03:23:49 2013
New Revision: 185522

URL: http://llvm.org/viewvc/llvm-project?rev=185522&view=rev
Log:
[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

Modified:
    cfe/trunk/lib/StaticAnalyzer/Checkers/NoReturnFunctionChecker.cpp
    cfe/trunk/test/Analysis/dtor.cpp

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/NoReturnFunctionChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/NoReturnFunctionChecker.cpp?rev=185522&r1=185521&r2=185522&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/NoReturnFunctionChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/NoReturnFunctionChecker.cpp Wed Jul  3 03:23:49 2013
@@ -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;
-
-    if (FD->getAttr<AnalyzerNoReturnAttr>() || FD->isNoReturn())
-      BuildSinks = true;
-    else if (const IdentifierInfo *II = FD->getIdentifier()) {
+  const Expr *Callee = CE.getOriginExpr();
+  if (!BuildSinks && Callee)
+    BuildSinks = getFunctionExtInfo(Callee->getType()).getNoReturn();
+
+  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.

Modified: cfe/trunk/test/Analysis/dtor.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/dtor.cpp?rev=185522&r1=185521&r2=185522&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/dtor.cpp (original)
+++ cfe/trunk/test/Analysis/dtor.cpp Wed Jul  3 03:23:49 2013
@@ -401,3 +401,19 @@ namespace LifetimeExtension {
     clang_analyzer_eval(SaveOnVirtualDestruct::lastOutput == 42); // expected-warning{{TRUE}}
   }
 }
+
+namespace NoReturn {
+  struct NR {
+    ~NR() __attribute__((noreturn));
+  };
+
+  void f(int **x) {
+    NR nr;
+  }
+
+  void g() {
+    int *x;
+    f(&x);
+    *x = 47; // no warning
+  }
+}





More information about the cfe-commits mailing list