blob: 7f53ea6292eeadcb2959cc764d57f74eab8e0f58 [file] [log] [blame]
Vedant Kumar42c17ec2017-03-14 01:56:34 +00001// REQUIRES: asserts
2// RUN: %clang_cc1 -x objective-c -emit-llvm -triple x86_64-apple-macosx10.10.0 -fsanitize=nullability-arg,nullability-assign,nullability-return -w %s -o - | FileCheck %s
Vedant Kumar6b22dda2017-04-26 21:55:17 +00003// RUN: %clang_cc1 -x objective-c++ -emit-llvm -triple x86_64-apple-macosx10.10.0 -fsanitize=nullability-arg,nullability-assign,nullability-return -w %s -o - | FileCheck %s
Vedant Kumar42c17ec2017-03-14 01:56:34 +00004
5// CHECK: [[NONNULL_RV_LOC1:@.*]] = private unnamed_addr global {{.*}} i32 109, i32 1 {{.*}} 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
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
13// CHECK: [[NONNULL_RV_LOC2:@.*]] = private unnamed_addr global {{.*}} i32 817, i32 1 {{.*}} i32 800, i32 6
14
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) {
22 // CHECK: br i1 true, label %[[NULL:.*]], label %[[NONULL:.*]], !nosanitize
23 // CHECK: [[NULL]]:
24 // CHECK: [[ICMP:%.*]] = icmp ne i32* {{.*}}, null, !nosanitize
25 // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize
Vedant Kumar2b9f48a2017-03-14 16:48:29 +000026 // CHECK: call void @__ubsan_handle_nullability_return{{.*}}[[NONNULL_RV_LOC1]]
Vedant Kumar42c17ec2017-03-14 01:56:34 +000027 return p;
28 // CHECK: [[NONULL]]:
29 // CHECK-NEXT: ret i32*
30}
31
32#line 190
33void nonnull_arg(int *_Nonnull p) {}
34
Vedant Kumar6b22dda2017-04-26 21:55:17 +000035// CHECK-LABEL: define void @{{.*}}call_func_with_nonnull_arg
Vedant Kumar42c17ec2017-03-14 01:56:34 +000036#line 200
37void call_func_with_nonnull_arg(int *_Nonnull p) {
38 // CHECK: [[ICMP:%.*]] = icmp ne i32* {{.*}}, null, !nosanitize
39 // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize
Vedant Kumar2b9f48a2017-03-14 16:48:29 +000040 // CHECK: call void @__ubsan_handle_nullability_arg{{.*}}[[NONNULL_ARG_LOC]]
Vedant Kumar42c17ec2017-03-14 01:56:34 +000041 nonnull_arg(p);
42}
43
Vedant Kumar6b22dda2017-04-26 21:55:17 +000044// CHECK-LABEL: define void @{{.*}}nonnull_assign1
Vedant Kumar42c17ec2017-03-14 01:56:34 +000045#line 300
46void nonnull_assign1(int *p) {
47 // CHECK: [[ICMP:%.*]] = icmp ne i32* {{.*}}, null, !nosanitize
48 // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize
49 // CHECK: call void @__ubsan_handle_type_mismatch{{.*}}[[NONNULL_ASSIGN1_LOC]]
50 int *_Nonnull local;
51 local = p;
52}
53
Vedant Kumar6b22dda2017-04-26 21:55:17 +000054// CHECK-LABEL: define void @{{.*}}nonnull_assign2
Vedant Kumar42c17ec2017-03-14 01:56:34 +000055#line 400
56void nonnull_assign2(int *p) {
57 // CHECK: [[ICMP:%.*]] = icmp ne i32* %{{.*}}, null, !nosanitize
58 // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize
59 // CHECK: call void @__ubsan_handle_type_mismatch{{.*}}[[NONNULL_ASSIGN2_LOC]]
60 int *_Nonnull arr[1];
61 arr[0] = p;
62}
63
64struct S1 {
65 int *_Nonnull mptr;
66};
67
Vedant Kumar6b22dda2017-04-26 21:55:17 +000068// CHECK-LABEL: define void @{{.*}}nonnull_assign3
Vedant Kumar42c17ec2017-03-14 01:56:34 +000069#line 500
70void nonnull_assign3(int *p) {
71 // CHECK: [[ICMP:%.*]] = icmp ne i32* %{{.*}}, null, !nosanitize
72 // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize
73 // CHECK: call void @__ubsan_handle_type_mismatch{{.*}}[[NONNULL_ASSIGN3_LOC]]
Vedant Kumar6b22dda2017-04-26 21:55:17 +000074 // CHECK-NOT: call void @__ubsan_handle_type_mismatch
Vedant Kumar42c17ec2017-03-14 01:56:34 +000075 struct S1 s;
76 s.mptr = p;
77}
78
Vedant Kumar6b22dda2017-04-26 21:55:17 +000079// CHECK-LABEL: define void @{{.*}}nonnull_init1
Vedant Kumar42c17ec2017-03-14 01:56:34 +000080#line 600
81void nonnull_init1(int *p) {
82 // CHECK: [[ICMP:%.*]] = icmp ne i32* %{{.*}}, null, !nosanitize
83 // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize
84 // CHECK: call void @__ubsan_handle_type_mismatch{{.*}}[[NONNULL_INIT1_LOC]]
85 int *_Nonnull local = p;
86}
87
Vedant Kumar6b22dda2017-04-26 21:55:17 +000088// CHECK-LABEL: define void @{{.*}}nonnull_init2
Vedant Kumar42c17ec2017-03-14 01:56:34 +000089#line 700
90void nonnull_init2(int *p) {
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_LOC1]]
94 // CHECK: [[ICMP:%.*]] = icmp ne i32* %{{.*}}, null, !nosanitize
95 // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize
96 // CHECK: call void @__ubsan_handle_type_mismatch{{.*}}[[NONNULL_INIT2_LOC2]]
97 int *_Nonnull arr[] = {p, p};
98}
99
Vedant Kumar6b22dda2017-04-26 21:55:17 +0000100// CHECK-LABEL: define i32* @{{.*}}nonnull_retval2
Vedant Kumar42c17ec2017-03-14 01:56:34 +0000101#line 800
102int *_Nonnull nonnull_retval2(int *_Nonnull arg1, //< Test this.
103 int *_Nonnull arg2, //< Test this.
104 int *_Nullable arg3, //< Don't test the rest.
105 int *arg4,
106 int arg5, ...) {
107 // CHECK: [[ARG1CMP:%.*]] = icmp ne i32* %arg1, null, !nosanitize
108 // CHECK-NEXT: [[DO_RV_CHECK_1:%.*]] = and i1 true, [[ARG1CMP]], !nosanitize
109 // CHECK: [[ARG2CMP:%.*]] = icmp ne i32* %arg2, null, !nosanitize
110 // CHECK-NEXT: [[DO_RV_CHECK_2:%.*]] = and i1 [[DO_RV_CHECK_1]], [[ARG2CMP]]
111 // CHECK: br i1 [[DO_RV_CHECK_2]], label %[[NULL:.*]], label %[[NONULL:.*]], !nosanitize
112 // CHECK: [[NULL]]:
113 // CHECK-NEXT: [[ICMP:%.*]] = icmp ne i32* {{.*}}, null, !nosanitize
114 // CHECK-NEXT: 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]]
132 // CHECK: br i1 [[DO_RV_CHECK]], label %[[NULL:.*]], label %[[NONULL:.*]], !nosanitize
133 // CHECK: [[NULL]]:
134 // CHECK-NEXT: [[ICMP:%.*]] = icmp ne i32* {{.*}}, null, !nosanitize
135 // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize
Vedant Kumar2b9f48a2017-03-14 16:48:29 +0000136 // CHECK: call void @__ubsan_handle_nullability_return{{.*}}
Vedant Kumar42c17ec2017-03-14 01:56:34 +0000137 return arg1;
138 // CHECK: [[NONULL]]:
139 // CHECK-NEXT: ret i32*
140}
141
142// CHECK-LABEL: define internal i32* @"\01-[A objc_method:]"
143-(int *_Nonnull) objc_method: (int *_Nonnull) arg1 {
144 // CHECK: [[ARG1CMP:%.*]] = icmp ne i32* %arg1, null, !nosanitize
145 // CHECK-NEXT: [[DO_RV_CHECK:%.*]] = and i1 true, [[ARG1CMP]]
146 // CHECK: br i1 [[DO_RV_CHECK]], label %[[NULL:.*]], label %[[NONULL:.*]], !nosanitize
147 // CHECK: [[NULL]]:
148 // CHECK-NEXT: [[ICMP:%.*]] = icmp ne i32* {{.*}}, null, !nosanitize
149 // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize
Vedant Kumar2b9f48a2017-03-14 16:48:29 +0000150 // CHECK: call void @__ubsan_handle_nullability_return{{.*}}
Vedant Kumar42c17ec2017-03-14 01:56:34 +0000151 return arg1;
152 // CHECK: [[NONULL]]:
153 // CHECK-NEXT: ret i32*
154}
155@end
156
Vedant Kumar6b22dda2017-04-26 21:55:17 +0000157// CHECK-LABEL: define void @{{.*}}call_A
Vedant Kumar42c17ec2017-03-14 01:56:34 +0000158void call_A(A *a, int *p) {
159 // CHECK: [[ICMP:%.*]] = icmp ne i32* [[P1:%.*]], null, !nosanitize
160 // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize
Vedant Kumar2b9f48a2017-03-14 16:48:29 +0000161 // CHECK: call void @__ubsan_handle_nullability_arg{{.*}} !nosanitize
Vedant Kumar42c17ec2017-03-14 01:56:34 +0000162 // CHECK: call i32* {{.*}} @objc_msgSend to i32* {{.*}}({{.*}}, i32* [[P1]])
163 [a objc_method: p];
164
165 // CHECK: [[ICMP:%.*]] = icmp ne i32* [[P2:%.*]], 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* [[P2]])
169 [A objc_clsmethod: p];
170}
171
172void dont_crash(int *_Nonnull p, ...) {}
173
174int main() {
Vedant Kumar6b22dda2017-04-26 21:55:17 +0000175 nonnull_retval1(INULL);
176 nonnull_retval2(INNULL, INNULL, INULL, (int *_Nullable)NULL, 0, 0, 0, 0);
177 call_func_with_nonnull_arg(INNULL);
178 nonnull_assign1(INULL);
179 nonnull_assign2(INULL);
180 nonnull_assign3(INULL);
181 nonnull_init1(INULL);
182 nonnull_init2(INULL);
183 call_A((A *)NULL, INULL);
184 dont_crash(INNULL, NULL);
Vedant Kumar42c17ec2017-03-14 01:56:34 +0000185 return 0;
186}