diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp index 04f13c7d7a6a3..7afd1fd10fb19 100644 --- a/clang/lib/CodeGen/CGDecl.cpp +++ b/clang/lib/CodeGen/CGDecl.cpp @@ -767,12 +767,11 @@ void CodeGenFunction::EmitNullabilityCheck(LValue LHS, llvm::Value *RHS, // Check if the right hand side of the assignment is nonnull, if the left // hand side must be nonnull. auto CheckOrdinal = SanitizerKind::SO_NullabilityAssign; - auto CheckHandler = SanitizerHandler::TypeMismatch; + auto CheckHandler = SanitizerHandler::NullPointerUseWithNullability; SanitizerDebugLocation SanScope(this, {CheckOrdinal}, CheckHandler); llvm::Value *IsNotNull = Builder.CreateIsNotNull(RHS); llvm::Constant *StaticData[] = { EmitCheckSourceLocation(Loc), EmitCheckTypeDescriptor(LHS.getType()), - llvm::ConstantInt::get(Int8Ty, 0), // The LogAlignment info is unused. llvm::ConstantInt::get(Int8Ty, TCK_NonnullAssign)}; EmitCheck({{IsNotNull, CheckOrdinal}}, CheckHandler, StaticData, RHS); } diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index 90aed796cf5ab..6b53d28bd14a3 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -766,18 +766,13 @@ void CodeGenFunction::EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc, llvm::BasicBlock *Done = nullptr; bool DoneViaNullSanitize = false; + llvm::Value *True = llvm::ConstantInt::getTrue(getLLVMContext()); + { - auto CheckHandler = SanitizerHandler::TypeMismatch; - SanitizerDebugLocation SanScope(this, - {SanitizerKind::SO_Null, - SanitizerKind::SO_ObjectSize, - SanitizerKind::SO_Alignment}, + auto CheckHandler = SanitizerHandler::NullPointerUse; + SanitizerDebugLocation SanScope(this, {SanitizerKind::SO_Null}, CheckHandler); - SmallVector, 3> - Checks; - - llvm::Value *True = llvm::ConstantInt::getTrue(getLLVMContext()); bool AllowNullPointers = isNullPointerAllowed(TCK); if ((SanOpts.has(SanitizerKind::Null) || AllowNullPointers) && !IsGuaranteedNonNull) { @@ -799,10 +794,20 @@ void CodeGenFunction::EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc, Builder.CreateCondBr(IsNonNull, Rest, Done); EmitBlock(Rest); } else { - Checks.push_back(std::make_pair(IsNonNull, SanitizerKind::SO_Null)); + llvm::Constant *StaticData[] = {EmitCheckSourceLocation(Loc), + EmitCheckTypeDescriptor(Ty), + llvm::ConstantInt::get(Int8Ty, TCK)}; + EmitCheck({{IsNonNull, SanitizerKind::SO_Null}}, CheckHandler, + StaticData, Ptr); } } } + } + + { + auto CheckHandler = SanitizerHandler::InsufficientObjectSize; + SanitizerDebugLocation SanScope(this, {SanitizerKind::SO_ObjectSize}, + CheckHandler); if (SanOpts.has(SanitizerKind::ObjectSize) && !SkippedChecks.has(SanitizerKind::ObjectSize) && @@ -827,10 +832,19 @@ void CodeGenFunction::EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc, llvm::Value *Dynamic = Builder.getFalse(); llvm::Value *LargeEnough = Builder.CreateICmpUGE( Builder.CreateCall(F, {Ptr, Min, NullIsUnknown, Dynamic}), Size); - Checks.push_back( - std::make_pair(LargeEnough, SanitizerKind::SO_ObjectSize)); + llvm::Constant *StaticData[] = {EmitCheckSourceLocation(Loc), + EmitCheckTypeDescriptor(Ty), + llvm::ConstantInt::get(Int8Ty, TCK)}; + EmitCheck({{LargeEnough, SanitizerKind::SO_ObjectSize}}, CheckHandler, + StaticData, Ptr); } } + } + + { + auto CheckHandler = SanitizerHandler::MisalignedPointerUse; + SanitizerDebugLocation SanScope(this, {SanitizerKind::SO_Alignment}, + CheckHandler); llvm::MaybeAlign AlignVal; llvm::Value *PtrAsInt = nullptr; @@ -851,19 +865,16 @@ void CodeGenFunction::EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc, PtrAsInt, llvm::ConstantInt::get(IntPtrTy, AlignVal->value() - 1)); llvm::Value *Aligned = Builder.CreateICmpEQ(Align, llvm::ConstantInt::get(IntPtrTy, 0)); - if (Aligned != True) - Checks.push_back( - std::make_pair(Aligned, SanitizerKind::SO_Alignment)); + if (Aligned != True) { + llvm::Constant *StaticData[] = { + EmitCheckSourceLocation(Loc), EmitCheckTypeDescriptor(Ty), + llvm::ConstantInt::get(Int8Ty, llvm::Log2(*AlignVal)), + llvm::ConstantInt::get(Int8Ty, TCK)}; + EmitCheck({{Aligned, SanitizerKind::SO_Alignment}}, CheckHandler, + StaticData, PtrAsInt ? PtrAsInt : Ptr); + } } } - - if (Checks.size() > 0) { - llvm::Constant *StaticData[] = { - EmitCheckSourceLocation(Loc), EmitCheckTypeDescriptor(Ty), - llvm::ConstantInt::get(Int8Ty, AlignVal ? llvm::Log2(*AlignVal) : 1), - llvm::ConstantInt::get(Int8Ty, TCK)}; - EmitCheck(Checks, CheckHandler, StaticData, PtrAsInt ? PtrAsInt : Ptr); - } } // If possible, check that the vptr indicates that there is a subobject of @@ -950,7 +961,7 @@ void CodeGenFunction::EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc, SanitizerDebugLocation SanScope( this, {DoneViaNullSanitize ? SanitizerKind::SO_Null : SanitizerKind::SO_Vptr}, - DoneViaNullSanitize ? SanitizerHandler::TypeMismatch + DoneViaNullSanitize ? SanitizerHandler::NullPointerUse : SanitizerHandler::DynamicTypeCacheMiss); Builder.CreateBr(Done); EmitBlock(Done); diff --git a/clang/lib/CodeGen/SanitizerHandler.h b/clang/lib/CodeGen/SanitizerHandler.h index a66e7ab354eb2..fab715b2e16be 100644 --- a/clang/lib/CodeGen/SanitizerHandler.h +++ b/clang/lib/CodeGen/SanitizerHandler.h @@ -70,6 +70,14 @@ SANITIZER_CHECK( \ VLABoundNotPositive, vla_bound_not_positive, 0, \ "Variable length array bound evaluates to non-positive value") \ + SANITIZER_CHECK(NullPointerUse, null_pointer_use, 0, "Null pointer usage") \ + SANITIZER_CHECK( \ + NullPointerUseWithNullability, null_pointer_use_with_nullability, 0, \ + "Assigning null to a lvalue which is annotated with _Nonnull") \ + SANITIZER_CHECK(MisalignedPointerUse, misaligned_pointer_use, 0, \ + "Misaligned pointer use") \ + SANITIZER_CHECK(InsufficientObjectSize, insufficient_object_size, 0, \ + "Insufficient object size") \ SANITIZER_CHECK(BoundsSafety, bounds_safety, 0, \ "") // BoundsSafety Msg is empty because it is not considered // part of UBSan; therefore, no trap reason is emitted for diff --git a/clang/test/CodeGen/allow-ubsan-check.c b/clang/test/CodeGen/allow-ubsan-check.c index e225fb63f08eb..6f4ba21c79292 100644 --- a/clang/test/CodeGen/allow-ubsan-check.c +++ b/clang/test/CodeGen/allow-ubsan-check.c @@ -14,13 +14,9 @@ // CHECK-NEXT: [[TMP1:%.*]] = icmp ne i32 [[X]], -2147483648, !nosanitize [[META2]] // CHECK-NEXT: [[TMP2:%.*]] = icmp ne i32 [[Y]], -1, !nosanitize [[META2]] // CHECK-NEXT: [[OR:%.*]] = or i1 [[TMP1]], [[TMP2]], !nosanitize [[META2]] -// -// 27 == SO_IntegerDivideByZero // CHECK-NEXT: [[TMP3:%.*]] = tail call i1 @llvm.allow.ubsan.check(i8 27), !nosanitize [[META2]] // CHECK-NEXT: [[TMP4:%.*]] = xor i1 [[TMP3]], true, !nosanitize [[META2]] // CHECK-NEXT: [[TMP5:%.*]] = or i1 [[TMP0]], [[TMP4]], !nosanitize [[META2]] -// -// 41 == SO_SignedIntegerOverflow // CHECK-NEXT: [[TMP6:%.*]] = tail call i1 @llvm.allow.ubsan.check(i8 41), !nosanitize [[META2]] // CHECK-NEXT: [[TMP7:%.*]] = xor i1 [[TMP6]], true, !nosanitize [[META2]] // CHECK-NEXT: [[TMP8:%.*]] = or i1 [[OR]], [[TMP7]], !nosanitize [[META2]] @@ -89,13 +85,11 @@ int div(int x, int y) { // CHECK-SAME: ptr noundef readonly captures(address_is_null) [[X:%.*]]) local_unnamed_addr #[[ATTR0]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[TMP0:%.*]] = icmp eq ptr [[X]], null, !nosanitize [[META2]] -// -// 29 == SO_Null // CHECK-NEXT: [[TMP1:%.*]] = tail call i1 @llvm.allow.ubsan.check(i8 29), !nosanitize [[META2]] // CHECK-NEXT: [[DOTNOT1:%.*]] = and i1 [[TMP0]], [[TMP1]] -// CHECK-NEXT: br i1 [[DOTNOT1]], label %[[HANDLER_TYPE_MISMATCH:.*]], label %[[CONT:.*]], !prof [[PROF4:![0-9]+]], !nosanitize [[META2]] -// CHECK: [[HANDLER_TYPE_MISMATCH]]: -// CHECK-NEXT: tail call void @__ubsan_handle_type_mismatch_v1_abort(ptr nonnull @[[GLOB2:[0-9]+]], i64 0) #[[ATTR6]], !nosanitize [[META2]] +// CHECK-NEXT: br i1 [[DOTNOT1]], label %[[HANDLER_NULL_POINTER_USE:.*]], label %[[CONT:.*]], !prof [[PROF4:![0-9]+]], !nosanitize [[META2]] +// CHECK: [[HANDLER_NULL_POINTER_USE]]: +// CHECK-NEXT: tail call void @__ubsan_handle_null_pointer_use_abort(ptr nonnull @[[GLOB2:[0-9]+]], i64 0) #[[ATTR6]], !nosanitize [[META2]] // CHECK-NEXT: unreachable, !nosanitize [[META2]] // CHECK: [[CONT]]: // CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr [[X]], align 4, !tbaa [[TBAA5:![0-9]+]] @@ -109,7 +103,7 @@ int div(int x, int y) { // TR-NEXT: [[DOTNOT1:%.*]] = and i1 [[TMP0]], [[TMP1]] // TR-NEXT: br i1 [[DOTNOT1]], label %[[TRAP:.*]], label %[[CONT:.*]], !prof [[PROF4:![0-9]+]], !nosanitize [[META2]] // TR: [[TRAP]]: -// TR-NEXT: tail call void @llvm.ubsantrap(i8 22) #[[ATTR5]], !nosanitize [[META2]] +// TR-NEXT: tail call void @llvm.ubsantrap(i8 25) #[[ATTR5]], !nosanitize [[META2]] // TR-NEXT: unreachable, !nosanitize [[META2]] // TR: [[CONT]]: // TR-NEXT: [[TMP2:%.*]] = load i32, ptr [[X]], align 4, !tbaa [[TBAA5:![0-9]+]] @@ -121,9 +115,9 @@ int div(int x, int y) { // REC-NEXT: [[TMP0:%.*]] = icmp eq ptr [[X]], null, !nosanitize [[META2]] // REC-NEXT: [[TMP1:%.*]] = tail call i1 @llvm.allow.ubsan.check(i8 29), !nosanitize [[META2]] // REC-NEXT: [[DOTNOT1:%.*]] = and i1 [[TMP0]], [[TMP1]] -// REC-NEXT: br i1 [[DOTNOT1]], label %[[HANDLER_TYPE_MISMATCH:.*]], label %[[CONT:.*]], !prof [[PROF4:![0-9]+]], !nosanitize [[META2]] -// REC: [[HANDLER_TYPE_MISMATCH]]: -// REC-NEXT: tail call void @__ubsan_handle_type_mismatch_v1(ptr nonnull @[[GLOB2:[0-9]+]], i64 0) #[[ATTR6]], !nosanitize [[META2]] +// REC-NEXT: br i1 [[DOTNOT1]], label %[[HANDLER_NULL_POINTER_USE:.*]], label %[[CONT:.*]], !prof [[PROF4:![0-9]+]], !nosanitize [[META2]] +// REC: [[HANDLER_NULL_POINTER_USE]]: +// REC-NEXT: tail call void @__ubsan_handle_null_pointer_use(ptr nonnull @[[GLOB2:[0-9]+]], i64 0) #[[ATTR6]], !nosanitize [[META2]] // REC-NEXT: br label %[[CONT]], !nosanitize [[META2]] // REC: [[CONT]]: // REC-NEXT: [[TMP2:%.*]] = load i32, ptr [[X]], align 4, !tbaa [[TBAA5:![0-9]+]] @@ -138,8 +132,6 @@ int null(int* x) { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[TMP0:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[X]], i32 [[Y]]), !nosanitize [[META2]] // CHECK-NEXT: [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, !nosanitize [[META2]] -// -// 41 == SO_SignedIntegerOverflow // CHECK-NEXT: [[TMP2:%.*]] = tail call i1 @llvm.allow.ubsan.check(i8 41), !nosanitize [[META2]] // CHECK-NEXT: [[DOTDEMORGAN:%.*]] = and i1 [[TMP1]], [[TMP2]] // CHECK-NEXT: br i1 [[DOTDEMORGAN]], label %[[HANDLER_ADD_OVERFLOW:.*]], label %[[CONT:.*]], !prof [[PROF4]], !nosanitize [[META2]] @@ -198,8 +190,6 @@ void use(double*); // CHECK-NEXT: call void @use(ptr noundef nonnull [[VLA]]) #[[ATTR7:[0-9]+]] // CHECK-NEXT: [[IDXPROM:%.*]] = sext i32 [[I]] to i64 // CHECK-NEXT: [[TMP1:%.*]] = icmp ule i64 [[TMP0]], [[IDXPROM]] -// -// 71 == SO_LocalBounds // CHECK-NEXT: [[TMP2:%.*]] = call i1 @llvm.allow.ubsan.check(i8 71), !nosanitize [[META2]] // CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP1]], [[TMP2]], !nosanitize [[META2]] // CHECK-NEXT: br i1 [[TMP3]], label %[[TRAP:.*]], label %[[BB4:.*]] diff --git a/clang/test/CodeGen/attr-counted-by.c b/clang/test/CodeGen/attr-counted-by.c index 101949af208e1..c8423a7f15dc0 100644 --- a/clang/test/CodeGen/attr-counted-by.c +++ b/clang/test/CodeGen/attr-counted-by.c @@ -1223,12 +1223,12 @@ int test12_a, test12_b; // SANITIZE-WITH-ATTR-NEXT: store i32 [[TMP2]], ptr @test12_b, align 4, !tbaa [[TBAA4]] // SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_LOAD:%.*]] = load i32, ptr @test12_foo, align 4 // SANITIZE-WITH-ATTR-NEXT: [[DOTNOT:%.*]] = icmp eq i32 [[DOTCOUNTED_BY_LOAD]], 0 -// SANITIZE-WITH-ATTR-NEXT: br i1 [[DOTNOT]], label [[HANDLER_OUT_OF_BOUNDS4:%.*]], label [[HANDLER_TYPE_MISMATCH6:%.*]], !prof [[PROF8]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[DOTNOT]], label [[HANDLER_OUT_OF_BOUNDS4:%.*]], label [[HANDLER_INSUFFICIENT_OBJECT_SIZE6:%.*]], !prof [[PROF8]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR: handler.out_of_bounds4: // SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB24:[0-9]+]], i64 0) #[[ATTR8]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] -// SANITIZE-WITH-ATTR: handler.type_mismatch6: -// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_type_mismatch_v1_abort(ptr nonnull @[[GLOB25:[0-9]+]], i64 ptrtoint (ptr getelementptr inbounds nuw (i8, ptr @test12_foo, i64 4) to i64)) #[[ATTR8]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: handler.insufficient_object_size6: +// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_insufficient_object_size_abort(ptr nonnull @[[GLOB25:[0-9]+]], i64 ptrtoint (ptr getelementptr inbounds nuw (i8, ptr @test12_foo, i64 4) to i64)) #[[ATTR8]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] // // NO-SANITIZE-WITH-ATTR-LABEL: define dso_local noundef i32 @test12( @@ -1265,12 +1265,12 @@ int test12_a, test12_b; // SANITIZE-WITHOUT-ATTR-NEXT: store i32 [[TMP2]], ptr @test12_b, align 4, !tbaa [[TBAA2]] // SANITIZE-WITHOUT-ATTR-NEXT: [[DOTCOUNTED_BY_LOAD:%.*]] = load i32, ptr @test12_foo, align 4 // SANITIZE-WITHOUT-ATTR-NEXT: [[DOTNOT:%.*]] = icmp eq i32 [[DOTCOUNTED_BY_LOAD]], 0 -// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[DOTNOT]], label [[HANDLER_OUT_OF_BOUNDS4:%.*]], label [[HANDLER_TYPE_MISMATCH6:%.*]], !prof [[PROF10:![0-9]+]], !nosanitize [[META9]] +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[DOTNOT]], label [[HANDLER_OUT_OF_BOUNDS4:%.*]], label [[HANDLER_INSUFFICIENT_OBJECT_SIZE6:%.*]], !prof [[PROF10:![0-9]+]], !nosanitize [[META9]] // SANITIZE-WITHOUT-ATTR: handler.out_of_bounds4: // SANITIZE-WITHOUT-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB4:[0-9]+]], i64 0) #[[ATTR8]], !nosanitize [[META9]] // SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META9]] -// SANITIZE-WITHOUT-ATTR: handler.type_mismatch6: -// SANITIZE-WITHOUT-ATTR-NEXT: tail call void @__ubsan_handle_type_mismatch_v1_abort(ptr nonnull @[[GLOB5:[0-9]+]], i64 ptrtoint (ptr getelementptr inbounds nuw (i8, ptr @test12_foo, i64 4) to i64)) #[[ATTR8]], !nosanitize [[META9]] +// SANITIZE-WITHOUT-ATTR: handler.insufficient_object_size6: +// SANITIZE-WITHOUT-ATTR-NEXT: tail call void @__ubsan_handle_insufficient_object_size_abort(ptr nonnull @[[GLOB5:[0-9]+]], i64 ptrtoint (ptr getelementptr inbounds nuw (i8, ptr @test12_foo, i64 4) to i64)) #[[ATTR8]], !nosanitize [[META9]] // SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META9]] // // NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local noundef i32 @test12( diff --git a/clang/test/CodeGen/catch-alignment-assumption-builtin_assume_aligned-polymorphism.cpp b/clang/test/CodeGen/catch-alignment-assumption-builtin_assume_aligned-polymorphism.cpp index e40c0f3ce95d6..d1aaf1144c900 100644 --- a/clang/test/CodeGen/catch-alignment-assumption-builtin_assume_aligned-polymorphism.cpp +++ b/clang/test/CodeGen/catch-alignment-assumption-builtin_assume_aligned-polymorphism.cpp @@ -24,10 +24,10 @@ void *f(C *c) { // CHECK-SANITIZE-NEXT: %[[PTRTOINT:.*]] = ptrtoint ptr %[[C_RELOAD]] to i64, !nosanitize // CHECK-SANITIZE-NEXT: %[[MASKEDPTR:.*]] = and i64 %[[PTRTOINT]], 3, !nosanitize // CHECK-SANITIZE-NEXT: %[[MASKCOND:.*]] = icmp eq i64 %[[MASKEDPTR]], 0, !nosanitize - // CHECK-SANITIZE-NEXT: br i1 %[[MASKCOND]], label %[[CONT:[^,]+]], label %[[HANDLER_TYPE_MISMATCH:[^,]+]] - // CHECK-SANITIZE: [[HANDLER_TYPE_MISMATCH]]: - // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort( - // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_type_mismatch_v1( + // CHECK-SANITIZE-NEXT: br i1 %[[MASKCOND]], label %[[CONT:[^,]+]], label %[[HANDLER_TYPE_MISALIGNED_POINTER_USE:[^,]+]] + // CHECK-SANITIZE: [[HANDLER_TYPE_MISALIGNED_POINTER_USE]]: + // CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_misaligned_pointer_use_abort( + // CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_misaligned_pointer_use( // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.ubsantrap( // CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize // CHECK-SANITIZE: [[CONT]]: diff --git a/clang/test/CodeGen/catch-undef-behavior.c b/clang/test/CodeGen/catch-undef-behavior.c index 14cb7705c3783..b6074d1041804 100644 --- a/clang/test/CodeGen/catch-undef-behavior.c +++ b/clang/test/CodeGen/catch-undef-behavior.c @@ -5,16 +5,18 @@ // CHECK-UBSAN: @[[INT:.*]] = private unnamed_addr constant { i16, i16, [6 x i8] } { i16 0, i16 11, [6 x i8] c"'int'\00" } // FIXME: When we only emit each type once, use [[INT]] more below. -// CHECK-UBSAN: @[[LINE_100:.*]] = private unnamed_addr global {{.*}}, i32 100, i32 5 {{.*}} @[[INT]], i8 2, i8 1 -// CHECK-UBSAN: @[[LINE_200:.*]] = {{.*}}, i32 200, i32 10 {{.*}}, i8 2, i8 0 +// CHECK-UBSAN: @[[LINE_100:.*]] = private unnamed_addr global {{.*}}, i32 100, i32 5 {{.*}} @[[INT]], i8 1 +// CHECK-UBSAN: @[[LINE_200_1:.*]] = {{.*}}, i32 200, i32 10 {{.*}}, i8 0 +// CHECK-UBSAN-NEXT: @[[LINE_200_2:.*]] = {{.*}}, i32 200, i32 10 {{.*}}, i8 0 +// CHECK-UBSAN-NEXT: @[[LINE_200_3:.*]] = {{.*}}, i32 200, i32 10 {{.*}}, i8 2, i8 0 // CHECK-UBSAN: @[[LINE_300:.*]] = {{.*}}, i32 300, i32 12 {{.*}} @{{.*}}, {{.*}} @{{.*}} // CHECK-UBSAN: @[[LINE_400:.*]] = {{.*}}, i32 400, i32 12 {{.*}} @{{.*}}, {{.*}} @{{.*}} -// CHECK-UBSAN: @[[LINE_500:.*]] = {{.*}}, i32 500, i32 10 {{.*}} @{{.*}}, i8 2, i8 0 } -// CHECK-UBSAN: @[[LINE_600:.*]] = {{.*}}, i32 600, i32 3 {{.*}} @{{.*}}, i8 2, i8 1 } +// CHECK-UBSAN: @[[LINE_500:.*]] = {{.*}}, i32 500, i32 10 {{.*}} @{{.*}}, i8 0 } +// CHECK-UBSAN: @[[LINE_600:.*]] = {{.*}}, i32 600, i32 3 {{.*}} @{{.*}}, i8 1 } // CHECK-UBSAN: @[[STRUCT_S:.*]] = private unnamed_addr constant { i16, i16, [11 x i8] } { i16 -1, i16 0, [11 x i8] c"'struct S'\00" } -// CHECK-UBSAN: @[[LINE_700:.*]] = {{.*}}, i32 700, i32 14 {{.*}} @[[STRUCT_S]], i8 2, i8 3 } +// CHECK-UBSAN: @[[LINE_700:.*]] = {{.*}}, i32 700, i32 14 {{.*}} @[[STRUCT_S]], i8 3 } // CHECK-UBSAN: @[[LINE_800:.*]] = {{.*}}, i32 800, i32 12 {{.*}} @{{.*}} } // CHECK-UBSAN: @[[LINE_900:.*]] = {{.*}}, i32 900, i32 11 {{.*}} @{{.*}} } // CHECK-UBSAN: @[[LINE_1000:.*]] = {{.*}}, i32 1000, i32 11 {{.*}} @{{.*}} } @@ -42,9 +44,9 @@ void foo(void) { // CHECK-TRAP: br i1 %[[OK]], {{.*}} // CHECK-UBSAN: %[[ARG:.*]] = ptrtoint {{.*}} %[[PTR]] to i64 - // CHECK-UBSAN-NEXT: call void @__ubsan_handle_type_mismatch_v1(ptr @[[LINE_100]], i64 %[[ARG]]) + // CHECK-UBSAN-NEXT: call void @__ubsan_handle_insufficient_object_size(ptr @[[LINE_100]], i64 %[[ARG]]) - // CHECK-TRAP: call void @llvm.ubsantrap(i8 22) [[NR_NUW:#[0-9]+]] + // CHECK-TRAP: call void @llvm.ubsantrap(i8 28) [[NR_NUW:#[0-9]+]] // CHECK-TRAP-NEXT: unreachable #line 100 u.i=1; @@ -56,12 +58,10 @@ int bar(int *a) { // CHECK-COMMON-NEXT: icmp uge i64 %[[SIZE]], 4 // CHECK-COMMON: %[[PTRINT:.*]] = ptrtoint - // CHECK-COMMON-NEXT: %[[MISALIGN:.*]] = and i64 %[[PTRINT]], 3 - // CHECK-COMMON-NEXT: icmp eq i64 %[[MISALIGN]], 0 - // CHECK-UBSAN: call void @__ubsan_handle_type_mismatch_v1(ptr @[[LINE_200]], i64 %[[PTRINT]]) + // CHECK-UBSAN: call void @__ubsan_handle_insufficient_object_size(ptr @[[LINE_200_2]], i64 %[[PTRINT]]) - // CHECK-TRAP: call void @llvm.ubsantrap(i8 22) [[NR_NUW]] + // CHECK-TRAP: call void @llvm.ubsantrap(i8 27) [[NR_NUW]] // CHECK-TRAP-NEXT: unreachable #line 200 @@ -127,9 +127,9 @@ int rsh_inbounds(int a, int b) { // CHECK-COMMON-LABEL: @load int load(int *p) { - // CHECK-UBSAN: call void @__ubsan_handle_type_mismatch_v1(ptr @[[LINE_500]], i64 %{{.*}}) + // CHECK-UBSAN: call void @__ubsan_handle_null_pointer_use(ptr @[[LINE_500]], i64 %{{.*}}) - // CHECK-TRAP: call void @llvm.ubsantrap(i8 22) [[NR_NUW]] + // CHECK-TRAP: call void @llvm.ubsantrap(i8 25) [[NR_NUW]] // CHECK-TRAP-NEXT: unreachable #line 500 return *p; @@ -137,9 +137,9 @@ int load(int *p) { // CHECK-COMMON-LABEL: @store void store(int *p, int q) { - // CHECK-UBSAN: call void @__ubsan_handle_type_mismatch_v1(ptr @[[LINE_600]], i64 %{{.*}}) + // CHECK-UBSAN: call void @__ubsan_handle_null_pointer_use(ptr @[[LINE_600]], i64 %{{.*}}) - // CHECK-TRAP: call void @llvm.ubsantrap(i8 22) [[NR_NUW]] + // CHECK-TRAP: call void @llvm.ubsantrap(i8 25) [[NR_NUW]] // CHECK-TRAP-NEXT: unreachable #line 600 *p = q; @@ -149,9 +149,9 @@ struct S { int k; }; // CHECK-COMMON-LABEL: @member_access int *member_access(struct S *p) { - // CHECK-UBSAN: call void @__ubsan_handle_type_mismatch_v1(ptr @[[LINE_700]], i64 %{{.*}}) + // CHECK-UBSAN: call void @__ubsan_handle_null_pointer_use(ptr @[[LINE_700]], i64 %{{.*}}) - // CHECK-TRAP: call void @llvm.ubsantrap(i8 22) [[NR_NUW]] + // CHECK-TRAP: call void @llvm.ubsantrap(i8 25) [[NR_NUW]] // CHECK-TRAP-NEXT: unreachable #line 700 return &p->k; @@ -382,20 +382,20 @@ void call_memcpy(long *p, short *q, int sz) { // CHECK-TRAP: call void @llvm.ubsantrap(i8 16) // CHECK-COMMON: and i64 %[[#]], 7, !nosanitize // CHECK-COMMON: icmp eq i64 %[[#]], 0, !nosanitize - // CHECK-UBSAN: call void @__ubsan_handle_type_mismatch_v1(ptr @[[LINE_1600]] - // CHECK-TRAP: call void @llvm.ubsantrap(i8 22) + // CHECK-UBSAN: call void @__ubsan_handle_misaligned_pointer_use(ptr @[[LINE_1600]] + // CHECK-TRAP: call void @llvm.ubsantrap(i8 27) // CHECK-COMMON: icmp ne ptr {{.*}}, null // CHECK-UBSAN: call void @__ubsan_handle_nonnull_arg( // CHECK-TRAP: call void @llvm.ubsantrap(i8 16) // CHECK-COMMON: and i64 %[[#]], 1, !nosanitize // CHECK-COMMON: icmp eq i64 %[[#]], 0, !nosanitize - // CHECK-UBSAN: call void @__ubsan_handle_type_mismatch_v1( - // CHECK-TRAP: call void @llvm.ubsantrap(i8 22) + // CHECK-UBSAN: call void @__ubsan_handle_misaligned_pointer_use( + // CHECK-TRAP: call void @llvm.ubsantrap(i8 27) // CHECK-COMMON: call void @llvm.memcpy.p0.p0.i64(ptr align 8 %0, ptr align 2 %1, i64 %conv, i1 false) - // CHECK-UBSAN-NOT: call void @__ubsan_handle_type_mismatch_v1( + // CHECK-UBSAN-NOT: call void @__ubsan_handle_misaligned_pointer_use( // CHECK-COMMON: call void @llvm.memcpy.p0.p0.i64(ptr align 1 %[[#]], ptr align 1 %[[#]], i64 %{{.*}}, i1 false) #line 1600 memcpy(p, q, sz); @@ -407,13 +407,13 @@ void call_memcpy(long *p, short *q, int sz) { void call_memcpy_inline(long *p, short *q) { // CHECK-COMMON: and i64 %[[#]], 7, !nosanitize // CHECK-COMMON: icmp eq i64 %[[#]], 0, !nosanitize - // CHECK-UBSAN: call void @__ubsan_handle_type_mismatch_v1( - // CHECK-TRAP: call void @llvm.ubsantrap(i8 22) + // CHECK-UBSAN: call void @__ubsan_handle_misaligned_pointer_use( + // CHECK-TRAP: call void @llvm.ubsantrap(i8 27) // CHECK-COMMON: and i64 %[[#]], 1, !nosanitize // CHECK-COMMON: icmp eq i64 %[[#]], 0, !nosanitize - // CHECK-UBSAN: call void @__ubsan_handle_type_mismatch_v1( - // CHECK-TRAP: call void @llvm.ubsantrap(i8 22) + // CHECK-UBSAN: call void @__ubsan_handle_misaligned_pointer_use( + // CHECK-TRAP: call void @llvm.ubsantrap(i8 27) // CHECK-COMMON: call void @llvm.memcpy.inline.p0.p0.i64(ptr align 8 %0, ptr align 2 %1, i64 2, i1 false) __builtin_memcpy_inline(p, q, 2); @@ -440,16 +440,16 @@ void call_memmove(long *p, short *q, int sz) { // CHECK-TRAP: call void @llvm.ubsantrap(i8 16) // CHECK-COMMON: and i64 %[[#]], 7, !nosanitize // CHECK-COMMON: icmp eq i64 %[[#]], 0, !nosanitize - // CHECK-UBSAN: call void @__ubsan_handle_type_mismatch_v1( - // CHECK-TRAP: call void @llvm.ubsantrap(i8 22) + // CHECK-UBSAN: call void @__ubsan_handle_misaligned_pointer_use( + // CHECK-TRAP: call void @llvm.ubsantrap(i8 27) // CHECK-COMMON: icmp ne ptr {{.*}}, null // CHECK-UBSAN: call void @__ubsan_handle_nonnull_arg( // CHECK-TRAP: call void @llvm.ubsantrap(i8 16) // CHECK-COMMON: and i64 %[[#]], 1, !nosanitize // CHECK-COMMON: icmp eq i64 %[[#]], 0, !nosanitize - // CHECK-UBSAN: call void @__ubsan_handle_type_mismatch_v1( - // CHECK-TRAP: call void @llvm.ubsantrap(i8 22) + // CHECK-UBSAN: call void @__ubsan_handle_misaligned_pointer_use( + // CHECK-TRAP: call void @llvm.ubsantrap(i8 27) // CHECK-COMMON: call void @llvm.memmove.p0.p0.i64(ptr align 8 %0, ptr align 2 %1, i64 %conv, i1 false) memmove(p, q, sz); diff --git a/clang/test/CodeGen/sanitize-ignorelist-mainfile.c b/clang/test/CodeGen/sanitize-ignorelist-mainfile.c index 599ff8e597c98..6e65cedbbee97 100644 --- a/clang/test/CodeGen/sanitize-ignorelist-mainfile.c +++ b/clang/test/CodeGen/sanitize-ignorelist-mainfile.c @@ -46,7 +46,7 @@ int foo(void *x) { // IGNORE-NOT: @___asan_gen_ // CHECK-LABEL: define {{.*}}@load( -// SANITIZE: call void @__ubsan_handle_type_mismatch_v1_abort( +// SANITIZE: call void @__ubsan_handle_misaligned_pointer_use_abort( // SANITIZE: call void @__asan_report_load4( -// IGNORE-NOT: call void @__ubsan_handle_type_mismatch_v1_abort( +// IGNORE-NOT: call void @__ubsan_handle_misaligned_pointer_use_abort( // IGNORE-NOT: call void @__asan_report_load4( diff --git a/clang/test/CodeGen/sanitize-recover.c b/clang/test/CodeGen/sanitize-recover.c index fa53c2e7ca45e..775826f25c5cc 100644 --- a/clang/test/CodeGen/sanitize-recover.c +++ b/clang/test/CodeGen/sanitize-recover.c @@ -24,5 +24,5 @@ void foo(void) { // PARTIAL: br i1 %[[CHECK0]], {{.*}} !nosanitize - // PARTIAL: call void @__ubsan_handle_type_mismatch_v1( + // PARTIAL: call void @__ubsan_handle_insufficient_object_size( } diff --git a/clang/test/CodeGen/ubsan-trap-reason-crash.cpp b/clang/test/CodeGen/ubsan-trap-reason-crash.cpp index 6add9bf2b6b34..d2eaaa8f5a31d 100644 --- a/clang/test/CodeGen/ubsan-trap-reason-crash.cpp +++ b/clang/test/CodeGen/ubsan-trap-reason-crash.cpp @@ -16,5 +16,5 @@ void caller() { // CHECK-LABEL: @_Z6callerv -// CHECK: call void @llvm.ubsantrap(i8 22){{.*}}!nosanitize +// CHECK: call void @llvm.ubsantrap(i8 25){{.*}}!nosanitize // CHECK-NOT: __clang_trap_msg diff --git a/clang/test/CodeGen/ubsan-trap-reason-type-mismatch.c b/clang/test/CodeGen/ubsan-trap-reason-type-mismatch.c index 802ec91b53a0d..2579bc6542b02 100644 --- a/clang/test/CodeGen/ubsan-trap-reason-type-mismatch.c +++ b/clang/test/CodeGen/ubsan-trap-reason-type-mismatch.c @@ -4,6 +4,6 @@ int type_mismatch(int *p) { return *p; } // CHECK-LABEL: @type_mismatch -// CHECK: call void @llvm.ubsantrap(i8 22) {{.*}}!dbg [[LOC:![0-9]+]] +// CHECK: call void @llvm.ubsantrap(i8 27) {{.*}}!dbg [[LOC:![0-9]+]] // CHECK: [[LOC]] = !DILocation(line: 0, scope: [[MSG:![0-9]+]], {{.+}}) -// CHECK: [[MSG]] = distinct !DISubprogram(name: "__clang_trap_msg$Undefined Behavior Sanitizer$Type mismatch in operation" +// CHECK: [[MSG]] = distinct !DISubprogram(name: "__clang_trap_msg$Undefined Behavior Sanitizer$Misaligned pointer use" diff --git a/clang/test/CodeGenCXX/catch-undef-behavior.cpp b/clang/test/CodeGenCXX/catch-undef-behavior.cpp index 15feebe0c0993..ce79d7058b60f 100644 --- a/clang/test/CodeGenCXX/catch-undef-behavior.cpp +++ b/clang/test/CodeGenCXX/catch-undef-behavior.cpp @@ -29,10 +29,12 @@ void reference_binding(int *p, S *q) { // CHECK: %[[SIZE:.*]] = call i64 @llvm.objectsize.i64 // CHECK-NEXT: icmp uge i64 %[[SIZE]], 4 + // CHECK: call void @__ubsan_handle_insufficient_object_size // CHECK: %[[PTRINT:.*]] = ptrtoint // CHECK-NEXT: %[[MISALIGN:.*]] = and i64 %[[PTRINT]], 3 // CHECK-NEXT: icmp eq i64 %[[MISALIGN]], 0 + // CHECK: call void @__ubsan_handle_misaligned_pointer_use int &r = *p; // A reference is not required to refer to an object within its lifetime. @@ -49,10 +51,12 @@ void member_access(S *p) { // CHECK: %[[SIZE:.*]] = call i64 @llvm.objectsize.i64 // CHECK-NEXT: icmp uge i64 %[[SIZE]], 24 + // CHECK: call void @__ubsan_handle_insufficient_object_size // CHECK: %[[PTRINT:.*]] = ptrtoint // CHECK-NEXT: %[[MISALIGN:.*]] = and i64 %[[PTRINT]], 7 // CHECK-NEXT: icmp eq i64 %[[MISALIGN]], 0 + // CHECK: call void @__ubsan_handle_misaligned_pointer_use // (1b) Check that 'p' actually points to an 'S'. @@ -91,10 +95,12 @@ void member_access(S *p) { // CHECK: %[[SIZE:.*]] = call i64 @llvm.objectsize.i64 // CHECK-NEXT: icmp uge i64 %[[SIZE]], 4 + // CHECK: call void @__ubsan_handle_insufficient_object_size // CHECK: %[[PTRINT:.*]] = ptrtoint // CHECK-NEXT: %[[MISALIGN:.*]] = and i64 %[[PTRINT]], 3 // CHECK-NEXT: icmp eq i64 %[[MISALIGN]], 0 + // CHECK: call void @__ubsan_handle_misaligned_pointer_use int k = p->b; // (3a) Check 'p' is appropriately sized and aligned for member function call. @@ -103,10 +109,12 @@ void member_access(S *p) { // CHECK: %[[SIZE:.*]] = call i64 @llvm.objectsize.i64 // CHECK-NEXT: icmp uge i64 %[[SIZE]], 24 + // CHECK: call void @__ubsan_handle_insufficient_object_size // CHECK: %[[PTRINT:.*]] = ptrtoint // CHECK-NEXT: %[[MISALIGN:.*]] = and i64 %[[PTRINT]], 7 // CHECK-NEXT: icmp eq i64 %[[MISALIGN]], 0 + // CHECK: call void @__ubsan_handle_misaligned_pointer_use // (3b) Check that 'p' actually points to an 'S' @@ -203,13 +211,12 @@ void bad_downcast_pointer(S *p) { // CHECK: %[[SIZE:.*]] = call i64 @llvm.objectsize.i64.p0( // CHECK: %[[E1:.*]] = icmp uge i64 %[[SIZE]], 24 + // CHECK: call void @__ubsan_handle_insufficient_object_size + // CHECK: %[[MISALIGN:.*]] = and i64 %{{.*}}, 7 // CHECK: %[[E2:.*]] = icmp eq i64 %[[MISALIGN]], 0 - // CHECK: %[[E12:.*]] = and i1 %[[E1]], %[[E2]] - // CHECK: br i1 %[[E12]], - - // CHECK: call void @__ubsan_handle_type_mismatch - // CHECK: br label + // CHECK: br i1 %[[E2]], + // CHECK: call void @__ubsan_handle_misaligned_pointer_use // CHECK: br i1 %{{.*}}, @@ -220,21 +227,17 @@ void bad_downcast_pointer(S *p) { // CHECK-LABEL: @_Z22bad_downcast_reference void bad_downcast_reference(S &p) { - // CHECK: %[[E1:.*]] = icmp ne {{.*}}, null - // CHECK-NOT: br i1 + // CHECK: %[[NONNULL:.*]] = icmp ne {{.*}}, null + // CHECK: br i1 %[[NONNULL]], // CHECK: %[[SIZE:.*]] = call i64 @llvm.objectsize.i64.p0( - // CHECK: %[[E2:.*]] = icmp uge i64 %[[SIZE]], 24 + // CHECK: %[[E1:.*]] = icmp uge i64 %[[SIZE]], 24 + // CHECK: call void @__ubsan_handle_insufficient_object_size // CHECK: %[[MISALIGN:.*]] = and i64 %{{.*}}, 7 - // CHECK: %[[E3:.*]] = icmp eq i64 %[[MISALIGN]], 0 - - // CHECK: %[[E12:.*]] = and i1 %[[E1]], %[[E2]] - // CHECK: %[[E123:.*]] = and i1 %[[E12]], %[[E3]] - // CHECK: br i1 %[[E123]], - - // CHECK: call void @__ubsan_handle_type_mismatch - // CHECK: br label + // CHECK: %[[E2:.*]] = icmp eq i64 %[[MISALIGN]], 0 + // CHECK: br i1 %[[E2]], + // CHECK: call void @__ubsan_handle_misaligned_pointer_use // CHECK: br i1 %{{.*}}, @@ -362,30 +365,38 @@ class C : public A, public B // align=16 void downcast_pointer(B *b) { (void) static_cast(b); // Alignment check from EmitTypeCheck(TCK_DowncastPointer, ...) + + // CHECK: %[[NULL:.*]] = icmp eq ptr {{.*}}, null + // CHECK: br i1 %[[NULL]], + // CHECK: [[SUB:%[.a-z0-9]*]] = getelementptr inbounds i8, ptr {{.*}}, i64 -16 - // null check goes here // CHECK: [[FROM_PHI:%.+]] = phi ptr [ [[SUB]], {{.*}} ], {{.*}} - // Objectsize check goes here + + // CHECK: %[[SIZE:.*]] = call i64 @llvm.objectsize.i64.p0( + // CHECK: %[[E1:.*]] = icmp uge i64 %[[SIZE]], 36 + // CHECK: call void @__ubsan_handle_insufficient_object_size + // CHECK: [[C_INT:%.+]] = ptrtoint ptr [[FROM_PHI]] to i64 // CHECK-NEXT: [[MASKED:%.+]] = and i64 [[C_INT]], 15 // CHECK-NEXT: [[TEST:%.+]] = icmp eq i64 [[MASKED]], 0 - // AND the alignment test with the objectsize test. - // CHECK-NEXT: [[AND:%.+]] = and i1 {{.*}}, [[TEST]] - // CHECK-NEXT: br i1 [[AND]] + // CHECK-NEXT: br i1 [[TEST]] + // CHECK: call void @__ubsan_handle_misaligned_pointer_use } // CHECK-LABEL: define{{.*}} void @_Z18downcast_referenceR1B(ptr nonnull align {{[0-9]+}} dereferenceable({{[0-9]+}}) %b) void downcast_reference(B &b) { (void) static_cast(b); // Alignment check from EmitTypeCheck(TCK_DowncastReference, ...) - // CHECK: [[SUB:%[.a-z0-9]*]] = getelementptr inbounds i8, ptr {{.*}}, i64 -16 - // Objectsize check goes here + // CHECK: [[SUB:%[.a-z0-9]*]] = getelementptr inbounds i8, ptr {{.*}}, i64 -16 + + // CHECK: %[[SIZE:.*]] = call i64 @llvm.objectsize.i64.p0( + // CHECK: %[[E1:.*]] = icmp uge i64 %[[SIZE]], 36 + // CHECK: call void @__ubsan_handle_insufficient_object_size + // CHECK: [[C_INT:%.+]] = ptrtoint ptr [[SUB]] to i64 // CHECK-NEXT: [[MASKED:%.+]] = and i64 [[C_INT]], 15 // CHECK-NEXT: [[TEST:%.+]] = icmp eq i64 [[MASKED]], 0 - // AND the alignment test with the objectsize test. - // CHECK: [[AND:%.+]] = and i1 {{.*}}, [[TEST]] - // CHECK-NEXT: br i1 [[AND]] + // CHECK-NEXT: br i1 [[TEST]] } // CHECK-FUNCSAN: @_Z22indirect_function_callPFviE({{.*}} !func_sanitize ![[FUNCSAN:.*]] { @@ -418,6 +429,7 @@ namespace VBaseObjectSize { // Size check: check for nvsize(B) == 16 (do not require size(B) == 32) // CHECK: [[SIZE:%.+]] = call i{{32|64}} @llvm.objectsize.i64.p0( // CHECK: icmp uge i{{32|64}} [[SIZE]], 16, + // CHECK: call void @__ubsan_handle_insufficient_object_size // Alignment check: check for nvalign(B) == 8 (do not require align(B) == 16) // CHECK: [[PTRTOINT:%.+]] = ptrtoint {{.*}} to i64, @@ -427,6 +439,7 @@ namespace VBaseObjectSize { // CHECK-LABEL: define {{.*}} @_ZN15VBaseObjectSize1B1gEv( void *B::g() { + // CHECK: call void @__ubsan_handle_null_pointer_use // Ensure that the check on the "this" pointer also uses the proper // alignment. We should be using nvalign(B) == 8, not 16. // CHECK: [[PTRTOINT:%.+]] = ptrtoint {{.*}} to i64, @@ -510,7 +523,7 @@ S* upcast_pointer(T* t) { // CHECK: %[[MISALIGN:.*]] = and i64 %{{.*}}, 7 // CHECK: icmp eq i64 %[[MISALIGN]], 0 - // CHECK: call void @__ubsan_handle_type_mismatch + // CHECK: call void @__ubsan_handle_misaligned_pointer_use return t; } @@ -523,7 +536,7 @@ void upcast_to_vbase() { // CHECK-NOT: br i1 // CHECK: call i64 @llvm.objectsize - // CHECK: call void @__ubsan_handle_type_mismatch + // CHECK: call void @__ubsan_handle_insufficient_object_size // CHECK: call void @__ubsan_handle_dynamic_type_cache_miss const S& s = getV(); } @@ -545,7 +558,7 @@ namespace NothrowNew { // CHECK: icmp uge i64 {{.*}}, 123456, // CHECK: br i1 // - // CHECK: call {{.*}}__ubsan_handle_type_mismatch + // CHECK: call void @__ubsan_handle_insufficient_object_size // // CHECK: [[null]]: // CHECK-NOT: {{ }}br{{ }} @@ -563,7 +576,7 @@ namespace NothrowNew { // CHECK: icmp uge i64 {{.*}}, 123456, // CHECK: br i1 // - // CHECK: call {{.*}}__ubsan_handle_type_mismatch + // CHECK: call void @__ubsan_handle_insufficient_object_size // // CHECK: call {{.*}}_ZN10NothrowNew1XC1Ev // @@ -578,12 +591,11 @@ namespace NothrowNew { // CHECK: icmp ne ptr{{.*}}, null // CHECK: %[[size:.*]] = mul // CHECK: llvm.objectsize - // CHECK: icmp uge i64 {{.*}}, %[[size]], - // CHECK: %[[ok:.*]] = and + // CHECK: %[[ok:.*]] = icmp uge i64 {{.*}}, %[[size]], // CHECK: br i1 %[[ok]], label %[[good:.*]], label %[[bad:[^,]*]] // // CHECK: [[bad]]: - // CHECK: call {{.*}}__ubsan_handle_type_mismatch + // CHECK: call void @__ubsan_handle_insufficient_object_size // // CHECK: [[good]]: // CHECK-NOT: {{ }}br{{ }} @@ -598,7 +610,7 @@ namespace NothrowNew { // CHECK: br i1 %[[nonnull]], label %[[good:.*]], label %[[bad:[^,]*]] // // CHECK: [[bad]]: - // CHECK: call {{.*}}__ubsan_handle_type_mismatch + // CHECK: call void @__ubsan_handle_null_pointer_use // // CHECK: [[good]]: // CHECK-NOT: {{ }}br{{ }} @@ -609,7 +621,7 @@ namespace NothrowNew { // CHECK-LABEL: define{{.*}}throwing_new_zero_size void *throwing_new_zero_size() { // Nothing to check here. - // CHECK-NOT: __ubsan_handle_type_mismatch + // CHECK-NOT: __ubsan_handle_null_pointer_use return new (nothrow{}) char[0]; // CHECK: ret } @@ -629,11 +641,12 @@ void ThisAlign::this_align_lambda() { // CHECK: %[[this_outer:.*]] = load ptr, ptr %[[this_outer_addr]], // // CHECK: %[[this_inner_isnonnull:.*]] = icmp ne ptr %[[this_inner]], null + // CHECK: br i1 %[[this_inner_isnonnull:.*]] + // CHECK: call void @__ubsan_handle_null_pointer_use // CHECK: %[[this_inner_asint:.*]] = ptrtoint ptr %[[this_inner]] to i // CHECK: %[[this_inner_misalignment:.*]] = and i{{32|64}} %[[this_inner_asint]], {{3|7}}, // CHECK: %[[this_inner_isaligned:.*]] = icmp eq i{{32|64}} %[[this_inner_misalignment]], 0 - // CHECK: %[[this_inner_valid:.*]] = and i1 %[[this_inner_isnonnull]], %[[this_inner_isaligned]], - // CHECK: br i1 %[[this_inner_valid:.*]] + // CHECK: br i1 %[[this_inner_isaligned:.*]] [&] { return this; } (); } diff --git a/clang/test/CodeGenCXX/ubsan-check-debuglocs.cpp b/clang/test/CodeGenCXX/ubsan-check-debuglocs.cpp index 81db5c4912613..993e185b3dee1 100644 --- a/clang/test/CodeGenCXX/ubsan-check-debuglocs.cpp +++ b/clang/test/CodeGenCXX/ubsan-check-debuglocs.cpp @@ -4,14 +4,14 @@ // Check that santizer check calls have a !dbg location. // CHECK: define {{.*}}acquire{{.*}} !dbg // CHECK-NOT: define -// CHECK: call void {{.*}}@__ubsan_handle_type_mismatch_v1 +// CHECK: call void {{.*}}@__ubsan_handle_null_pointer_use // CHECK-SAME: !dbg struct SourceLocation { SourceLocation acquire() { return {}; }; }; -extern "C" void __ubsan_handle_type_mismatch_v1(SourceLocation *Loc); -static void handleTypeMismatchImpl(SourceLocation *Loc) { Loc->acquire(); } -void __ubsan_handle_type_mismatch_v1(SourceLocation *Loc) { - handleTypeMismatchImpl(Loc); +extern "C" void __ubsan_handle_null_pointer_use(SourceLocation *Loc); +static void handleNullPointerUseImpl(SourceLocation *Loc) { Loc->acquire(); } +void __ubsan_handle_null_pointer_use(SourceLocation *Loc) { + handleNullPointerUseImpl(Loc); } diff --git a/clang/test/CodeGenCXX/ubsan-devirtualized-calls.cpp b/clang/test/CodeGenCXX/ubsan-devirtualized-calls.cpp index 8a4dc0427b7b8..660c4b5c0603e 100644 --- a/clang/test/CodeGenCXX/ubsan-devirtualized-calls.cpp +++ b/clang/test/CodeGenCXX/ubsan-devirtualized-calls.cpp @@ -67,7 +67,7 @@ void t4() { // We were able to skip the null check on the first type check because 'p' // is backed by an alloca. We can't skip the second null check because 'badp' // is a (bitcast (load ...)). - // CHECK: call void @__ubsan_handle_type_mismatch + // CHECK: call void @__ubsan_handle_null_pointer_use // // CHECK: %[[BADP1:[0-9]+]] = ptrtoint ptr {{%[0-9]+}} to i{{[0-9]+}}, !nosanitize // CHECK-NEXT: call void @__ubsan_handle_dynamic_type_cache{{[_a-z]*}}({{.*}} [[UBSAN_TI_BASE1]], i{{[0-9]+}} %[[BADP1]] @@ -81,7 +81,7 @@ void t5() { // CHECK-NEXT: call void @__ubsan_handle_dynamic_type_cache{{[_a-z]*}}({{.*}} [[UBSAN_TI_DERIVED4_1]], i{{[0-9]+}} %[[P1]] static_cast(badp)->f1(); //< Devirt Base1::f1 to Derived4::f1. - // CHECK: call void @__ubsan_handle_type_mismatch + // CHECK: call void @__ubsan_handle_null_pointer_use // // CHECK: %[[BADP1:[0-9]+]] = ptrtoint ptr {{%[0-9]+}} to i{{[0-9]+}}, !nosanitize // CHECK-NEXT: call void @__ubsan_handle_dynamic_type_cache{{[_a-z]*}}({{.*}} [[UBSAN_TI_DERIVED4_2]], i{{[0-9]+}} %[[BADP1]] diff --git a/clang/test/CodeGenCXX/ubsan-global-alignment.cpp b/clang/test/CodeGenCXX/ubsan-global-alignment.cpp index e6fc95c207c9c..0315b5c6c7d6d 100644 --- a/clang/test/CodeGenCXX/ubsan-global-alignment.cpp +++ b/clang/test/CodeGenCXX/ubsan-global-alignment.cpp @@ -24,6 +24,6 @@ int load_from_extern_array(int I) { // CHECK-NEXT: [[AND:%.*]] = and i64 [[PTRTOINT]], 3, !nosanitize // CHECK-NEXT: [[ICMP:%.*]] = icmp eq i64 [[AND]], 0, !nosanitize // CHECK-NEXT: br i1 [[ICMP]] - // CHECK: call void @__ubsan_handle_type_mismatch + // CHECK: call void @__ubsan_handle_misaligned_pointer_use_abort return array_S[I].I; } diff --git a/clang/test/CodeGenCXX/ubsan-nullability-assign.cpp b/clang/test/CodeGenCXX/ubsan-nullability-assign.cpp index 08c7f0090220e..4d47c1ec32f5a 100644 --- a/clang/test/CodeGenCXX/ubsan-nullability-assign.cpp +++ b/clang/test/CodeGenCXX/ubsan-nullability-assign.cpp @@ -19,17 +19,17 @@ void f1(int *p) { // CHECK: [[ICMP:%.*]] = icmp ne ptr {{.*}}, null, !nosanitize // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize - // CHECK: call void @__ubsan_handle_type_mismatch{{.*}} !nosanitize + // CHECK: call void @__ubsan_handle_null_pointer_use_with_nullability{{.*}} !nosanitize // CHECK: store u.s1.p = p; // CHECK: [[ICMP:%.*]] = icmp ne ptr {{.*}}, null, !nosanitize // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize - // CHECK: call void @__ubsan_handle_type_mismatch{{.*}} !nosanitize + // CHECK: call void @__ubsan_handle_null_pointer_use_with_nullability{{.*}} !nosanitize // CHECK: store u.s2.s1.p = p; - // CHECK-NOT: __ubsan_handle_type_mismatch + // CHECK-NOT: __ubsan_handle_null_pointer_use_with_nullability // CHECK-NOT: store // CHECK: ret void } diff --git a/clang/test/CodeGenCXX/ubsan-suppress-checks.cpp b/clang/test/CodeGenCXX/ubsan-suppress-checks.cpp index da7a60bddee33..2d13b82234b51 100644 --- a/clang/test/CodeGenCXX/ubsan-suppress-checks.cpp +++ b/clang/test/CodeGenCXX/ubsan-suppress-checks.cpp @@ -24,7 +24,7 @@ void use_us16_aligned_array_elements() { use_array(Arr); // CHECK-NOT: br i1 true - // ALIGN-NOT: call void @__ubsan_handle_type_mismatch + // ALIGN-NOT: call void @__ubsan_handle_misaligned_pointer_use // CHECK: ret void } @@ -35,10 +35,12 @@ struct A { void do_nothing() { // ALIGN: %[[THISINT1:[0-9]+]] = ptrtoint ptr %{{.*}} to i64, !nosanitize // ALIGN: and i64 %[[THISINT1]], 3, !nosanitize + // ALIGN: call void @__ubsan_handle_misaligned_pointer_use + // ALIGN-NOT: call void @__ubsan_handle_misaligned_pointer_use // NULL: icmp ne ptr %[[THIS1:[a-z0-9]+]], null, !nosanitize // NULL: ptrtoint ptr %[[THIS1]] to i64, !nosanitize - // CHECK: call void @__ubsan_handle_type_mismatch - // CHECK-NOT: call void @__ubsan_handle_type_mismatch + // NULL: call void @__ubsan_handle_null_pointer_use + // NULL-NOT: call void @__ubsan_handle_null_pointer_use // CHECK: ret void } @@ -46,24 +48,28 @@ struct A { // LAMBDA-LABEL: define linkonce_odr void @_ZN1A22do_nothing_with_lambdaEv void do_nothing_with_lambda() { // LAMBDA: icmp ne ptr %[[THIS2:[a-z0-9]+]], null, !nosanitize + // LAMBDA: call void @__ubsan_handle_null_pointer_use // LAMBDA: %[[THISINT2:[0-9]+]] = ptrtoint ptr %[[THIS2]] to i64, !nosanitize // LAMBDA: and i64 %[[THISINT2]], 3, !nosanitize - // LAMBDA: call void @__ubsan_handle_type_mismatch + // LAMBDA: call void @__ubsan_handle_misaligned_pointer_use auto f = [&] { foo = 0; }; f(); - // LAMBDA-NOT: call void @__ubsan_handle_type_mismatch + // LAMBDA-NOT: call void @__ubsan_handle_null_pointer_use + // LAMBDA-NOT: call void @__ubsan_handle_misaligned_pointer_use // LAMBDA: ret void } // Check the IR for the lambda: // // LAMBDA-LABEL: define linkonce_odr void @_ZZN1A22do_nothing_with_lambdaEvENKUlvE_clEv -// LAMBDA: call void @__ubsan_handle_type_mismatch -// LAMBDA-NOT: call void @__ubsan_handle_type_mismatch +// LAMBDA: call void @__ubsan_handle_null_pointer_use +// LAMBDA: call void @__ubsan_handle_misaligned_pointer_use +// LAMBDA-NOT: call void @__ubsan_handle_null_pointer_use +// LAMBDA-NOT: call void @__ubsan_handle_misaligned_pointer_use // LAMBDA: ret void #endif @@ -71,10 +77,12 @@ struct A { int load_member() { // ALIGN: %[[THISINT3:[0-9]+]] = ptrtoint ptr %{{.*}} to i64, !nosanitize // ALIGN: and i64 %[[THISINT3]], 3, !nosanitize + // ALIGN: call void @__ubsan_handle_misaligned_pointer_use + // ALIGN-NOT: call void @__ubsan_handle_misaligned_pointer_use // NULL: icmp ne ptr %[[THIS3:[a-z0-9]+]], null, !nosanitize // NULL: ptrtoint ptr %[[THIS3]] to i64, !nosanitize - // CHECK: call void @__ubsan_handle_type_mismatch - // CHECK-NOT: call void @__ubsan_handle_type_mismatch + // NULL: call void @__ubsan_handle_null_pointer_use + // NULL-NOT: call void @__ubsan_handle_null_pointer_use return foo; // CHECK: ret i32 } @@ -83,10 +91,12 @@ struct A { int call_method() { // ALIGN: %[[THISINT4:[0-9]+]] = ptrtoint ptr %{{.*}} to i64, !nosanitize // ALIGN: and i64 %[[THISINT4]], 3, !nosanitize + // ALIGN: call void @__ubsan_handle_misaligned_pointer_use + // ALIGN-NOT: call void @__ubsan_handle_misaligned_pointer_use // NULL: icmp ne ptr %[[THIS4:[a-z0-9]+]], null, !nosanitize // NULL: ptrtoint ptr %[[THIS4]] to i64, !nosanitize - // CHECK: call void @__ubsan_handle_type_mismatch - // CHECK-NOT: call void @__ubsan_handle_type_mismatch + // NULL: call void @__ubsan_handle_null_pointer_use + // NULL-NOT: call void @__ubsan_handle_null_pointer_use return load_member(); // CHECK: ret i32 } @@ -95,10 +105,12 @@ struct A { void assign_member_1() { // ALIGN: %[[THISINT5:[0-9]+]] = ptrtoint ptr %{{.*}} to i64, !nosanitize // ALIGN: and i64 %[[THISINT5]], 3, !nosanitize + // ALIGN: call void @__ubsan_handle_misaligned_pointer_use + // ALIGN-NOT: call void @__ubsan_handle_misaligned_pointer_use // NULL: icmp ne ptr %[[THIS5:[a-z0-9]+]], null, !nosanitize // NULL: ptrtoint ptr %[[THIS5]] to i64, !nosanitize - // CHECK: call void @__ubsan_handle_type_mismatch - // CHECK-NOT: call void @__ubsan_handle_type_mismatch + // NULL: call void @__ubsan_handle_null_pointer_use + // NULL-NOT: call void @__ubsan_handle_null_pointer_use foo = 0; // CHECK: ret void } @@ -107,10 +119,12 @@ struct A { void assign_member_2() { // ALIGN: %[[THISINT6:[0-9]+]] = ptrtoint ptr %{{.*}} to i64, !nosanitize // ALIGN: and i64 %[[THISINT6]], 3, !nosanitize + // ALIGN: call void @__ubsan_handle_misaligned_pointer_use + // ALIGN-NOT: call void @__ubsan_handle_misaligned_pointer_use // NULL: icmp ne ptr %[[THIS6:[a-z0-9]+]], null, !nosanitize // NULL: ptrtoint ptr %[[THIS6]] to i64, !nosanitize - // CHECK: call void @__ubsan_handle_type_mismatch - // CHECK-NOT: call void @__ubsan_handle_type_mismatch + // NULL: call void @__ubsan_handle_null_pointer_use + // NULL-NOT: call void @__ubsan_handle_null_pointer_use (__extension__ (this))->foo = 0; // CHECK: ret void } @@ -119,10 +133,12 @@ struct A { void assign_member_3() const { // ALIGN: %[[THISINT7:[0-9]+]] = ptrtoint ptr %{{.*}} to i64, !nosanitize // ALIGN: and i64 %[[THISINT7]], 3, !nosanitize + // ALIGN: call void @__ubsan_handle_misaligned_pointer_use + // ALIGN-NOT: call void @__ubsan_handle_misaligned_pointer_use // NULL: icmp ne ptr %[[THIS7:[a-z0-9]+]], null, !nosanitize // NULL: ptrtoint ptr %[[THIS7]] to i64, !nosanitize - // CHECK: call void @__ubsan_handle_type_mismatch - // CHECK-NOT: call void @__ubsan_handle_type_mismatch + // NULL: call void @__ubsan_handle_null_pointer_use + // NULL-NOT: call void @__ubsan_handle_null_pointer_use const_cast(this)->foo = 0; // CHECK: ret void } @@ -131,15 +147,16 @@ struct A { static int call_through_reference(A &a) { // ALIGN: %[[OBJINT:[0-9]+]] = ptrtoint ptr %{{.*}} to i64, !nosanitize // ALIGN: and i64 %[[OBJINT]], 3, !nosanitize - // ALIGN: call void @__ubsan_handle_type_mismatch - // NULL-NOT: call void @__ubsan_handle_type_mismatch + // ALIGN: call void @__ubsan_handle_misaligned_pointer_use + // NULL-NOT: call void @__ubsan_handle_null_pointer_use return a.load_member(); // CHECK: ret i32 } // CHECK-LABEL: define linkonce_odr noundef i32 @_ZN1A20call_through_pointerEPS_ static int call_through_pointer(A *a) { - // CHECK: call void @__ubsan_handle_type_mismatch + // ALIGN: call void @__ubsan_handle_misaligned_pointer_use + // NULL: call void @__ubsan_handle_null_pointer_use return a->load_member(); // CHECK: ret i32 } @@ -151,12 +168,14 @@ struct B { // CHECK-LABEL: define linkonce_odr noundef i32 @_ZN1B11load_memberEPS_ static int load_member(B *bp) { // Check &b before converting it to an A*. - // CHECK: call void @__ubsan_handle_type_mismatch + // ALIGN: call void @__ubsan_handle_misaligned_pointer_use + // NULL: call void @__ubsan_handle_null_pointer_use // // Check the result of the conversion before using it. - // NULL: call void @__ubsan_handle_type_mismatch + // NULL: call void @__ubsan_handle_null_pointer_use // - // CHECK-NOT: call void @__ubsan_handle_type_mismatch + // ALIGN-NOT: call void @__ubsan_handle_misaligned_pointer_use + // NULL-NOT: call void @__ubsan_handle_null_pointer_use return static_cast(*bp)->load_member(); // CHECK: ret i32 } @@ -175,15 +194,18 @@ struct Derived : public Base { int load_member_2() { // ALIGN: %[[THISINT8:[0-9]+]] = ptrtoint ptr %{{.*}} to i64, !nosanitize // ALIGN: and i64 %[[THISINT8]], 7, !nosanitize - // ALIGN: call void @__ubsan_handle_type_mismatch + // ALIGN: call void @__ubsan_handle_misaligned_pointer_use // NULL: icmp ne ptr %[[THIS8:[a-z0-9]+]], null, !nosanitize // NULL: ptrtoint ptr %[[THIS8]] to i64, !nosanitize - // CHECK: call void @__ubsan_handle_type_mismatch + // ALIGN: call void @__ubsan_handle_misaligned_pointer_use + // NULL: call void @__ubsan_handle_null_pointer_use // // Check the result of the cast before using it. - // CHECK: call void @__ubsan_handle_type_mismatch + // ALIGN: call void @__ubsan_handle_misaligned_pointer_use + // NULL: call void @__ubsan_handle_null_pointer_use // - // CHECK-NOT: call void @__ubsan_handle_type_mismatch + // ALIGN-NOT: call void @__ubsan_handle_misaligned_pointer_use + // NULL-NOT: call void @__ubsan_handle_null_pointer_use return dynamic_cast(this)->load_member_1(); // CHECK: ret i32 } @@ -192,12 +214,14 @@ struct Derived : public Base { int load_member_3() { // ALIGN: %[[THISINT9:[0-9]+]] = ptrtoint ptr %{{.*}} to i64, !nosanitize // ALIGN: and i64 %[[THISINT9]], 7, !nosanitize - // ALIGN: call void @__ubsan_handle_type_mismatch - // ALIGN: call void @__ubsan_handle_type_mismatch + // ALIGN: call void @__ubsan_handle_misaligned_pointer_use + // ALIGN: call void @__ubsan_handle_misaligned_pointer_use // NULL: icmp ne ptr %[[THIS9:[a-z0-9]+]], null, !nosanitize // NULL: ptrtoint ptr %[[THIS9]] to i64, !nosanitize - // CHECK: call void @__ubsan_handle_type_mismatch - // CHECK-NOT: call void @__ubsan_handle_type_mismatch + // ALIGN: call void @__ubsan_handle_misaligned_pointer_use + // ALIGN-NOT: call void @__ubsan_handle_misaligned_pointer_use + // NULL: call void @__ubsan_handle_null_pointer_use + // NULL-NOT: call void @__ubsan_handle_null_pointer_use return reinterpret_cast(static_cast(this))->foo; // CHECK: ret i32 } @@ -206,11 +230,13 @@ struct Derived : public Base { int load_member_1() override { // ALIGN: %[[THISINT10:[0-9]+]] = ptrtoint ptr %{{.*}} to i64, !nosanitize // ALIGN: and i64 %[[THISINT10]], 7, !nosanitize - // ALIGN: call void @__ubsan_handle_type_mismatch + // ALIGN: call void @__ubsan_handle_misaligned_pointer_use // NULL: icmp ne ptr %[[THIS10:[a-z0-9]+]], null, !nosanitize // NULL: ptrtoint ptr %[[THIS10]] to i64, !nosanitize - // CHECK: call void @__ubsan_handle_type_mismatch - // CHECK-NOT: call void @__ubsan_handle_type_mismatch + // ALIGN: call void @__ubsan_handle_misaligned_pointer_use + // ALIGN-NOT: call void @__ubsan_handle_misaligned_pointer_use + // NULL: call void @__ubsan_handle_null_pointer_use + // NULL-NOT: call void @__ubsan_handle_null_pointer_use return foo + bar; // CHECK: ret i32 } diff --git a/clang/test/CodeGenCXX/ubsan-type-checks.cpp b/clang/test/CodeGenCXX/ubsan-type-checks.cpp index cf2118c9bd963..f42d60de6c52c 100644 --- a/clang/test/CodeGenCXX/ubsan-type-checks.cpp +++ b/clang/test/CodeGenCXX/ubsan-type-checks.cpp @@ -8,9 +8,9 @@ struct A { // COMMON-LABEL: define linkonce_odr void @_ZN1A10do_nothingEv void do_nothing() { // ALIGN-NOT: ptrtoint ptr %{{.*}} to i64, !nosanitize - + // NULL: icmp ne ptr %{{.*}}, null, !nosanitize - + // OBJSIZE-NOT: call i64 @llvm.objectsize } }; @@ -48,7 +48,7 @@ void invalid_cast(Cat *cat = nullptr) { // // VPTR: [[ICMP:%.*]] = icmp ne ptr {{.*}}, null // VPTR-NEXT: br i1 [[ICMP]] - // VPTR: call void @__ubsan_handle_type_mismatch + // VPTR: call void @__ubsan_handle_null_pointer_use_abort // VPTR-NOT: icmp ne ptr {{.*}}, null // VPTR: br i1 [[ICMP]] // VPTR: call void @__ubsan_handle_dynamic_type_cache_miss @@ -56,7 +56,7 @@ void invalid_cast(Cat *cat = nullptr) { // Fall back to the vptr sanitizer's null check when -fsanitize=null isn't // available. // - // VPTR_NO_NULL-NOT: call void @__ubsan_handle_type_mismatch + // VPTR_NO_NULL-NOT: call void @__ubsan_handle_null_pointer_use_abort // VPTR_NO_NULL: [[ICMP:%.*]] = icmp ne ptr {{.*}}, null // VPTR_NO_NULL-NEXT: br i1 [[ICMP]] // VPTR_NO_NULL: call void @__ubsan_handle_dynamic_type_cache_miss @@ -67,7 +67,7 @@ void invalid_cast(Cat *cat = nullptr) { // VPTR_NO_NULL-LABEL: define{{.*}} void @_Z13invalid_cast2v void invalid_cast2() { // We've got a pointer to an alloca, so there's no run-time null check needed. - // VPTR_NO_NULL-NOT: call void @__ubsan_handle_type_mismatch + // VPTR_NO_NULL-NOT: call void @__ubsan_handle_null_pointer_use_abort // VPTR_NO_NULL: call void @__ubsan_handle_dynamic_type_cache_miss Cat cat; cat.speak(); diff --git a/clang/test/CodeGenCXX/ubsan-vtable-checks.cpp b/clang/test/CodeGenCXX/ubsan-vtable-checks.cpp index c891ff0a4fa42..b8d4f846ea71b 100644 --- a/clang/test/CodeGenCXX/ubsan-vtable-checks.cpp +++ b/clang/test/CodeGenCXX/ubsan-vtable-checks.cpp @@ -26,7 +26,7 @@ int get_v(T* t) { // CHECK-NULL-NOT: load {{.*}} (ptr{{.*}})**, {{.*}} (ptr{{.*}})*** // CHECK-NULL: [[UBSAN_CMP_RES:%[0-9]+]] = icmp ne ptr %{{[_a-z0-9]+}}, null // CHECK-NULL-NEXT: br i1 [[UBSAN_CMP_RES]], label %{{.*}}, label %{{.*}} - // CHECK-NULL: call void @__ubsan_handle_type_mismatch_v1_abort + // CHECK-NULL: call void @__ubsan_handle_null_pointer_use_abort // Second, we check that vtable is actually loaded once the type check is done. // CHECK-NULL: load ptr, ptr {{.*}} @@ -51,7 +51,7 @@ int get_v(T* t) { void delete_it(T *t) { // CHECK-VPTR-NOT: load {{.*}} (ptr{{.*}})**, {{.*}} (ptr{{.*}})*** // CHECK-VPTR: br i1 {{.*}} label %{{.*}} - // CHECK-VPTR: call void @__ubsan_handle_type_mismatch_v1_abort + // CHECK-VPTR: call void @__ubsan_handle_null_pointer_use_abort // Second, we check that vtable is actually loaded once the type check is done. // CHECK-VPTR: load ptr, ptr {{.*}} diff --git a/clang/test/CodeGenHIP/sanitize-undefined-null.hip b/clang/test/CodeGenHIP/sanitize-undefined-null.hip index 9418b125f9955..92472faa96827 100644 --- a/clang/test/CodeGenHIP/sanitize-undefined-null.hip +++ b/clang/test/CodeGenHIP/sanitize-undefined-null.hip @@ -10,7 +10,7 @@ //. // CHECK: @.src = private unnamed_addr addrspace(4) constant [{{[0-9]+}} x i8] c // CHECK: @0 = private unnamed_addr addrspace(1) constant { i16, i16, [7 x i8] } { i16 0, i16 7, [7 x i8] c"'char'\00" } -// CHECK: @1 = private unnamed_addr addrspace(1) global { { ptr, i32, i32 }, ptr addrspace(1), i8, i8 } { { ptr, i32, i32 } { ptr addrspacecast (ptr addrspace(4) @.src to ptr), i32 {{[0-9]+}}, i32 3 }, ptr addrspace(1) @0, i8 1, i8 1 } +// CHECK: @1 = private unnamed_addr addrspace(1) global { { ptr, i32, i32 }, ptr addrspace(1), i8 } { { ptr, i32, i32 } { ptr addrspacecast (ptr addrspace(4) @.src to ptr), i32 34, i32 3 }, ptr addrspace(1) @0, i8 1 } //. // CHECK-LABEL: @_Z3fooPc( // CHECK-NEXT: entry: @@ -22,9 +22,9 @@ // CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P_ADDR_ASCAST]], align 8 // CHECK-NEXT: [[TMP1:%.*]] = icmp ne ptr [[TMP0]], null, !nosanitize !4 // CHECK-NEXT: br i1 [[TMP1]], label [[CONT:%.*]], label [[HANDLER_TYPE_MISMATCH:%.*]], !prof [[PROF4:![0-9]+]], !nosanitize !4 -// CHECK: handler.type_mismatch: +// CHECK: handler.null_pointer_use: // CHECK-NEXT: [[TMP2:%.*]] = ptrtoint ptr [[TMP0]] to i64, !nosanitize !4 -// CHECK-NEXT: call void @__ubsan_handle_type_mismatch_v1_abort(ptr addrspace(1) @[[GLOB1:[0-9]+]], i64 [[TMP2]]) #[[ATTR2:[0-9]+]], !nosanitize !4 +// CHECK-NEXT: call void @__ubsan_handle_null_pointer_use_abort(ptr addrspace(1) @[[GLOB1:[0-9]+]], i64 [[TMP2]]) #[[ATTR2:[0-9]+]], !nosanitize !4 // CHECK-NEXT: unreachable, !nosanitize !4 // CHECK: cont: // CHECK-NEXT: store i8 0, ptr [[TMP0]], align 1 diff --git a/clang/test/CodeGenObjC/ubsan-nullability.m b/clang/test/CodeGenObjC/ubsan-nullability.m index cb399587c6e06..c0dd35626f068 100644 --- a/clang/test/CodeGenObjC/ubsan-nullability.m +++ b/clang/test/CodeGenObjC/ubsan-nullability.m @@ -44,7 +44,7 @@ void call_func_with_nonnull_arg(int *_Nonnull p) { void nonnull_assign1(int *p) { // CHECK: [[ICMP:%.*]] = icmp ne ptr {{.*}}, null, !nosanitize // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize - // CHECK: call void @__ubsan_handle_type_mismatch{{.*}}[[NONNULL_ASSIGN1_LOC]] + // CHECK: call void @__ubsan_handle_null_pointer_use_with_nullability{{.*}}[[NONNULL_ASSIGN1_LOC]] int *_Nonnull local; local = p; } @@ -54,7 +54,7 @@ void nonnull_assign1(int *p) { void nonnull_assign2(int *p) { // CHECK: [[ICMP:%.*]] = icmp ne ptr %{{.*}}, null, !nosanitize // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize - // CHECK: call void @__ubsan_handle_type_mismatch{{.*}}[[NONNULL_ASSIGN2_LOC]] + // CHECK: call void @__ubsan_handle_null_pointer_use_with_nullability{{.*}}[[NONNULL_ASSIGN2_LOC]] int *_Nonnull arr[1]; arr[0] = p; } @@ -68,8 +68,8 @@ void nonnull_assign2(int *p) { void nonnull_assign3(int *p) { // CHECK: [[ICMP:%.*]] = icmp ne ptr %{{.*}}, null, !nosanitize // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize - // CHECK: call void @__ubsan_handle_type_mismatch{{.*}}[[NONNULL_ASSIGN3_LOC]] - // CHECK-NOT: call void @__ubsan_handle_type_mismatch + // CHECK: call void @__ubsan_handle_null_pointer_use_with_nullability{{.*}}[[NONNULL_ASSIGN3_LOC]] + // CHECK-NOT: call void @__ubsan_handle_null_pointer_use_with_nullability struct S1 s; s.mptr = p; } @@ -79,7 +79,7 @@ void nonnull_assign3(int *p) { void nonnull_init1(int *p) { // CHECK: [[ICMP:%.*]] = icmp ne ptr %{{.*}}, null, !nosanitize // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize - // CHECK: call void @__ubsan_handle_type_mismatch{{.*}}[[NONNULL_INIT1_LOC]] + // CHECK: call void @__ubsan_handle_null_pointer_use_with_nullability{{.*}}[[NONNULL_INIT1_LOC]] int *_Nonnull local = p; } @@ -88,10 +88,10 @@ void nonnull_init1(int *p) { void nonnull_init2(int *p) { // CHECK: [[ICMP:%.*]] = icmp ne ptr %{{.*}}, null, !nosanitize // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize - // CHECK: call void @__ubsan_handle_type_mismatch{{.*}}[[NONNULL_INIT2_LOC1]] + // CHECK: call void @__ubsan_handle_null_pointer_use_with_nullability{{.*}}[[NONNULL_INIT2_LOC1]] // CHECK: [[ICMP:%.*]] = icmp ne ptr %{{.*}}, null, !nosanitize // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize - // CHECK: call void @__ubsan_handle_type_mismatch{{.*}}[[NONNULL_INIT2_LOC2]] + // CHECK: call void @__ubsan_handle_null_pointer_use_with_nullability{{.*}}[[NONNULL_INIT2_LOC2]] int *_Nonnull arr[] = {p, p}; } diff --git a/compiler-rt/lib/ubsan/ubsan_handlers.cpp b/compiler-rt/lib/ubsan/ubsan_handlers.cpp index 63319f46734a4..a1df6f7e3ac41 100644 --- a/compiler-rt/lib/ubsan/ubsan_handlers.cpp +++ b/compiler-rt/lib/ubsan/ubsan_handlers.cpp @@ -148,6 +148,162 @@ void __ubsan::__ubsan_handle_type_mismatch_v1_abort(TypeMismatchData *Data, Die(); } +static void handleNullPointerUseImpl(NullPointerUseData *Data, + ValueHandle Pointer, ReportOptions Opts) { + Location Loc = Data->Loc.acquire(); + + ErrorType ET = ErrorType::NullPointerUse; + + // Use the SourceLocation from Data to track deduplication, even if it's + // invalid. + if (ignoreReport(Loc.getSourceLocation(), Opts, ET)) + return; + + SymbolizedStackHolder FallbackLoc; + if (Data->Loc.isInvalid()) { + FallbackLoc.reset(getCallerLocation(Opts.pc)); + Loc = FallbackLoc; + } + + ScopedReport R(Opts, Loc, ET); + + Diag(Loc, DL_Error, ET, "%0 null pointer of type %1") + << TypeCheckKinds[Data->TypeCheckKind] << Data->Type; +} + +void __ubsan::__ubsan_handle_null_pointer_use(NullPointerUseData *Data, + ValueHandle Pointer) { + GET_REPORT_OPTIONS(false); + handleNullPointerUseImpl(Data, Pointer, Opts); +} +void __ubsan::__ubsan_handle_null_pointer_use_abort(NullPointerUseData *Data, + ValueHandle Pointer) { + GET_REPORT_OPTIONS(true); + handleNullPointerUseImpl(Data, Pointer, Opts); + Die(); +} + +static void +handleNullPointerUseWithNullabilityImpl(NullPointerUseWithNullabilityData *Data, + ValueHandle Pointer, + ReportOptions Opts) { + Location Loc = Data->Loc.acquire(); + + ErrorType ET = ErrorType::NullPointerUseWithNullability; + + // Use the SourceLocation from Data to track deduplication, even if it's + // invalid. + if (ignoreReport(Loc.getSourceLocation(), Opts, ET)) + return; + + SymbolizedStackHolder FallbackLoc; + if (Data->Loc.isInvalid()) { + FallbackLoc.reset(getCallerLocation(Opts.pc)); + Loc = FallbackLoc; + } + + ScopedReport R(Opts, Loc, ET); + + Diag(Loc, DL_Error, ET, "%0 null pointer of type %1") + << TypeCheckKinds[Data->TypeCheckKind] << Data->Type; +} + +void __ubsan::__ubsan_handle_null_pointer_use_with_nullability( + NullPointerUseWithNullabilityData *Data, ValueHandle Pointer) { + GET_REPORT_OPTIONS(false); + handleNullPointerUseWithNullabilityImpl(Data, Pointer, Opts); +} +void __ubsan::__ubsan_handle_null_pointer_use_with_nullability_abort( + NullPointerUseWithNullabilityData *Data, ValueHandle Pointer) { + GET_REPORT_OPTIONS(true); + handleNullPointerUseWithNullabilityImpl(Data, Pointer, Opts); + Die(); +} + +static void handleMisalignedPointerUseImpl(MisalignedPointerUseData *Data, + ValueHandle Pointer, + ReportOptions Opts) { + Location Loc = Data->Loc.acquire(); + + uptr Alignment = (uptr)1 << Data->LogAlignment; + ErrorType ET = ErrorType::MisalignedPointerUse; + + // Use the SourceLocation from Data to track deduplication, even if it's + // invalid. + if (ignoreReport(Loc.getSourceLocation(), Opts, ET)) + return; + + SymbolizedStackHolder FallbackLoc; + if (Data->Loc.isInvalid()) { + FallbackLoc.reset(getCallerLocation(Opts.pc)); + Loc = FallbackLoc; + } + + ScopedReport R(Opts, Loc, ET); + + Diag(Loc, DL_Error, ET, + "%0 misaligned address %1 for type %3, " + "which requires %2 byte alignment") + << TypeCheckKinds[Data->TypeCheckKind] << (void *)Pointer << Alignment + << Data->Type; + + if (Pointer) + Diag(Pointer, DL_Note, ET, "pointer points here"); +} + +void __ubsan::__ubsan_handle_misaligned_pointer_use( + MisalignedPointerUseData *Data, ValueHandle Pointer) { + GET_REPORT_OPTIONS(false); + handleMisalignedPointerUseImpl(Data, Pointer, Opts); +} +void __ubsan::__ubsan_handle_misaligned_pointer_use_abort( + MisalignedPointerUseData *Data, ValueHandle Pointer) { + GET_REPORT_OPTIONS(true); + handleMisalignedPointerUseImpl(Data, Pointer, Opts); + Die(); +} + +static void handleInsufficientObjectSizeImpl(InsufficientObjectSizeData *Data, + ValueHandle Pointer, + ReportOptions Opts) { + Location Loc = Data->Loc.acquire(); + + ErrorType ET = ErrorType::InsufficientObjectSize; + + // Use the SourceLocation from Data to track deduplication, even if it's + // invalid. + if (ignoreReport(Loc.getSourceLocation(), Opts, ET)) + return; + + SymbolizedStackHolder FallbackLoc; + if (Data->Loc.isInvalid()) { + FallbackLoc.reset(getCallerLocation(Opts.pc)); + Loc = FallbackLoc; + } + + ScopedReport R(Opts, Loc, ET); + + Diag(Loc, DL_Error, ET, + "%0 address %1 with insufficient space " + "for an object of type %2") + << TypeCheckKinds[Data->TypeCheckKind] << (void *)Pointer << Data->Type; + + if (Pointer) + Diag(Pointer, DL_Note, ET, "pointer points here"); +} + +void __ubsan::__ubsan_handle_insufficient_object_size( + InsufficientObjectSizeData *Data, ValueHandle Pointer) { + GET_REPORT_OPTIONS(false); + handleInsufficientObjectSizeImpl(Data, Pointer, Opts); +} +void __ubsan::__ubsan_handle_insufficient_object_size_abort( + InsufficientObjectSizeData *Data, ValueHandle Pointer) { + GET_REPORT_OPTIONS(true); + handleInsufficientObjectSizeImpl(Data, Pointer, Opts); + Die(); +} + static void handleAlignmentAssumptionImpl(AlignmentAssumptionData *Data, ValueHandle Pointer, ValueHandle Alignment, diff --git a/compiler-rt/lib/ubsan/ubsan_handlers.h b/compiler-rt/lib/ubsan/ubsan_handlers.h index 521caa96bc771..18c41ee9ff180 100644 --- a/compiler-rt/lib/ubsan/ubsan_handlers.h +++ b/compiler-rt/lib/ubsan/ubsan_handlers.h @@ -38,6 +38,48 @@ struct TypeMismatchData { /// type. RECOVERABLE(type_mismatch_v1, TypeMismatchData *Data, ValueHandle Pointer) +struct NullPointerUseData { + SourceLocation Loc; + const TypeDescriptor &Type; + unsigned char TypeCheckKind; +}; + +/// \brief Handle a runtime type check failure, caused by a null pointer usage. +RECOVERABLE(null_pointer_use, NullPointerUseData *Data, ValueHandle Pointer) + +struct NullPointerUseWithNullabilityData { + SourceLocation Loc; + const TypeDescriptor &Type; + unsigned char TypeCheckKind; +}; + +/// \brief Handle a runtime type check failure, caused by assigning null to a +/// lvalue which is annotated with _Nonnull. +RECOVERABLE(null_pointer_use_with_nullability, + NullPointerUseWithNullabilityData *Data, ValueHandle Pointer) + +struct MisalignedPointerUseData { + SourceLocation Loc; + const TypeDescriptor &Type; + unsigned char LogAlignment; + unsigned char TypeCheckKind; +}; + +/// \brief Handle a runtime type check failure, caused by a misaligned pointer. +RECOVERABLE(misaligned_pointer_use, MisalignedPointerUseData *Data, + ValueHandle Pointer) + +struct InsufficientObjectSizeData { + SourceLocation Loc; + const TypeDescriptor &Type; + unsigned char TypeCheckKind; +}; + +/// \brief Handle a runtime type check failure, caused by a pointer to +/// insufficient storage for the type. +RECOVERABLE(insufficient_object_size, InsufficientObjectSizeData *Data, + ValueHandle Pointer) + struct AlignmentAssumptionData { SourceLocation Loc; SourceLocation AssumptionLoc; diff --git a/compiler-rt/lib/ubsan/ubsan_interface.inc b/compiler-rt/lib/ubsan/ubsan_interface.inc index 0eb109f37d445..db0a04f16efae 100644 --- a/compiler-rt/lib/ubsan/ubsan_interface.inc +++ b/compiler-rt/lib/ubsan/ubsan_interface.inc @@ -25,12 +25,16 @@ INTERFACE_FUNCTION(__ubsan_handle_function_type_mismatch) INTERFACE_FUNCTION(__ubsan_handle_function_type_mismatch_abort) INTERFACE_FUNCTION(__ubsan_handle_implicit_conversion) INTERFACE_FUNCTION(__ubsan_handle_implicit_conversion_abort) +INTERFACE_FUNCTION(__ubsan_handle_insufficient_object_size) +INTERFACE_FUNCTION(__ubsan_handle_insufficient_object_size_abort) INTERFACE_FUNCTION(__ubsan_handle_invalid_builtin) INTERFACE_FUNCTION(__ubsan_handle_invalid_builtin_abort) INTERFACE_FUNCTION(__ubsan_handle_invalid_objc_cast) INTERFACE_FUNCTION(__ubsan_handle_invalid_objc_cast_abort) INTERFACE_FUNCTION(__ubsan_handle_load_invalid_value) INTERFACE_FUNCTION(__ubsan_handle_load_invalid_value_abort) +INTERFACE_FUNCTION(__ubsan_handle_misaligned_pointer_use) +INTERFACE_FUNCTION(__ubsan_handle_misaligned_pointer_use_abort) INTERFACE_FUNCTION(__ubsan_handle_missing_return) INTERFACE_FUNCTION(__ubsan_handle_mul_overflow) INTERFACE_FUNCTION(__ubsan_handle_mul_overflow_abort) @@ -40,6 +44,10 @@ INTERFACE_FUNCTION(__ubsan_handle_nonnull_arg) INTERFACE_FUNCTION(__ubsan_handle_nonnull_arg_abort) INTERFACE_FUNCTION(__ubsan_handle_nonnull_return_v1) INTERFACE_FUNCTION(__ubsan_handle_nonnull_return_v1_abort) +INTERFACE_FUNCTION(__ubsan_handle_null_pointer_use) +INTERFACE_FUNCTION(__ubsan_handle_null_pointer_use_abort) +INTERFACE_FUNCTION(__ubsan_handle_null_pointer_use_with_nullability) +INTERFACE_FUNCTION(__ubsan_handle_null_pointer_use_with_nullability_abort) INTERFACE_FUNCTION(__ubsan_handle_nullability_arg) INTERFACE_FUNCTION(__ubsan_handle_nullability_arg_abort) INTERFACE_FUNCTION(__ubsan_handle_nullability_return_v1) diff --git a/compiler-rt/lib/ubsan_minimal/ubsan_minimal_handlers.cpp b/compiler-rt/lib/ubsan_minimal/ubsan_minimal_handlers.cpp index ebc36a8583e05..613fb662312af 100644 --- a/compiler-rt/lib/ubsan_minimal/ubsan_minimal_handlers.cpp +++ b/compiler-rt/lib/ubsan_minimal/ubsan_minimal_handlers.cpp @@ -160,3 +160,7 @@ HANDLER(nullability_arg, "nullability-arg") HANDLER(nullability_return, "nullability-return") HANDLER(pointer_overflow, "pointer-overflow") HANDLER(cfi_check_fail, "cfi-check-fail") +HANDLER(null_pointer_use, "null-pointer-use") +HANDLER(null_pointer_use_with_nullability, "null-pointer-use-with-nullability") +HANDLER(misaligned_pointer_use, "misaligned-pointer-use") +HANDLER(insufficient_object_size, "insufficient-object-size")