[PATCH] [analyzer] Improve handling of noreturn destructors

Pavel Labath labath at google.com
Tue Jul 2 03:21:02 PDT 2013


  Should be fixed, if I got your point right.

Hi jordan_rose,

http://llvm-reviews.chandlerc.com/D1056

CHANGE SINCE LAST DIFF
  http://llvm-reviews.chandlerc.com/D1056?vs=2595&id=2648#toc

Files:
  lib/StaticAnalyzer/Checkers/NoReturnFunctionChecker.cpp
  test/Analysis/dtor.cpp

Index: lib/StaticAnalyzer/Checkers/NoReturnFunctionChecker.cpp
===================================================================
--- lib/StaticAnalyzer/Checkers/NoReturnFunctionChecker.cpp
+++ lib/StaticAnalyzer/Checkers/NoReturnFunctionChecker.cpp
@@ -26,31 +26,29 @@
 
 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.
Index: test/Analysis/dtor.cpp
===================================================================
--- test/Analysis/dtor.cpp
+++ test/Analysis/dtor.cpp
@@ -401,3 +401,19 @@
     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
+  }
+}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D1056.2.patch
Type: text/x-patch
Size: 2538 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20130702/0e37003b/attachment.bin>


More information about the cfe-commits mailing list