blob: 8e7a9cba7c71c8cfc2851ef3130f44d88e295890 [file] [log] [blame]
Vedant Kumar42c17ec2017-03-14 01:56:34 +00001// REQUIRES: asserts
Vedant Kumar03dd1502018-06-26 02:50:04 +00002// 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
Vedant Kumar42c17ec2017-03-14 01:56:34 +00004
Vedant Kumarc34d3432017-06-23 21:32:38 +00005// CHECK: [[NONNULL_RV_LOC1:@.*]] = private unnamed_addr global {{.*}} i32 100, i32 6
Vedant Kumar42c17ec2017-03-14 01:56:34 +00006// 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
Vedant Kumar6b22dda2017-04-26 21:55:17 +00009// CHECK: [[NONNULL_ASSIGN3_LOC:@.*]] = private unnamed_addr global {{.*}} i32 506, i32 10
Vedant Kumar42c17ec2017-03-14 01:56:34 +000010// 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
Vedant Kumarc34d3432017-06-23 21:32:38 +000013// CHECK: [[NONNULL_RV_LOC2:@.*]] = private unnamed_addr global {{.*}} i32 800, i32 6
Vedant Kumar42c17ec2017-03-14 01:56:34 +000014
15#define NULL ((void *)0)
Vedant Kumar6b22dda2017-04-26 21:55:17 +000016#define INULL ((int *)NULL)
17#define INNULL ((int *_Nonnull)NULL)
Vedant Kumar42c17ec2017-03-14 01:56:34 +000018
Vedant Kumar6b22dda2017-04-26 21:55:17 +000019// CHECK-LABEL: define i32* @{{.*}}nonnull_retval1
Vedant Kumar42c17ec2017-03-14 01:56:34 +000020#line 100
21int *_Nonnull nonnull_retval1(int *p) {
Vedant Kumar42c17ec2017-03-14 01:56:34 +000022 // CHECK: [[ICMP:%.*]] = icmp ne i32* {{.*}}, null, !nosanitize
Vedant Kumarc34d3432017-06-23 21:32:38 +000023 // CHECK: br i1 [[ICMP]], {{.*}}, !nosanitize
Vedant Kumar2b9f48a2017-03-14 16:48:29 +000024 // CHECK: call void @__ubsan_handle_nullability_return{{.*}}[[NONNULL_RV_LOC1]]
Vedant Kumar42c17ec2017-03-14 01:56:34 +000025 return p;
Vedant Kumarc34d3432017-06-23 21:32:38 +000026 // CHECK: ret i32*
Vedant Kumar42c17ec2017-03-14 01:56:34 +000027}
28
29#line 190
30void nonnull_arg(int *_Nonnull p) {}
31
Vedant Kumar6b22dda2017-04-26 21:55:17 +000032// CHECK-LABEL: define void @{{.*}}call_func_with_nonnull_arg
Vedant Kumar42c17ec2017-03-14 01:56:34 +000033#line 200
34void call_func_with_nonnull_arg(int *_Nonnull p) {
35 // CHECK: [[ICMP:%.*]] = icmp ne i32* {{.*}}, null, !nosanitize
36 // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize
Vedant Kumar2b9f48a2017-03-14 16:48:29 +000037 // CHECK: call void @__ubsan_handle_nullability_arg{{.*}}[[NONNULL_ARG_LOC]]
Vedant Kumar42c17ec2017-03-14 01:56:34 +000038 nonnull_arg(p);
39}
40
Vedant Kumar6b22dda2017-04-26 21:55:17 +000041// CHECK-LABEL: define void @{{.*}}nonnull_assign1
Vedant Kumar42c17ec2017-03-14 01:56:34 +000042#line 300
43void 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
Vedant Kumar6b22dda2017-04-26 21:55:17 +000051// CHECK-LABEL: define void @{{.*}}nonnull_assign2
Vedant Kumar42c17ec2017-03-14 01:56:34 +000052#line 400
53void 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
61struct S1 {
62 int *_Nonnull mptr;
63};
64
Vedant Kumar6b22dda2017-04-26 21:55:17 +000065// CHECK-LABEL: define void @{{.*}}nonnull_assign3
Vedant Kumar42c17ec2017-03-14 01:56:34 +000066#line 500
67void 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]]
Vedant Kumar6b22dda2017-04-26 21:55:17 +000071 // CHECK-NOT: call void @__ubsan_handle_type_mismatch
Vedant Kumar42c17ec2017-03-14 01:56:34 +000072 struct S1 s;
73 s.mptr = p;
74}
75
Vedant Kumar6b22dda2017-04-26 21:55:17 +000076// CHECK-LABEL: define void @{{.*}}nonnull_init1
Vedant Kumar42c17ec2017-03-14 01:56:34 +000077#line 600
78void 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
Vedant Kumar6b22dda2017-04-26 21:55:17 +000085// CHECK-LABEL: define void @{{.*}}nonnull_init2
Vedant Kumar42c17ec2017-03-14 01:56:34 +000086#line 700
87void 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
Vedant Kumar6b22dda2017-04-26 21:55:17 +000097// CHECK-LABEL: define i32* @{{.*}}nonnull_retval2
Vedant Kumar42c17ec2017-03-14 01:56:34 +000098#line 800
99int *_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]]
Vedant Kumarc34d3432017-06-23 21:32:38 +0000108 // 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
Vedant Kumar42c17ec2017-03-14 01:56:34 +0000112 // CHECK: [[NULL]]:
113 // CHECK-NEXT: [[ICMP:%.*]] = icmp ne i32* {{.*}}, null, !nosanitize
Vedant Kumarc34d3432017-06-23 21:32:38 +0000114 // CHECK: br i1 [[ICMP]], {{.*}}, !nosanitize
Vedant Kumar2b9f48a2017-03-14 16:48:29 +0000115 // CHECK: call void @__ubsan_handle_nullability_return{{.*}}[[NONNULL_RV_LOC2]]
Vedant Kumar42c17ec2017-03-14 01:56:34 +0000116 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]]
Vedant Kumarc34d3432017-06-23 21:32:38 +0000132 // 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
Vedant Kumar42c17ec2017-03-14 01:56:34 +0000136 // CHECK: [[NULL]]:
137 // CHECK-NEXT: [[ICMP:%.*]] = icmp ne i32* {{.*}}, null, !nosanitize
Vedant Kumarc34d3432017-06-23 21:32:38 +0000138 // CHECK: br i1 [[ICMP]], {{.*}}, !nosanitize
Vedant Kumar2b9f48a2017-03-14 16:48:29 +0000139 // CHECK: call void @__ubsan_handle_nullability_return{{.*}}
Vedant Kumar42c17ec2017-03-14 01:56:34 +0000140 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]]
Vedant Kumarc34d3432017-06-23 21:32:38 +0000149 // 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
Vedant Kumar42c17ec2017-03-14 01:56:34 +0000153 // CHECK: [[NULL]]:
154 // CHECK-NEXT: [[ICMP:%.*]] = icmp ne i32* {{.*}}, null, !nosanitize
Vedant Kumarc34d3432017-06-23 21:32:38 +0000155 // CHECK: br i1 [[ICMP]], {{.*}}, !nosanitize
Vedant Kumar2b9f48a2017-03-14 16:48:29 +0000156 // CHECK: call void @__ubsan_handle_nullability_return{{.*}}
Vedant Kumar42c17ec2017-03-14 01:56:34 +0000157 return arg1;
158 // CHECK: [[NONULL]]:
159 // CHECK-NEXT: ret i32*
160}
161@end
162
Vedant Kumar6b22dda2017-04-26 21:55:17 +0000163// CHECK-LABEL: define void @{{.*}}call_A
Vedant Kumar42c17ec2017-03-14 01:56:34 +0000164void call_A(A *a, int *p) {
165 // CHECK: [[ICMP:%.*]] = icmp ne i32* [[P1:%.*]], null, !nosanitize
166 // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize
Vedant Kumar2b9f48a2017-03-14 16:48:29 +0000167 // CHECK: call void @__ubsan_handle_nullability_arg{{.*}} !nosanitize
Vedant Kumar42c17ec2017-03-14 01:56:34 +0000168 // 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
Vedant Kumar2b9f48a2017-03-14 16:48:29 +0000173 // CHECK: call void @__ubsan_handle_nullability_arg{{.*}} !nosanitize
Vedant Kumar42c17ec2017-03-14 01:56:34 +0000174 // CHECK: call i32* {{.*}} @objc_msgSend to i32* {{.*}}({{.*}}, i32* [[P2]])
175 [A objc_clsmethod: p];
176}
177
178void dont_crash(int *_Nonnull p, ...) {}
179
Vedant Kumar03dd1502018-06-26 02:50:04 +0000180@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.
189NSObject *get_nonnull_error() {
190 // Use nil for convenience. The actual object doesn't matter.
191 return (NSObject *)NULL;
192}
193
194NSObject *_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
Vedant Kumar42c17ec2017-03-14 01:56:34 +0000211int main() {
Vedant Kumar6b22dda2017-04-26 21:55:17 +0000212 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);
Vedant Kumar03dd1502018-06-26 02:50:04 +0000222 no_null_return_value_diagnostic(0);
223 no_null_return_value_diagnostic(1);
Vedant Kumar42c17ec2017-03-14 01:56:34 +0000224 return 0;
225}