k-wisniewski updated this revision to Diff 79213. k-wisniewski added a comment.
I have added method for getting Objective-C message receivers (as it is related somewhat). This might however be broken for super calls as @NoQ told me as I was writing this comment. @dcoughlin - yes, there are cases when I don't have call event and need to get SVal for instance with which the method was called. The example is when I go up the call stack in RecursionChecker. I have changed CXXRecordDecl to CXXMethodDecl following your suggestion. https://reviews.llvm.org/D26762 Files: include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h Index: include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h =================================================================== --- include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h +++ include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h @@ -14,6 +14,7 @@ #ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_PROGRAMSTATE_H #define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_PROGRAMSTATE_H +#include "clang/AST/ExprCXX.h" #include "clang/Basic/LLVM.h" #include "clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h" #include "clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeInfo.h" @@ -298,6 +299,16 @@ /// that created the given stack frame SVal getArgSVal(const StackFrameContext *SFC, const unsigned ArgIdx) const; + /// Get the symbolic value of the "this" object for a method call + /// that created the given stack frame. Returns None if the + /// stack frame does not represent a method call. + Optional<SVal> getThisSVal(const StackFrameContext *SFC) const; + + /// Get the symbolic value of the receiveer object for a method call + /// that created the given stack frame. Returns None if the + /// stack frame does not represent a method call. + Optional<SVal> getObjCMessageReceiverSVal(const StackFrameContext *SFC) const; + /// Returns the SVal bound to the statement 'S' in the state's environment. SVal getSVal(const Stmt *S, const LocationContext *LCtx) const; @@ -759,6 +770,42 @@ } } +inline Optional<SVal> +ProgramState::getThisSVal(const StackFrameContext *SFC) const { + if (SFC->inTopFrame()) { + const FunctionDecl *FD = SFC->getDecl()->getAsFunction(); + if (!FD) + return None; + const CXXMethodDecl *MD = dyn_cast_or_null<CXXMethodDecl>(FD->getParent()); + if (!MD) + return None; + Loc ThisLoc = getStateManager().getSValBuilder().getCXXThis(MD, SFC); + return getSVal(ThisLoc); + } else { + const Stmt *S = SFC->getCallSite(); + if (!S) + return None; + if (const auto *MCE = dyn_cast<CXXMemberCallExpr>(S)) + return getSVal(MCE->getImplicitObjectArgument(), SFC->getParent()); + else if (const auto *CCE = dyn_cast<CXXConstructExpr>(S)) + return getSVal(CCE, SFC->getParent()); + return None; + } +} + +inline Optional<SVal> +ProgramState::getObjCMessageReceiverSVal(const StackFrameContext *SFC) const { + if (SFC->inTopFrame()) { + const ObjCMethodDecl *methodDecl = dyn_cast<ObjCMethodDecl>(SFC->getDecl()); + Loc SelfLoc = getLValue(methodDecl->getSelfDecl(), SFC); + return getSVal(SelfLoc); + } else { + const ObjCMessageExpr *messageExpr = + dyn_cast<ObjCMessageExpr>(SFC->getCallSite()); + return getSVal(messageExpr->getInstanceReceiver(), SFC); + } +} + inline SVal ProgramState::getSVal(const Stmt *Ex, const LocationContext *LCtx) const{ return Env.getSVal(EnvironmentEntry(Ex, LCtx),
Index: include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h =================================================================== --- include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h +++ include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h @@ -14,6 +14,7 @@ #ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_PROGRAMSTATE_H #define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_PROGRAMSTATE_H +#include "clang/AST/ExprCXX.h" #include "clang/Basic/LLVM.h" #include "clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h" #include "clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeInfo.h" @@ -298,6 +299,16 @@ /// that created the given stack frame SVal getArgSVal(const StackFrameContext *SFC, const unsigned ArgIdx) const; + /// Get the symbolic value of the "this" object for a method call + /// that created the given stack frame. Returns None if the + /// stack frame does not represent a method call. + Optional<SVal> getThisSVal(const StackFrameContext *SFC) const; + + /// Get the symbolic value of the receiveer object for a method call + /// that created the given stack frame. Returns None if the + /// stack frame does not represent a method call. + Optional<SVal> getObjCMessageReceiverSVal(const StackFrameContext *SFC) const; + /// Returns the SVal bound to the statement 'S' in the state's environment. SVal getSVal(const Stmt *S, const LocationContext *LCtx) const; @@ -759,6 +770,42 @@ } } +inline Optional<SVal> +ProgramState::getThisSVal(const StackFrameContext *SFC) const { + if (SFC->inTopFrame()) { + const FunctionDecl *FD = SFC->getDecl()->getAsFunction(); + if (!FD) + return None; + const CXXMethodDecl *MD = dyn_cast_or_null<CXXMethodDecl>(FD->getParent()); + if (!MD) + return None; + Loc ThisLoc = getStateManager().getSValBuilder().getCXXThis(MD, SFC); + return getSVal(ThisLoc); + } else { + const Stmt *S = SFC->getCallSite(); + if (!S) + return None; + if (const auto *MCE = dyn_cast<CXXMemberCallExpr>(S)) + return getSVal(MCE->getImplicitObjectArgument(), SFC->getParent()); + else if (const auto *CCE = dyn_cast<CXXConstructExpr>(S)) + return getSVal(CCE, SFC->getParent()); + return None; + } +} + +inline Optional<SVal> +ProgramState::getObjCMessageReceiverSVal(const StackFrameContext *SFC) const { + if (SFC->inTopFrame()) { + const ObjCMethodDecl *methodDecl = dyn_cast<ObjCMethodDecl>(SFC->getDecl()); + Loc SelfLoc = getLValue(methodDecl->getSelfDecl(), SFC); + return getSVal(SelfLoc); + } else { + const ObjCMessageExpr *messageExpr = + dyn_cast<ObjCMessageExpr>(SFC->getCallSite()); + return getSVal(messageExpr->getInstanceReceiver(), SFC); + } +} + inline SVal ProgramState::getSVal(const Stmt *Ex, const LocationContext *LCtx) const{ return Env.getSVal(EnvironmentEntry(Ex, LCtx),
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits