ObjCDynTypePopagation.m revision c4c647c88ced2e953f15f8987952ede9b96aa969
1// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-ipa=dynamic -verify %s 2 3typedef signed char BOOL; 4 5void clang_analyzer_eval(BOOL); 6 7@protocol NSObject - (BOOL)isEqual:(id)object; @end 8@interface NSObject <NSObject> {} 9+(id)alloc; 10-(id)init; 11+(id)new; 12-(id)autorelease; 13-(id)copy; 14- (Class)class; 15-(id)retain; 16@end 17 18@interface MyParent : NSObject 19- (int)getZeroOverridden; 20@end 21@implementation MyParent 22- (int) getZeroOverridden { 23 return 1; 24} 25- (int) getZero { 26 return 0; 27} 28@end 29 30@interface MyClass : MyParent 31- (int) getZeroOverridden; 32@end 33 34MyClass *getObj(); 35 36@implementation MyClass 37- (int) getZeroOverridden { 38 return 0; 39} 40 41/* Test that we get the right type from call to alloc. */ 42 43+ (void) testAllocSelf { 44 id a = [self alloc]; 45 clang_analyzer_eval([a getZeroOverridden] == 0); // expected-warning{{TRUE}} 46} 47 48 49+ (void) testAllocClass { 50 id a = [MyClass alloc]; 51 clang_analyzer_eval([a getZeroOverridden] == 0); // expected-warning{{TRUE}} 52} 53 54+ (void) testAllocSuperOverriden { 55 id a = [super alloc]; 56 // Evaluates to 1 in the parent. 57 clang_analyzer_eval([a getZeroOverridden] == 0); // expected-warning{{FALSE}} 58} 59 60+ (void) testAllocSuper { 61 id a = [super alloc]; 62 clang_analyzer_eval([a getZero] == 0); // expected-warning{{TRUE}} 63} 64 65+ (void) testAllocInit { 66 id a = [[self alloc] init]; 67 clang_analyzer_eval([a getZeroOverridden] == 0); // expected-warning{{TRUE}} 68} 69 70+ (void) testNewSelf { 71 id a = [self new]; 72 clang_analyzer_eval([a getZeroOverridden] == 0); // expected-warning{{TRUE}} 73} 74 75// Casting to parent should not pessimize the dynamic type. 76+ (void) testCastToParent { 77 id a = [[self alloc] init]; 78 MyParent *p = a; 79 clang_analyzer_eval([p getZeroOverridden] == 0); // expected-warning{{TRUE}} 80} 81 82// The type of parameter gets used. 83+ (void)testTypeFromParam:(MyParent*) p { 84 clang_analyzer_eval([p getZero] == 0); // expected-warning{{TRUE}} 85} 86 87// Test implisit cast. 88+ (void) testCastFromId:(id) a { 89 MyParent *p = a; 90 clang_analyzer_eval([p getZero] == 0); // expected-warning{{TRUE}} 91} 92 93@end