aboutsummaryrefslogtreecommitdiff
path: root/clang
diff options
context:
space:
mode:
authorGeorge Karpenkov <ekarpenkov@apple.com>2019-01-11 23:35:04 +0000
committerGeorge Karpenkov <ekarpenkov@apple.com>2019-01-11 23:35:04 +0000
commit9f3a279f2c999a9d2d26104824b9bd5fc14be6cb (patch)
treeb9100ea84427923501f6dde2a1ea05902a30b1fd /clang
parentc1fde4fa943fd03a3d40bc5d32b9e0045fd29208 (diff)
[analyzer] Introduce a convenience method for getting a CallEvent from an arbitrary Stmt
Differential Revision: https://reviews.llvm.org/D56300 llvm-svn: 350981
Diffstat (limited to 'clang')
-rw-r--r--clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h7
-rw-r--r--clang/lib/StaticAnalyzer/Core/CallEvent.cpp52
2 files changed, 37 insertions, 22 deletions
diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
index a53e8ee693f4..81dd83fc1071 100644
--- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
+++ b/clang/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/clang/lib/StaticAnalyzer/Core/CallEvent.cpp b/clang/lib/StaticAnalyzer/Core/CallEvent.cpp
index 20baa302658e..e26e7de10e8c 100644
--- a/clang/lib/StaticAnalyzer/Core/CallEvent.cpp
+++ b/clang/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;
+ }
+}