[docs] Add LICENSE.txt to the root of the mono-repo
[llvm-project.git] / clang / test / CodeGenObjC / ubsan-nullability.m
bloba4382417affb9840a0e75a99f417ac74f57e6d89
1 // REQUIRES: asserts
2 // RUN: %clang_cc1 -no-opaque-pointers -no-enable-noundef-analysis -x objective-c -emit-llvm -triple x86_64-apple-macosx10.10.0 -fblocks -fobjc-arc -fsanitize=nullability-arg,nullability-assign,nullability-return -w %s -o - | FileCheck %s
3 // RUN: %clang_cc1 -no-opaque-pointers -no-enable-noundef-analysis -x objective-c++ -emit-llvm -triple x86_64-apple-macosx10.10.0 -fblocks -fobjc-arc -fsanitize=nullability-arg,nullability-assign,nullability-return -w %s -o - | FileCheck %s
5 // CHECK: [[NONNULL_RV_LOC1:@.*]] = private unnamed_addr global {{.*}} i32 100, i32 6
6 // CHECK: [[NONNULL_ARG_LOC:@.*]] = private unnamed_addr global {{.*}} i32 204, i32 15 {{.*}} i32 190, i32 23
7 // CHECK: [[NONNULL_ASSIGN1_LOC:@.*]] = private unnamed_addr global {{.*}} i32 305, i32 9
8 // CHECK: [[NONNULL_ASSIGN2_LOC:@.*]] = private unnamed_addr global {{.*}} i32 405, i32 10
9 // CHECK: [[NONNULL_ASSIGN3_LOC:@.*]] = private unnamed_addr global {{.*}} i32 506, i32 10
10 // CHECK: [[NONNULL_INIT1_LOC:@.*]] = private unnamed_addr global {{.*}} i32 604, i32 25
11 // CHECK: [[NONNULL_INIT2_LOC1:@.*]] = private unnamed_addr global {{.*}} i32 707, i32 26
12 // CHECK: [[NONNULL_INIT2_LOC2:@.*]] = private unnamed_addr global {{.*}} i32 707, i32 29
13 // CHECK: [[NONNULL_RV_LOC2:@.*]] = private unnamed_addr global {{.*}} i32 800, i32 6
15 #define NULL ((void *)0)
16 #define INULL ((int *)NULL)
17 #define INNULL ((int *_Nonnull)NULL)
19 // CHECK-LABEL: define{{.*}} i32* @{{.*}}nonnull_retval1
20 #line 100
21 int *_Nonnull nonnull_retval1(int *p) {
22   // CHECK: [[ICMP:%.*]] = icmp ne i32* {{.*}}, null, !nosanitize
23   // CHECK: br i1 [[ICMP]], {{.*}}, !nosanitize
24   // CHECK: call void @__ubsan_handle_nullability_return{{.*}}[[NONNULL_RV_LOC1]]
25   return p;
26   // CHECK: ret i32*
29 #line 190
30 void nonnull_arg(int *_Nonnull p) {}
32 // CHECK-LABEL: define{{.*}} void @{{.*}}call_func_with_nonnull_arg
33 #line 200
34 void call_func_with_nonnull_arg(int *_Nonnull p) {
35   // CHECK: [[ICMP:%.*]] = icmp ne i32* {{.*}}, null, !nosanitize
36   // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize
37   // CHECK: call void @__ubsan_handle_nullability_arg{{.*}}[[NONNULL_ARG_LOC]]
38   nonnull_arg(p);
41 // CHECK-LABEL: define{{.*}} void @{{.*}}nonnull_assign1
42 #line 300
43 void nonnull_assign1(int *p) {
44   // CHECK: [[ICMP:%.*]] = icmp ne i32* {{.*}}, null, !nosanitize
45   // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize
46   // CHECK: call void @__ubsan_handle_type_mismatch{{.*}}[[NONNULL_ASSIGN1_LOC]]
47   int *_Nonnull local;
48   local = p;
51 // CHECK-LABEL: define{{.*}} void @{{.*}}nonnull_assign2
52 #line 400
53 void nonnull_assign2(int *p) {
54   // CHECK: [[ICMP:%.*]] = icmp ne i32* %{{.*}}, null, !nosanitize
55   // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize
56   // CHECK: call void @__ubsan_handle_type_mismatch{{.*}}[[NONNULL_ASSIGN2_LOC]]
57   int *_Nonnull arr[1];
58   arr[0] = p;
61 struct S1 {
62   int *_Nonnull mptr;
65 // CHECK-LABEL: define{{.*}} void @{{.*}}nonnull_assign3
66 #line 500
67 void nonnull_assign3(int *p) {
68   // CHECK: [[ICMP:%.*]] = icmp ne i32* %{{.*}}, null, !nosanitize
69   // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize
70   // CHECK: call void @__ubsan_handle_type_mismatch{{.*}}[[NONNULL_ASSIGN3_LOC]]
71   // CHECK-NOT: call void @__ubsan_handle_type_mismatch
72   struct S1 s;
73   s.mptr = p;
76 // CHECK-LABEL: define{{.*}} void @{{.*}}nonnull_init1
77 #line 600
78 void nonnull_init1(int *p) {
79   // CHECK: [[ICMP:%.*]] = icmp ne i32* %{{.*}}, null, !nosanitize
80   // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize
81   // CHECK: call void @__ubsan_handle_type_mismatch{{.*}}[[NONNULL_INIT1_LOC]]
82   int *_Nonnull local = p;
85 // CHECK-LABEL: define{{.*}} void @{{.*}}nonnull_init2
86 #line 700
87 void nonnull_init2(int *p) {
88   // CHECK: [[ICMP:%.*]] = icmp ne i32* %{{.*}}, null, !nosanitize
89   // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize
90   // CHECK: call void @__ubsan_handle_type_mismatch{{.*}}[[NONNULL_INIT2_LOC1]]
91   // CHECK: [[ICMP:%.*]] = icmp ne i32* %{{.*}}, null, !nosanitize
92   // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize
93   // CHECK: call void @__ubsan_handle_type_mismatch{{.*}}[[NONNULL_INIT2_LOC2]]
94   int *_Nonnull arr[] = {p, p};
97 // CHECK-LABEL: define{{.*}} i32* @{{.*}}nonnull_retval2
98 #line 800
99 int *_Nonnull nonnull_retval2(int *_Nonnull arg1,  //< Test this.
100                               int *_Nonnull arg2,  //< Test this.
101                               int *_Nullable arg3, //< Don't test the rest.
102                               int *arg4,
103                               int arg5, ...) {
104   // CHECK: [[ARG1CMP:%.*]] = icmp ne i32* %arg1, null, !nosanitize
105   // CHECK-NEXT: [[DO_RV_CHECK_1:%.*]] = and i1 true, [[ARG1CMP]], !nosanitize
106   // CHECK: [[ARG2CMP:%.*]] = icmp ne i32* %arg2, null, !nosanitize
107   // CHECK-NEXT: [[DO_RV_CHECK_2:%.*]] = and i1 [[DO_RV_CHECK_1]], [[ARG2CMP]]
108   // CHECK: [[SLOC_PTR:%.*]] = load i8*, i8** %return.sloc.ptr
109   // CHECK-NEXT: [[SLOC_NONNULL:%.*]] = icmp ne i8* [[SLOC_PTR]], null
110   // CHECK-NEXT: [[DO_RV_CHECK_3:%.*]] = and i1 [[SLOC_NONNULL]], [[DO_RV_CHECK_2]]
111   // CHECK: br i1 [[DO_RV_CHECK_3]], label %[[NULL:.*]], label %[[NONULL:.*]], !nosanitize
112   // CHECK: [[NULL]]:
113   // CHECK-NEXT: [[ICMP:%.*]] = icmp ne i32* {{.*}}, null, !nosanitize
114   // CHECK: br i1 [[ICMP]], {{.*}}, !nosanitize
115   // CHECK: call void @__ubsan_handle_nullability_return{{.*}}[[NONNULL_RV_LOC2]]
116   return arg1;
117   // CHECK: [[NONULL]]:
118   // CHECK-NEXT: ret i32*
121 @interface A
122 +(int *_Nonnull) objc_clsmethod: (int *_Nonnull) arg1;
123 -(int *_Nonnull) objc_method: (int *_Nonnull) arg1;
124 @end
126 @implementation A
128 // CHECK-LABEL: define internal i32* @"\01+[A objc_clsmethod:]"
129 +(int *_Nonnull) objc_clsmethod: (int *_Nonnull) arg1 {
130   // CHECK: [[ARG1CMP:%.*]] = icmp ne i32* %arg1, null, !nosanitize
131   // CHECK-NEXT: [[DO_RV_CHECK:%.*]] = and i1 true, [[ARG1CMP]]
132   // CHECK: [[SLOC_PTR:%.*]] = load i8*, i8** %return.sloc.ptr
133   // CHECK-NEXT: [[SLOC_NONNULL:%.*]] = icmp ne i8* [[SLOC_PTR]], null
134   // CHECK-NEXT: [[DO_RV_CHECK_2:%.*]] = and i1 [[SLOC_NONNULL]], [[DO_RV_CHECK]]
135   // CHECK: br i1 [[DO_RV_CHECK_2]], label %[[NULL:.*]], label %[[NONULL:.*]], !nosanitize
136   // CHECK: [[NULL]]:
137   // CHECK-NEXT: [[ICMP:%.*]] = icmp ne i32* {{.*}}, null, !nosanitize
138   // CHECK: br i1 [[ICMP]], {{.*}}, !nosanitize
139   // CHECK: call void @__ubsan_handle_nullability_return{{.*}}
140   return arg1;
141   // CHECK: [[NONULL]]:
142   // CHECK-NEXT: ret i32*
145 // CHECK-LABEL: define internal i32* @"\01-[A objc_method:]"
146 -(int *_Nonnull) objc_method: (int *_Nonnull) arg1 {
147   // CHECK: [[ARG1CMP:%.*]] = icmp ne i32* %arg1, null, !nosanitize
148   // CHECK-NEXT: [[DO_RV_CHECK:%.*]] = and i1 true, [[ARG1CMP]]
149   // CHECK: [[SLOC_PTR:%.*]] = load i8*, i8** %return.sloc.ptr
150   // CHECK-NEXT: [[SLOC_NONNULL:%.*]] = icmp ne i8* [[SLOC_PTR]], null
151   // CHECK-NEXT: [[DO_RV_CHECK_2:%.*]] = and i1 [[SLOC_NONNULL]], [[DO_RV_CHECK]]
152   // CHECK: br i1 [[DO_RV_CHECK_2]], label %[[NULL:.*]], label %[[NONULL:.*]], !nosanitize
153   // CHECK: [[NULL]]:
154   // CHECK-NEXT: [[ICMP:%.*]] = icmp ne i32* {{.*}}, null, !nosanitize
155   // CHECK: br i1 [[ICMP]], {{.*}}, !nosanitize
156   // CHECK: call void @__ubsan_handle_nullability_return{{.*}}
157   return arg1;
158   // CHECK: [[NONULL]]:
159   // CHECK-NEXT: ret i32*
161 @end
163 // CHECK-LABEL: define{{.*}} void @{{.*}}call_A
164 void call_A(A *a, int *p) {
165   // CHECK: [[ICMP:%.*]] = icmp ne i32* [[P1:%.*]], null, !nosanitize
166   // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize
167   // CHECK: call void @__ubsan_handle_nullability_arg{{.*}} !nosanitize
168   // CHECK: call i32* {{.*}} @objc_msgSend to i32* {{.*}}({{.*}}, i32* [[P1]])
169   [a objc_method: p];
171   // CHECK: [[ICMP:%.*]] = icmp ne i32* [[P2:%.*]], null, !nosanitize
172   // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize
173   // CHECK: call void @__ubsan_handle_nullability_arg{{.*}} !nosanitize
174   // CHECK: call i32* {{.*}} @objc_msgSend to i32* {{.*}}({{.*}}, i32* [[P2]])
175   [A objc_clsmethod: p];
178 void dont_crash(int *_Nonnull p, ...) {}
180 @protocol NSObject
181 - (id)init;
182 @end
183 @interface NSObject <NSObject> {}
184 @end
186 #pragma clang assume_nonnull begin
188 /// Create a "NSObject * _Nonnull" instance.
189 NSObject *get_nonnull_error(void) {
190   // Use nil for convenience. The actual object doesn't matter.
191   return (NSObject *)NULL;
194 NSObject *_Nullable no_null_return_value_diagnostic(int flag) {
195 // CHECK-LABEL: define internal {{.*}}no_null_return_value_diagnostic{{i?}}_block_invoke
196 // CHECK-NOT: @__ubsan_handle_nullability_return
197   NSObject *_Nullable (^foo)(void) = ^(void) {
198     if (flag) {
199       // Clang should not infer a nonnull return value for this block when this
200       // call is present.
201       return get_nonnull_error();
202     } else {
203       return (NSObject *)NULL;
204     }
205   };
206   return foo();
209 #pragma clang assume_nonnull end
211 int main(void) {
212   nonnull_retval1(INULL);
213   nonnull_retval2(INNULL, INNULL, INULL, (int *_Nullable)NULL, 0, 0, 0, 0);
214   call_func_with_nonnull_arg(INNULL);
215   nonnull_assign1(INULL);
216   nonnull_assign2(INULL);
217   nonnull_assign3(INULL);
218   nonnull_init1(INULL);
219   nonnull_init2(INULL);
220   call_A((A *)NULL, INULL);
221   dont_crash(INNULL, NULL);
222   no_null_return_value_diagnostic(0);
223   no_null_return_value_diagnostic(1);
224   return 0;