diff options
author | George Karpenkov <ekarpenkov@apple.com> | 2019-01-11 23:35:04 +0000 |
---|---|---|
committer | George Karpenkov <ekarpenkov@apple.com> | 2019-01-11 23:35:04 +0000 |
commit | 99a758aff1a1e1135183732b6a28358dd8a2525d (patch) | |
tree | 121866b3cbc2f02d0b9bdfc4fa1f190bfd4e9198 | |
parent | 27e3ee93074f6cdadfda79bfee6406bc540b88ea (diff) |
[analyzer] Introduce a convenience method for getting a CallEvent from an arbitrary Stmt
Differential Revision: https://reviews.llvm.org/D56300
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350981 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h | 7 | ||||
-rw-r--r-- | lib/StaticAnalyzer/Core/CallEvent.cpp | 52 |
2 files changed, 37 insertions, 22 deletions
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h b/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h index a53e8ee693..81dd83fc10 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h @@ -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); diff --git a/lib/StaticAnalyzer/Core/CallEvent.cpp b/lib/StaticAnalyzer/Core/CallEvent.cpp index 20baa30265..e26e7de10e 100644 --- a/lib/StaticAnalyzer/Core/CallEvent.cpp +++ b/lib/StaticAnalyzer/Core/CallEvent.cpp @@ -1369,28 +1369,23 @@ CallEventManager::getCaller(const StackFrameContext *CalleeCtx, const Stmt *CallSite = CalleeCtx->getCallSite(); if (CallSite) { - if (const CallExpr *CE = dyn_cast<CallExpr>(CallSite)) - return getSimpleCall(CE, State, CallerCtx); - - 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."); - } + if (CallEventRef<> Out = getCall(CallSite, State, CallerCtx)) + return Out; + + 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 StackFrameContext *CalleeCtx, 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; + } +} |