forked from OSchip/llvm-project
[analyzer] Introduce a convenience method for getting a CallEvent from an arbitrary Stmt
Differential Revision: https://reviews.llvm.org/D56300 llvm-svn: 350981
This commit is contained in:
parent
c1fde4fa94
commit
9f3a279f2c
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
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);
|
||||
Stmt::StmtClass SC = CallSite->getStmtClass();
|
||||
|
||||
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.");
|
||||
}
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue