1 // RUN: %clang_cc1 -no-opaque-pointers -no-enable-noundef-analysis -std=c++11 -fsanitize=signed-integer-overflow,integer-divide-by-zero,float-divide-by-zero,shift-base,shift-exponent,unreachable,return,vla-bound,alignment,null,vptr,object-size,float-cast-overflow,bool,enum,array-bounds,function -fsanitize-recover=signed-integer-overflow,integer-divide-by-zero,float-divide-by-zero,shift-base,shift-exponent,vla-bound,alignment,null,vptr,object-size,float-cast-overflow,bool,enum,array-bounds,function -emit-llvm %s -o - -triple x86_64-linux-gnu | opt -instnamer -S | FileCheck %s --check-prefixes=CHECK,CHECK-FUNCSAN 2 // RUN: %clang_cc1 -no-opaque-pointers -no-enable-noundef-analysis -std=c++11 -fsanitize=vptr,address -fsanitize-recover=vptr,address -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s --check-prefix=CHECK-ASAN 3 // RUN: %clang_cc1 -no-opaque-pointers -no-enable-noundef-analysis -std=c++11 -fsanitize=vptr -fsanitize-recover=vptr -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s --check-prefix=DOWNCAST-NULL 4 // RUN: %clang_cc1 -no-opaque-pointers -no-enable-noundef-analysis -std=c++11 -fsanitize=function -emit-llvm %s -o - -triple x86_64-linux-gnux32 | FileCheck %s --check-prefix=CHECK-FUNCSAN 5 // RUN: %clang_cc1 -no-opaque-pointers -no-enable-noundef-analysis -std=c++11 -fsanitize=function -emit-llvm %s -o - -triple i386-linux-gnu | FileCheck %s --check-prefix=CHECK-FUNCSAN 6 7 struct S { 8 double d; 9 int a, b; 10 virtual int f(); 11 }; 12 13 // Check that type descriptor global is not modified by ASan. 14 // CHECK-ASAN: [[TYPE_DESCR:@[0-9]+]] = private unnamed_addr constant { i16, i16, [4 x i8] } { i16 -1, i16 0, [4 x i8] c"'S'\00" } 15 16 // Check that type mismatch handler is not modified by ASan. 17 // CHECK-ASAN: private unnamed_addr global { { [{{.*}} x i8]*, i32, i32 }, { i16, i16, [4 x i8] }*, i8*, i8 } { {{.*}}, { i16, i16, [4 x i8] }* [[TYPE_DESCR]], {{.*}} } 18 19 // CHECK-FUNCSAN: [[PROXY:@.+]] = private unnamed_addr constant i8* bitcast ({ i8*, i8* }* @_ZTIFvPFviEE to i8*) 20 21 struct T : S {}; 22 23 // CHECK-LABEL: @_Z17reference_binding 24 void reference_binding(int *p, S *q) { 25 // C++ core issue 453: If an lvalue to which a reference is directly bound 26 // designates neither an existing object or function of an appropriate type, 27 // nor a region of storage of suitable size and alignment to contain an object 28 // of the reference's type, the behavior is undefined. 29 30 // CHECK: icmp ne {{.*}}, null 31 32 // CHECK: %[[SIZE:.*]] = call i64 @llvm.objectsize.i64 33 // CHECK-NEXT: icmp uge i64 %[[SIZE]], 4 34 35 // CHECK: %[[PTRINT:.*]] = ptrtoint 36 // CHECK-NEXT: %[[MISALIGN:.*]] = and i64 %[[PTRINT]], 3 37 // CHECK-NEXT: icmp eq i64 %[[MISALIGN]], 0 38 int &r = *p; 39 40 // A reference is not required to refer to an object within its lifetime. 41 // CHECK-NOT: __ubsan_handle_dynamic_type_cache_miss 42 S &r2 = *q; 43 } 44 45 // CHECK-LABEL: @_Z13member_access 46 // CHECK-ASAN-LABEL: @_Z13member_access 47 void member_access(S *p) { 48 // (1a) Check 'p' is appropriately sized and aligned for member access. 49 50 // CHECK: icmp ne {{.*}}, null 51 52 // CHECK: %[[SIZE:.*]] = call i64 @llvm.objectsize.i64 53 // CHECK-NEXT: icmp uge i64 %[[SIZE]], 24 54 55 // CHECK: %[[PTRINT:.*]] = ptrtoint 56 // CHECK-NEXT: %[[MISALIGN:.*]] = and i64 %[[PTRINT]], 7 57 // CHECK-NEXT: icmp eq i64 %[[MISALIGN]], 0 58 59 // (1b) Check that 'p' actually points to an 'S'. 60 61 // CHECK: %[[VPTRADDR:.*]] = bitcast {{.*}} to i64* 62 // CHECK-NEXT: %[[VPTR:.*]] = load i64, i64* %[[VPTRADDR]] 63 // 64 // hash_16_bytes: 65 // 66 // If this number changes, it indicates that either the mangled name of ::S 67 // has changed, or that LLVM's hashing function has changed. The latter case 68 // is OK if the hashing function is still stable. 69 // 70 // The two hash values are for 64- and 32-bit Clang binaries, respectively. 71 // FIXME: We should produce a 64-bit value either way. 72 // 73 // CHECK-NEXT: xor i64 {{-4030275160588942838|1107558922}}, %[[VPTR]] 74 // CHECK-NEXT: mul i64 {{.*}}, -7070675565921424023 75 // CHECK-NEXT: lshr i64 {{.*}}, 47 76 // CHECK-NEXT: xor i64 77 // CHECK-NEXT: xor i64 %[[VPTR]] 78 // CHECK-NEXT: mul i64 {{.*}}, -7070675565921424023 79 // CHECK-NEXT: lshr i64 {{.*}}, 47 80 // CHECK-NEXT: xor i64 81 // CHECK-NEXT: %[[HASH:.*]] = mul i64 {{.*}}, -7070675565921424023 82 // 83 // Check the hash against the table: 84 // 85 // CHECK-NEXT: %[[IDX:.*]] = and i64 %{{.*}}, 127 86 // CHECK-NEXT: getelementptr inbounds [128 x i64], [128 x i64]* @__ubsan_vptr_type_cache, i32 0, i64 %[[IDX]] 87 // CHECK-NEXT: %[[CACHEVAL:.*]] = load i64, i64* 88 // CHECK-NEXT: icmp eq i64 %[[CACHEVAL]], %[[HASH]] 89 // CHECK-NEXT: br i1 90 91 // CHECK: call void @__ubsan_handle_dynamic_type_cache_miss({{.*}}, i64 %{{.*}}, i64 %[[HASH]]) 92 // CHECK-NOT: unreachable 93 // CHECK: {{.*}}: 94 95 // (2) Check 'p->b' is appropriately sized and aligned for a load. 96 97 // FIXME: Suppress this in the trivial case of a member access, because we 98 // know we've just checked the member access expression itself. 99 100 // CHECK: %[[SIZE:.*]] = call i64 @llvm.objectsize.i64 101 // CHECK-NEXT: icmp uge i64 %[[SIZE]], 4 102 103 // CHECK: %[[PTRINT:.*]] = ptrtoint 104 // CHECK-NEXT: %[[MISALIGN:.*]] = and i64 %[[PTRINT]], 3 105 // CHECK-NEXT: icmp eq i64 %[[MISALIGN]], 0 106 int k = p->b; 107 108 // (3a) Check 'p' is appropriately sized and aligned for member function call. 109 110 // CHECK: icmp ne {{.*}}, null 111 112 // CHECK: %[[SIZE:.*]] = call i64 @llvm.objectsize.i64 113 // CHECK-NEXT: icmp uge i64 %[[SIZE]], 24 114 115 // CHECK: %[[PTRINT:.*]] = ptrtoint 116 // CHECK-NEXT: %[[MISALIGN:.*]] = and i64 %[[PTRINT]], 7 117 // CHECK-NEXT: icmp eq i64 %[[MISALIGN]], 0 118 119 // (3b) Check that 'p' actually points to an 'S' 120 121 // CHECK: load i64, i64* 122 // CHECK-NEXT: xor i64 {{-4030275160588942838|1107558922}}, 123 // [...] 124 // CHECK: getelementptr inbounds [128 x i64], [128 x i64]* @__ubsan_vptr_type_cache, i32 0, i64 % 125 // CHECK: br i1 126 // CHECK: call void @__ubsan_handle_dynamic_type_cache_miss({{.*}}, i64 %{{.*}}, i64 %{{.*}}) 127 // CHECK-NOT: unreachable 128 // CHECK: {{.*}}: 129 130 k = p->f(); 131 } 132 133 // CHECK-LABEL: @_Z12lsh_overflow 134 int lsh_overflow(int a, int b) { 135 // CHECK: %[[RHS_INBOUNDS:.*]] = icmp ule i32 %[[RHS:.*]], 31 136 // CHECK-NEXT: br i1 %[[RHS_INBOUNDS]], label %[[CHECK_BB:.*]], label %[[CONT_BB:.*]], 137 138 // CHECK: [[CHECK_BB]]: 139 // CHECK-NEXT: %[[SHIFTED_OUT_WIDTH:.*]] = sub nuw nsw i32 31, %[[RHS]] 140 // CHECK-NEXT: %[[SHIFTED_OUT:.*]] = lshr i32 %[[LHS:.*]], %[[SHIFTED_OUT_WIDTH]] 141 142 // This is present for C++11 but not for C: C++ core issue 1457 allows a '1' 143 // to be shifted into the sign bit, but not out of it. 144 // CHECK-NEXT: %[[SHIFTED_OUT_NOT_SIGN:.*]] = lshr i32 %[[SHIFTED_OUT]], 1 145 146 // CHECK-NEXT: %[[NO_OVERFLOW:.*]] = icmp eq i32 %[[SHIFTED_OUT_NOT_SIGN]], 0 147 // CHECK-NEXT: br label %[[CONT_BB]] 148 149 // CHECK: [[CONT_BB]]: 150 // CHECK-NEXT: %[[VALID_BASE:.*]] = phi i1 [ true, {{.*}} ], [ %[[NO_OVERFLOW]], %[[CHECK_BB]] ] 151 // CHECK-NEXT: %[[VALID:.*]] = and i1 %[[RHS_INBOUNDS]], %[[VALID_BASE]] 152 // CHECK-NEXT: br i1 %[[VALID]] 153 154 // CHECK: call void @__ubsan_handle_shift_out_of_bounds 155 // CHECK-NOT: call void @__ubsan_handle_shift_out_of_bounds 156 157 // CHECK: %[[RET:.*]] = shl i32 %[[LHS]], %[[RHS]] 158 // CHECK-NEXT: ret i32 %[[RET]] 159 return a << b; 160 } 161 162 // CHECK-LABEL: @_Z9no_return 163 int no_return() { 164 // CHECK: call void @__ubsan_handle_missing_return(i8* bitcast ({{.*}}* @{{.*}} to i8*)) [[NR_NUW:#[0-9]+]] 165 // CHECK-NEXT: unreachable 166 } 167 168 // CHECK-LABEL: @_Z9sour_bool 169 bool sour_bool(bool *p) { 170 // CHECK: %[[OK:.*]] = icmp ule i8 {{.*}}, 1 171 // CHECK: br i1 %[[OK]] 172 // CHECK: call void @__ubsan_handle_load_invalid_value(i8* bitcast ({{.*}}), i64 {{.*}}) 173 return *p; 174 } 175 176 enum E1 { e1a = 0, e1b = 127 } e1; 177 enum E2 { e2a = -1, e2b = 64 } e2; 178 enum E3 { e3a = (1u << 31) - 1 } e3; 179 180 // CHECK-LABEL: @_Z14bad_enum_value 181 int bad_enum_value() { 182 // CHECK: %[[E1:.*]] = icmp ule i32 {{.*}}, 127 183 // CHECK: br i1 %[[E1]] 184 // CHECK: call void @__ubsan_handle_load_invalid_value( 185 int a = e1; 186 187 // CHECK: %[[E2HI:.*]] = icmp sle i32 {{.*}}, 127 188 // CHECK: %[[E2LO:.*]] = icmp sge i32 {{.*}}, -128 189 // CHECK: %[[E2:.*]] = and i1 %[[E2HI]], %[[E2LO]] 190 // CHECK: br i1 %[[E2]] 191 // CHECK: call void @__ubsan_handle_load_invalid_value( 192 int b = e2; 193 194 // CHECK: %[[E3:.*]] = icmp ule i32 {{.*}}, 2147483647 195 // CHECK: br i1 %[[E3]] 196 // CHECK: call void @__ubsan_handle_load_invalid_value( 197 int c = e3; 198 return a + b + c; 199 } 200 201 // CHECK-LABEL: @_Z20bad_downcast_pointer 202 // DOWNCAST-NULL-LABEL: @_Z20bad_downcast_pointer 203 void bad_downcast_pointer(S *p) { 204 // CHECK: %[[NONNULL:.*]] = icmp ne {{.*}}, null 205 // CHECK: br i1 %[[NONNULL]], 206 207 // A null pointer access is guarded without -fsanitize=null. 208 // DOWNCAST-NULL: %[[NONNULL:.*]] = icmp ne {{.*}}, null 209 // DOWNCAST-NULL: br i1 %[[NONNULL]], 210 211 // CHECK: %[[SIZE:.*]] = call i64 @llvm.objectsize.i64.p0i8( 212 // CHECK: %[[E1:.*]] = icmp uge i64 %[[SIZE]], 24 213 // CHECK: %[[MISALIGN:.*]] = and i64 %{{.*}}, 7 214 // CHECK: %[[E2:.*]] = icmp eq i64 %[[MISALIGN]], 0 215 // CHECK: %[[E12:.*]] = and i1 %[[E1]], %[[E2]] 216 // CHECK: br i1 %[[E12]], 217 218 // CHECK: call void @__ubsan_handle_type_mismatch 219 // CHECK: br label 220 221 // CHECK: br i1 %{{.*}}, 222 223 // CHECK: call void @__ubsan_handle_dynamic_type_cache_miss 224 // CHECK: br label 225 (void) static_cast<T*>(p); 226 } 227 228 // CHECK-LABEL: @_Z22bad_downcast_reference 229 void bad_downcast_reference(S &p) { 230 // CHECK: %[[E1:.*]] = icmp ne {{.*}}, null 231 // CHECK-NOT: br i1 232 233 // CHECK: %[[SIZE:.*]] = call i64 @llvm.objectsize.i64.p0i8( 234 // CHECK: %[[E2:.*]] = icmp uge i64 %[[SIZE]], 24 235 236 // CHECK: %[[MISALIGN:.*]] = and i64 %{{.*}}, 7 237 // CHECK: %[[E3:.*]] = icmp eq i64 %[[MISALIGN]], 0 238 239 // CHECK: %[[E12:.*]] = and i1 %[[E1]], %[[E2]] 240 // CHECK: %[[E123:.*]] = and i1 %[[E12]], %[[E3]] 241 // CHECK: br i1 %[[E123]], 242 243 // CHECK: call void @__ubsan_handle_type_mismatch 244 // CHECK: br label 245 246 // CHECK: br i1 %{{.*}}, 247 248 // CHECK: call void @__ubsan_handle_dynamic_type_cache_miss 249 // CHECK: br label 250 (void) static_cast<T&>(p); 251 } 252 253 // CHECK-LABEL: @_Z11array_index 254 int array_index(const int (&a)[4], int n) { 255 // CHECK: %[[K1_OK:.*]] = icmp ult i64 %{{.*}}, 4 256 // CHECK: br i1 %[[K1_OK]] 257 // CHECK: call void @__ubsan_handle_out_of_bounds( 258 int k1 = a[n]; 259 260 // CHECK: %[[R1_OK:.*]] = icmp ule i64 %{{.*}}, 4 261 // CHECK: br i1 %[[R1_OK]] 262 // CHECK: call void @__ubsan_handle_out_of_bounds( 263 const int *r1 = &a[n]; 264 265 // CHECK: %[[K2_OK:.*]] = icmp ult i64 %{{.*}}, 8 266 // CHECK: br i1 %[[K2_OK]] 267 // CHECK: call void @__ubsan_handle_out_of_bounds( 268 int k2 = ((const int(&)[8])a)[n]; 269 270 // CHECK: %[[K3_OK:.*]] = icmp ult i64 %{{.*}}, 4 271 // CHECK: br i1 %[[K3_OK]] 272 // CHECK: call void @__ubsan_handle_out_of_bounds( 273 int k3 = n[a]; 274 275 return k1 + *r1 + k2; 276 } 277 278 // CHECK-LABEL: @_Z17multi_array_index 279 int multi_array_index(int n, int m) { 280 int arr[4][6]; 281 282 // CHECK: %[[IDX1_OK:.*]] = icmp ult i64 %{{.*}}, 4 283 // CHECK: br i1 %[[IDX1_OK]] 284 // CHECK: call void @__ubsan_handle_out_of_bounds( 285 286 // CHECK: %[[IDX2_OK:.*]] = icmp ult i64 %{{.*}}, 6 287 // CHECK: br i1 %[[IDX2_OK]] 288 // CHECK: call void @__ubsan_handle_out_of_bounds( 289 return arr[n][m]; 290 } 291 292 // CHECK-LABEL: @_Z11array_arith 293 int array_arith(const int (&a)[4], int n) { 294 // CHECK: %[[K1_OK:.*]] = icmp ule i64 %{{.*}}, 4 295 // CHECK: br i1 %[[K1_OK]] 296 // CHECK: call void @__ubsan_handle_out_of_bounds( 297 const int *k1 = a + n; 298 299 // CHECK: %[[K2_OK:.*]] = icmp ule i64 %{{.*}}, 8 300 // CHECK: br i1 %[[K2_OK]] 301 // CHECK: call void @__ubsan_handle_out_of_bounds( 302 const int *k2 = (const int(&)[8])a + n; 303 304 return *k1 + *k2; 305 } 306 307 struct ArrayMembers { 308 int a1[5]; 309 int a2[1]; 310 }; 311 // CHECK-LABEL: @_Z18struct_array_index 312 int struct_array_index(ArrayMembers *p, int n) { 313 // CHECK: %[[IDX_OK:.*]] = icmp ult i64 %{{.*}}, 5 314 // CHECK: br i1 %[[IDX_OK]] 315 // CHECK: call void @__ubsan_handle_out_of_bounds( 316 return p->a1[n]; 317 } 318 319 // CHECK-LABEL: @_Z16flex_array_index 320 int flex_array_index(ArrayMembers *p, int n) { 321 // CHECK-NOT: call void @__ubsan_handle_out_of_bounds( 322 return p->a2[n]; 323 } 324 325 extern int incomplete[]; 326 // CHECK-LABEL: @_Z22incomplete_array_index 327 int incomplete_array_index(int n) { 328 // CHECK-NOT: call void @__ubsan_handle_out_of_bounds( 329 return incomplete[n]; 330 } 331 332 typedef __attribute__((ext_vector_type(4))) int V4I; 333 // CHECK-LABEL: @_Z12vector_index 334 int vector_index(V4I v, int n) { 335 // CHECK: %[[IDX_OK:.*]] = icmp ult i64 %{{.*}}, 4 336 // CHECK: br i1 %[[IDX_OK]] 337 // CHECK: call void @__ubsan_handle_out_of_bounds( 338 return v[n]; 339 } 340 341 // CHECK-LABEL: @_Z12string_index 342 char string_index(int n) { 343 // CHECK: %[[IDX_OK:.*]] = icmp ult i64 %{{.*}}, 6 344 // CHECK: br i1 %[[IDX_OK]] 345 // CHECK: call void @__ubsan_handle_out_of_bounds( 346 return "Hello"[n]; 347 } 348 349 class A // align=4 350 { 351 int a1, a2, a3; 352 }; 353 354 class B // align=8 355 { 356 long b1, b2; 357 }; 358 359 class C : public A, public B // align=16 360 { 361 alignas(16) int c1; 362 }; 363 364 // Make sure we check the alignment of the pointer after subtracting any 365 // offset. The pointer before subtraction doesn't need to be aligned for 366 // the destination type. 367 368 // CHECK-LABEL: define{{.*}} void @_Z16downcast_pointerP1B(%class.B* %b) 369 void downcast_pointer(B *b) { 370 (void) static_cast<C*>(b); 371 // Alignment check from EmitTypeCheck(TCK_DowncastPointer, ...) 372 // CHECK: [[SUB:%[.a-z0-9]*]] = getelementptr inbounds i8, i8* {{.*}}, i64 -16 373 // CHECK-NEXT: [[C:%.+]] = bitcast i8* [[SUB]] to %class.C* 374 // null check goes here 375 // CHECK: [[FROM_PHI:%.+]] = phi %class.C* [ [[C]], {{.*}} ], {{.*}} 376 // Objectsize check goes here 377 // CHECK: [[C_INT:%.+]] = ptrtoint %class.C* [[FROM_PHI]] to i64 378 // CHECK-NEXT: [[MASKED:%.+]] = and i64 [[C_INT]], 15 379 // CHECK-NEXT: [[TEST:%.+]] = icmp eq i64 [[MASKED]], 0 380 // AND the alignment test with the objectsize test. 381 // CHECK-NEXT: [[AND:%.+]] = and i1 {{.*}}, [[TEST]] 382 // CHECK-NEXT: br i1 [[AND]] 383 } 384 385 // CHECK-LABEL: define{{.*}} void @_Z18downcast_referenceR1B(%class.B* nonnull align {{[0-9]+}} dereferenceable({{[0-9]+}}) %b) 386 void downcast_reference(B &b) { 387 (void) static_cast<C&>(b); 388 // Alignment check from EmitTypeCheck(TCK_DowncastReference, ...) 389 // CHECK: [[SUB:%[.a-z0-9]*]] = getelementptr inbounds i8, i8* {{.*}}, i64 -16 390 // CHECK-NEXT: [[C:%.+]] = bitcast i8* [[SUB]] to %class.C* 391 // Objectsize check goes here 392 // CHECK: [[C_INT:%.+]] = ptrtoint %class.C* [[C]] to i64 393 // CHECK-NEXT: [[MASKED:%.+]] = and i64 [[C_INT]], 15 394 // CHECK-NEXT: [[TEST:%.+]] = icmp eq i64 [[MASKED]], 0 395 // AND the alignment test with the objectsize test. 396 // CHECK: [[AND:%.+]] = and i1 {{.*}}, [[TEST]] 397 // CHECK-NEXT: br i1 [[AND]] 398 } 399 400 // CHECK-FUNCSAN: @_Z22indirect_function_callPFviE({{.*}} !func_sanitize ![[FUNCSAN:.*]] { 401 void indirect_function_call(void (*p)(int)) { 402 // CHECK: [[PTR:%.+]] = bitcast void (i32)* {{.*}} to <{ i32, i32 }>* 403 404 // Signature check 405 // CHECK-NEXT: [[SIGPTR:%.+]] = getelementptr <{ i32, i32 }>, <{ i32, i32 }>* [[PTR]], i32 0, i32 0 406 // CHECK-NEXT: [[SIG:%.+]] = load i32, i32* [[SIGPTR]] 407 // CHECK-NEXT: [[SIGCMP:%.+]] = icmp eq i32 [[SIG]], 846595819 408 // CHECK-NEXT: br i1 [[SIGCMP]] 409 410 // RTTI pointer check 411 // CHECK: [[RTTIPTR:%.+]] = getelementptr <{ i32, i32 }>, <{ i32, i32 }>* [[PTR]], i32 0, i32 1 412 // CHECK-NEXT: [[RTTIEncIntTrunc:%.+]] = load i32, i32* [[RTTIPTR]] 413 // CHECK-NEXT: [[RTTIEncInt:%.+]] = sext i32 [[RTTIEncIntTrunc]] to i64 414 // CHECK-NEXT: [[FuncAddrInt:%.+]] = ptrtoint void (i32)* {{.*}} to i64 415 // CHECK-NEXT: [[IndirectGVInt:%.+]] = add i64 [[RTTIEncInt]], [[FuncAddrInt]] 416 // CHECK-NEXT: [[IndirectGV:%.+]] = inttoptr i64 [[IndirectGVInt]] to i8** 417 // CHECK-NEXT: [[RTTI:%.+]] = load i8*, i8** [[IndirectGV]], align 8 418 // CHECK-NEXT: [[RTTICMP:%.+]] = icmp eq i8* [[RTTI]], bitcast ({ i8*, i8* }* @_ZTIFviE to i8*) 419 // CHECK-NEXT: br i1 [[RTTICMP]] 420 421 p(42); 422 } 423 424 namespace VBaseObjectSize { 425 // Note: C is laid out such that offsetof(C, B) + sizeof(B) extends outside 426 // the C object. 427 struct alignas(16) A { void *a1, *a2; }; 428 struct B : virtual A { void *b; void* g(); }; 429 struct C : virtual A, virtual B { }; 430 // CHECK-LABEL: define {{.*}} @_ZN15VBaseObjectSize1fERNS_1BE( 431 B &f(B &b) { 432 // Size check: check for nvsize(B) == 16 (do not require size(B) == 32) 433 // CHECK: [[SIZE:%.+]] = call i{{32|64}} @llvm.objectsize.i64.p0i8( 434 // CHECK: icmp uge i{{32|64}} [[SIZE]], 16, 435 436 // Alignment check: check for nvalign(B) == 8 (do not require align(B) == 16) 437 // CHECK: [[PTRTOINT:%.+]] = ptrtoint {{.*}} to i64, 438 // CHECK: and i64 [[PTRTOINT]], 7, 439 return b; 440 } 441 442 // CHECK-LABEL: define {{.*}} @_ZN15VBaseObjectSize1B1gEv( 443 void *B::g() { 444 // Ensure that the check on the "this" pointer also uses the proper 445 // alignment. We should be using nvalign(B) == 8, not 16. 446 // CHECK: [[PTRTOINT:%.+]] = ptrtoint {{.*}} to i64, 447 // CHECK: and i64 [[PTRTOINT]], 7 448 return nullptr; 449 } 450 } 451 452 namespace FunctionSanitizerVirtualCalls { 453 struct A { 454 virtual void f() {} 455 virtual void g() {} 456 void h() {} 457 }; 458 459 struct B : virtual A { 460 virtual void b() {} 461 virtual void f(); 462 void g() final {} 463 static void q() {} 464 }; 465 466 void B::f() {} 467 468 void force_irgen() { 469 A a; 470 a.g(); 471 a.h(); 472 473 B b; 474 b.f(); 475 b.b(); 476 b.g(); 477 B::q(); 478 } 479 480 // CHECK-LABEL: define{{.*}} void @_ZN29FunctionSanitizerVirtualCalls1B1fEv 481 // CHECK-NOT: !func_sanitize 482 // 483 // CHECK-LABEL: define{{.*}} void @_ZTv0_n24_N29FunctionSanitizerVirtualCalls1B1fEv 484 // CHECK-NOT: !func_sanitize 485 // 486 // CHECK-LABEL: define{{.*}} void @_ZN29FunctionSanitizerVirtualCalls11force_irgenEv() 487 // CHECK: !func_sanitize 488 // 489 // CHECK-LABEL: define linkonce_odr void @_ZN29FunctionSanitizerVirtualCalls1AC1Ev 490 // CHECK-NOT: !func_sanitize 491 // 492 // CHECK-LABEL: define linkonce_odr void @_ZN29FunctionSanitizerVirtualCalls1A1gEv 493 // CHECK-NOT: !func_sanitize 494 // 495 // CHECK-LABEL: define linkonce_odr void @_ZN29FunctionSanitizerVirtualCalls1A1hEv 496 // CHECK-NOT: !func_sanitize 497 // 498 // CHECK-LABEL: define linkonce_odr void @_ZN29FunctionSanitizerVirtualCalls1BC1Ev 499 // CHECK-NOT: !func_sanitize 500 // 501 // CHECK-LABEL: define linkonce_odr void @_ZN29FunctionSanitizerVirtualCalls1B1bEv 502 // CHECK-NOT: !func_sanitize 503 // 504 // CHECK-LABEL: define linkonce_odr void @_ZN29FunctionSanitizerVirtualCalls1B1gEv 505 // CHECK-NOT: !func_sanitize 506 // 507 // CHECK-LABEL: define linkonce_odr void @_ZN29FunctionSanitizerVirtualCalls1B1qEv 508 // CHECK: !func_sanitize 509 510 } 511 512 namespace UpcastPointerTest { 513 struct S {}; 514 struct T : S { double d; }; 515 struct V : virtual S {}; 516 517 // CHECK-LABEL: upcast_pointer 518 S* upcast_pointer(T* t) { 519 // Check for null pointer 520 // CHECK: %[[NONNULL:.*]] = icmp ne {{.*}}, null 521 // CHECK: br i1 %[[NONNULL]] 522 523 // Check alignment 524 // CHECK: %[[MISALIGN:.*]] = and i64 %{{.*}}, 7 525 // CHECK: icmp eq i64 %[[MISALIGN]], 0 526 527 // CHECK: call void @__ubsan_handle_type_mismatch 528 return t; 529 } 530 531 V getV(); 532 533 // CHECK-LABEL: upcast_to_vbase 534 void upcast_to_vbase() { 535 // No need to check for null here, as we have a temporary here. 536 537 // CHECK-NOT: br i1 538 539 // CHECK: call i64 @llvm.objectsize 540 // CHECK: call void @__ubsan_handle_type_mismatch 541 // CHECK: call void @__ubsan_handle_dynamic_type_cache_miss 542 const S& s = getV(); 543 } 544 } 545 546 struct nothrow {}; 547 void *operator new[](__SIZE_TYPE__, nothrow) noexcept; 548 549 namespace NothrowNew { 550 struct X { X(); }; 551 552 // CHECK-LABEL: define{{.*}}nothrow_new_trivial 553 void *nothrow_new_trivial() { 554 // CHECK: %[[is_null:.*]] = icmp eq i8*{{.*}}, null 555 // CHECK: br i1 %[[is_null]], label %[[null:.*]], label %[[nonnull:.*]] 556 557 // CHECK: [[nonnull]]: 558 // CHECK: llvm.objectsize 559 // CHECK: icmp uge i64 {{.*}}, 123456, 560 // CHECK: br i1 561 // 562 // CHECK: call {{.*}}__ubsan_handle_type_mismatch 563 // 564 // CHECK: [[null]]: 565 // CHECK-NOT: {{ }}br{{ }} 566 // CHECK: ret 567 return new (nothrow{}) char[123456]; 568 } 569 570 // CHECK-LABEL: define{{.*}}nothrow_new_nontrivial 571 void *nothrow_new_nontrivial() { 572 // CHECK: %[[is_null:.*]] = icmp eq i8*{{.*}}, null 573 // CHECK: br i1 %[[is_null]], label %[[null:.*]], label %[[nonnull:.*]] 574 575 // CHECK: [[nonnull]]: 576 // CHECK: llvm.objectsize 577 // CHECK: icmp uge i64 {{.*}}, 123456, 578 // CHECK: br i1 579 // 580 // CHECK: call {{.*}}__ubsan_handle_type_mismatch 581 // 582 // CHECK: call {{.*}}_ZN10NothrowNew1XC1Ev 583 // 584 // CHECK: [[null]]: 585 // CHECK-NOT: {{ }}br{{ }} 586 // CHECK: ret 587 return new (nothrow{}) X[123456]; 588 } 589 590 // CHECK-LABEL: define{{.*}}throwing_new 591 void *throwing_new(int size) { 592 // CHECK: icmp ne i8*{{.*}}, null 593 // CHECK: %[[size:.*]] = mul 594 // CHECK: llvm.objectsize 595 // CHECK: icmp uge i64 {{.*}}, %[[size]], 596 // CHECK: %[[ok:.*]] = and 597 // CHECK: br i1 %[[ok]], label %[[good:.*]], label %[[bad:[^,]*]] 598 // 599 // CHECK: [[bad]]: 600 // CHECK: call {{.*}}__ubsan_handle_type_mismatch 601 // 602 // CHECK: [[good]]: 603 // CHECK-NOT: {{ }}br{{ }} 604 // CHECK: ret 605 return new char[size]; 606 } 607 608 // CHECK-LABEL: define{{.*}}nothrow_new_zero_size 609 void *nothrow_new_zero_size() { 610 // CHECK: %[[nonnull:.*]] = icmp ne i8*{{.*}}, null 611 // CHECK-NOT: llvm.objectsize 612 // CHECK: br i1 %[[nonnull]], label %[[good:.*]], label %[[bad:[^,]*]] 613 // 614 // CHECK: [[bad]]: 615 // CHECK: call {{.*}}__ubsan_handle_type_mismatch 616 // 617 // CHECK: [[good]]: 618 // CHECK-NOT: {{ }}br{{ }} 619 // CHECK: ret 620 return new char[0]; 621 } 622 623 // CHECK-LABEL: define{{.*}}throwing_new_zero_size 624 void *throwing_new_zero_size() { 625 // Nothing to check here. 626 // CHECK-NOT: __ubsan_handle_type_mismatch 627 return new (nothrow{}) char[0]; 628 // CHECK: ret 629 } 630 } 631 632 struct ThisAlign { 633 void this_align_lambda(); 634 void this_align_lambda_2(); 635 }; 636 void ThisAlign::this_align_lambda() { 637 // CHECK-LABEL: define internal %struct.ThisAlign* @"_ZZN9ThisAlign17this_align_lambdaEvENK3$_0clEv" 638 // CHECK-SAME: (%{{.*}}* {{[^,]*}} %[[this:[^)]*]]) 639 // CHECK: %[[this_addr:.*]] = alloca 640 // CHECK: store %{{.*}}* %[[this]], %{{.*}}** %[[this_addr]], 641 // CHECK: %[[this_inner:.*]] = load %{{.*}}*, %{{.*}}** %[[this_addr]], 642 // CHECK: %[[this_outer_addr:.*]] = getelementptr inbounds %{{.*}}, %{{.*}}* %[[this_inner]], i32 0, i32 0 643 // CHECK: %[[this_outer:.*]] = load %{{.*}}*, %{{.*}}** %[[this_outer_addr]], 644 // 645 // CHECK: %[[this_inner_isnonnull:.*]] = icmp ne %{{.*}}* %[[this_inner]], null 646 // CHECK: %[[this_inner_asint:.*]] = ptrtoint %{{.*}}* %[[this_inner]] to i 647 // CHECK: %[[this_inner_misalignment:.*]] = and i{{32|64}} %[[this_inner_asint]], {{3|7}}, 648 // CHECK: %[[this_inner_isaligned:.*]] = icmp eq i{{32|64}} %[[this_inner_misalignment]], 0 649 // CHECK: %[[this_inner_valid:.*]] = and i1 %[[this_inner_isnonnull]], %[[this_inner_isaligned]], 650 // CHECK: br i1 %[[this_inner_valid:.*]] 651 [&] { return this; } (); 652 } 653 654 namespace CopyValueRepresentation { 655 // CHECK-LABEL: define {{.*}} @_ZN23CopyValueRepresentation2S3aSERKS0_ 656 // CHECK-NOT: call {{.*}} @__ubsan_handle_load_invalid_value 657 // CHECK-LABEL: define {{.*}} @_ZN23CopyValueRepresentation2S4aSEOS0_ 658 // CHECK-NOT: call {{.*}} @__ubsan_handle_load_invalid_value 659 // CHECK-LABEL: define {{.*}} @_ZN23CopyValueRepresentation2S1C2ERKS0_ 660 // CHECK-NOT: call {{.*}} __ubsan_handle_load_invalid_value 661 // CHECK-LABEL: define {{.*}} @_ZN23CopyValueRepresentation2S2C2ERKS0_ 662 // CHECK: __ubsan_handle_load_invalid_value 663 // CHECK-LABEL: define {{.*}} @_ZN23CopyValueRepresentation2S5C2ERKS0_ 664 // CHECK-NOT: call {{.*}} __ubsan_handle_load_invalid_value 665 666 struct CustomCopy { CustomCopy(); CustomCopy(const CustomCopy&); }; 667 struct S1 { 668 CustomCopy CC; 669 bool b; 670 }; 671 void callee1(S1); 672 void test1() { 673 S1 s11; 674 callee1(s11); 675 S1 s12; 676 s12 = s11; 677 } 678 679 static bool some_global_bool; 680 struct ExprCopy { 681 ExprCopy(); 682 ExprCopy(const ExprCopy&, bool b = some_global_bool); 683 }; 684 struct S2 { 685 ExprCopy EC; 686 bool b; 687 }; 688 void callee2(S2); 689 void test2(void) { 690 S2 s21; 691 callee2(s21); 692 S2 s22; 693 s22 = s21; 694 } 695 696 struct CustomAssign { CustomAssign &operator=(const CustomAssign&); }; 697 struct S3 { 698 CustomAssign CA; 699 bool b; 700 }; 701 void test3() { 702 S3 x, y; 703 x = y; 704 } 705 706 struct CustomMove { 707 CustomMove(); 708 CustomMove(const CustomMove&&); 709 CustomMove &operator=(const CustomMove&&); 710 }; 711 struct S4 { 712 CustomMove CM; 713 bool b; 714 }; 715 void test4() { 716 S4 x, y; 717 x = static_cast<S4&&>(y); 718 } 719 720 struct EnumCustomCopy { 721 EnumCustomCopy(); 722 EnumCustomCopy(const EnumCustomCopy&); 723 }; 724 struct S5 { 725 EnumCustomCopy ECC; 726 bool b; 727 }; 728 void callee5(S5); 729 void test5() { 730 S5 s51; 731 callee5(s51); 732 S5 s52; 733 s52 = s51; 734 } 735 } 736 737 void ThisAlign::this_align_lambda_2() { 738 // CHECK-LABEL: define internal void @"_ZZN9ThisAlign19this_align_lambda_2EvENK3$_1clEv" 739 // CHECK-SAME: (%{{.*}}* {{[^,]*}} %[[this:[^)]*]]) 740 // CHECK: %[[this_addr:.*]] = alloca 741 // CHECK: store %{{.*}}* %[[this]], %{{.*}}** %[[this_addr]], 742 // CHECK: %[[this_inner:.*]] = load %{{.*}}*, %{{.*}}** %[[this_addr]], 743 // 744 // Do not perform a null check on the 'this' pointer if the function might be 745 // called from a static invoker. 746 // CHECK-NOT: icmp ne %{{.*}}* %[[this_inner]], null 747 auto *p = +[] {}; 748 p(); 749 } 750 751 // CHECK: attributes [[NR_NUW]] = { noreturn nounwind } 752 753 // CHECK-FUNCSAN: ![[FUNCSAN]] = !{i32 846595819, i8** [[PROXY]]} 754