r324052 - [analyzer] Expose return statement from CallExit program point

George Karpenkov via cfe-commits cfe-commits at lists.llvm.org
Thu Feb 1 18:19:43 PST 2018


Author: george.karpenkov
Date: Thu Feb  1 18:19:43 2018
New Revision: 324052

URL: http://llvm.org/viewvc/llvm-project?rev=324052&view=rev
Log:
[analyzer] Expose return statement from CallExit program point

If the return statement is stored, we might as well allow querying
against it.
Also fix the bug where the return statement is not stored
if there is no return value.
This change un-merges two ExplodedNodes during call exit when the state
is otherwise identical - the CallExitBegin node itself and the "Bind
Return Value"-tagged node.
And expose the return statement through
getStatement helper function.

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

Added:
    cfe/trunk/test/Analysis/return-stmt-merge.cpp
Modified:
    cfe/trunk/include/clang/Analysis/ProgramPoint.h
    cfe/trunk/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp
    cfe/trunk/lib/StaticAnalyzer/Core/CoreEngine.cpp
    cfe/trunk/lib/StaticAnalyzer/Core/PathDiagnostic.cpp

Modified: cfe/trunk/include/clang/Analysis/ProgramPoint.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/ProgramPoint.h?rev=324052&r1=324051&r2=324052&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/ProgramPoint.h (original)
+++ cfe/trunk/include/clang/Analysis/ProgramPoint.h Thu Feb  1 18:19:43 2018
@@ -641,6 +641,10 @@ public:
   CallExitBegin(const StackFrameContext *L, const ReturnStmt *RS)
     : ProgramPoint(RS, CallExitBeginKind, L, nullptr) { }
 
+  const ReturnStmt *getReturnStmt() const {
+    return static_cast<const ReturnStmt *>(getData1());
+  }
+
 private:
   friend class ProgramPoint;
   CallExitBegin() = default;

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp?rev=324052&r1=324051&r2=324052&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp Thu Feb  1 18:19:43 2018
@@ -37,7 +37,9 @@ class AnalysisOrderChecker
                      check::PostCall,
                      check::NewAllocator,
                      check::Bind,
-                     check::RegionChanges> {
+                     check::RegionChanges,
+                     check::LiveSymbols> {
+
   bool isCallbackEnabled(AnalyzerOptions &Opts, StringRef CallbackName) const {
     return Opts.getBooleanOption("*", false, this) ||
         Opts.getBooleanOption(CallbackName, false, this);
@@ -118,6 +120,11 @@ public:
       llvm::errs() << "Bind\n";
   }
 
+  void checkLiveSymbols(ProgramStateRef State, SymbolReaper &SymReaper) const {
+    if (isCallbackEnabled(State, "LiveSymbols"))
+      llvm::errs() << "LiveSymbols\n";
+  }
+
   ProgramStateRef
   checkRegionChanges(ProgramStateRef State,
                      const InvalidatedSymbols *Invalidated,

Modified: cfe/trunk/lib/StaticAnalyzer/Core/CoreEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/CoreEngine.cpp?rev=324052&r1=324051&r2=324052&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/CoreEngine.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/CoreEngine.cpp Thu Feb  1 18:19:43 2018
@@ -307,10 +307,7 @@ void CoreEngine::HandleBlockEdge(const B
     const ReturnStmt *RS = nullptr;
     if (!L.getSrc()->empty()) {
       if (Optional<CFGStmt> LastStmt = L.getSrc()->back().getAs<CFGStmt>()) {
-        if ((RS = dyn_cast<ReturnStmt>(LastStmt->getStmt()))) {
-          if (!RS->getRetValue())
-            RS = nullptr;
-        }
+        RS = dyn_cast<ReturnStmt>(LastStmt->getStmt());
       }
     }
 

Modified: cfe/trunk/lib/StaticAnalyzer/Core/PathDiagnostic.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/PathDiagnostic.cpp?rev=324052&r1=324051&r2=324052&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/PathDiagnostic.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/PathDiagnostic.cpp Thu Feb  1 18:19:43 2018
@@ -742,6 +742,8 @@ const Stmt *PathDiagnosticLocation::getS
     return CEE->getCalleeContext()->getCallSite();
   if (Optional<PostInitializer> PIPP = P.getAs<PostInitializer>())
     return PIPP->getInitializer()->getInit();
+  if (Optional<CallExitBegin> CEB = P.getAs<CallExitBegin>())
+    return CEB->getReturnStmt();
 
   return nullptr;
 }

Added: cfe/trunk/test/Analysis/return-stmt-merge.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/return-stmt-merge.cpp?rev=324052&view=auto
==============================================================================
--- cfe/trunk/test/Analysis/return-stmt-merge.cpp (added)
+++ cfe/trunk/test/Analysis/return-stmt-merge.cpp Thu Feb  1 18:19:43 2018
@@ -0,0 +1,37 @@
+// RUN: %clang_analyze_cc1 -analyzer-checker=debug.AnalysisOrder,debug.ExprInspection -analyzer-config debug.AnalysisOrder:PreCall=true,debug.AnalysisOrder:PostCall=true,debug.AnalysisOrder:LiveSymbols=true %s 2>&1 | FileCheck %s
+
+// This test ensures that check::LiveSymbols is called as many times on the
+// path through the second "return" as it is through the first "return"
+// (three), and therefore the two paths were not merged prematurely before the
+// respective return statement is evaluated.
+// The paths would still be merged later, so we'd have only one post-call for
+// foo(), but it is incorrect to merge them in the middle of evaluating two
+// different statements.
+int coin();
+
+void foo() {
+  int x = coin();
+  if (x > 0)
+    return;
+  else
+    return;
+}
+
+void bar() {
+  foo();
+}
+
+// CHECK:      LiveSymbols
+// CHECK-NEXT: LiveSymbols
+// CHECK-NEXT: PreCall (foo)
+// CHECK-NEXT: LiveSymbols
+// CHECK-NEXT: LiveSymbols
+// CHECK-NEXT: PreCall (coin)
+// CHECK-NEXT: PostCall (coin)
+// CHECK-NEXT: LiveSymbols
+// CHECK-NEXT: LiveSymbols
+// CHECK-NEXT: LiveSymbols
+// CHECK-NEXT: PostCall (foo)
+// CHECK-NEXT: LiveSymbols
+// CHECK-NEXT: LiveSymbols
+// CHECK-NEXT: LiveSymbols




More information about the cfe-commits mailing list