r350981 - [analyzer] Introduce a convenience method for getting a CallEvent from an arbitrary Stmt

George Karpenkov via cfe-commits cfe-commits at lists.llvm.org
Fri Jan 11 15:35:04 PST 2019


Author: george.karpenkov
Date: Fri Jan 11 15:35:04 2019
New Revision: 350981

URL: http://llvm.org/viewvc/llvm-project?rev=350981&view=rev
Log:
[analyzer] Introduce a convenience method for getting a CallEvent from an arbitrary Stmt

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

Modified:
    cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
    cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp

Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h?rev=350981&r1=350980&r2=350981&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h Fri Jan 11 15:35:04 2019
@@ -1138,9 +1138,16 @@ class CallEventManager {
 public:
   CallEventManager(llvm::BumpPtrAllocator &alloc) : Alloc(alloc) {}
 
+  /// Gets an outside caller given a callee context.
   CallEventRef<>
   getCaller(const StackFrameContext *CalleeCtx, ProgramStateRef State);
 
+  /// Gets a call event for a function call, Objective-C method call,
+  /// or a 'new' call.
+  CallEventRef<>
+  getCall(const Stmt *S, ProgramStateRef State,
+          const LocationContext *LC);
+
   CallEventRef<>
   getSimpleCall(const CallExpr *E, ProgramStateRef State,
                 const LocationContext *LCtx);

Modified: cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp?rev=350981&r1=350980&r2=350981&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp Fri Jan 11 15:35:04 2019
@@ -1369,28 +1369,23 @@ CallEventManager::getCaller(const StackF
   const Stmt *CallSite = CalleeCtx->getCallSite();
 
   if (CallSite) {
-    if (const CallExpr *CE = dyn_cast<CallExpr>(CallSite))
-      return getSimpleCall(CE, State, CallerCtx);
+    if (CallEventRef<> Out = getCall(CallSite, State, CallerCtx))
+      return Out;
 
-    switch (CallSite->getStmtClass()) {
-    case Stmt::CXXConstructExprClass:
-    case Stmt::CXXTemporaryObjectExprClass: {
-      SValBuilder &SVB = State->getStateManager().getSValBuilder();
-      const auto *Ctor = cast<CXXMethodDecl>(CalleeCtx->getDecl());
-      Loc ThisPtr = SVB.getCXXThis(Ctor, CalleeCtx);
-      SVal ThisVal = State->getSVal(ThisPtr);
-
-      return getCXXConstructorCall(cast<CXXConstructExpr>(CallSite),
-                                   ThisVal.getAsRegion(), State, CallerCtx);
-    }
-    case Stmt::CXXNewExprClass:
-      return getCXXAllocatorCall(cast<CXXNewExpr>(CallSite), State, CallerCtx);
-    case Stmt::ObjCMessageExprClass:
-      return getObjCMethodCall(cast<ObjCMessageExpr>(CallSite),
-                               State, CallerCtx);
-    default:
-      llvm_unreachable("This is not an inlineable statement.");
-    }
+    Stmt::StmtClass SC = CallSite->getStmtClass();
+
+    // All other cases are handled by getCall.
+    assert(SC == Stmt::CXXConstructExprClass ||
+           SC == Stmt::CXXTemporaryObjectExprClass &&
+               "This is not an inlineable statement");
+
+    SValBuilder &SVB = State->getStateManager().getSValBuilder();
+    const auto *Ctor = cast<CXXMethodDecl>(CalleeCtx->getDecl());
+    Loc ThisPtr = SVB.getCXXThis(Ctor, CalleeCtx);
+    SVal ThisVal = State->getSVal(ThisPtr);
+
+    return getCXXConstructorCall(cast<CXXConstructExpr>(CallSite),
+                                 ThisVal.getAsRegion(), State, CallerCtx);
   }
 
   // Fall back to the CFG. The only thing we haven't handled yet is
@@ -1417,3 +1412,16 @@ CallEventManager::getCaller(const StackF
                               E.getAs<CFGBaseDtor>().hasValue(), State,
                               CallerCtx);
 }
+
+CallEventRef<> CallEventManager::getCall(const Stmt *S, ProgramStateRef State,
+                                         const LocationContext *LC) {
+  if (const auto *CE = dyn_cast<CallExpr>(S)) {
+    return getSimpleCall(CE, State, LC);
+  } else if (const auto *NE = dyn_cast<CXXNewExpr>(S)) {
+    return getCXXAllocatorCall(NE, State, LC);
+  } else if (const auto *ME = dyn_cast<ObjCMessageExpr>(S)) {
+    return getObjCMethodCall(ME, State, LC);
+  } else {
+    return nullptr;
+  }
+}




More information about the cfe-commits mailing list