255 lines · plain
1// RUN: %clang_cc1 -fobjc-runtime=macosx-10.10.0 -emit-llvm -o - %s -fno-objc-convert-messages-to-runtime-calls -fobjc-exceptions -fexceptions | FileCheck %s --check-prefix=MSGS2// RUN: %clang_cc1 -fobjc-runtime=macosx-10.10.0 -emit-llvm -o - %s -fobjc-exceptions -fexceptions | FileCheck %s --check-prefix=CALLS3// RUN: %clang_cc1 -fobjc-runtime=macosx-10.9.0 -emit-llvm -o - %s -fobjc-exceptions -fexceptions | FileCheck %s --check-prefix=MSGS4// RUN: %clang_cc1 -fobjc-runtime=macosx-fragile-10.10.0 -emit-llvm -o - %s -fobjc-exceptions -fexceptions | FileCheck %s --check-prefix=MSGS5// RUN: %clang_cc1 -fobjc-runtime=ios-8.0 -emit-llvm -o - %s -fobjc-exceptions -fexceptions | FileCheck %s --check-prefix=CALLS6// RUN: %clang_cc1 -fobjc-runtime=ios-7.0 -emit-llvm -o - %s -fobjc-exceptions -fexceptions | FileCheck %s --check-prefix=MSGS7// Note: This line below is for tvos for which the driver passes through to use the ios9.0 runtime.8// RUN: %clang_cc1 -fobjc-runtime=ios-9.0 -emit-llvm -o - %s -fobjc-exceptions -fexceptions | FileCheck %s --check-prefix=CALLS9// RUN: %clang_cc1 -fobjc-runtime=watchos-2.0 -emit-llvm -o - %s -fobjc-exceptions -fexceptions | FileCheck %s --check-prefix=CALLS10 11#define nil (id)012 13@interface NSObject14+ (id)alloc;15+ (id)allocWithZone:(void*)zone;16+ (id)alloc2;17- (id)retain;18- (void)release;19- (id)autorelease;20@end21 22// CHECK-LABEL: define {{.*}}void @test123void test1(id x) {24 // MSGS: {{call.*@objc_msgSend}}25 // MSGS: {{call.*@objc_msgSend}}26 // MSGS: {{call.*@objc_msgSend}}27 // MSGS: {{call.*@objc_msgSend}}28 // MSGS: {{call.*@objc_msgSend}}29 // CALLS: {{call.*@objc_alloc}}30 // CALLS: {{call.*@objc_allocWithZone}}31 32 // Note that calls to the intrinsics are not allowed for33 // retain/release/autorelease they're marked `thisreturn`, which isn't34 // guaranteed to be true for classes that define their own `-retain`, for35 // example. Be sure to keep these as normal function calls:36 // CALLS: {{call.*@objc_retain}}37 // CALLS: {{call.*@objc_release}}38 // CALLS: {{tail call.*@objc_autorelease}}39 [NSObject alloc];40 [NSObject allocWithZone:nil];41 [x retain];42 [x release];43 [x autorelease];44}45 46// CHECK-LABEL: define {{.*}}void @check_invoke47void check_invoke(void) {48 // MSGS: {{invoke.*@objc_msgSend}}49 // MSGS: {{invoke.*@objc_msgSend}}50 // CALLS: {{invoke.*@objc_alloc}}51 // CALLS: {{invoke.*@objc_allocWithZone}}52 @try {53 [NSObject alloc];54 [NSObject allocWithZone:nil];55 } @catch (...) {56 }57}58 59// CHECK-LABEL: define {{.*}}void @test260void test2(void* x) {61 // MSGS: {{call.*@objc_msgSend}}62 // MSGS: {{call.*@objc_msgSend}}63 // MSGS: {{call.*@objc_msgSend}}64 // CALLS: {{call.*@objc_msgSend}}65 // CALLS: {{call.*@objc_msgSend}}66 // CALLS: {{call.*@objc_msgSend}}67 [NSObject alloc2];68 [NSObject allocWithZone:(void*)-1];69 [NSObject allocWithZone:x];70}71 72@class A;73@interface B74+ (A*) alloc;75+ (A*) allocWithZone:(void*)zone;76- (A*) alloc;77- (A*) allocWithZone:(void*)zone;78- (A*) retain;79- (A*) autorelease;80@end81 82// CHECK-LABEL: define {{.*}}void @test_alloc_class_ptr83A* test_alloc_class_ptr(void) {84 // CALLS: {{call.*@objc_alloc}}85 // CALLS-NEXT: ret86 return [B alloc];87}88 89// CHECK-LABEL: define {{.*}}void @test_alloc_class_ptr90A* test_allocWithZone_class_ptr(void) {91 // CALLS: {{call.*@objc_allocWithZone}}92 // CALLS-NEXT: ret93 return [B allocWithZone:nil];94}95 96// Only call objc_alloc on a Class, not an instance97// CHECK-LABEL: define {{.*}}void @test_alloc_instance98void test_alloc_instance(A *a) {99 // CALLS: {{call.*@objc_alloc}}100 // CALLS: {{call.*@objc_allocWithZone}}101 // CALLS: {{call.*@objc_msgSend}}102 // CALLS: {{call.*@objc_msgSend}}103 [A alloc];104 [A allocWithZone:nil];105 [a alloc];106 [a allocWithZone:nil];107}108 109// Make sure we get a bitcast on the return type as the110// call will return ptr which we have to cast to A*111// CHECK-LABEL: define {{.*}}void @test_retain_class_ptr112A* test_retain_class_ptr(B *b) {113 // CALLS: {{call.*@objc_retain}}114 // CALLS-NEXT: ret115 return [b retain];116}117 118// Make sure we get a bitcast on the return type as the119// call will return ptr which we have to cast to A*120// CHECK-LABEL: define {{.*}}void @test_autorelease_class_ptr121A* test_autorelease_class_ptr(B *b) {122 // CALLS: {{tail call.*@objc_autorelease}}123 // CALLS-NEXT: ret124 return [b autorelease];125}126 127 128@interface C129+ (id)allocWithZone:(int)intArg;130- (float) retain;131@end132 133// Make sure we only accept pointer types134// CHECK-LABEL: define {{.*}}void @test_allocWithZone_int135C* test_allocWithZone_int(void) {136 // MSGS: {{call.*@objc_msgSend}}137 // CALLS: {{call.*@objc_msgSend}}138 return [C allocWithZone:3];139}140 141// Make sure we use a message and not a call as the return type is142// not a pointer type.143// CHECK-LABEL: define {{.*}}void @test_cannot_message_return_float144float test_cannot_message_return_float(C *c) {145 // MSGS: {{call.*@objc_msgSend}}146 // CALLS: {{call.*@objc_msgSend}}147 return [c retain];148}149 150@interface TestSelf151+ (instancetype)alloc;152+ (instancetype)allocWithZone:(void*)zone;153+ (id)classMeth;154- (id)instanceMeth;155@end156 157@implementation TestSelf158// CHECK-LABEL: define internal ptr @"\01+[TestSelf classMeth]"(159+ (id)classMeth {160 // MSGS: {{call.*@objc_msgSend}}161 // MSGS: {{call.*@objc_msgSend}}162 // CALLS: {{call.*@objc_allocWithZone\(}}163 // CALLS: {{call.*@objc_alloc\(}}164 [self allocWithZone:nil];165 return [self alloc];166}167// CHECK-LABEL: define internal ptr @"\01-[TestSelf instanceMeth]"(168- (id)instanceMeth {169 // MSGS: {{call.*@objc_msgSend}}170 // MSGS: {{call.*@objc_msgSend}}171 // CALLS: {{call.*@objc_msgSend}}172 // CALLS: {{call.*@objc_msgSend}}173 [self allocWithZone:nil];174 return [self alloc];175}176@end177 178@interface NSString : NSObject179+ (void)retain_self;180- (void)retain_super;181@end182 183@implementation NSString184 185// Make sure we can convert a message to a dynamic receiver to a call186// CHECK-LABEL: define {{.*}}void @retain_self187+ (void)retain_self {188 // MSGS: {{call.*@objc_msgSend}}189 // CALLS: {{call.*@objc_retain}}190 [self retain];191}192 193// Make sure we never convert a message to super to a call194// CHECK-LABEL: define {{.*}}void @retain_super195- (void)retain_super {196 // MSGS: {{call.*@objc_msgSend}}197 // CALLS: {{call.*@objc_msgSend}}198 [super retain];199}200 201@end202 203@class Ety;204 205// CHECK-LABEL: define {{.*}}void @testException_release206void testException_release(NSObject *a) {207 // MSGS: {{invoke.*@objc_msgSend}}208 // CALLS: invoke{{.*}}void @objc_release(ptr %209 @try {210 [a release];211 } @catch (Ety *e) {212 }213}214 215// CHECK-LABEL: define {{.*}}void @testException_autorelease216void testException_autorelease(NSObject *a) {217 @try {218 // MSGS: {{invoke.*@objc_msgSend}}219 // CALLS: invoke{{.*}}objc_autorelease(ptr %220 [a autorelease];221 } @catch (Ety *e) {222 }223}224 225// CHECK-LABEL: define {{.*}}void @testException_retain226void testException_retain(NSObject *a) {227 @try {228 // MSGS: {{invoke.*@objc_msgSend}}229 // CALLS: invoke{{.*}}@objc_retain(ptr %230 [a retain];231 } @catch (Ety *e) {232 }233}234 235 236// CHECK-LABEL: define {{.*}}void @testException_alloc(237void testException_alloc(void) {238 @try {239 // MSGS: {{invoke.*@objc_msgSend}}240 // CALLS: invoke{{.*}}@objc_alloc(ptr %241 [A alloc];242 } @catch (Ety *e) {243 }244}245 246// CHECK-LABEL: define {{.*}}void @testException_allocWithZone247void testException_allocWithZone(void) {248 @try {249 // MSGS: {{invoke.*@objc_msgSend}}250 // CALLS: invoke{{.*}}@objc_allocWithZone(ptr %251 [A allocWithZone:nil];252 } @catch (Ety *e) {253 }254}255