summaryrefslogtreecommitdiffstats
path: root/clang/lib/StaticAnalyzer/Core/CallEvent.cpp
diff options
context:
space:
mode:
authorAnna Zaks <ganna@apple.com>2012-08-09 00:21:33 +0000
committerAnna Zaks <ganna@apple.com>2012-08-09 00:21:33 +0000
commit123af098b8780809a409c369d41b28a5ccb95380 (patch)
treed6ff5a279d515335e14c723a7c3ad80bda5f7b2e /clang/lib/StaticAnalyzer/Core/CallEvent.cpp
parenta7b3214c4e1314081086adee0376eb635d4992ad (diff)
downloadbcm5719-llvm-123af098b8780809a409c369d41b28a5ccb95380.tar.gz
bcm5719-llvm-123af098b8780809a409c369d41b28a5ccb95380.zip
[analyzer] Bifurcate the path with dynamic dispatch.
This is an initial (unoptimized) version. We split the path when inlining ObjC instance methods. On one branch we always assume that the type information for the given memory region is precise. On the other we assume that we don't have the exact type info. It is important to check since the class could be subclassed and the method can be overridden. If we always inline we can loose coverage. Had to refactor some of the call eval functions. llvm-svn: 161552
Diffstat (limited to 'clang/lib/StaticAnalyzer/Core/CallEvent.cpp')
-rw-r--r--clang/lib/StaticAnalyzer/Core/CallEvent.cpp40
1 files changed, 22 insertions, 18 deletions
diff --git a/clang/lib/StaticAnalyzer/Core/CallEvent.cpp b/clang/lib/StaticAnalyzer/Core/CallEvent.cpp
index 006ca1043ab..2d96a1ea761 100644
--- a/clang/lib/StaticAnalyzer/Core/CallEvent.cpp
+++ b/clang/lib/StaticAnalyzer/Core/CallEvent.cpp
@@ -382,14 +382,14 @@ static const CXXMethodDecl *devirtualize(const CXXMethodDecl *MD, SVal ThisVal){
}
-const Decl *CXXInstanceCall::getRuntimeDefinition() const {
- const Decl *D = SimpleCall::getRuntimeDefinition();
+RuntimeDefinition CXXInstanceCall::getRuntimeDefinition() const {
+ const Decl *D = SimpleCall::getRuntimeDefinition().Decl;
if (!D)
- return 0;
+ return RuntimeDefinition();
const CXXMethodDecl *MD = cast<CXXMethodDecl>(D);
if (!MD->isVirtual())
- return MD;
+ return RuntimeDefinition(MD, 0);
// If the method is virtual, see if we can find the actual implementation
// based on context-sensitivity.
@@ -398,9 +398,9 @@ const Decl *CXXInstanceCall::getRuntimeDefinition() const {
// because a /partially/ constructed object can be referred to through a
// base pointer. We'll eventually want to use DynamicTypeInfo here.
if (const CXXMethodDecl *Devirtualized = devirtualize(MD, getCXXThisVal()))
- return Devirtualized;
+ return RuntimeDefinition(Devirtualized, 0);
- return 0;
+ return RuntimeDefinition();
}
void CXXInstanceCall::getInitialStackFrameContents(
@@ -512,14 +512,14 @@ void CXXDestructorCall::getExtraInvalidatedRegions(RegionList &Regions) const {
Regions.push_back(static_cast<const MemRegion *>(Data));
}
-const Decl *CXXDestructorCall::getRuntimeDefinition() const {
- const Decl *D = AnyFunctionCall::getRuntimeDefinition();
+RuntimeDefinition CXXDestructorCall::getRuntimeDefinition() const {
+ const Decl *D = AnyFunctionCall::getRuntimeDefinition().Decl;
if (!D)
- return 0;
+ return RuntimeDefinition();
const CXXMethodDecl *MD = cast<CXXMethodDecl>(D);
if (!MD->isVirtual())
- return MD;
+ return RuntimeDefinition(MD, 0);
// If the method is virtual, see if we can find the actual implementation
// based on context-sensitivity.
@@ -528,9 +528,9 @@ const Decl *CXXDestructorCall::getRuntimeDefinition() const {
// because a /partially/ constructed object can be referred to through a
// base pointer. We'll eventually want to use DynamicTypeInfo here.
if (const CXXMethodDecl *Devirtualized = devirtualize(MD, getCXXThisVal()))
- return Devirtualized;
+ return RuntimeDefinition(Devirtualized, 0);
- return 0;
+ return RuntimeDefinition();
}
void CXXDestructorCall::getInitialStackFrameContents(
@@ -659,7 +659,7 @@ ObjCMessageKind ObjCMethodCall::getMessageKind() const {
return static_cast<ObjCMessageKind>(Info.getInt());
}
-const Decl *ObjCMethodCall::getRuntimeDefinition() const {
+RuntimeDefinition ObjCMethodCall::getRuntimeDefinition() const {
const ObjCMessageExpr *E = getOriginExpr();
assert(E);
Selector Sel = E->getSelector();
@@ -669,12 +669,16 @@ const Decl *ObjCMethodCall::getRuntimeDefinition() const {
// Find the the receiver type.
const ObjCObjectPointerType *ReceiverT = 0;
QualType SupersType = E->getSuperType();
+ const MemRegion *Receiver = 0;
+
if (!SupersType.isNull()) {
+ // Super always means the type of immediate predecessor to the method
+ // where the call occurs.
ReceiverT = cast<ObjCObjectPointerType>(SupersType);
} else {
- const MemRegion *Receiver = getReceiverSVal().getAsRegion();
+ Receiver = getReceiverSVal().getAsRegion();
if (!Receiver)
- return 0;
+ return RuntimeDefinition();
QualType DynType = getState()->getDynamicTypeInfo(Receiver).getType();
ReceiverT = dyn_cast<ObjCObjectPointerType>(DynType);
@@ -683,7 +687,7 @@ const Decl *ObjCMethodCall::getRuntimeDefinition() const {
// Lookup the method implementation.
if (ReceiverT)
if (ObjCInterfaceDecl *IDecl = ReceiverT->getInterfaceDecl())
- return IDecl->lookupPrivateMethod(Sel);
+ return RuntimeDefinition(IDecl->lookupPrivateMethod(Sel), Receiver);
} else {
// This is a class method.
@@ -691,11 +695,11 @@ const Decl *ObjCMethodCall::getRuntimeDefinition() const {
// class name.
if (ObjCInterfaceDecl *IDecl = E->getReceiverInterface()) {
// Find/Return the method implementation.
- return IDecl->lookupPrivateClassMethod(Sel);
+ return RuntimeDefinition(IDecl->lookupPrivateClassMethod(Sel), 0);
}
}
- return 0;
+ return RuntimeDefinition();
}
void ObjCMethodCall::getInitialStackFrameContents(
OpenPOWER on IntegriCloud