[docs] Add LICENSE.txt to the root of the mono-repo
[llvm-project.git] / clang / test / CodeGenObjC / gnu-nil-receiver.m
blob27f3126aff8b2303b093049d7a0fe440b93f2c41
1 // RUN: %clang_cc1 -no-opaque-pointers -triple x86_64-unknown-freebsd -fobjc-arc -S -emit-llvm -fobjc-runtime=gnustep-2.0 -o - %s | FileCheck %s
3 typedef struct {
4   int x[12];
5 } Big;
7 @protocol P
8 - (Big) foo;
9 - (Big) fooConsuming: (__attribute__((ns_consumed)) id) arg;
10 - (_Complex float) complex;
11 @end
13 @interface SuperClass
14 - (Big) foo;
15 @end
17 @implementation TestClass : SuperClass
18 //   Check that we don't do a nil check when messaging self in ARC
19 //   (which forbids reassigning self)
20 // CHECK-LABEL: define{{.*}} void @_i_TestClass__test_self_send(
21 // CHECK-NOT:   icmp
22 // CHECK:       @objc_msg_lookup_sender
23 - (void) test_self_send {
24   Big big = [self foo];
27 //   Check that we don't do a nil test when messaging super.
28 // CHECK-LABEL: define{{.*}} void @_i_TestClass__test_super_send(
29 // CHECK-NOT:   icmp
30 // CHECK:       @objc_msg_lookup_super
31 - (void) test_super_send {
32   Big big = [super foo];
34 @end
36 // CHECK-LABEL: define{{.*}} void @test_loop_zeroing(
37 // CHECK:         [[P:%.*]] = alloca i8*,
38 // CHECK:         [[BIG:%.*]] = alloca %struct.Big,
39 // CHECK:         br label %for.cond
41 // CHECK:       for.cond:
42 // CHECK-NEXT:    [[RECEIVER:%.*]] = load i8*, i8** [[P]],
43 // CHECK-NEXT:    [[ISNIL:%.*]] = icmp eq i8* [[RECEIVER]], null
44 // CHECK-NEXT:    br i1 [[ISNIL]], label %nilReceiverCleanup, label %msgSend
46 // CHECK:       msgSend:
47 // CHECK:         @objc_msg_lookup_sender
48 // CHECK:         call void {{%.*}}({{.*}} [[BIG]],
49 // CHECK:         br label %continue
51 // CHECK:       nilReceiverCleanup:
52 // CHECK-NEXT:    [[T0:%.*]] = bitcast %struct.Big* [[BIG]] to i8*
53 // CHECK-NEXT:    call void @llvm.memset.p0i8.i64(i8* align 4 [[T0]], i8 0, i64 48, i1 false)
54 // CHECK-NEXT:    br label %continue
56 // CHECK:       continue:
57 // CHECK-NEXT:    br label %for.cond
58 void test_loop_zeroing(id<P> p) {
59   for (;;) {
60     Big big = [p foo];
61   }
64 // CHECK-LABEL: define{{.*}} void @test_zeroing_and_consume(
65 // CHECK:         [[P:%.*]] = alloca i8*,
66 // CHECK:         [[Q:%.*]] = alloca i8*,
67 // CHECK:         [[BIG:%.*]] = alloca %struct.Big,
68 // CHECK:         br label %for.cond
70 // CHECK:       for.cond:
71 // CHECK-NEXT:    [[RECEIVER:%.*]] = load i8*, i8** [[P]],
72 // CHECK-NEXT:    [[Q_LOAD:%.*]] = load i8*, i8** [[Q]],
73 // CHECK-NEXT:    [[Q_RETAIN:%.*]] = call i8* @llvm.objc.retain(i8* [[Q_LOAD]])
74 // CHECK-NEXT:    [[ISNIL:%.*]] = icmp eq i8* [[RECEIVER]], null
75 // CHECK-NEXT:    br i1 [[ISNIL]], label %nilReceiverCleanup, label %msgSend
77 // CHECK:       msgSend:
78 // CHECK:         @objc_msg_lookup_sender
79 // CHECK:         call void {{%.*}}({{.*}} [[BIG]],
80 // CHECK:         br label %continue
82 // CHECK:       nilReceiverCleanup:
83 // CHECK-NEXT:    call void @llvm.objc.release(i8* [[Q_RETAIN]])
84 // CHECK-NEXT:    [[T0:%.*]] = bitcast %struct.Big* [[BIG]] to i8*
85 // CHECK-NEXT:    call void @llvm.memset.p0i8.i64(i8* align 4 [[T0]], i8 0, i64 48, i1 false)
86 // CHECK-NEXT:    br label %continue
88 // CHECK:       continue:
89 // CHECK-NEXT:    br label %for.cond
90 void test_zeroing_and_consume(id<P> p, id q) {
91   for (;;) {
92     Big big = [p fooConsuming: q];
93   }
96 // CHECK-LABEL: define{{.*}} void @test_complex(
97 // CHECK:         [[P:%.*]] = alloca i8*,
98 // CHECK:         [[RECEIVER:%.*]] = load i8*, i8** [[P]],
99 // CHECK-NEXT:    [[ISNIL:%.*]] = icmp eq i8* [[RECEIVER]], null
100 // CHECK-NEXT:    br i1 [[ISNIL]], label %continue, label %msgSend
101 // CHECK:       msgSend:
102 // CHECK:         @objc_msg_lookup_sender
103 // CHECK:         br label %continue
104 // CHECK:       continue:
105 // CHECK-NEXT:    phi float
106 // CHECK-NEXT:    phi float
107 void test_complex(id<P> p) {
108   _Complex float f = [p complex];