aboutsummaryrefslogtreecommitdiff
path: root/lib/StaticAnalyzer/Core/CallEvent.cpp
diff options
context:
space:
mode:
authorAnna Zaks <ganna@apple.com>2012-08-24 00:06:12 +0000
committerAnna Zaks <ganna@apple.com>2012-08-24 00:06:12 +0000
commit5a90193ad825656d4a03099cd5e9c928d1782b5e (patch)
tree117e852258e6a0ee104c11f0a0c4499870b1959b /lib/StaticAnalyzer/Core/CallEvent.cpp
parent70ff1091315c60fed68d7197c637ec8c588e67a1 (diff)
[analyzer] Make analyzer less aggressive when dealing with [self init].
With inlining, retain count checker starts tracking 'self' through the init methods. The analyser results were too noisy if the developer did not follow 'self = [super init]' pattern (which is common especially in older code bases) - we reported self init anti-pattern AND possible use-after-free. This patch teaches the retain count checker to assume that [super init] does not fail when it's not consumed by another expression. This silences the retain count warning that warns about possibility of use-after-free when init fails, while preserving all the other checking on 'self'. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@162508 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/StaticAnalyzer/Core/CallEvent.cpp')
-rw-r--r--lib/StaticAnalyzer/Core/CallEvent.cpp29
1 files changed, 25 insertions, 4 deletions
diff --git a/lib/StaticAnalyzer/Core/CallEvent.cpp b/lib/StaticAnalyzer/Core/CallEvent.cpp
index 5345bd5170..d4ee84174e 100644
--- a/lib/StaticAnalyzer/Core/CallEvent.cpp
+++ b/lib/StaticAnalyzer/Core/CallEvent.cpp
@@ -574,6 +574,14 @@ QualType ObjCMethodCall::getDeclaredResultType() const {
return D->getResultType();
}
+SVal ObjCMethodCall::getSelfSVal() const {
+ const LocationContext *LCtx = getLocationContext();
+ const ImplicitParamDecl *SelfDecl = LCtx->getSelfDecl();
+ if (!SelfDecl)
+ return SVal();
+ return getState()->getSVal(getState()->getRegion(SelfDecl, LCtx));
+}
+
SVal ObjCMethodCall::getReceiverSVal() const {
// FIXME: Is this the best way to handle class receivers?
if (!isInstanceMessage())
@@ -584,10 +592,23 @@ SVal ObjCMethodCall::getReceiverSVal() const {
// An instance message with no expression means we are sending to super.
// In this case the object reference is the same as 'self'.
- const LocationContext *LCtx = getLocationContext();
- const ImplicitParamDecl *SelfDecl = LCtx->getSelfDecl();
- assert(SelfDecl && "No message receiver Expr, but not in an ObjC method");
- return getState()->getSVal(getState()->getRegion(SelfDecl, LCtx));
+ assert(getOriginExpr()->getReceiverKind() == ObjCMessageExpr::SuperInstance);
+ SVal SelfVal = getSelfSVal();
+ assert(SelfVal.isValid() && "Calling super but not in ObjC method");
+ return SelfVal;
+}
+
+bool ObjCMethodCall::isReceiverSelfOrSuper() const {
+ if (getOriginExpr()->getReceiverKind() == ObjCMessageExpr::SuperInstance ||
+ getOriginExpr()->getReceiverKind() == ObjCMessageExpr::SuperClass)
+ return true;
+
+ if (!isInstanceMessage())
+ return false;
+
+ SVal RecVal = getSVal(getOriginExpr()->getInstanceReceiver());
+
+ return (RecVal == getSelfSVal());
}
SourceRange ObjCMethodCall::getSourceRange() const {