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
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits