[clang] Implement lifetime analysis for lifetime_capture_by(X) (#115921)
[llvm-project.git] / clang / test / CodeGenObjC / gnu-nil-receiver.m
blob8d4027a9381476bbd27db26feeb3e22ea147d111
1 // RUN: %clang_cc1 -triple x86_64-unknown-freebsd -fobjc-arc -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 ptr,
38 // CHECK:         [[BIG:%.*]] = alloca %struct.Big,
39 // CHECK:         br label %for.cond
41 // CHECK:       for.cond:
42 // CHECK-NEXT:    [[RECEIVER:%.*]] = load ptr, ptr [[P]],
43 // CHECK-NEXT:    [[ISNIL:%.*]] = icmp eq ptr [[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:    call void @llvm.memset.p0.i64(ptr align 4 [[BIG]], i8 0, i64 48, i1 false)
53 // CHECK-NEXT:    br label %continue
55 // CHECK:       continue:
56 // CHECK-NEXT:    br label %for.cond
57 void test_loop_zeroing(id<P> p) {
58   for (;;) {
59     Big big = [p foo];
60   }
63 // CHECK-LABEL: define{{.*}} void @test_zeroing_and_consume(
64 // CHECK:         [[P:%.*]] = alloca ptr,
65 // CHECK:         [[Q:%.*]] = alloca ptr,
66 // CHECK:         [[BIG:%.*]] = alloca %struct.Big,
67 // CHECK:         br label %for.cond
69 // CHECK:       for.cond:
70 // CHECK-NEXT:    [[RECEIVER:%.*]] = load ptr, ptr [[P]],
71 // CHECK-NEXT:    [[Q_LOAD:%.*]] = load ptr, ptr [[Q]],
72 // CHECK-NEXT:    [[Q_RETAIN:%.*]] = call ptr @llvm.objc.retain(ptr [[Q_LOAD]])
73 // CHECK-NEXT:    [[ISNIL:%.*]] = icmp eq ptr [[RECEIVER]], null
74 // CHECK-NEXT:    br i1 [[ISNIL]], label %nilReceiverCleanup, label %msgSend
76 // CHECK:       msgSend:
77 // CHECK:         @objc_msg_lookup_sender
78 // CHECK:         call void {{%.*}}({{.*}} [[BIG]],
79 // CHECK:         br label %continue
81 // CHECK:       nilReceiverCleanup:
82 // CHECK-NEXT:    call void @llvm.objc.release(ptr [[Q_RETAIN]])
83 // CHECK-NEXT:    call void @llvm.memset.p0.i64(ptr align 4 [[BIG]], i8 0, i64 48, i1 false)
84 // CHECK-NEXT:    br label %continue
86 // CHECK:       continue:
87 // CHECK-NEXT:    br label %for.cond
88 void test_zeroing_and_consume(id<P> p, id q) {
89   for (;;) {
90     Big big = [p fooConsuming: q];
91   }
94 // CHECK-LABEL: define{{.*}} void @test_complex(
95 // CHECK:         [[P:%.*]] = alloca ptr,
96 // CHECK:         [[RECEIVER:%.*]] = load ptr, ptr [[P]],
97 // CHECK-NEXT:    [[ISNIL:%.*]] = icmp eq ptr [[RECEIVER]], null
98 // CHECK-NEXT:    br i1 [[ISNIL]], label %continue, label %msgSend
99 // CHECK:       msgSend:
100 // CHECK:         @objc_msg_lookup_sender
101 // CHECK:         br label %continue
102 // CHECK:       continue:
103 // CHECK-NEXT:    phi float
104 // CHECK-NEXT:    phi float
105 void test_complex(id<P> p) {
106   _Complex float f = [p complex];