rnkovacs updated this revision to Diff 158680.
rnkovacs added a comment.

In https://reviews.llvm.org/D49811#1175726, @NoQ wrote:

> I guess you could write a test with `debug.AnalysisOrder` (by making its 
> `checkEndFunction` callback (that you'll have to define) print different 
> things depending on the return statement), not sure if it's worth it; you can 
> also merge this commit with https://reviews.llvm.org/D49361 instead.


This is what I could come up with, what do you think?


https://reviews.llvm.org/D49811

Files:
  lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp
  lib/StaticAnalyzer/Core/CoreEngine.cpp
  test/Analysis/end-function-return-stmt.cpp

Index: test/Analysis/end-function-return-stmt.cpp
===================================================================
--- /dev/null
+++ test/Analysis/end-function-return-stmt.cpp
@@ -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
Index: lib/StaticAnalyzer/Core/CoreEngine.cpp
===================================================================
--- lib/StaticAnalyzer/Core/CoreEngine.cpp
+++ lib/StaticAnalyzer/Core/CoreEngine.cpp
@@ -223,8 +223,12 @@
     // 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());
       }
     }
 
Index: lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp
===================================================================
--- lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp
+++ lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp
@@ -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 @@
                      check::PostStmt<OffsetOfExpr>,
                      check::PreCall,
                      check::PostCall,
+                     check::EndFunction,
                      check::NewAllocator,
                      check::Bind,
                      check::RegionChanges,
@@ -121,6 +123,23 @@
     }
   }
 
+  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"))
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to