Vedant Kumar | 42c17ec | 2017-03-14 01:56:34 +0000 | [diff] [blame] | 1 | // 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 Kumar | 6b22dda | 2017-04-26 21:55:17 +0000 | [diff] [blame^] | 3 | // 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 Kumar | 42c17ec | 2017-03-14 01:56:34 +0000 | [diff] [blame] | 4 | |
| 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 Kumar | 6b22dda | 2017-04-26 21:55:17 +0000 | [diff] [blame^] | 9 | // CHECK: [[NONNULL_ASSIGN3_LOC:@.*]] = private unnamed_addr global {{.*}} i32 506, i32 10 |
Vedant Kumar | 42c17ec | 2017-03-14 01:56:34 +0000 | [diff] [blame] | 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 817, i32 1 {{.*}} i32 800, i32 6 |
| 14 | |
| 15 | #define NULL ((void *)0) |
Vedant Kumar | 6b22dda | 2017-04-26 21:55:17 +0000 | [diff] [blame^] | 16 | #define INULL ((int *)NULL) |
| 17 | #define INNULL ((int *_Nonnull)NULL) |
Vedant Kumar | 42c17ec | 2017-03-14 01:56:34 +0000 | [diff] [blame] | 18 | |
Vedant Kumar | 6b22dda | 2017-04-26 21:55:17 +0000 | [diff] [blame^] | 19 | // CHECK-LABEL: define i32* @{{.*}}nonnull_retval1 |
Vedant Kumar | 42c17ec | 2017-03-14 01:56:34 +0000 | [diff] [blame] | 20 | #line 100 |
| 21 | int *_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 Kumar | 2b9f48a | 2017-03-14 16:48:29 +0000 | [diff] [blame] | 26 | // CHECK: call void @__ubsan_handle_nullability_return{{.*}}[[NONNULL_RV_LOC1]] |
Vedant Kumar | 42c17ec | 2017-03-14 01:56:34 +0000 | [diff] [blame] | 27 | return p; |
| 28 | // CHECK: [[NONULL]]: |
| 29 | // CHECK-NEXT: ret i32* |
| 30 | } |
| 31 | |
| 32 | #line 190 |
| 33 | void nonnull_arg(int *_Nonnull p) {} |
| 34 | |
Vedant Kumar | 6b22dda | 2017-04-26 21:55:17 +0000 | [diff] [blame^] | 35 | // CHECK-LABEL: define void @{{.*}}call_func_with_nonnull_arg |
Vedant Kumar | 42c17ec | 2017-03-14 01:56:34 +0000 | [diff] [blame] | 36 | #line 200 |
| 37 | void call_func_with_nonnull_arg(int *_Nonnull p) { |
| 38 | // CHECK: [[ICMP:%.*]] = icmp ne i32* {{.*}}, null, !nosanitize |
| 39 | // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize |
Vedant Kumar | 2b9f48a | 2017-03-14 16:48:29 +0000 | [diff] [blame] | 40 | // CHECK: call void @__ubsan_handle_nullability_arg{{.*}}[[NONNULL_ARG_LOC]] |
Vedant Kumar | 42c17ec | 2017-03-14 01:56:34 +0000 | [diff] [blame] | 41 | nonnull_arg(p); |
| 42 | } |
| 43 | |
Vedant Kumar | 6b22dda | 2017-04-26 21:55:17 +0000 | [diff] [blame^] | 44 | // CHECK-LABEL: define void @{{.*}}nonnull_assign1 |
Vedant Kumar | 42c17ec | 2017-03-14 01:56:34 +0000 | [diff] [blame] | 45 | #line 300 |
| 46 | void 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 Kumar | 6b22dda | 2017-04-26 21:55:17 +0000 | [diff] [blame^] | 54 | // CHECK-LABEL: define void @{{.*}}nonnull_assign2 |
Vedant Kumar | 42c17ec | 2017-03-14 01:56:34 +0000 | [diff] [blame] | 55 | #line 400 |
| 56 | void 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 | |
| 64 | struct S1 { |
| 65 | int *_Nonnull mptr; |
| 66 | }; |
| 67 | |
Vedant Kumar | 6b22dda | 2017-04-26 21:55:17 +0000 | [diff] [blame^] | 68 | // CHECK-LABEL: define void @{{.*}}nonnull_assign3 |
Vedant Kumar | 42c17ec | 2017-03-14 01:56:34 +0000 | [diff] [blame] | 69 | #line 500 |
| 70 | void 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 Kumar | 6b22dda | 2017-04-26 21:55:17 +0000 | [diff] [blame^] | 74 | // CHECK-NOT: call void @__ubsan_handle_type_mismatch |
Vedant Kumar | 42c17ec | 2017-03-14 01:56:34 +0000 | [diff] [blame] | 75 | struct S1 s; |
| 76 | s.mptr = p; |
| 77 | } |
| 78 | |
Vedant Kumar | 6b22dda | 2017-04-26 21:55:17 +0000 | [diff] [blame^] | 79 | // CHECK-LABEL: define void @{{.*}}nonnull_init1 |
Vedant Kumar | 42c17ec | 2017-03-14 01:56:34 +0000 | [diff] [blame] | 80 | #line 600 |
| 81 | void 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 Kumar | 6b22dda | 2017-04-26 21:55:17 +0000 | [diff] [blame^] | 88 | // CHECK-LABEL: define void @{{.*}}nonnull_init2 |
Vedant Kumar | 42c17ec | 2017-03-14 01:56:34 +0000 | [diff] [blame] | 89 | #line 700 |
| 90 | void 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 Kumar | 6b22dda | 2017-04-26 21:55:17 +0000 | [diff] [blame^] | 100 | // CHECK-LABEL: define i32* @{{.*}}nonnull_retval2 |
Vedant Kumar | 42c17ec | 2017-03-14 01:56:34 +0000 | [diff] [blame] | 101 | #line 800 |
| 102 | int *_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 Kumar | 2b9f48a | 2017-03-14 16:48:29 +0000 | [diff] [blame] | 115 | // CHECK: call void @__ubsan_handle_nullability_return{{.*}}[[NONNULL_RV_LOC2]] |
Vedant Kumar | 42c17ec | 2017-03-14 01:56:34 +0000 | [diff] [blame] | 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: 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 Kumar | 2b9f48a | 2017-03-14 16:48:29 +0000 | [diff] [blame] | 136 | // CHECK: call void @__ubsan_handle_nullability_return{{.*}} |
Vedant Kumar | 42c17ec | 2017-03-14 01:56:34 +0000 | [diff] [blame] | 137 | 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 Kumar | 2b9f48a | 2017-03-14 16:48:29 +0000 | [diff] [blame] | 150 | // CHECK: call void @__ubsan_handle_nullability_return{{.*}} |
Vedant Kumar | 42c17ec | 2017-03-14 01:56:34 +0000 | [diff] [blame] | 151 | return arg1; |
| 152 | // CHECK: [[NONULL]]: |
| 153 | // CHECK-NEXT: ret i32* |
| 154 | } |
| 155 | @end |
| 156 | |
Vedant Kumar | 6b22dda | 2017-04-26 21:55:17 +0000 | [diff] [blame^] | 157 | // CHECK-LABEL: define void @{{.*}}call_A |
Vedant Kumar | 42c17ec | 2017-03-14 01:56:34 +0000 | [diff] [blame] | 158 | void call_A(A *a, int *p) { |
| 159 | // CHECK: [[ICMP:%.*]] = icmp ne i32* [[P1:%.*]], null, !nosanitize |
| 160 | // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize |
Vedant Kumar | 2b9f48a | 2017-03-14 16:48:29 +0000 | [diff] [blame] | 161 | // CHECK: call void @__ubsan_handle_nullability_arg{{.*}} !nosanitize |
Vedant Kumar | 42c17ec | 2017-03-14 01:56:34 +0000 | [diff] [blame] | 162 | // 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 Kumar | 2b9f48a | 2017-03-14 16:48:29 +0000 | [diff] [blame] | 167 | // CHECK: call void @__ubsan_handle_nullability_arg{{.*}} !nosanitize |
Vedant Kumar | 42c17ec | 2017-03-14 01:56:34 +0000 | [diff] [blame] | 168 | // CHECK: call i32* {{.*}} @objc_msgSend to i32* {{.*}}({{.*}}, i32* [[P2]]) |
| 169 | [A objc_clsmethod: p]; |
| 170 | } |
| 171 | |
| 172 | void dont_crash(int *_Nonnull p, ...) {} |
| 173 | |
| 174 | int main() { |
Vedant Kumar | 6b22dda | 2017-04-26 21:55:17 +0000 | [diff] [blame^] | 175 | 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 Kumar | 42c17ec | 2017-03-14 01:56:34 +0000 | [diff] [blame] | 185 | return 0; |
| 186 | } |