-
Notifications
You must be signed in to change notification settings - Fork 15.2k
[Clang][CodeGen][Sanitizers] Add extra context for trap messages #153845
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
[Clang][CodeGen][Sanitizers] Add extra context for trap messages #153845
Conversation
|
@llvm/pr-subscribers-clang-codegen @llvm/pr-subscribers-clang Author: Anthony Tran (anthonyhatran) ChangesServes as an improvement to the current Part of a GSoC 2025 Project. Patch is 34.54 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/153845.diff 13 Files Affected:
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 ...
[truncated]
|
|
@delcypher @Michael137 I've added additional context to the SanitizerHandlers that were discussed, but I am open to adding more context to other handlers if any are spotted. I also still need to remove some stray headers since some are unused. May need to also remove the hard-coded strings inside Just realized I missed BoundsSafety, so I'll add it in next commit (empty string). |
Serves as an improvement to the current
-fsanitize-debug-trap-reasonsby providing additional context to the user regarding the trap reason.Part of a GSoC 2025 Project.