[clang] [Clang][CodeGen][Sanitizers] Add extra context for trap messages (PR #153845)
Anthony Tran via cfe-commits
cfe-commits at lists.llvm.org
Fri Aug 15 10:47:04 PDT 2025
https://github.com/anthonyhatran created https://github.com/llvm/llvm-project/pull/153845
Serves as an improvement to the current [`-fsanitize-debug-trap-reasons`](https://github.com/llvm/llvm-project/pull/145967) by providing additional context to the user regarding the trap reason.
Part of a GSoC 2025 Project.
>From 13140e96b9fa67e3258a036bf2a19ae78d7a0b40 Mon Sep 17 00:00:00 2001
From: Anthony Tran <atran881 at usc.edu>
Date: Fri, 15 Aug 2025 10:16:07 -0700
Subject: [PATCH] Add extra context for trap messages
---
clang/lib/CodeGen/CGExpr.cpp | 105 +++++++++++++++---
clang/lib/CodeGen/CGExprScalar.cpp | 53 +++++++--
clang/lib/CodeGen/CodeGenFunction.h | 14 ++-
.../CodeGen/ubsan-trap-reason-add-overflow.c | 22 +++-
.../ubsan-trap-reason-div-rem-overflow.c | 18 ++-
clang/test/CodeGen/ubsan-trap-reason-flag.c | 2 +-
.../ubsan-trap-reason-float-cast-overflow.c | 2 +-
...ubsan-trap-reason-function-type-mismatch.c | 2 +-
.../ubsan-trap-reason-implicit-conversion.c | 48 ++++++--
.../CodeGen/ubsan-trap-reason-mul-overflow.c | 22 +++-
.../ubsan-trap-reason-negate-overflow.c | 2 +-
.../ubsan-trap-reason-shift-out-of-bounds.c | 25 ++++-
.../CodeGen/ubsan-trap-reason-sub-overflow.c | 22 +++-
13 files changed, 270 insertions(+), 67 deletions(-)
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index d5df6dd3e303c..9622db24c97e0 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -23,6 +23,7 @@
#include "CodeGenModule.h"
#include "CodeGenPGO.h"
#include "ConstantEmitter.h"
+#include "SanitizerHandler.h"
#include "TargetInfo.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/ASTLambda.h"
@@ -37,6 +38,7 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/ScopeExit.h"
#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/LLVMContext.h"
@@ -44,6 +46,7 @@
#include "llvm/IR/MatrixBuilder.h"
#include "llvm/Support/ConvertUTF.h"
#include "llvm/Support/Endian.h"
+#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/xxhash.h"
@@ -85,15 +88,84 @@ enum VariableTypeDescriptorKind : uint16_t {
// Miscellaneous Helper Methods
//===--------------------------------------------------------------------===//
-static llvm::StringRef GetUBSanTrapForHandler(SanitizerHandler ID) {
- switch (ID) {
-#define SANITIZER_CHECK(Enum, Name, Version, Msg) \
- case SanitizerHandler::Enum: \
- return Msg;
- LIST_SANITIZER_CHECKS
-#undef SANITIZER_CHECK
+std::string CodeGenFunction::BuildSanitizerTrapMessage(
+ SanitizerHandler Handler, QualType LhsTy, QualType OpType, bool IsLeftShift,
+ bool IsSigned, std::string ReasonStr, bool IsDivideByZero,
+ bool IsTruncation) {
+ switch (Handler) {
+ case SanitizerHandler::AddOverflow:
+ return llvm::formatv("{0} integer addition overflow on type '{1}'",
+ IsSigned ? "Signed" : "Unsigned", LhsTy.getAsString());
+ case SanitizerHandler::BuiltinUnreachable:
+ return "_builtin_unreachable(), execution reached an unreachable program "
+ "point";
+ case SanitizerHandler::CFICheckFail:
+ return "Control flow integrity check failed";
+ case SanitizerHandler::DivremOverflow:
+ return llvm::formatv("{0} on type '{1}'", ReasonStr, LhsTy.getAsString());
+ case SanitizerHandler::DynamicTypeCacheMiss:
+ return "Dynamic type cache miss, member call made on an object whose "
+ "dynamic type differs from the expected type";
+ case SanitizerHandler::FloatCastOverflow:
+ return llvm::formatv("Float cast overflow converting from floating-point "
+ "type '{0}' to integer type '{1}'",
+ LhsTy.getAsString(), OpType.getAsString());
+ case SanitizerHandler::FunctionTypeMismatch:
+ return llvm::formatv("Call through function pointer of type '{0}' with an "
+ "incompatible target",
+ (LhsTy->getPointeeType()).getAsString());
+ case SanitizerHandler::ImplicitConversion:
+ return llvm::formatv(
+ "Implicit {0}conversion from '{1}' to '{2}' caused {3}",
+ IsTruncation ? (IsSigned ? "signed " : "unsigned ") : "",
+ LhsTy.getAsString(), OpType.getAsString(),
+ IsTruncation ? "truncation" : "sign-change");
+ case SanitizerHandler::InvalidBuiltin:
+ return "Invalid use of builtin function";
+ case SanitizerHandler::InvalidObjCCast:
+ return "Invalid Objective-C cast";
+ case SanitizerHandler::LoadInvalidValue:
+ return "Loaded an invalid or uninitialized value for the type";
+ case SanitizerHandler::MissingReturn:
+ return "Execution reached the end of a value-returning function without "
+ "returning a value";
+ case SanitizerHandler::MulOverflow:
+ return llvm::formatv("{0} integer multiplication overflow on type '{1}'",
+ IsSigned ? "Signed" : "Unsigned", LhsTy.getAsString());
+ case SanitizerHandler::NegateOverflow:
+ return llvm::formatv("Integer negation overflow on type '{0}'",
+ LhsTy.getAsString());
+ case SanitizerHandler::NullabilityArg:
+ return "Passing null as an argument which is annotated with _Nonnull";
+ case SanitizerHandler::NullabilityReturn:
+ return "Returning null from a function with a return type annotated with "
+ "_Nonnull";
+ case SanitizerHandler::NonnullArg:
+ return "Passing null pointer as an argument which is declared to never be "
+ "null";
+ case SanitizerHandler::NonnullReturn:
+ return "Returning null pointer from a function which is declared to never "
+ "return null";
+ case SanitizerHandler::OutOfBounds:
+ return "Array index out of bounds";
+ case SanitizerHandler::PointerOverflow:
+ return "Pointer arithmetic overflowed bounds";
+ case SanitizerHandler::ShiftOutOfBounds:
+ return llvm::formatv("{0} shift is too large for {1}-bit type '{2}'",
+ IsLeftShift ? "Left" : "Right",
+ getContext().getIntWidth(LhsTy), LhsTy.getAsString());
+ case SanitizerHandler::SubOverflow:
+ return llvm::formatv("{0} integer subtraction overflow on type '{1}'",
+ IsSigned ? "Signed" : "Unsigned", LhsTy.getAsString());
+ case SanitizerHandler::TypeMismatch:
+ return "Type mismatch in operation";
+ case SanitizerHandler::AlignmentAssumption:
+ return "Alignment assumption violated";
+ case SanitizerHandler::VLABoundNotPositive:
+ return "Variable length array bound evaluates to non-positive value";
+ default:
+ return "";
}
- llvm_unreachable("unhandled switch case");
}
/// CreateTempAlloca - This creates a alloca and inserts it into the entry
@@ -3720,7 +3792,7 @@ static void emitCheckHandlerCall(CodeGenFunction &CGF,
void CodeGenFunction::EmitCheck(
ArrayRef<std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>> Checked,
SanitizerHandler CheckHandler, ArrayRef<llvm::Constant *> StaticArgs,
- ArrayRef<llvm::Value *> DynamicArgs) {
+ ArrayRef<llvm::Value *> DynamicArgs, std::string TrapMessage) {
assert(IsSanitizerScope);
assert(Checked.size() > 0);
assert(CheckHandler >= 0 &&
@@ -3759,7 +3831,7 @@ void CodeGenFunction::EmitCheck(
}
if (TrapCond)
- EmitTrapCheck(TrapCond, CheckHandler, NoMerge);
+ EmitTrapCheck(TrapCond, CheckHandler, NoMerge, TrapMessage);
if (!FatalCond && !RecoverableCond)
return;
@@ -4071,7 +4143,7 @@ void CodeGenFunction::EmitUnreachable(SourceLocation Loc) {
void CodeGenFunction::EmitTrapCheck(llvm::Value *Checked,
SanitizerHandler CheckHandlerID,
- bool NoMerge) {
+ bool NoMerge, std::string TrapMessage) {
llvm::BasicBlock *Cont = createBasicBlock("cont");
// If we're optimizing, collapse all calls to trap down to just one per
@@ -4082,7 +4154,11 @@ void CodeGenFunction::EmitTrapCheck(llvm::Value *Checked,
llvm::BasicBlock *&TrapBB = TrapBBs[CheckHandlerID];
llvm::DILocation *TrapLocation = Builder.getCurrentDebugLocation();
- llvm::StringRef TrapMessage = GetUBSanTrapForHandler(CheckHandlerID);
+ // If no additional context was needed for building the trap message, we build
+ // it here instead
+ if (TrapMessage.empty()) {
+ TrapMessage = BuildSanitizerTrapMessage(CheckHandlerID, {}, {});
+ }
if (getDebugInfo() && !TrapMessage.empty() &&
CGM.getCodeGenOpts().SanitizeDebugTrapReasons && TrapLocation) {
@@ -6404,8 +6480,11 @@ RValue CodeGenFunction::EmitCall(QualType CalleeType,
Builder.CreateICmpEQ(CalleeTypeHash, TypeHash);
llvm::Constant *StaticData[] = {EmitCheckSourceLocation(E->getBeginLoc()),
EmitCheckTypeDescriptor(CalleeType)};
+ std::string Msg =
+ BuildSanitizerTrapMessage(SanitizerHandler::FunctionTypeMismatch,
+ CalleeType, {}, {}, {}, {}, {});
EmitCheck(std::make_pair(CalleeTypeHashMatch, CheckOrdinal), CheckHandler,
- StaticData, {CalleePtr});
+ StaticData, {CalleePtr}, Msg);
Builder.CreateBr(Cont);
EmitBlock(Cont);
diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp
index 155b80df36715..66f082a030a21 100644
--- a/clang/lib/CodeGen/CGExprScalar.cpp
+++ b/clang/lib/CodeGen/CGExprScalar.cpp
@@ -31,6 +31,7 @@
#include "clang/Basic/CodeGenOptions.h"
#include "clang/Basic/TargetInfo.h"
#include "llvm/ADT/APFixedPoint.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/IR/Argument.h"
#include "llvm/IR/CFG.h"
#include "llvm/IR/Constants.h"
@@ -284,7 +285,7 @@ class ScalarExprEmitter
void EmitBinOpCheck(
ArrayRef<std::pair<Value *, SanitizerKind::SanitizerOrdinal>> Checks,
- const BinOpInfo &Info);
+ const BinOpInfo &Info, std::string TrapMessage = "");
Value *EmitLoadOfLValue(LValue LV, SourceLocation Loc) {
return CGF.EmitLoadOfLValue(LV, Loc).getScalarVal();
@@ -1058,8 +1059,12 @@ void ScalarExprEmitter::EmitFloatConversionCheck(
llvm::Constant *StaticArgs[] = {CGF.EmitCheckSourceLocation(Loc),
CGF.EmitCheckTypeDescriptor(OrigSrcType),
CGF.EmitCheckTypeDescriptor(DstType)};
+ std::string Msg =
+ CGF.BuildSanitizerTrapMessage(SanitizerHandler::FloatCastOverflow,
+ OrigSrcType, DstType, {}, {}, {}, {});
+
CGF.EmitCheck(std::make_pair(Check, CheckOrdinal), CheckHandler, StaticArgs,
- OrigSrc);
+ OrigSrc, Msg);
}
// Should be called within CodeGenFunction::SanitizerScope RAII scope.
@@ -1172,7 +1177,11 @@ void ScalarExprEmitter::EmitIntegerTruncationCheck(Value *Src, QualType SrcType,
llvm::ConstantInt::get(Builder.getInt8Ty(), Check.first),
llvm::ConstantInt::get(Builder.getInt32Ty(), 0)};
- CGF.EmitCheck(Check.second, CheckHandler, StaticArgs, {Src, Dst});
+ std::string Msg = CGF.BuildSanitizerTrapMessage(
+ SanitizerHandler::ImplicitConversion, SrcType, DstType, {},
+ (SrcSigned || DstSigned), {}, {}, true);
+
+ CGF.EmitCheck(Check.second, CheckHandler, StaticArgs, {Src, Dst}, Msg);
}
static llvm::Value *EmitIsNegativeTestHelper(Value *V, QualType VType,
@@ -1327,8 +1336,11 @@ void ScalarExprEmitter::EmitIntegerSignChangeCheck(Value *Src, QualType SrcType,
CGF.EmitCheckTypeDescriptor(DstType),
llvm::ConstantInt::get(Builder.getInt8Ty(), CheckKind),
llvm::ConstantInt::get(Builder.getInt32Ty(), 0)};
+ std::string Msg = CGF.BuildSanitizerTrapMessage(
+ SanitizerHandler::ImplicitConversion, SrcType, DstType, {},
+ (SrcSigned || DstSigned), {}, {}, false);
// EmitCheck() will 'and' all the checks together.
- CGF.EmitCheck(Checks, CheckHandler, StaticArgs, {Src, Dst});
+ CGF.EmitCheck(Checks, CheckHandler, StaticArgs, {Src, Dst}, Msg);
}
// Should be called within CodeGenFunction::SanitizerScope RAII scope.
@@ -1808,7 +1820,7 @@ Value *ScalarExprEmitter::EmitNullValue(QualType Ty) {
/// are \c true.
void ScalarExprEmitter::EmitBinOpCheck(
ArrayRef<std::pair<Value *, SanitizerKind::SanitizerOrdinal>> Checks,
- const BinOpInfo &Info) {
+ const BinOpInfo &Info, std::string TrapMessage) {
assert(CGF.IsSanitizerScope);
SanitizerHandler Check;
SmallVector<llvm::Constant *, 4> StaticData;
@@ -1824,6 +1836,8 @@ void ScalarExprEmitter::EmitBinOpCheck(
Check = SanitizerHandler::NegateOverflow;
StaticData.push_back(CGF.EmitCheckTypeDescriptor(UO->getType()));
DynamicData.push_back(Info.RHS);
+ TrapMessage = CGF.BuildSanitizerTrapMessage(Check, UO->getType(), {}, false,
+ true, {}, {}, {});
} else {
if (BinaryOperator::isShiftOp(Opcode)) {
// Shift LHS negative or too large, or RHS out of bounds.
@@ -1851,7 +1865,7 @@ void ScalarExprEmitter::EmitBinOpCheck(
DynamicData.push_back(Info.RHS);
}
- CGF.EmitCheck(Checks, Check, StaticData, DynamicData);
+ CGF.EmitCheck(Checks, Check, StaticData, DynamicData, TrapMessage);
}
//===----------------------------------------------------------------------===//
@@ -3969,8 +3983,10 @@ void ScalarExprEmitter::EmitUndefinedBehaviorIntegerDivAndRemCheck(
const BinOpInfo &Ops, llvm::Value *Zero, bool isDiv) {
SmallVector<std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>, 2>
Checks;
+ std::string ReasonStr;
if (CGF.SanOpts.has(SanitizerKind::IntegerDivideByZero)) {
+ ReasonStr = "Division by zero";
Checks.push_back(std::make_pair(Builder.CreateICmpNE(Ops.RHS, Zero),
SanitizerKind::SO_IntegerDivideByZero));
}
@@ -3991,10 +4007,18 @@ void ScalarExprEmitter::EmitUndefinedBehaviorIntegerDivAndRemCheck(
llvm::Value *NotOverflow = Builder.CreateOr(LHSCmp, RHSCmp, "or");
Checks.push_back(
std::make_pair(NotOverflow, SanitizerKind::SO_SignedIntegerOverflow));
+ if (!ReasonStr.empty()) {
+ ReasonStr += " or signed integer division overflow";
+ } else {
+ ReasonStr = "Signed integer division overflow";
+ }
}
- if (Checks.size() > 0)
- EmitBinOpCheck(Checks, Ops);
+ if (Checks.size() > 0) {
+ std::string Msg = CGF.BuildSanitizerTrapMessage(
+ SanitizerHandler::DivremOverflow, Ops.Ty, {}, {}, {}, ReasonStr, {});
+ EmitBinOpCheck(Checks, Ops, Msg);
+ }
}
Value *ScalarExprEmitter::EmitDiv(const BinOpInfo &Ops) {
@@ -4132,7 +4156,9 @@ Value *ScalarExprEmitter::EmitOverflowCheckedBinOp(const BinOpInfo &Ops) {
SanitizerKind::SanitizerOrdinal Ordinal =
isSigned ? SanitizerKind::SO_SignedIntegerOverflow
: SanitizerKind::SO_UnsignedIntegerOverflow;
- EmitBinOpCheck(std::make_pair(NotOverflow, Ordinal), Ops);
+ std::string Msg = CGF.BuildSanitizerTrapMessage(OverflowKind, Ops.Ty, {},
+ {}, isSigned, {}, {});
+ EmitBinOpCheck(std::make_pair(NotOverflow, Ordinal), Ops, Msg);
} else
CGF.EmitTrapCheck(Builder.CreateNot(overflow), OverflowKind);
return result;
@@ -4774,6 +4800,8 @@ Value *ScalarExprEmitter::EmitShl(const BinOpInfo &Ops) {
RHS = ConstrainShiftValue(Ops.LHS, RHS, "shl.mask");
else if ((SanitizeBase || SanitizeExponent) &&
isa<llvm::IntegerType>(Ops.LHS->getType())) {
+ std::string Msg = CGF.BuildSanitizerTrapMessage(
+ SanitizerHandler::ShiftOutOfBounds, Ops.Ty, {}, true, {}, {}, {});
SmallVector<SanitizerKind::SanitizerOrdinal, 3> Ordinals;
if (SanitizeSignedBase)
Ordinals.push_back(SanitizerKind::SO_ShiftBase);
@@ -4832,7 +4860,7 @@ Value *ScalarExprEmitter::EmitShl(const BinOpInfo &Ops) {
}
assert(!Checks.empty());
- EmitBinOpCheck(Checks, Ops);
+ EmitBinOpCheck(Checks, Ops, Msg);
}
return Builder.CreateShl(Ops.LHS, RHS, "shl");
@@ -4859,7 +4887,10 @@ Value *ScalarExprEmitter::EmitShr(const BinOpInfo &Ops) {
bool RHSIsSigned = Ops.rhsHasSignedIntegerRepresentation();
llvm::Value *Valid = Builder.CreateICmpULE(
Ops.RHS, GetMaximumShiftAmount(Ops.LHS, Ops.RHS, RHSIsSigned));
- EmitBinOpCheck(std::make_pair(Valid, SanitizerKind::SO_ShiftExponent), Ops);
+ std::string Msg = CGF.BuildSanitizerTrapMessage(
+ SanitizerHandler::ShiftOutOfBounds, Ops.Ty, {}, false, {}, {}, {});
+ EmitBinOpCheck(std::make_pair(Valid, SanitizerKind::SO_ShiftExponent), Ops,
+ Msg);
}
if (Ops.Ty->hasUnsignedIntegerRepresentation())
diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h
index ad318f289ee83..c6d2df8025aa2 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -38,12 +38,14 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/Frontend/OpenMP/OMPIRBuilder.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/ValueHandle.h"
#include "llvm/Support/Debug.h"
#include "llvm/Transforms/Utils/SanitizerStats.h"
#include <optional>
+#include <string>
namespace llvm {
class BasicBlock;
@@ -636,6 +638,14 @@ class CodeGenFunction : public CodeGenTypeCache {
/// condition is a known constant.
bool checkIfLoopMustProgress(const Expr *, bool HasEmptyBody);
+ std::string BuildSanitizerTrapMessage(SanitizerHandler Handler,
+ QualType LhsTy, QualType OpType,
+ bool IsLeftShift = false,
+ bool isSigned = false,
+ std::string ReasonStr = "",
+ bool IsDivideByZero = false,
+ bool IsTruncation = false);
+
const CodeGen::CGBlockInfo *BlockInfo = nullptr;
llvm::Value *BlockPointer = nullptr;
@@ -5273,7 +5283,7 @@ class CodeGenFunction : public CodeGenTypeCache {
EmitCheck(ArrayRef<std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
Checked,
SanitizerHandler Check, ArrayRef<llvm::Constant *> StaticArgs,
- ArrayRef<llvm::Value *> DynamicArgs);
+ ArrayRef<llvm::Value *> DynamicArgs, std::string TrapMessage = "");
/// Emit a slow path cross-DSO CFI check which calls __cfi_slowpath
/// if Cond if false.
@@ -5289,7 +5299,7 @@ class CodeGenFunction : public CodeGenTypeCache {
/// Create a basic block that will call the trap intrinsic, and emit a
/// conditional branch to it, for the -ftrapv checks.
void EmitTrapCheck(llvm::Value *Checked, SanitizerHandler CheckHandlerID,
- bool NoMerge = false);
+ bool NoMerge = false, std::string TrapMesage = "");
/// Emit a call to trap or debugtrap and attach function attribute
/// "trap-func-name" if specified.
diff --git a/clang/test/CodeGen/ubsan-trap-reason-add-overflow.c b/clang/test/CodeGen/ubsan-trap-reason-add-overflow.c
index 225778d68833d..eee47538ceb0c 100644
--- a/clang/test/CodeGen/ubsan-trap-reason-add-overflow.c
+++ b/clang/test/CodeGen/ubsan-trap-reason-add-overflow.c
@@ -1,9 +1,19 @@
// RUN: %clang_cc1 -triple arm64-apple-macosx14.0.0 -O0 -debug-info-kind=standalone -dwarf-version=5 \
-// RUN: -fsanitize=signed-integer-overflow -fsanitize-trap=signed-integer-overflow -emit-llvm %s -o - | FileCheck %s
+// RUN: -fsanitize=signed-integer-overflow -fsanitize-trap=signed-integer-overflow -emit-llvm %s -o - | FileCheck %s --check-prefix=SIO
-int add_overflow(int a, int b) { return a + b; }
+int signed_add_overflow(int a, int b) { return a + b; }
-// CHECK-LABEL: @add_overflow
-// CHECK: call void @llvm.ubsantrap(i8 0) {{.*}}!dbg [[LOC:![0-9]+]]
-// CHECK: [[LOC]] = !DILocation(line: 0, scope: [[MSG:![0-9]+]], {{.+}})
-// CHECK: [[MSG]] = distinct !DISubprogram(name: "__clang_trap_msg$Undefined Behavior Sanitizer$Integer addition overflowed"
+// SIO-LABEL: @signed_add_overflow
+// SIO: call void @llvm.ubsantrap(i8 0) {{.*}}!dbg [[LOC:![0-9]+]]
+// SIO: [[LOC]] = !DILocation(line: 0, scope: [[MSG:![0-9]+]], {{.+}})
+// SIO: [[MSG]] = distinct !DISubprogram(name: "__clang_trap_msg$Undefined Behavior Sanitizer$Signed integer addition overflow on type 'int'"
+
+// RUN: %clang_cc1 -triple arm64-apple-macosx14.0.0 -O0 -debug-info-kind=standalone -dwarf-version=5 \
+// RUN: -fsanitize=unsigned-integer-overflow -fsanitize-trap=unsigned-integer-overflow -emit-llvm %s -o - | FileCheck %s --check-prefix=UIO
+
+unsigned int unsigned_add_overflow(unsigned int a, unsigned int b) { return a + b; }
+
+// UIO-LABEL: @unsigned_add_overflow
+// UIO: call void @llvm.ubsantrap(i8 0) {{.*}}!dbg [[LOC:![0-9]+]]
+// UIO: [[LOC]] = !DILocation(line: 0, scope: [[MSG:![0-9]+]], {{.+}})
+// UIO: [[MSG]] = distinct !DISubprogram(name: "__clang_trap_msg$Undefined Behavior Sanitizer$Unsigned integer addition overflow on type 'unsigned int'"
diff --git a/clang/test/CodeGen/ubsan-trap-reason-div-rem-overflow.c b/clang/test/CodeGen/ubsan-trap-reason-div-rem-overflow.c
index d0b21dd173894..e6567a82d0b39 100644
--- a/clang/test/CodeGen/ubsan-trap-reason-div-rem-overflow.c
+++ b/clang/test/CodeGen/ubsan-trap-reason-div-rem-overflow.c
@@ -1,9 +1,17 @@
// RUN: %clang_cc1 -triple arm64-apple-macosx14.0.0 -O0 -debug-info-kind=standalone -dwarf-version=5 \
-// RUN: -fsanitize=signed-integer-overflow -fsanitize-trap=signed-integer-overflow -emit-llvm %s -o - | FileCheck %s
+// RUN: -fsanitize=signed-integer-overflow -fsanitize-trap=signed-integer-overflow -emit-llvm %s -o - | FileCheck %s --check-prefix=SIO
+
+// RUN: %clang_cc1 -triple arm64-apple-macosx14.0.0 -O0 -debug-info-kind=standalone -dwarf-version=5 \
+// RUN: -fsanitize=integer-divide-by-zero -fsanitize-trap=integer-divide-by-zero -emit-llvm %s -o - | FileCheck %s --check-prefix=DBZ
int div_rem_overflow(int a, int b) { return a / b; }
-// CHECK-LABEL: @div_rem_overflow
-// CHECK: call void @llvm.ubsantrap(i8 3) {{.*}}!dbg [[LOC:![0-9]+]]
-// CHECK: [[LOC]] = !DILocation(line: 0, scope: [[MSG:![0-9]+]], {{.+}})
-// CHECK: [[MSG]] = distinct !DISubprogram(name: "__clang_trap_msg$Undefined Behavior Sanitizer$Integer divide or remainder overflowed"
+// SIO-LABEL: @div_rem_overflow
+// SIO: call void @llvm.ubsantrap(i8 3) {{.*}}!dbg [[LOC:![0-9]+]]
+// SIO: [[LOC]] = !DILocation(line: 0, scope: [[MSG:![0-9]+]], {{.+}})
+// SIO: [[MSG]] = distinct !DISubprogram(name: "__clang_trap_msg$Undefined Behavior Sanitizer$Signed integer division overflow on type 'int'"
+
+// DBZ-LABEL: @div_rem_overflow
+// DBZ: call void @llvm.ubsantrap(i8 3) {{.*}}!dbg [[LOC:![0-9]+]]
+// DBZ: [[LOC]] = !DILocation(line: 0, scope: [[MSG:![0-9]+]], {{.+}})
+// DBZ: [[MSG]] = distinct !DISubprogram(name: "__clang_trap_msg$Undefined Behavior Sanitizer$Division by zero on type 'int'"
diff --git a/clang/test/CodeGen/ubsan-trap-reason-flag.c b/clang/test/CodeGen/ubsan-trap-reason-flag.c
index 5cc16d154bf68..94f529c1566a9 100644
--- a/clang/test/CodeGen/ubsan-trap-reason-flag.c
+++ b/clang/test/CodeGen/ubsan-trap-reason-flag.c
@@ -15,7 +15,7 @@ int add_overflow(int a, int b) { return a + b; }
// ANNOTATE-LABEL: @add_overflow
// ANNOTATE: call void @llvm.ubsantrap(i8 0) {{.*}}!dbg [[LOC:![0-9]+]]
// ANNOTATE: [[LOC]] = !DILocation(line: 0, scope: [[MSG:![0-9]+]], {{.+}})
-// ANNOTATE: [[MSG]] = distinct !DISubprogram(name: "__clang_trap_msg$Undefined Behavior Sanitizer$Integer addition overflowed"
+// ANNOTATE: [[MSG]] = distinct !DISubprogram(name: "__clang_trap_msg$Undefined Behavior Sanitizer$Signed integer addition overflow on type 'int'"
// NO-ANNOTATE-LABEL: @add_overflow
// NO-ANNOTATE: call void @llvm.ubsantrap(i8 0) {{.*}}!dbg [[LOC:![0-9]+]]
diff --git a/clang/test/CodeGen/ubsan-trap-reason-float-cast-overflow.c b/clang/test/CodeGen/ubsan-trap-reason-float-cast-overflow.c
index 079a191e05d4b..d7d26fa692175 100644
--- a/clang/test/CodeGen/ubsan-trap-reason-float-cast-overflow.c
+++ b/clang/test/CodeGen/ubsan-trap-reason-float-cast-overflow.c
@@ -6,4 +6,4 @@ int float_cast_overflow(float x) { return (int)x; }
// CHECK-LABEL: @float_cast_overflow
// CHECK: call void @llvm.ubsantrap(i8 5) {{.*}}!dbg [[LOC:![0-9]+]]
// CHECK: [[LOC]] = !DILocation(line: 0, scope: [[MSG:![0-9]+]], {{.+}})
-// CHECK: [[MSG]] = distinct !DISubprogram(name: "__clang_trap_msg$Undefined Behavior Sanitizer$Floating-point to integer conversion overflowed"
+// CHECK: [[MSG]] = distinct !DISubprogram(name: "__clang_trap_msg$Undefined Behavior Sanitizer$Float cast overflow converting from floating-point type 'float' to integer type 'int'"
diff --git a/clang/test/CodeGen/ubsan-trap-reason-function-type-mismatch.c b/clang/test/CodeGen/ubsan-trap-reason-function-type-mismatch.c
index 1727f9c092a4c..6808dcf2a654f 100644
--- a/clang/test/CodeGen/ubsan-trap-reason-function-type-mismatch.c
+++ b/clang/test/CodeGen/ubsan-trap-reason-function-type-mismatch.c
@@ -15,4 +15,4 @@ int function_type_mismatch(void) {
// CHECK-LABEL: @function_type_mismatch
// CHECK: call void @llvm.ubsantrap(i8 6) {{.*}}!dbg [[LOC:![0-9]+]]
// CHECK: [[LOC]] = !DILocation(line: 0, scope: [[MSG:![0-9]+]], {{.+}})
-// CHECK: [[MSG]] = distinct !DISubprogram(name: "__clang_trap_msg$Undefined Behavior Sanitizer$Function called with mismatched signature"
+// CHECK: [[MSG]] = distinct !DISubprogram(name: "__clang_trap_msg$Undefined Behavior Sanitizer$Call through function pointer of type 'int (int)' with an incompatible target"
diff --git a/clang/test/CodeGen/ubsan-trap-reason-implicit-conversion.c b/clang/test/CodeGen/ubsan-trap-reason-implicit-conversion.c
index 43c091d51a5c2..ae4caabbc6abf 100644
--- a/clang/test/CodeGen/ubsan-trap-reason-implicit-conversion.c
+++ b/clang/test/CodeGen/ubsan-trap-reason-implicit-conversion.c
@@ -1,11 +1,43 @@
-// RUN: %clang_cc1 -triple arm64-apple-macosx14.0.0 -O0 -debug-info-kind=standalone -dwarf-version=5 \
-// RUN: -fsanitize=implicit-unsigned-integer-truncation -fsanitize-trap=implicit-unsigned-integer-truncation -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -triple arm64-apple-macosx14.0.0 -O0 -debug-info-kind=standalone -dwarf-version=5 -fsanitize=implicit-signed-integer-truncation \
+// RUN: -fsanitize-trap=implicit-signed-integer-truncation -emit-llvm %s -o - | FileCheck %s --check-prefix=SIC
-unsigned long long big;
+long long signedBig;
-unsigned implicit_conversion(void) { return big; }
+int signed_implicit_conversion_truncation(void) { return signedBig; }
-// CHECK-LABEL: @implicit_conversion
-// CHECK: call void @llvm.ubsantrap(i8 7) {{.*}}!dbg [[LOC:![0-9]+]]
-// CHECK: [[LOC]] = !DILocation(line: 0, scope: [[MSG:![0-9]+]], {{.+}})
-// CHECK: [[MSG]] = distinct !DISubprogram(name: "__clang_trap_msg$Undefined Behavior Sanitizer$Implicit integer conversion overflowed or lost data"
+// SIC-LABEL: @signed_implicit_conversion_truncation
+// SIC: call void @llvm.ubsantrap(i8 7) {{.*}}!dbg [[LOC:![0-9]+]]
+// SIC: [[LOC]] = !DILocation(line: 0, scope: [[MSG:![0-9]+]], {{.+}})
+// SIC: [[MSG]] = distinct !DISubprogram(name: "__clang_trap_msg$Undefined Behavior Sanitizer$Implicit signed conversion from 'long long' to 'int' caused truncation"
+
+// RUN: %clang_cc1 -triple arm64-apple-macosx14.0.0 -O0 -debug-info-kind=standalone -dwarf-version=5 -fsanitize=implicit-unsigned-integer-truncation \
+// RUN: -fsanitize-trap=implicit-unsigned-integer-truncation -emit-llvm %s -o - | FileCheck %s --check-prefix=UIC
+
+unsigned long long unsignedBig;
+
+unsigned unsigned_implicit_conversion_truncation(void) { return unsignedBig; }
+
+// UIC-LABEL: @unsigned_implicit_conversion_truncation
+// UIC: call void @llvm.ubsantrap(i8 7) {{.*}}!dbg [[LOC:![0-9]+]]
+// UIC: [[LOC]] = !DILocation(line: 0, scope: [[MSG:![0-9]+]], {{.+}})
+// UIC: [[MSG]] = distinct !DISubprogram(name: "__clang_trap_msg$Undefined Behavior Sanitizer$Implicit unsigned conversion from 'unsigned long long' to 'unsigned int' caused truncation"
+
+// RUN: %clang_cc1 -triple arm64-apple-macosx14.0.0 -O0 -debug-info-kind=standalone -dwarf-version=5 -fsanitize=implicit-integer-sign-change \
+// RUN: -fsanitize-trap=implicit-integer-sign-change -emit-llvm %s -o - | FileCheck %s --check-prefix=ISCUFS
+
+unsigned to_unsigned_from_signed(int x) { return x; }
+
+// ISCUFS-LABEL: @to_unsigned_from_signed
+// ISCUFS: call void @llvm.ubsantrap(i8 7) {{.*}}!dbg [[LOC1:![0-9]+]]
+// ISCUFS: [[LOC1]] = !DILocation(line: 0, scope: [[MSG1:![0-9]+]], {{.+}})
+// ISCUFS: [[MSG1]] = distinct !DISubprogram(name: "__clang_trap_msg$Undefined Behavior Sanitizer$Implicit conversion from 'int' to 'unsigned int' caused sign-change"
+
+// RUN: %clang_cc1 -triple arm64-apple-macosx14.0.0 -O0 -debug-info-kind=standalone -dwarf-version=5 -fsanitize=implicit-integer-sign-change \
+// RUN: -fsanitize-trap=implicit-integer-sign-change -emit-llvm %s -o - | FileCheck %s --check-prefix=ISCSFU
+
+int to_signed_from_unsigned(unsigned x) { return x; }
+
+// ISCSFU-LABEL: @to_signed_from_unsigned
+// ISCSFU: call void @llvm.ubsantrap(i8 7) {{.*}}!dbg [[LOC2:![0-9]+]]
+// ISCSFU: [[LOC2]] = !DILocation(line: 0, scope: [[MSG2:![0-9]+]], {{.+}})
+// ISCSFU: [[MSG2]] = distinct !DISubprogram(name: "__clang_trap_msg$Undefined Behavior Sanitizer$Implicit conversion from 'unsigned int' to 'int' caused sign-change"
diff --git a/clang/test/CodeGen/ubsan-trap-reason-mul-overflow.c b/clang/test/CodeGen/ubsan-trap-reason-mul-overflow.c
index cf9a0b4e7439c..6b86527087f88 100644
--- a/clang/test/CodeGen/ubsan-trap-reason-mul-overflow.c
+++ b/clang/test/CodeGen/ubsan-trap-reason-mul-overflow.c
@@ -1,9 +1,19 @@
// RUN: %clang_cc1 -triple arm64-apple-macosx14.0.0 -O0 -debug-info-kind=standalone -dwarf-version=5 \
-// RUN: -fsanitize=signed-integer-overflow -fsanitize-trap=signed-integer-overflow -emit-llvm %s -o - | FileCheck %s
+// RUN: -fsanitize=signed-integer-overflow -fsanitize-trap=signed-integer-overflow -emit-llvm %s -o - | FileCheck %s --check-prefix=SIO
-int mul_overflow(int a, int b) { return a * b; }
+int signed_mul_overflow(int a, int b) { return a * b; }
-// CHECK-LABEL: @mul_overflow
-// CHECK: call void @llvm.ubsantrap(i8 12) {{.*}}!dbg [[LOC:![0-9]+]]
-// CHECK: [[LOC]] = !DILocation(line: 0, scope: [[MSG:![0-9]+]], {{.+}})
-// CHECK: [[MSG]] = distinct !DISubprogram(name: "__clang_trap_msg$Undefined Behavior Sanitizer$Integer multiplication overflowed"
+// SIO-LABEL: @signed_mul_overflow
+// SIO: call void @llvm.ubsantrap(i8 12) {{.*}}!dbg [[LOC:![0-9]+]]
+// SIO: [[LOC]] = !DILocation(line: 0, scope: [[MSG:![0-9]+]], {{.+}})
+// SIO: [[MSG]] = distinct !DISubprogram(name: "__clang_trap_msg$Undefined Behavior Sanitizer$Signed integer multiplication overflow on type 'int'"
+
+// RUN: %clang_cc1 -triple arm64-apple-macosx14.0.0 -O0 -debug-info-kind=standalone -dwarf-version=5 \
+// RUN: -fsanitize=unsigned-integer-overflow -fsanitize-trap=unsigned-integer-overflow -emit-llvm %s -o - | FileCheck %s --check-prefix=UIO
+
+unsigned unsigned_mul_overflow(unsigned a, unsigned b) { return a * b; }
+
+// UIO-LABEL: @unsigned_mul_overflow
+// UIO: call void @llvm.ubsantrap(i8 12) {{.*}}!dbg [[LOC:![0-9]+]]
+// UIO: [[LOC]] = !DILocation(line: 0, scope: [[MSG:![0-9]+]], {{.+}})
+// UIO: [[MSG]] = distinct !DISubprogram(name: "__clang_trap_msg$Undefined Behavior Sanitizer$Unsigned integer multiplication overflow on type 'unsigned int'"
diff --git a/clang/test/CodeGen/ubsan-trap-reason-negate-overflow.c b/clang/test/CodeGen/ubsan-trap-reason-negate-overflow.c
index 55346794b2928..76302b95ca8df 100644
--- a/clang/test/CodeGen/ubsan-trap-reason-negate-overflow.c
+++ b/clang/test/CodeGen/ubsan-trap-reason-negate-overflow.c
@@ -9,4 +9,4 @@ int negate_overflow() {
// CHECK-LABEL: @negate_overflow
// CHECK: call void @llvm.ubsantrap(i8 13) {{.*}}!dbg [[LOC:![0-9]+]]
// CHECK: [[LOC]] = !DILocation(line: 0, scope: [[MSG:![0-9]+]], {{.+}})
-// CHECK: [[MSG]] = distinct !DISubprogram(name: "__clang_trap_msg$Undefined Behavior Sanitizer$Integer negation overflowed"
+// CHECK: [[MSG]] = distinct !DISubprogram(name: "__clang_trap_msg$Undefined Behavior Sanitizer$Integer negation overflow on type 'int'"
diff --git a/clang/test/CodeGen/ubsan-trap-reason-shift-out-of-bounds.c b/clang/test/CodeGen/ubsan-trap-reason-shift-out-of-bounds.c
index 1a7465d93aef5..eed4eb411c3da 100644
--- a/clang/test/CodeGen/ubsan-trap-reason-shift-out-of-bounds.c
+++ b/clang/test/CodeGen/ubsan-trap-reason-shift-out-of-bounds.c
@@ -1,12 +1,25 @@
// RUN: %clang_cc1 -triple arm64-apple-macosx14.0.0 -O0 -debug-info-kind=standalone -dwarf-version=5 \
-// RUN: -fsanitize=shift-base -fsanitize-trap=shift-base -emit-llvm %s -o - | FileCheck %s
+// RUN: -fsanitize=shift-exponent -fsanitize-trap=shift-exponent -emit-llvm %s -o - | FileCheck %s --check-prefix=RS
-int shift_out_of_bounds(void) {
+int right_shift_out_of_bounds(void) {
+ int sh = 32;
+ return 1 >> sh;
+}
+
+// RS-LABEL: @right_shift_out_of_bounds
+// RS: call void @llvm.ubsantrap(i8 20) {{.*}}!dbg [[LOC:![0-9]+]]
+// RS: [[LOC]] = !DILocation(line: 0, scope: [[MSG:![0-9]+]], {{.+}})
+// RS: [[MSG]] = distinct !DISubprogram(name: "__clang_trap_msg$Undefined Behavior Sanitizer$Right shift is too large for 32-bit type 'int'"
+
+// RUN: %clang_cc1 -triple arm64-apple-macosx14.0.0 -O0 -debug-info-kind=standalone -dwarf-version=5 \
+// RUN: -fsanitize=shift-exponent -fsanitize-trap=shift-exponent -emit-llvm %s -o - | FileCheck %s --check-prefix=LS
+
+int left_shift_out_of_bounds(void) {
int sh = 32;
return 1 << sh;
}
-// CHECK-LABEL: @shift_out_of_bounds
-// CHECK: call void @llvm.ubsantrap(i8 20) {{.*}}!dbg [[LOC:![0-9]+]]
-// CHECK: [[LOC]] = !DILocation(line: 0, scope: [[MSG:![0-9]+]], {{.+}})
-// CHECK: [[MSG]] = distinct !DISubprogram(name: "__clang_trap_msg$Undefined Behavior Sanitizer$Shift exponent is too large for the type"
+// LS-LABEL: @left_shift_out_of_bounds
+// LS: call void @llvm.ubsantrap(i8 20) {{.*}}!dbg [[LOC:![0-9]+]]
+// LS: [[LOC]] = !DILocation(line: 0, scope: [[MSG:![0-9]+]], {{.+}})
+// LS: [[MSG]] = distinct !DISubprogram(name: "__clang_trap_msg$Undefined Behavior Sanitizer$Left shift is too large for 32-bit type 'int'"
diff --git a/clang/test/CodeGen/ubsan-trap-reason-sub-overflow.c b/clang/test/CodeGen/ubsan-trap-reason-sub-overflow.c
index 62aa7fc953dad..4eddc9d5fee08 100644
--- a/clang/test/CodeGen/ubsan-trap-reason-sub-overflow.c
+++ b/clang/test/CodeGen/ubsan-trap-reason-sub-overflow.c
@@ -1,9 +1,19 @@
// RUN: %clang_cc1 -triple arm64-apple-macosx14.0.0 -O0 -debug-info-kind=standalone -dwarf-version=5 \
-// RUN: -fsanitize=signed-integer-overflow -fsanitize-trap=signed-integer-overflow -emit-llvm %s -o - | FileCheck %s
+// RUN: -fsanitize=signed-integer-overflow -fsanitize-trap=signed-integer-overflow -emit-llvm %s -o - | FileCheck %s --check-prefix=SIO
-int sub_overflow(int a, int b) { return a - b; }
+int signed_sub_overflow(int a, int b) { return a - b; }
-// CHECK-LABEL: @sub_overflow
-// CHECK: call void @llvm.ubsantrap(i8 21) {{.*}}!dbg [[LOC:![0-9]+]]
-// CHECK: [[LOC]] = !DILocation(line: 0, scope: [[MSG:![0-9]+]], {{.+}})
-// CHECK: [[MSG]] = distinct !DISubprogram(name: "__clang_trap_msg$Undefined Behavior Sanitizer$Integer subtraction overflowed"
+// SIO-LABEL: @signed_sub_overflow
+// SIO: call void @llvm.ubsantrap(i8 21) {{.*}}!dbg [[LOC:![0-9]+]]
+// SIO: [[LOC]] = !DILocation(line: 0, scope: [[MSG:![0-9]+]], {{.+}})
+// SIO: [[MSG]] = distinct !DISubprogram(name: "__clang_trap_msg$Undefined Behavior Sanitizer$Signed integer subtraction overflow on type 'int'"
+
+// RUN: %clang_cc1 -triple arm64-apple-macosx14.0.0 -O0 -debug-info-kind=standalone -dwarf-version=5 \
+// RUN: -fsanitize=unsigned-integer-overflow -fsanitize-trap=unsigned-integer-overflow -emit-llvm %s -o - | FileCheck %s --check-prefix=UIO
+
+unsigned int unsigned_sub_overflow(unsigned int a, unsigned int b) { return a - b; }
+
+// UIO-LABEL: @unsigned_sub_overflow
+// UIO: call void @llvm.ubsantrap(i8 21) {{.*}}!dbg [[LOC:![0-9]+]]
+// UIO: [[LOC]] = !DILocation(line: 0, scope: [[MSG:![0-9]+]], {{.+}})
+// UIO: [[MSG]] = distinct !DISubprogram(name: "__clang_trap_msg$Undefined Behavior Sanitizer$Unsigned integer subtraction overflow on type 'unsigned int'"
More information about the cfe-commits
mailing list