comparison clang/test/CodeGenObjC/ubsan-nullability.m @ 252:1f2b6ac9f198 llvm-original

LLVM16-1
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Fri, 18 Aug 2023 09:04:13 +0900
parents c4bab56944e8
children
comparison
equal deleted inserted replaced
237:c80f45b162ad 252:1f2b6ac9f198
1 // REQUIRES: asserts 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 2 // RUN: %clang_cc1 -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 3 // RUN: %clang_cc1 -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
4 4
5 // CHECK: [[NONNULL_RV_LOC1:@.*]] = private unnamed_addr global {{.*}} i32 100, i32 6 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 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 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 8 // CHECK: [[NONNULL_ASSIGN2_LOC:@.*]] = private unnamed_addr global {{.*}} i32 405, i32 10
14 14
15 #define NULL ((void *)0) 15 #define NULL ((void *)0)
16 #define INULL ((int *)NULL) 16 #define INULL ((int *)NULL)
17 #define INNULL ((int *_Nonnull)NULL) 17 #define INNULL ((int *_Nonnull)NULL)
18 18
19 // CHECK-LABEL: define{{.*}} i32* @{{.*}}nonnull_retval1 19 // CHECK-LABEL: define{{.*}} ptr @{{.*}}nonnull_retval1
20 #line 100 20 #line 100
21 int *_Nonnull nonnull_retval1(int *p) { 21 int *_Nonnull nonnull_retval1(int *p) {
22 // CHECK: [[ICMP:%.*]] = icmp ne i32* {{.*}}, null, !nosanitize 22 // CHECK: nullcheck:
23 // CHECK: [[ICMP:%.*]] = icmp ne ptr {{.*}}, null, !nosanitize
23 // CHECK: br i1 [[ICMP]], {{.*}}, !nosanitize 24 // CHECK: br i1 [[ICMP]], {{.*}}, !nosanitize
24 // CHECK: call void @__ubsan_handle_nullability_return{{.*}}[[NONNULL_RV_LOC1]] 25 // CHECK: call void @__ubsan_handle_nullability_return{{.*}}[[NONNULL_RV_LOC1]]
25 return p; 26 return p;
26 // CHECK: ret i32* 27 // CHECK: ret ptr
27 } 28 }
28 29
29 #line 190 30 #line 190
30 void nonnull_arg(int *_Nonnull p) {} 31 void nonnull_arg(int *_Nonnull p) {}
31 32
32 // CHECK-LABEL: define{{.*}} void @{{.*}}call_func_with_nonnull_arg 33 // CHECK-LABEL: define{{.*}} void @{{.*}}call_func_with_nonnull_arg
33 #line 200 34 #line 200
34 void call_func_with_nonnull_arg(int *_Nonnull p) { 35 void call_func_with_nonnull_arg(int *_Nonnull p) {
35 // CHECK: [[ICMP:%.*]] = icmp ne i32* {{.*}}, null, !nosanitize 36 // CHECK: [[ICMP:%.*]] = icmp ne ptr {{.*}}, null, !nosanitize
36 // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize 37 // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize
37 // CHECK: call void @__ubsan_handle_nullability_arg{{.*}}[[NONNULL_ARG_LOC]] 38 // CHECK: call void @__ubsan_handle_nullability_arg{{.*}}[[NONNULL_ARG_LOC]]
38 nonnull_arg(p); 39 nonnull_arg(p);
39 } 40 }
40 41
41 // CHECK-LABEL: define{{.*}} void @{{.*}}nonnull_assign1 42 // CHECK-LABEL: define{{.*}} void @{{.*}}nonnull_assign1
42 #line 300 43 #line 300
43 void nonnull_assign1(int *p) { 44 void nonnull_assign1(int *p) {
44 // CHECK: [[ICMP:%.*]] = icmp ne i32* {{.*}}, null, !nosanitize 45 // CHECK: [[ICMP:%.*]] = icmp ne ptr {{.*}}, null, !nosanitize
45 // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize 46 // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize
46 // CHECK: call void @__ubsan_handle_type_mismatch{{.*}}[[NONNULL_ASSIGN1_LOC]] 47 // CHECK: call void @__ubsan_handle_type_mismatch{{.*}}[[NONNULL_ASSIGN1_LOC]]
47 int *_Nonnull local; 48 int *_Nonnull local;
48 local = p; 49 local = p;
49 } 50 }
50 51
51 // CHECK-LABEL: define{{.*}} void @{{.*}}nonnull_assign2 52 // CHECK-LABEL: define{{.*}} void @{{.*}}nonnull_assign2
52 #line 400 53 #line 400
53 void nonnull_assign2(int *p) { 54 void nonnull_assign2(int *p) {
54 // CHECK: [[ICMP:%.*]] = icmp ne i32* %{{.*}}, null, !nosanitize 55 // CHECK: [[ICMP:%.*]] = icmp ne ptr %{{.*}}, null, !nosanitize
55 // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize 56 // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize
56 // CHECK: call void @__ubsan_handle_type_mismatch{{.*}}[[NONNULL_ASSIGN2_LOC]] 57 // CHECK: call void @__ubsan_handle_type_mismatch{{.*}}[[NONNULL_ASSIGN2_LOC]]
57 int *_Nonnull arr[1]; 58 int *_Nonnull arr[1];
58 arr[0] = p; 59 arr[0] = p;
59 } 60 }
63 }; 64 };
64 65
65 // CHECK-LABEL: define{{.*}} void @{{.*}}nonnull_assign3 66 // CHECK-LABEL: define{{.*}} void @{{.*}}nonnull_assign3
66 #line 500 67 #line 500
67 void nonnull_assign3(int *p) { 68 void nonnull_assign3(int *p) {
68 // CHECK: [[ICMP:%.*]] = icmp ne i32* %{{.*}}, null, !nosanitize 69 // CHECK: [[ICMP:%.*]] = icmp ne ptr %{{.*}}, null, !nosanitize
69 // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize 70 // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize
70 // CHECK: call void @__ubsan_handle_type_mismatch{{.*}}[[NONNULL_ASSIGN3_LOC]] 71 // CHECK: call void @__ubsan_handle_type_mismatch{{.*}}[[NONNULL_ASSIGN3_LOC]]
71 // CHECK-NOT: call void @__ubsan_handle_type_mismatch 72 // CHECK-NOT: call void @__ubsan_handle_type_mismatch
72 struct S1 s; 73 struct S1 s;
73 s.mptr = p; 74 s.mptr = p;
74 } 75 }
75 76
76 // CHECK-LABEL: define{{.*}} void @{{.*}}nonnull_init1 77 // CHECK-LABEL: define{{.*}} void @{{.*}}nonnull_init1
77 #line 600 78 #line 600
78 void nonnull_init1(int *p) { 79 void nonnull_init1(int *p) {
79 // CHECK: [[ICMP:%.*]] = icmp ne i32* %{{.*}}, null, !nosanitize 80 // CHECK: [[ICMP:%.*]] = icmp ne ptr %{{.*}}, null, !nosanitize
80 // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize 81 // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize
81 // CHECK: call void @__ubsan_handle_type_mismatch{{.*}}[[NONNULL_INIT1_LOC]] 82 // CHECK: call void @__ubsan_handle_type_mismatch{{.*}}[[NONNULL_INIT1_LOC]]
82 int *_Nonnull local = p; 83 int *_Nonnull local = p;
83 } 84 }
84 85
85 // CHECK-LABEL: define{{.*}} void @{{.*}}nonnull_init2 86 // CHECK-LABEL: define{{.*}} void @{{.*}}nonnull_init2
86 #line 700 87 #line 700
87 void nonnull_init2(int *p) { 88 void nonnull_init2(int *p) {
88 // CHECK: [[ICMP:%.*]] = icmp ne i32* %{{.*}}, null, !nosanitize 89 // CHECK: [[ICMP:%.*]] = icmp ne ptr %{{.*}}, null, !nosanitize
89 // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize 90 // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize
90 // CHECK: call void @__ubsan_handle_type_mismatch{{.*}}[[NONNULL_INIT2_LOC1]] 91 // CHECK: call void @__ubsan_handle_type_mismatch{{.*}}[[NONNULL_INIT2_LOC1]]
91 // CHECK: [[ICMP:%.*]] = icmp ne i32* %{{.*}}, null, !nosanitize 92 // CHECK: [[ICMP:%.*]] = icmp ne ptr %{{.*}}, null, !nosanitize
92 // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize 93 // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize
93 // CHECK: call void @__ubsan_handle_type_mismatch{{.*}}[[NONNULL_INIT2_LOC2]] 94 // CHECK: call void @__ubsan_handle_type_mismatch{{.*}}[[NONNULL_INIT2_LOC2]]
94 int *_Nonnull arr[] = {p, p}; 95 int *_Nonnull arr[] = {p, p};
95 } 96 }
96 97
97 // CHECK-LABEL: define{{.*}} i32* @{{.*}}nonnull_retval2 98 // CHECK-LABEL: define{{.*}} ptr @{{.*}}nonnull_retval2
98 #line 800 99 #line 800
99 int *_Nonnull nonnull_retval2(int *_Nonnull arg1, //< Test this. 100 int *_Nonnull nonnull_retval2(int *_Nonnull arg1, //< Test this.
100 int *_Nonnull arg2, //< Test this. 101 int *_Nonnull arg2, //< Test this.
101 int *_Nullable arg3, //< Don't test the rest. 102 int *_Nullable arg3, //< Don't test the rest.
102 int *arg4, 103 int *arg4,
103 int arg5, ...) { 104 int arg5, ...) {
104 // CHECK: [[ARG1CMP:%.*]] = icmp ne i32* %arg1, null, !nosanitize 105 // CHECK: [[ARG1CMP:%.*]] = icmp ne ptr %arg1, null, !nosanitize
105 // CHECK-NEXT: [[DO_RV_CHECK_1:%.*]] = and i1 true, [[ARG1CMP]], !nosanitize 106 // CHECK-NEXT: [[DO_RV_CHECK_1:%.*]] = and i1 true, [[ARG1CMP]], !nosanitize
106 // CHECK: [[ARG2CMP:%.*]] = icmp ne i32* %arg2, null, !nosanitize 107 // CHECK: [[ARG2CMP:%.*]] = icmp ne ptr %arg2, null, !nosanitize
107 // CHECK-NEXT: [[DO_RV_CHECK_2:%.*]] = and i1 [[DO_RV_CHECK_1]], [[ARG2CMP]] 108 // 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: [[SLOC_PTR:%.*]] = load ptr, ptr %return.sloc.ptr
109 // CHECK-NEXT: [[SLOC_NONNULL:%.*]] = icmp ne i8* [[SLOC_PTR]], null 110 // CHECK-NEXT: [[SLOC_NONNULL:%.*]] = icmp ne ptr [[SLOC_PTR]], null
110 // CHECK-NEXT: [[DO_RV_CHECK_3:%.*]] = and i1 [[SLOC_NONNULL]], [[DO_RV_CHECK_2]] 111 // 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: br i1 [[DO_RV_CHECK_3]], label %[[NULL:.*]], label %[[NONULL:.*]], !nosanitize
112 // CHECK: [[NULL]]: 113 // CHECK: [[NULL]]:
113 // CHECK-NEXT: [[ICMP:%.*]] = icmp ne i32* {{.*}}, null, !nosanitize 114 // CHECK-NEXT: [[ICMP:%.*]] = icmp ne ptr {{.*}}, null, !nosanitize
114 // CHECK: br i1 [[ICMP]], {{.*}}, !nosanitize 115 // CHECK: br i1 [[ICMP]], {{.*}}, !nosanitize
115 // CHECK: call void @__ubsan_handle_nullability_return{{.*}}[[NONNULL_RV_LOC2]] 116 // CHECK: call void @__ubsan_handle_nullability_return{{.*}}[[NONNULL_RV_LOC2]]
116 return arg1; 117 return arg1;
117 // CHECK: [[NONULL]]: 118 // CHECK: [[NONULL]]:
118 // CHECK-NEXT: ret i32* 119 // CHECK-NEXT: ret ptr
119 } 120 }
120 121
121 @interface A 122 @interface A
122 +(int *_Nonnull) objc_clsmethod: (int *_Nonnull) arg1; 123 +(int *_Nonnull) objc_clsmethod: (int *_Nonnull) arg1;
123 -(int *_Nonnull) objc_method: (int *_Nonnull) arg1; 124 -(int *_Nonnull) objc_method: (int *_Nonnull) arg1;
124 @end 125 @end
125 126
126 @implementation A 127 @implementation A
127 128
128 // CHECK-LABEL: define internal i32* @"\01+[A objc_clsmethod:]" 129 // CHECK-LABEL: define internal ptr @"\01+[A objc_clsmethod:]"
129 +(int *_Nonnull) objc_clsmethod: (int *_Nonnull) arg1 { 130 +(int *_Nonnull) objc_clsmethod: (int *_Nonnull) arg1 {
130 // CHECK: [[ARG1CMP:%.*]] = icmp ne i32* %arg1, null, !nosanitize 131 // CHECK: [[ARG1CMP:%.*]] = icmp ne ptr %arg1, null, !nosanitize
131 // CHECK-NEXT: [[DO_RV_CHECK:%.*]] = and i1 true, [[ARG1CMP]] 132 // CHECK-NEXT: [[DO_RV_CHECK:%.*]] = and i1 true, [[ARG1CMP]]
132 // CHECK: [[SLOC_PTR:%.*]] = load i8*, i8** %return.sloc.ptr 133 // CHECK: [[SLOC_PTR:%.*]] = load ptr, ptr %return.sloc.ptr
133 // CHECK-NEXT: [[SLOC_NONNULL:%.*]] = icmp ne i8* [[SLOC_PTR]], null 134 // CHECK-NEXT: [[SLOC_NONNULL:%.*]] = icmp ne ptr [[SLOC_PTR]], null
134 // CHECK-NEXT: [[DO_RV_CHECK_2:%.*]] = and i1 [[SLOC_NONNULL]], [[DO_RV_CHECK]] 135 // 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: br i1 [[DO_RV_CHECK_2]], label %[[NULL:.*]], label %[[NONULL:.*]], !nosanitize
136 // CHECK: [[NULL]]: 137 // CHECK: [[NULL]]:
137 // CHECK-NEXT: [[ICMP:%.*]] = icmp ne i32* {{.*}}, null, !nosanitize 138 // CHECK-NEXT: [[ICMP:%.*]] = icmp ne ptr {{.*}}, null, !nosanitize
138 // CHECK: br i1 [[ICMP]], {{.*}}, !nosanitize 139 // CHECK: br i1 [[ICMP]], {{.*}}, !nosanitize
139 // CHECK: call void @__ubsan_handle_nullability_return{{.*}} 140 // CHECK: call void @__ubsan_handle_nullability_return{{.*}}
140 return arg1; 141 return arg1;
141 // CHECK: [[NONULL]]: 142 // CHECK: [[NONULL]]:
142 // CHECK-NEXT: ret i32* 143 // CHECK-NEXT: ret ptr
143 } 144 }
144 145
145 // CHECK-LABEL: define internal i32* @"\01-[A objc_method:]" 146 // CHECK-LABEL: define internal ptr @"\01-[A objc_method:]"
146 -(int *_Nonnull) objc_method: (int *_Nonnull) arg1 { 147 -(int *_Nonnull) objc_method: (int *_Nonnull) arg1 {
147 // CHECK: [[ARG1CMP:%.*]] = icmp ne i32* %arg1, null, !nosanitize 148 // CHECK: [[ARG1CMP:%.*]] = icmp ne ptr %arg1, null, !nosanitize
148 // CHECK-NEXT: [[DO_RV_CHECK:%.*]] = and i1 true, [[ARG1CMP]] 149 // CHECK-NEXT: [[DO_RV_CHECK:%.*]] = and i1 true, [[ARG1CMP]]
149 // CHECK: [[SLOC_PTR:%.*]] = load i8*, i8** %return.sloc.ptr 150 // CHECK: [[SLOC_PTR:%.*]] = load ptr, ptr %return.sloc.ptr
150 // CHECK-NEXT: [[SLOC_NONNULL:%.*]] = icmp ne i8* [[SLOC_PTR]], null 151 // CHECK-NEXT: [[SLOC_NONNULL:%.*]] = icmp ne ptr [[SLOC_PTR]], null
151 // CHECK-NEXT: [[DO_RV_CHECK_2:%.*]] = and i1 [[SLOC_NONNULL]], [[DO_RV_CHECK]] 152 // 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: br i1 [[DO_RV_CHECK_2]], label %[[NULL:.*]], label %[[NONULL:.*]], !nosanitize
153 // CHECK: [[NULL]]: 154 // CHECK: [[NULL]]:
154 // CHECK-NEXT: [[ICMP:%.*]] = icmp ne i32* {{.*}}, null, !nosanitize 155 // CHECK-NEXT: [[ICMP:%.*]] = icmp ne ptr {{.*}}, null, !nosanitize
155 // CHECK: br i1 [[ICMP]], {{.*}}, !nosanitize 156 // CHECK: br i1 [[ICMP]], {{.*}}, !nosanitize
156 // CHECK: call void @__ubsan_handle_nullability_return{{.*}} 157 // CHECK: call void @__ubsan_handle_nullability_return{{.*}}
157 return arg1; 158 return arg1;
158 // CHECK: [[NONULL]]: 159 // CHECK: [[NONULL]]:
159 // CHECK-NEXT: ret i32* 160 // CHECK-NEXT: ret ptr
160 } 161 }
161 @end 162 @end
162 163
163 // CHECK-LABEL: define{{.*}} void @{{.*}}call_A 164 // CHECK-LABEL: define{{.*}} void @{{.*}}call_A
164 void call_A(A *a, int *p) { 165 void call_A(A *a, int *p) {
165 // CHECK: [[ICMP:%.*]] = icmp ne i32* [[P1:%.*]], null, !nosanitize 166 // CHECK: [[ICMP:%.*]] = icmp ne ptr [[P1:%.*]], null, !nosanitize
166 // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize 167 // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize
167 // CHECK: call void @__ubsan_handle_nullability_arg{{.*}} !nosanitize 168 // CHECK: call void @__ubsan_handle_nullability_arg{{.*}} !nosanitize
168 // CHECK: call i32* {{.*}} @objc_msgSend to i32* {{.*}}({{.*}}, i32* [[P1]]) 169 // CHECK: call ptr @objc_msgSend({{.*}}, ptr [[P1]])
169 [a objc_method: p]; 170 [a objc_method: p];
170 171
171 // CHECK: [[ICMP:%.*]] = icmp ne i32* [[P2:%.*]], null, !nosanitize 172 // CHECK: [[ICMP:%.*]] = icmp ne ptr [[P2:%.*]], null, !nosanitize
172 // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize 173 // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize
173 // CHECK: call void @__ubsan_handle_nullability_arg{{.*}} !nosanitize 174 // CHECK: call void @__ubsan_handle_nullability_arg{{.*}} !nosanitize
174 // CHECK: call i32* {{.*}} @objc_msgSend to i32* {{.*}}({{.*}}, i32* [[P2]]) 175 // CHECK: call ptr @objc_msgSend({{.*}}, ptr [[P2]])
175 [A objc_clsmethod: p]; 176 [A objc_clsmethod: p];
176 } 177 }
177 178
178 void dont_crash(int *_Nonnull p, ...) {} 179 void dont_crash(int *_Nonnull p, ...) {}
179 180