aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnna Zaks <ganna@apple.com>2012-08-14 00:36:20 +0000
committerAnna Zaks <ganna@apple.com>2012-08-14 00:36:20 +0000
commitc739406d37b9b1dc95bc3a3d899024e5ce31e5d5 (patch)
tree8370bae29350df3100cfa3f00d1c13341621743b
parentc95bb76e85ff9a37de23821f713d947dcbc98f35 (diff)
[analyzer] Teach live variable analyzes that super uses self pointer.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@161822 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Analysis/LiveVariables.cpp8
-rw-r--r--test/Analysis/inlining/RetainCountExamples.m33
2 files changed, 41 insertions, 0 deletions
diff --git a/lib/Analysis/LiveVariables.cpp b/lib/Analysis/LiveVariables.cpp
index 584d81284e..38f8199bff 100644
--- a/lib/Analysis/LiveVariables.cpp
+++ b/lib/Analysis/LiveVariables.cpp
@@ -284,6 +284,14 @@ void TransferFunctions::Visit(Stmt *S) {
}
break;
}
+ case Stmt::ObjCMessageExprClass: {
+ // In calls to super, include the implicit "self" pointer as being live.
+ ObjCMessageExpr *CE = cast<ObjCMessageExpr>(S);
+ if (CE->getReceiverKind() == ObjCMessageExpr::SuperInstance)
+ val.liveDecls = LV.DSetFact.add(val.liveDecls,
+ LV.analysisContext.getSelfDecl());
+ break;
+ }
case Stmt::DeclStmtClass: {
const DeclStmt *DS = cast<DeclStmt>(S);
if (const VarDecl *VD = dyn_cast<VarDecl>(DS->getSingleDecl())) {
diff --git a/test/Analysis/inlining/RetainCountExamples.m b/test/Analysis/inlining/RetainCountExamples.m
new file mode 100644
index 0000000000..2b682c2b4b
--- /dev/null
+++ b/test/Analysis/inlining/RetainCountExamples.m
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount -analyzer-ipa=dynamic-bifurcate -verify %s
+
+typedef signed char BOOL;
+typedef struct objc_class *Class;
+typedef struct objc_object {
+ Class isa;
+} *id;
+@protocol NSObject - (BOOL)isEqual:(id)object; @end
+@interface NSObject <NSObject> {}
++(id)alloc;
++(id)new;
+- (oneway void)release;
+-(id)init;
+-(id)autorelease;
+-(id)copy;
+- (Class)class;
+-(id)retain;
+@end
+
+@interface SelfStaysLive : NSObject
+- (id)init;
+@end
+
+@implementation SelfStaysLive
+- (id)init {
+ return [super init];
+}
+@end
+
+void selfStaysLive() {
+ SelfStaysLive *foo = [[SelfStaysLive alloc] init];
+ [foo release];
+} \ No newline at end of file