blob: 457f071363494e100039a23e1c773a1f26f361e5 [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
3
4// CHECK: [[NONNULL_RV_LOC1:@.*]] = private unnamed_addr global {{.*}} i32 109, i32 1 {{.*}} i32 100, i32 6
5// CHECK: [[NONNULL_ARG_LOC:@.*]] = private unnamed_addr global {{.*}} i32 204, i32 15 {{.*}} i32 190, i32 23
6// CHECK: [[NONNULL_ASSIGN1_LOC:@.*]] = private unnamed_addr global {{.*}} i32 305, i32 9
7// CHECK: [[NONNULL_ASSIGN2_LOC:@.*]] = private unnamed_addr global {{.*}} i32 405, i32 10
8// CHECK: [[NONNULL_ASSIGN3_LOC:@.*]] = private unnamed_addr global {{.*}} i32 505, i32 10
9// CHECK: [[NONNULL_INIT1_LOC:@.*]] = private unnamed_addr global {{.*}} i32 604, i32 25
10// CHECK: [[NONNULL_INIT2_LOC1:@.*]] = private unnamed_addr global {{.*}} i32 707, i32 26
11// CHECK: [[NONNULL_INIT2_LOC2:@.*]] = private unnamed_addr global {{.*}} i32 707, i32 29
12// CHECK: [[NONNULL_RV_LOC2:@.*]] = private unnamed_addr global {{.*}} i32 817, i32 1 {{.*}} i32 800, i32 6
13
14#define NULL ((void *)0)
15
16// CHECK-LABEL: define i32* @nonnull_retval1
17#line 100
18int *_Nonnull nonnull_retval1(int *p) {
19 // CHECK: br i1 true, label %[[NULL:.*]], label %[[NONULL:.*]], !nosanitize
20 // CHECK: [[NULL]]:
21 // CHECK: [[ICMP:%.*]] = icmp ne i32* {{.*}}, null, !nosanitize
22 // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize
Vedant Kumar2b9f48a2017-03-14 16:48:29 +000023 // CHECK: call void @__ubsan_handle_nullability_return{{.*}}[[NONNULL_RV_LOC1]]
Vedant Kumar42c17ec2017-03-14 01:56:34 +000024 return p;
25 // CHECK: [[NONULL]]:
26 // CHECK-NEXT: ret i32*
27}
28
29#line 190
30void nonnull_arg(int *_Nonnull p) {}
31
32// CHECK-LABEL: define void @call_func_with_nonnull_arg
33#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
41// CHECK-LABEL: define void @nonnull_assign1
42#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
51// CHECK-LABEL: define void @nonnull_assign2
52#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
65// CHECK-LABEL: define void @nonnull_assign3
66#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]]
71 struct S1 s;
72 s.mptr = p;
73}
74
75// CHECK-LABEL: define void @nonnull_init1
76#line 600
77void nonnull_init1(int *p) {
78 // CHECK: [[ICMP:%.*]] = icmp ne i32* %{{.*}}, null, !nosanitize
79 // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize
80 // CHECK: call void @__ubsan_handle_type_mismatch{{.*}}[[NONNULL_INIT1_LOC]]
81 int *_Nonnull local = p;
82}
83
84// CHECK-LABEL: define void @nonnull_init2
85#line 700
86void nonnull_init2(int *p) {
87 // CHECK: [[ICMP:%.*]] = icmp ne i32* %{{.*}}, null, !nosanitize
88 // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize
89 // CHECK: call void @__ubsan_handle_type_mismatch{{.*}}[[NONNULL_INIT2_LOC1]]
90 // CHECK: [[ICMP:%.*]] = icmp ne i32* %{{.*}}, null, !nosanitize
91 // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize
92 // CHECK: call void @__ubsan_handle_type_mismatch{{.*}}[[NONNULL_INIT2_LOC2]]
93 int *_Nonnull arr[] = {p, p};
94}
95
96// CHECK-LABEL: define i32* @nonnull_retval2
97#line 800
98int *_Nonnull nonnull_retval2(int *_Nonnull arg1, //< Test this.
99 int *_Nonnull arg2, //< Test this.
100 int *_Nullable arg3, //< Don't test the rest.
101 int *arg4,
102 int arg5, ...) {
103 // CHECK: [[ARG1CMP:%.*]] = icmp ne i32* %arg1, null, !nosanitize
104 // CHECK-NEXT: [[DO_RV_CHECK_1:%.*]] = and i1 true, [[ARG1CMP]], !nosanitize
105 // CHECK: [[ARG2CMP:%.*]] = icmp ne i32* %arg2, null, !nosanitize
106 // CHECK-NEXT: [[DO_RV_CHECK_2:%.*]] = and i1 [[DO_RV_CHECK_1]], [[ARG2CMP]]
107 // CHECK: br i1 [[DO_RV_CHECK_2]], label %[[NULL:.*]], label %[[NONULL:.*]], !nosanitize
108 // CHECK: [[NULL]]:
109 // CHECK-NEXT: [[ICMP:%.*]] = icmp ne i32* {{.*}}, null, !nosanitize
110 // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize
Vedant Kumar2b9f48a2017-03-14 16:48:29 +0000111 // CHECK: call void @__ubsan_handle_nullability_return{{.*}}[[NONNULL_RV_LOC2]]
Vedant Kumar42c17ec2017-03-14 01:56:34 +0000112 return arg1;
113 // CHECK: [[NONULL]]:
114 // CHECK-NEXT: ret i32*
115}
116
117@interface A
118+(int *_Nonnull) objc_clsmethod: (int *_Nonnull) arg1;
119-(int *_Nonnull) objc_method: (int *_Nonnull) arg1;
120@end
121
122@implementation A
123
124// CHECK-LABEL: define internal i32* @"\01+[A objc_clsmethod:]"
125+(int *_Nonnull) objc_clsmethod: (int *_Nonnull) arg1 {
126 // CHECK: [[ARG1CMP:%.*]] = icmp ne i32* %arg1, null, !nosanitize
127 // CHECK-NEXT: [[DO_RV_CHECK:%.*]] = and i1 true, [[ARG1CMP]]
128 // CHECK: br i1 [[DO_RV_CHECK]], label %[[NULL:.*]], label %[[NONULL:.*]], !nosanitize
129 // CHECK: [[NULL]]:
130 // CHECK-NEXT: [[ICMP:%.*]] = icmp ne i32* {{.*}}, null, !nosanitize
131 // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize
Vedant Kumar2b9f48a2017-03-14 16:48:29 +0000132 // CHECK: call void @__ubsan_handle_nullability_return{{.*}}
Vedant Kumar42c17ec2017-03-14 01:56:34 +0000133 return arg1;
134 // CHECK: [[NONULL]]:
135 // CHECK-NEXT: ret i32*
136}
137
138// CHECK-LABEL: define internal i32* @"\01-[A objc_method:]"
139-(int *_Nonnull) objc_method: (int *_Nonnull) arg1 {
140 // CHECK: [[ARG1CMP:%.*]] = icmp ne i32* %arg1, null, !nosanitize
141 // CHECK-NEXT: [[DO_RV_CHECK:%.*]] = and i1 true, [[ARG1CMP]]
142 // CHECK: br i1 [[DO_RV_CHECK]], label %[[NULL:.*]], label %[[NONULL:.*]], !nosanitize
143 // CHECK: [[NULL]]:
144 // CHECK-NEXT: [[ICMP:%.*]] = icmp ne i32* {{.*}}, null, !nosanitize
145 // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize
Vedant Kumar2b9f48a2017-03-14 16:48:29 +0000146 // CHECK: call void @__ubsan_handle_nullability_return{{.*}}
Vedant Kumar42c17ec2017-03-14 01:56:34 +0000147 return arg1;
148 // CHECK: [[NONULL]]:
149 // CHECK-NEXT: ret i32*
150}
151@end
152
153// CHECK-LABEL: define void @call_A
154void call_A(A *a, int *p) {
155 // CHECK: [[ICMP:%.*]] = icmp ne i32* [[P1:%.*]], null, !nosanitize
156 // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize
Vedant Kumar2b9f48a2017-03-14 16:48:29 +0000157 // CHECK: call void @__ubsan_handle_nullability_arg{{.*}} !nosanitize
Vedant Kumar42c17ec2017-03-14 01:56:34 +0000158 // CHECK: call i32* {{.*}} @objc_msgSend to i32* {{.*}}({{.*}}, i32* [[P1]])
159 [a objc_method: p];
160
161 // CHECK: [[ICMP:%.*]] = icmp ne i32* [[P2:%.*]], null, !nosanitize
162 // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize
Vedant Kumar2b9f48a2017-03-14 16:48:29 +0000163 // CHECK: call void @__ubsan_handle_nullability_arg{{.*}} !nosanitize
Vedant Kumar42c17ec2017-03-14 01:56:34 +0000164 // CHECK: call i32* {{.*}} @objc_msgSend to i32* {{.*}}({{.*}}, i32* [[P2]])
165 [A objc_clsmethod: p];
166}
167
168void dont_crash(int *_Nonnull p, ...) {}
169
170int main() {
171 nonnull_retval1(NULL);
172 nonnull_retval2(NULL, NULL, NULL, NULL, 0, 0, 0, 0);
173 call_func_with_nonnull_arg(NULL);
174 nonnull_assign1(NULL);
175 nonnull_assign2(NULL);
176 nonnull_assign3(NULL);
177 nonnull_init1(NULL);
178 nonnull_init2(NULL);
179 call_A(NULL, NULL);
180 dont_crash(NULL, NULL);
181 return 0;
182}