1// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-MRC
2// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fobjc-arc -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-ARC
3
4__attribute__((objc_root_class))
5@interface Root
6- (instancetype) init;
7@end
8
9@interface Base : Root
10@end
11
12@interface Middle : Base
13+ (void) abort __attribute__((noreturn));
14- (void) fail __attribute__((noreturn));
15@end
16
17@interface Derived : Middle
18@end
19
20// An arbitrary instance pointer may be null.
21void testInstanceMethod(Derived *x) {
22  [x fail];
23}
24// CHECK-LABEL: @testInstanceMethod
25// CHECK: call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*)*)(i8* {{.*}}, i8* {{.*}}){{$}}
26
27// A direct call of a class method will normally never have a null receiver.
28void testClassMethod() {
29  [Derived abort];
30}
31// CHECK-LABEL: @testClassMethod
32// CHECK: call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*)*)(i8* {{.*}}, i8* {{.*}}) [[NORETURN:#[0-9]+]]
33
34__attribute__((weak_import))
35@interface WeakMiddle : Base
36@end
37
38@interface WeakDerived : WeakMiddle
39+ (void) abort __attribute__((noreturn));
40@end
41
42// The class pointer of a weakly-imported class may be null.
43void testWeakImport() {
44  [WeakDerived abort];
45}
46// CHECK-LABEL: @testWeakImport
47// CHECK: call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*)*)(i8* {{.*}}, i8* {{.*}}){{$}}
48
49@interface Derived (MyMethods)
50@end
51
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 where
57// self is not reassigned.
58- (void) testSelfInstanceMethod {
59  [self fail];
60}
61// CHECK-LABEL: [Derived(MyMethods) testSelfInstanceMethod]
62// CHECK-MRC: call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*)*)(i8* {{.*}}, i8* {{.*}}){{$}}
63// CHECK-ARC: call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*)*)(i8* {{.*}}, i8* {{.*}}) [[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 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*)*)(i8* {{.*}}, i8* {{.*}}){{$}}
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 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*)*)(i8* {{.*}}, i8* {{.*}}){{$}}
80// CHECK-ARC: call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*)*)(i8* {{.*}}, i8* {{.*}}) [[NORETURN]]
81
82// Super invocations may never be used with a null pointer; this is a
83// constraint on user code when it isn't enforced by the ARC const-self
84// rule.
85- (void) testSuperInstanceMethod {
86  [super fail];
87}
88// CHECK-LABEL: [Derived(MyMethods) testSuperInstanceMethod]
89// CHECK: call void bitcast (i8* ([[SUPER_T:%.*]]*, i8*, ...)* @objc_msgSendSuper2 to void ([[SUPER_T]]*, i8*)*)([[SUPER_T]]* {{.*}}, i8* {{.*}}) [[NORETURN]]
90
91+ (void) testSuperClassMethod {
92  [super abort];
93}
94// CHECK-LABEL: [Derived(MyMethods) testSuperClassMethod]
95// CHECK: call void bitcast (i8* ([[SUPER_T]]*, i8*, ...)* @objc_msgSendSuper2 to void ([[SUPER_T]]*, i8*)*)([[SUPER_T]]* {{.*}}, i8* {{.*}}) [[NORETURN]]
96@end
97
98// CHECK: attributes [[NORETURN]] = { noreturn }
99