1// REQUIRES: asserts 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-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 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 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 9// CHECK: [[NONNULL_ASSIGN3_LOC:@.*]] = private unnamed_addr global {{.*}} i32 506, i32 10 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 800, i32 6 14 15#define NULL ((void *)0) 16#define INULL ((int *)NULL) 17#define INNULL ((int *_Nonnull)NULL) 18 19// CHECK-LABEL: define{{.*}} ptr @{{.*}}nonnull_retval1 20#line 100 21int *_Nonnull nonnull_retval1(int *p) { 22 // CHECK: nullcheck: 23 // CHECK: [[ICMP:%.*]] = icmp ne ptr {{.*}}, null, !nosanitize 24 // CHECK: br i1 [[ICMP]], {{.*}}, !nosanitize 25 // CHECK: call void @__ubsan_handle_nullability_return{{.*}}[[NONNULL_RV_LOC1]] 26 return p; 27 // CHECK: ret ptr 28} 29 30#line 190 31void nonnull_arg(int *_Nonnull p) {} 32 33// CHECK-LABEL: define{{.*}} void @{{.*}}call_func_with_nonnull_arg 34#line 200 35void call_func_with_nonnull_arg(int *_Nonnull p) { 36 // CHECK: [[ICMP:%.*]] = icmp ne ptr {{.*}}, null, !nosanitize 37 // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize 38 // CHECK: call void @__ubsan_handle_nullability_arg{{.*}}[[NONNULL_ARG_LOC]] 39 nonnull_arg(p); 40} 41 42// CHECK-LABEL: define{{.*}} void @{{.*}}nonnull_assign1 43#line 300 44void nonnull_assign1(int *p) { 45 // CHECK: [[ICMP:%.*]] = icmp ne ptr {{.*}}, null, !nosanitize 46 // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize 47 // CHECK: call void @__ubsan_handle_type_mismatch{{.*}}[[NONNULL_ASSIGN1_LOC]] 48 int *_Nonnull local; 49 local = p; 50} 51 52// CHECK-LABEL: define{{.*}} void @{{.*}}nonnull_assign2 53#line 400 54void nonnull_assign2(int *p) { 55 // CHECK: [[ICMP:%.*]] = icmp ne ptr %{{.*}}, null, !nosanitize 56 // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize 57 // CHECK: call void @__ubsan_handle_type_mismatch{{.*}}[[NONNULL_ASSIGN2_LOC]] 58 int *_Nonnull arr[1]; 59 arr[0] = p; 60} 61 62struct S1 { 63 int *_Nonnull mptr; 64}; 65 66// CHECK-LABEL: define{{.*}} void @{{.*}}nonnull_assign3 67#line 500 68void nonnull_assign3(int *p) { 69 // CHECK: [[ICMP:%.*]] = icmp ne ptr %{{.*}}, null, !nosanitize 70 // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize 71 // CHECK: call void @__ubsan_handle_type_mismatch{{.*}}[[NONNULL_ASSIGN3_LOC]] 72 // CHECK-NOT: call void @__ubsan_handle_type_mismatch 73 struct S1 s; 74 s.mptr = p; 75} 76 77// CHECK-LABEL: define{{.*}} void @{{.*}}nonnull_init1 78#line 600 79void nonnull_init1(int *p) { 80 // CHECK: [[ICMP:%.*]] = icmp ne ptr %{{.*}}, null, !nosanitize 81 // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize 82 // CHECK: call void @__ubsan_handle_type_mismatch{{.*}}[[NONNULL_INIT1_LOC]] 83 int *_Nonnull local = p; 84} 85 86// CHECK-LABEL: define{{.*}} void @{{.*}}nonnull_init2 87#line 700 88void nonnull_init2(int *p) { 89 // CHECK: [[ICMP:%.*]] = icmp ne ptr %{{.*}}, null, !nosanitize 90 // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize 91 // CHECK: call void @__ubsan_handle_type_mismatch{{.*}}[[NONNULL_INIT2_LOC1]] 92 // CHECK: [[ICMP:%.*]] = icmp ne ptr %{{.*}}, null, !nosanitize 93 // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize 94 // CHECK: call void @__ubsan_handle_type_mismatch{{.*}}[[NONNULL_INIT2_LOC2]] 95 int *_Nonnull arr[] = {p, p}; 96} 97 98// CHECK-LABEL: define{{.*}} ptr @{{.*}}nonnull_retval2 99#line 800 100int *_Nonnull nonnull_retval2(int *_Nonnull arg1, //< Test this. 101 int *_Nonnull arg2, //< Test this. 102 int *_Nullable arg3, //< Don't test the rest. 103 int *arg4, 104 int arg5, ...) { 105 // CHECK: [[ARG1CMP:%.*]] = icmp ne ptr %arg1, null, !nosanitize 106 // CHECK-NEXT: [[DO_RV_CHECK_1:%.*]] = and i1 true, [[ARG1CMP]], !nosanitize 107 // CHECK: [[ARG2CMP:%.*]] = icmp ne ptr %arg2, null, !nosanitize 108 // CHECK-NEXT: [[DO_RV_CHECK_2:%.*]] = and i1 [[DO_RV_CHECK_1]], [[ARG2CMP]] 109 // CHECK: [[SLOC_PTR:%.*]] = load ptr, ptr %return.sloc.ptr 110 // CHECK-NEXT: [[SLOC_NONNULL:%.*]] = icmp ne ptr [[SLOC_PTR]], null 111 // CHECK-NEXT: [[DO_RV_CHECK_3:%.*]] = and i1 [[SLOC_NONNULL]], [[DO_RV_CHECK_2]] 112 // CHECK: br i1 [[DO_RV_CHECK_3]], label %[[NULL:.*]], label %[[NONULL:.*]], !nosanitize 113 // CHECK: [[NULL]]: 114 // CHECK-NEXT: [[ICMP:%.*]] = icmp ne ptr {{.*}}, null, !nosanitize 115 // CHECK: br i1 [[ICMP]], {{.*}}, !nosanitize 116 // CHECK: call void @__ubsan_handle_nullability_return{{.*}}[[NONNULL_RV_LOC2]] 117 return arg1; 118 // CHECK: [[NONULL]]: 119 // CHECK-NEXT: ret ptr 120} 121 122@interface A 123+(int *_Nonnull) objc_clsmethod: (int *_Nonnull) arg1; 124-(int *_Nonnull) objc_method: (int *_Nonnull) arg1; 125@end 126 127@implementation A 128 129// CHECK-LABEL: define internal ptr @"\01+[A objc_clsmethod:]" 130+(int *_Nonnull) objc_clsmethod: (int *_Nonnull) arg1 { 131 // CHECK: [[ARG1CMP:%.*]] = icmp ne ptr %arg1, null, !nosanitize 132 // CHECK-NEXT: [[DO_RV_CHECK:%.*]] = and i1 true, [[ARG1CMP]] 133 // CHECK: [[SLOC_PTR:%.*]] = load ptr, ptr %return.sloc.ptr 134 // CHECK-NEXT: [[SLOC_NONNULL:%.*]] = icmp ne ptr [[SLOC_PTR]], null 135 // CHECK-NEXT: [[DO_RV_CHECK_2:%.*]] = and i1 [[SLOC_NONNULL]], [[DO_RV_CHECK]] 136 // CHECK: br i1 [[DO_RV_CHECK_2]], label %[[NULL:.*]], label %[[NONULL:.*]], !nosanitize 137 // CHECK: [[NULL]]: 138 // CHECK-NEXT: [[ICMP:%.*]] = icmp ne ptr {{.*}}, null, !nosanitize 139 // CHECK: br i1 [[ICMP]], {{.*}}, !nosanitize 140 // CHECK: call void @__ubsan_handle_nullability_return{{.*}} 141 return arg1; 142 // CHECK: [[NONULL]]: 143 // CHECK-NEXT: ret ptr 144} 145 146// CHECK-LABEL: define internal ptr @"\01-[A objc_method:]" 147-(int *_Nonnull) objc_method: (int *_Nonnull) arg1 { 148 // CHECK: [[ARG1CMP:%.*]] = icmp ne ptr %arg1, null, !nosanitize 149 // CHECK-NEXT: [[DO_RV_CHECK:%.*]] = and i1 true, [[ARG1CMP]] 150 // CHECK: [[SLOC_PTR:%.*]] = load ptr, ptr %return.sloc.ptr 151 // CHECK-NEXT: [[SLOC_NONNULL:%.*]] = icmp ne ptr [[SLOC_PTR]], null 152 // CHECK-NEXT: [[DO_RV_CHECK_2:%.*]] = and i1 [[SLOC_NONNULL]], [[DO_RV_CHECK]] 153 // CHECK: br i1 [[DO_RV_CHECK_2]], label %[[NULL:.*]], label %[[NONULL:.*]], !nosanitize 154 // CHECK: [[NULL]]: 155 // CHECK-NEXT: [[ICMP:%.*]] = icmp ne ptr {{.*}}, null, !nosanitize 156 // CHECK: br i1 [[ICMP]], {{.*}}, !nosanitize 157 // CHECK: call void @__ubsan_handle_nullability_return{{.*}} 158 return arg1; 159 // CHECK: [[NONULL]]: 160 // CHECK-NEXT: ret ptr 161} 162@end 163 164// CHECK-LABEL: define{{.*}} void @{{.*}}call_A 165void call_A(A *a, int *p) { 166 // CHECK: [[ICMP:%.*]] = icmp ne ptr [[P1:%.*]], null, !nosanitize 167 // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize 168 // CHECK: call void @__ubsan_handle_nullability_arg{{.*}} !nosanitize 169 // CHECK: call ptr @objc_msgSend({{.*}}, ptr [[P1]]) 170 [a objc_method: p]; 171 172 // CHECK: [[ICMP:%.*]] = icmp ne ptr [[P2:%.*]], null, !nosanitize 173 // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize 174 // CHECK: call void @__ubsan_handle_nullability_arg{{.*}} !nosanitize 175 // CHECK: call ptr @objc_msgSend({{.*}}, ptr [[P2]]) 176 [A objc_clsmethod: p]; 177} 178 179void dont_crash(int *_Nonnull p, ...) {} 180 181@protocol NSObject 182- (id)init; 183@end 184@interface NSObject <NSObject> {} 185@end 186 187#pragma clang assume_nonnull begin 188 189/// Create a "NSObject * _Nonnull" instance. 190NSObject *get_nonnull_error(void) { 191 // Use nil for convenience. The actual object doesn't matter. 192 return (NSObject *)NULL; 193} 194 195NSObject *_Nullable no_null_return_value_diagnostic(int flag) { 196// CHECK-LABEL: define internal {{.*}}no_null_return_value_diagnostic{{i?}}_block_invoke 197// CHECK-NOT: @__ubsan_handle_nullability_return 198 NSObject *_Nullable (^foo)(void) = ^(void) { 199 if (flag) { 200 // Clang should not infer a nonnull return value for this block when this 201 // call is present. 202 return get_nonnull_error(); 203 } else { 204 return (NSObject *)NULL; 205 } 206 }; 207 return foo(); 208} 209 210#pragma clang assume_nonnull end 211 212int main(void) { 213 nonnull_retval1(INULL); 214 nonnull_retval2(INNULL, INNULL, INULL, (int *_Nullable)NULL, 0, 0, 0, 0); 215 call_func_with_nonnull_arg(INNULL); 216 nonnull_assign1(INULL); 217 nonnull_assign2(INULL); 218 nonnull_assign3(INULL); 219 nonnull_init1(INULL); 220 nonnull_init2(INULL); 221 call_A((A *)NULL, INULL); 222 dont_crash(INNULL, NULL); 223 no_null_return_value_diagnostic(0); 224 no_null_return_value_diagnostic(1); 225 return 0; 226} 227