1 | // REQUIRES: asserts |
2 | // RUN: %clang_cc1 -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 -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 |
4 | |
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 |
14 | |
15 | #define NULL ((void *)0) |
16 | #define INULL ((int *)NULL) |
17 | #define INNULL ((int *_Nonnull)NULL) |
18 | |
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* |
27 | } |
28 | |
29 | #line 190 |
30 | void nonnull_arg(int *_Nonnull p) {} |
31 | |
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); |
39 | } |
40 | |
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; |
49 | } |
50 | |
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; |
59 | } |
60 | |
61 | struct S1 { |
62 | int *_Nonnull mptr; |
63 | }; |
64 | |
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; |
74 | } |
75 | |
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; |
83 | } |
84 | |
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}; |
95 | } |
96 | |
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* |
119 | } |
120 | |
121 | @interface A |
122 | +(int *_Nonnull) objc_clsmethod: (int *_Nonnull) arg1; |
123 | -(int *_Nonnull) objc_method: (int *_Nonnull) arg1; |
124 | @end |
125 | |
126 | @implementation A |
127 | |
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* |
143 | } |
144 | |
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* |
160 | } |
161 | @end |
162 | |
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]; |
170 | |
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]; |
176 | } |
177 | |
178 | void dont_crash(int *_Nonnull p, ...) {} |
179 | |
180 | @protocol NSObject |
181 | - (id)init; |
182 | @end |
183 | @interface NSObject <NSObject> {} |
184 | @end |
185 | |
186 | #pragma clang assume_nonnull begin |
187 | |
188 | /// Create a "NSObject * _Nonnull" instance. |
189 | NSObject *get_nonnull_error() { |
190 | // Use nil for convenience. The actual object doesn't matter. |
191 | return (NSObject *)NULL; |
192 | } |
193 | |
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)() = ^() { |
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(); |
207 | } |
208 | |
209 | #pragma clang assume_nonnull end |
210 | |
211 | int main() { |
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; |
225 | } |
226 | |