r338777 - [analyzer] Obtain a ReturnStmt from a CFGAutomaticObjDtor.

Reka Kovacs via cfe-commits cfe-commits at lists.llvm.org
Thu Aug 2 15:31:03 PDT 2018


Author: rkovacs
Date: Thu Aug  2 15:31:03 2018
New Revision: 338777

URL: http://llvm.org/viewvc/llvm-project?rev=338777&view=rev
Log:
[analyzer] Obtain a ReturnStmt from a CFGAutomaticObjDtor.

The CoreEngine only gives us a ReturnStmt if the last element in the
CFGBlock is a CFGStmt, otherwise the ReturnStmt is nullptr.
This patch adds support for the case when the last element is a
CFGAutomaticObjDtor, by returning its TriggerStmt as a ReturnStmt.

Differential Revision: https://reviews.llvm.org/D49811

Added:
    cfe/trunk/test/Analysis/end-function-return-stmt.cpp
Modified:
    cfe/trunk/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp
    cfe/trunk/lib/StaticAnalyzer/Core/CoreEngine.cpp

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp?rev=338777&r1=338776&r2=338777&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp Thu Aug  2 15:31:03 2018
@@ -16,6 +16,7 @@
 
 #include "ClangSACheckers.h"
 #include "clang/AST/ExprCXX.h"
+#include "clang/Analysis/CFGStmtMap.h"
 #include "clang/StaticAnalyzer/Core/Checker.h"
 #include "clang/StaticAnalyzer/Core/CheckerManager.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
@@ -37,6 +38,7 @@ class AnalysisOrderChecker
                      check::PostStmt<OffsetOfExpr>,
                      check::PreCall,
                      check::PostCall,
+                     check::EndFunction,
                      check::NewAllocator,
                      check::Bind,
                      check::RegionChanges,
@@ -121,6 +123,23 @@ public:
     }
   }
 
+  void checkEndFunction(const ReturnStmt *S, CheckerContext &C) const {
+    if (isCallbackEnabled(C, "EndFunction")) {
+      llvm::errs() << "EndFunction\nReturnStmt: " << (S ? "yes" : "no") << "\n";
+      if (!S)
+        return;
+
+      llvm::errs() << "CFGElement: ";
+      CFGStmtMap *Map = C.getCurrentAnalysisDeclContext()->getCFGStmtMap();
+      CFGElement LastElement = Map->getBlock(S)->back();
+
+      if (LastElement.getAs<CFGStmt>())
+        llvm::errs() << "CFGStmt\n";
+      else if (LastElement.getAs<CFGAutomaticObjDtor>())
+        llvm::errs() << "CFGAutomaticObjDtor\n";
+    }
+  }
+
   void checkNewAllocator(const CXXNewExpr *CNE, SVal Target,
                          CheckerContext &C) const {
     if (isCallbackEnabled(C, "NewAllocator"))

Modified: cfe/trunk/lib/StaticAnalyzer/Core/CoreEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/CoreEngine.cpp?rev=338777&r1=338776&r2=338777&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/CoreEngine.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/CoreEngine.cpp Thu Aug  2 15:31:03 2018
@@ -223,8 +223,12 @@ void CoreEngine::HandleBlockEdge(const B
     // Get return statement..
     const ReturnStmt *RS = nullptr;
     if (!L.getSrc()->empty()) {
-      if (Optional<CFGStmt> LastStmt = L.getSrc()->back().getAs<CFGStmt>()) {
+      CFGElement LastElement = L.getSrc()->back();
+      if (Optional<CFGStmt> LastStmt = LastElement.getAs<CFGStmt>()) {
         RS = dyn_cast<ReturnStmt>(LastStmt->getStmt());
+      } else if (Optional<CFGAutomaticObjDtor> AutoDtor =
+                 LastElement.getAs<CFGAutomaticObjDtor>()) {
+        RS = dyn_cast<ReturnStmt>(AutoDtor->getTriggerStmt());
       }
     }
 

Added: cfe/trunk/test/Analysis/end-function-return-stmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/end-function-return-stmt.cpp?rev=338777&view=auto
==============================================================================
--- cfe/trunk/test/Analysis/end-function-return-stmt.cpp (added)
+++ cfe/trunk/test/Analysis/end-function-return-stmt.cpp Thu Aug  2 15:31:03 2018
@@ -0,0 +1,34 @@
+//RUN: %clang_analyze_cc1 -analyzer-checker=debug.AnalysisOrder -analyzer-config debug.AnalysisOrder:EndFunction=true %s 2>&1 | FileCheck %s
+
+// At the end of a function, we can only obtain a ReturnStmt if the last
+// CFGElement in the CFGBlock is either a CFGStmt or a CFGAutomaticObjDtor.
+
+void noReturnStmt() {}
+
+struct S {
+  S();
+  ~S();
+};
+
+int dtorAfterReturnStmt() {
+  S s;
+  return 0;
+}
+
+S endsWithReturnStmt() {
+  return S();
+}
+
+// endsWithReturnStmt()
+// CHECK:      EndFunction
+// CHECK-NEXT: ReturnStmt: yes
+// CHECK-NEXT: CFGElement: CFGStmt
+
+// dtorAfterReturnStmt()
+// CHECK:      EndFunction
+// CHECK-NEXT: ReturnStmt: yes
+// CHECK-NEXT: CFGElement: CFGAutomaticObjDtor
+
+// noReturnStmt()
+// CHECK:      EndFunction
+// CHECK-NEXT: ReturnStmt: no




More information about the cfe-commits mailing list