99 lines · plain
1// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-MRC2// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fobjc-arc -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-ARC3 4__attribute__((objc_root_class))5@interface Root6- (instancetype) init;7@end8 9@interface Base : Root10@end11 12@interface Middle : Base13+ (void) abort __attribute__((noreturn));14- (void) fail __attribute__((noreturn));15@end16 17@interface Derived : Middle18@end19 20// An arbitrary instance pointer may be null.21void testInstanceMethod(Derived *x) {22 [x fail];23}24// CHECK-LABEL: @testInstanceMethod25// CHECK: call void @objc_msgSend(ptr {{.*}}, ptr {{.*}}){{$}}26 27// A direct call of a class method will normally never have a null receiver.28void testClassMethod(void) {29 [Derived abort];30}31// CHECK-LABEL: @testClassMethod32// CHECK: call void @objc_msgSend(ptr {{.*}}, ptr {{.*}}) [[NORETURN:#[0-9]+]]33 34__attribute__((weak_import))35@interface WeakMiddle : Base36@end37 38@interface WeakDerived : WeakMiddle39+ (void) abort __attribute__((noreturn));40@end41 42// The class pointer of a weakly-imported class may be null.43void testWeakImport(void) {44 [WeakDerived abort];45}46// CHECK-LABEL: @testWeakImport47// CHECK: call void @objc_msgSend(ptr {{.*}}, ptr {{.*}}){{$}}48 49@interface Derived (MyMethods)50@end51 52@implementation Derived (MyMethods)53 54// In general, self can be reassigned, so we can't make stronger assumptions.55// But ARC makes self const in an ordinary method.56// TODO: do the analysis to take advantage of the dominant case where57// self is not reassigned.58- (void) testSelfInstanceMethod {59 [self fail];60}61// CHECK-LABEL: [Derived(MyMethods) testSelfInstanceMethod]62// CHECK-MRC: call void @objc_msgSend(ptr {{.*}}, ptr {{.*}}){{$}}63// CHECK-ARC: call void @objc_msgSend(ptr {{.*}}, ptr {{.*}}) [[NORETURN]]64 65// The ARC rule doesn't apply in -init methods.66- (id) initWhileTestingSelfInstanceMethod {67 self = [super init];68 [self fail];69 return self;70}71// CHECK-LABEL: [Derived(MyMethods) initWhileTestingSelfInstanceMethod]72// CHECK: call void @objc_msgSend(ptr {{.*}}, ptr {{.*}}){{$}}73 74// Same thing applies to class methods.75+ (void) testSelfClassMethod {76 [self abort];77}78// CHECK-LABEL: [Derived(MyMethods) testSelfClassMethod]79// CHECK-MRC: call void @objc_msgSend(ptr {{.*}}, ptr {{.*}}){{$}}80// CHECK-ARC: call void @objc_msgSend(ptr {{.*}}, ptr {{.*}}) [[NORETURN]]81 82// Super invocations may never be used with a null pointer; this is a83// constraint on user code when it isn't enforced by the ARC const-self84// rule.85- (void) testSuperInstanceMethod {86 [super fail];87}88// CHECK-LABEL: [Derived(MyMethods) testSuperInstanceMethod]89// CHECK: call void @objc_msgSendSuper2(ptr {{.*}}, ptr {{.*}}) [[NORETURN]]90 91+ (void) testSuperClassMethod {92 [super abort];93}94// CHECK-LABEL: [Derived(MyMethods) testSuperClassMethod]95// CHECK: call void @objc_msgSendSuper2(ptr {{.*}}, ptr {{.*}}) [[NORETURN]]96@end97 98// CHECK: attributes [[NORETURN]] = { noreturn }99