-
Notifications
You must be signed in to change notification settings - Fork 13.9k
[clang][CodeGen] Added SanitizerHandler mapping, trap messages in debug info, and corresponding test cases. #143758
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?
Conversation
Thank you for submitting a Pull Request (PR) to the LLVM Project! This PR will be automatically labeled and the relevant teams will be notified. If you wish to, you can add reviewers by using the "Reviewers" section on this page. If this is not working for you, it is probably because you do not have write permissions for the repository. In which case you can instead tag reviewers by name in a comment by using If you have received no comments on your PR for a week, you can request a review by "ping"ing the PR by adding a comment “Ping”. The common courtesy "ping" rate is once a week. Please remember that you are asking for valuable time from other developers. If you have further questions, they may be answered by the LLVM GitHub User Guide. You can also ask questions in a comment on this PR, on the LLVM Discord or on the forums. |
@llvm/pr-subscribers-clang-codegen @llvm/pr-subscribers-clang Author: None (anthonyhatran) ChangesGSoC 2025 Ran the clang test suite before and after changes, and some (~5) test cases failed: Still need to modify the hard-coded strings after further discussion Patch is 21.80 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/143758.diff 22 Files Affected:
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index 6cb348ffdf55f..9100ef80c13f4 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -85,6 +85,98 @@ enum VariableTypeDescriptorKind : uint16_t {
// Miscellaneous Helper Methods
//===--------------------------------------------------------------------===//
+static llvm::StringRef GetTrapMessageForHandler(SanitizerHandler ID) {
+ switch (ID) {
+ case SanitizerHandler::AddOverflow:
+ return "The addition of two signed integers resulted in overflow.";
+
+ case SanitizerHandler::BuiltinUnreachable:
+ return "_builtin_unreachable encountered.";
+
+ case SanitizerHandler::CFICheckFail:
+ return "Control flow integrity check failed.";
+
+ case SanitizerHandler::DivremOverflow: // Unsure
+ return "stub";
+
+ case SanitizerHandler::DynamicTypeCacheMiss: // Unsure
+ return "Data requested for dynamic type not found in cache memory.";
+
+ case SanitizerHandler::FloatCastOverflow: // Pasted from LLVM docs, maybe
+ // something better to put here.
+ return "Conversion to, from, or between floating-point types which would "
+ "overflow the destination.";
+
+ case SanitizerHandler::FunctionTypeMismatch:
+ return "Function called with arguments of a different data type than "
+ "expected";
+
+ case SanitizerHandler::ImplicitConversion:
+ return "Implicit conversion occurred.";
+
+ case SanitizerHandler::InvalidBuiltin:
+ return "Built-in function or keyword not recognized.";
+
+ case SanitizerHandler::InvalidObjCCast:
+ return "Invalid Objective-C cast.";
+
+ case SanitizerHandler::LoadInvalidValue:
+ return "stub";
+
+ case SanitizerHandler::MissingReturn:
+ return "Function is missing a return.";
+
+ case SanitizerHandler::MulOverflow:
+ return "The multiplication of two signed integers resulted in overflow.";
+
+ case SanitizerHandler::NegateOverflow:
+ return "Underflow/negative overflow occurred.";
+
+ case SanitizerHandler::
+ NullabilityArg: // Next 4 pasted from
+ // https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html
+ return "Passing null as a function parameter 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 as a function parameter which is declared to never be "
+ "null";
+
+ case SanitizerHandler::NonnullReturn:
+ return "Returning null pointer from a function which is declared to never "
+ "be null";
+
+ case SanitizerHandler::OutOfBounds:
+ return "Out of bounds -- memory accessed outside of expected boundaries.";
+
+ case SanitizerHandler::PointerOverflow:
+ return "stub";
+
+ case SanitizerHandler::ShiftOutOfBounds:
+ return "Bit shift attempted to move bits beyond boundaries of data type's "
+ "bit size.";
+
+ case SanitizerHandler::SubOverflow:
+ return "The subtraction of two signed integers resulted in overflow.";
+
+ case SanitizerHandler::TypeMismatch:
+ return "Type mismatch -- value type used does not match type expected.";
+
+ case SanitizerHandler::AlignmentAssumption: // Help on bottom 2
+ return "stub";
+
+ case SanitizerHandler::VLABoundNotPositive:
+ return "stub";
+
+ default:
+ return "";
+ }
+}
+
/// CreateTempAlloca - This creates a alloca and inserts it into the entry
/// block.
RawAddress
@@ -4041,7 +4133,8 @@ void CodeGenFunction::EmitUnreachable(SourceLocation Loc) {
void CodeGenFunction::EmitTrapCheck(llvm::Value *Checked,
SanitizerHandler CheckHandlerID,
- bool NoMerge) {
+ bool NoMerge, StringRef Annotation,
+ StringRef TrapMessage) {
llvm::BasicBlock *Cont = createBasicBlock("cont");
// If we're optimizing, collapse all calls to trap down to just one per
@@ -4051,6 +4144,14 @@ void CodeGenFunction::EmitTrapCheck(llvm::Value *Checked,
llvm::BasicBlock *&TrapBB = TrapBBs[CheckHandlerID];
+ llvm::DILocation *TrapLocation = Builder.getCurrentDebugLocation();
+ llvm::StringRef Category = GetTrapMessageForHandler(CheckHandlerID);
+
+ if (getDebugInfo() && !Category.empty()) {
+ TrapLocation = getDebugInfo()->CreateTrapFailureMessageFor(
+ TrapLocation, Category, TrapMessage);
+ }
+
NoMerge = NoMerge || !CGM.getCodeGenOpts().OptimizationLevel ||
(CurCodeDecl && CurCodeDecl->hasAttr<OptimizeNoneAttr>());
@@ -4059,8 +4160,16 @@ void CodeGenFunction::EmitTrapCheck(llvm::Value *Checked,
auto Call = TrapBB->begin();
assert(isa<llvm::CallInst>(Call) && "Expected call in trap BB");
- Call->applyMergedLocation(Call->getDebugLoc(),
- Builder.getCurrentDebugLocation());
+ // Call->applyMergedLocation(Call->getDebugLoc(),
+ // Builder.getCurrentDebugLocation());
+ Call->applyMergedLocation(Call->getDebugLoc(), TrapLocation);
+
+ auto Unreachable = ++TrapBB->begin();
+ if (isa<llvm::UnreachableInst>(Unreachable)) {
+ Unreachable->applyMergedLocation(Unreachable->getDebugLoc(),
+ TrapLocation);
+ }
+
Builder.CreateCondBr(Checked, Cont, TrapBB,
MDHelper.createLikelyBranchWeights());
} else {
@@ -4069,6 +4178,8 @@ void CodeGenFunction::EmitTrapCheck(llvm::Value *Checked,
MDHelper.createLikelyBranchWeights());
EmitBlock(TrapBB);
+ ApplyDebugLocation applyTrapDI(*this, TrapLocation);
+
llvm::CallInst *TrapCall =
Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::ubsantrap),
llvm::ConstantInt::get(CGM.Int8Ty, CheckHandlerID));
diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h
index a5ab9df01dba9..aa9c862511579 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -5281,7 +5281,8 @@ 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, StringRef Annotation = "",
+ StringRef TrapMessage = "");
/// 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
new file mode 100644
index 0000000000000..822a1c003d16a
--- /dev/null
+++ b/clang/test/CodeGen/ubsan-trap-reason-add-overflow.c
@@ -0,0 +1,10 @@
+// RUN: %clang -O0 -g -debug-info-kind=standalone -dwarf-version=5 -fsanitize=undefined \
+// RUN: -fsanitize-trap=undefined -emit-llvm -S -c %s -o - | FileCheck %s
+
+int add_overflow(int a, int b) {
+ return a + b;
+}
+
+// CHECK: call void @llvm.ubsantrap(i8 0) {{.*}}!dbg [[LOC:![0-9]+]]
+// CHECK: [[LOC]] = !DILocation(line: 0, scope: [[MSG:![0-9]+]], {{.+}})
+// CHECK: distinct !DISubprogram(name: "__clang_trap_msg$
diff --git a/clang/test/CodeGen/ubsan-trap-reason-builtin-unreachable.c b/clang/test/CodeGen/ubsan-trap-reason-builtin-unreachable.c
new file mode 100644
index 0000000000000..ada4c372a92b7
--- /dev/null
+++ b/clang/test/CodeGen/ubsan-trap-reason-builtin-unreachable.c
@@ -0,0 +1,12 @@
+// RUN: %clang -O0 -g -debug-info-kind=standalone -dwarf-version=5 -fsanitize=unreachable \
+// RUN: -fsanitize-trap=unreachable -emit-llvm -S -c %s -o - | FileCheck %s
+
+int call_builtin_unreachable()
+{
+ __builtin_unreachable();
+}
+
+
+// CHECK: call void @llvm.ubsantrap(i8 1) {{.*}}!dbg [[LOC:![0-9]+]]
+// CHECK: [[LOC]] = !DILocation(line: 0, scope: [[MSG:![0-9]+]], {{.+}})
+// CHECK: distinct !DISubprogram(name: "__clang_trap_msg$
\ No newline at end of file
diff --git a/clang/test/CodeGen/ubsan-trap-reason-div-rem-overflow.c b/clang/test/CodeGen/ubsan-trap-reason-div-rem-overflow.c
new file mode 100644
index 0000000000000..17b6dca16cc62
--- /dev/null
+++ b/clang/test/CodeGen/ubsan-trap-reason-div-rem-overflow.c
@@ -0,0 +1,10 @@
+// RUN: %clang -O0 -g -debug-info-kind=standalone -dwarf-version=5 -fsanitize=undefined \
+// RUN: -fsanitize-trap=undefined -emit-llvm -S -c %s -o - | FileCheck %s
+
+int div_rem_overflow(int a, int b) {
+ return a / b;
+}
+
+// CHECK: call void @llvm.ubsantrap(i8 3) {{.*}}!dbg [[LOC:![0-9]+]]
+// CHECK: [[LOC]] = !DILocation(line: 0, scope: [[MSG:![0-9]+]], {{.+}})
+// CHECK: distinct !DISubprogram(name: "__clang_trap_msg$
diff --git a/clang/test/CodeGen/ubsan-trap-reason-float-cast-overflow.c b/clang/test/CodeGen/ubsan-trap-reason-float-cast-overflow.c
new file mode 100644
index 0000000000000..b761e638c5293
--- /dev/null
+++ b/clang/test/CodeGen/ubsan-trap-reason-float-cast-overflow.c
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -O0 -debug-info-kind=standalone -dwarf-version=5 -fsanitize=float-cast-overflow \
+// RUN: -fsanitize-trap=float-cast-overflow -emit-llvm %s -o - | FileCheck %s
+
+int f(float x) {
+ return (int)x;
+}
+
+// CHECK: call void @llvm.ubsantrap(i8 5) {{.*}}!dbg [[LOC:![0-9]+]]
+// CHECK: [[LOC]] = !DILocation(line: 0, scope: [[MSG:![0-9]+]], {{.+}})
+// CHECK: distinct !DISubprogram(name: "__clang_trap_msg$
\ No newline at end of file
diff --git a/clang/test/CodeGen/ubsan-trap-reason-function-type-mismatch.c b/clang/test/CodeGen/ubsan-trap-reason-function-type-mismatch.c
new file mode 100644
index 0000000000000..25063b69a894c
--- /dev/null
+++ b/clang/test/CodeGen/ubsan-trap-reason-function-type-mismatch.c
@@ -0,0 +1,16 @@
+// RUN: %clang -O0 -g -debug-info-kind=standalone -dwarf-version=5 -fsanitize=undefined \
+// RUN: -fsanitize-trap=undefined -emit-llvm -S -c %s -o - | FileCheck %s
+
+void target() { }
+
+int function_type_mismatch() {
+ int (*fp_int)(int);
+
+ fp_int = (int (*)(int))(void *)target;
+
+ return fp_int(42);
+}
+
+// CHECK: call void @llvm.ubsantrap(i8 6) {{.*}}!dbg [[LOC:![0-9]+]]
+// CHECK: [[LOC]] = !DILocation(line: 0, scope: [[MSG:![0-9]+]], {{.+}})
+// CHECK: distinct !DISubprogram(name: "__clang_trap_msg$
\ No newline at end of file
diff --git a/clang/test/CodeGen/ubsan-trap-reason-implicit-conversion.c b/clang/test/CodeGen/ubsan-trap-reason-implicit-conversion.c
new file mode 100644
index 0000000000000..48eb86d09b51a
--- /dev/null
+++ b/clang/test/CodeGen/ubsan-trap-reason-implicit-conversion.c
@@ -0,0 +1,13 @@
+// RUN: %clang -O0 -g -debug-info-kind=standalone -dwarf-version=5 -fsanitize=implicit-conversion \
+// RUN: -fsanitize-trap=implicit-conversion -emit-llvm -S -c %s -o - | FileCheck %s
+
+unsigned long long big;
+
+unsigned implicit_conversion()
+{
+ return big;
+}
+
+// CHECK: call void @llvm.ubsantrap(i8 7) {{.*}}!dbg [[LOC:![0-9]+]]
+// CHECK: [[LOC]] = !DILocation(line: 0, scope: [[MSG:![0-9]+]], {{.+}})
+// CHECK: distinct !DISubprogram(name: "__clang_trap_msg$
\ No newline at end of file
diff --git a/clang/test/CodeGen/ubsan-trap-reason-invalid-builtin.c b/clang/test/CodeGen/ubsan-trap-reason-invalid-builtin.c
new file mode 100644
index 0000000000000..cd136df2f0ed4
--- /dev/null
+++ b/clang/test/CodeGen/ubsan-trap-reason-invalid-builtin.c
@@ -0,0 +1,12 @@
+// RUN: %clang -O0 -g -debug-info-kind=standalone -dwarf-version=5 -fsanitize=builtin \
+// RUN: -fsanitize-trap=builtin -emit-llvm -S -c %s -o - | FileCheck %s
+
+unsigned invalid_builtin(unsigned x)
+{
+ return __builtin_clz(x);
+}
+
+
+// CHECK: call void @llvm.ubsantrap(i8 8) {{.*}}!dbg [[LOC:![0-9]+]]
+// CHECK: [[LOC]] = !DILocation(line: 0, scope: [[MSG:![0-9]+]], {{.+}})
+// CHECK: distinct !DISubprogram(name: "__clang_trap_msg$
\ No newline at end of file
diff --git a/clang/test/CodeGen/ubsan-trap-reason-load-invalid-value.c b/clang/test/CodeGen/ubsan-trap-reason-load-invalid-value.c
new file mode 100644
index 0000000000000..09d8d588f0a32
--- /dev/null
+++ b/clang/test/CodeGen/ubsan-trap-reason-load-invalid-value.c
@@ -0,0 +1,15 @@
+// RUN: %clang -O0 -g -debug-info-kind=standalone -dwarf-version=5 -fsanitize=undefined \
+// RUN: -fsanitize-trap=undefined -emit-llvm -S -c %s -o - | FileCheck %s
+#include <stdbool.h>
+
+unsigned char bad_byte;
+
+bool load_invalid_value()
+{
+ return *((bool *)&bad_byte);
+}
+
+
+// CHECK: call void @llvm.ubsantrap(i8 10) {{.*}}!dbg [[LOC:![0-9]+]]
+// CHECK: [[LOC]] = !DILocation(line: 0, scope: [[MSG:![0-9]+]], {{.+}})
+// CHECK: distinct !DISubprogram(name: "__clang_trap_msg$
\ No newline at end of file
diff --git a/clang/test/CodeGen/ubsan-trap-reason-missing-return.cpp b/clang/test/CodeGen/ubsan-trap-reason-missing-return.cpp
new file mode 100644
index 0000000000000..7f0265abd2305
--- /dev/null
+++ b/clang/test/CodeGen/ubsan-trap-reason-missing-return.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang -O0 -g -debug-info-kind=standalone -dwarf-version=5 -fsanitize=return \
+// RUN: -fsanitize-trap=return -emit-llvm -S -c %s -o - | FileCheck %s
+
+int missing_return(int x)
+{
+ if (x > 0)
+ return x;
+}
+
+// CHECK: call void @llvm.ubsantrap(i8 11) {{.*}}!dbg [[LOC:![0-9]+]]
+// CHECK: [[LOC]] = !DILocation(line: 0, scope: [[MSG:![0-9]+]], {{.+}})
+// CHECK: distinct !DISubprogram(name: "__clang_trap_msg$
\ No newline at end of file
diff --git a/clang/test/CodeGen/ubsan-trap-reason-mul-overflow.c b/clang/test/CodeGen/ubsan-trap-reason-mul-overflow.c
new file mode 100644
index 0000000000000..e9f76b87455c9
--- /dev/null
+++ b/clang/test/CodeGen/ubsan-trap-reason-mul-overflow.c
@@ -0,0 +1,10 @@
+// RUN: %clang -O0 -g -debug-info-kind=standalone -dwarf-version=5 -fsanitize=undefined \
+// RUN: -fsanitize-trap=undefined -emit-llvm -S -c %s -o - | FileCheck %s
+
+int mul_overflow(int a, int b) {
+ return a * b;
+}
+
+// CHECK: call void @llvm.ubsantrap(i8 12) {{.*}}!dbg [[LOC:![0-9]+]]
+// CHECK: [[LOC]] = !DILocation(line: 0, scope: [[MSG:![0-9]+]], {{.+}})
+// CHECK: distinct !DISubprogram(name: "__clang_trap_msg$
diff --git a/clang/test/CodeGen/ubsan-trap-reason-negate-overflow.c b/clang/test/CodeGen/ubsan-trap-reason-negate-overflow.c
new file mode 100644
index 0000000000000..5660c6bb08d03
--- /dev/null
+++ b/clang/test/CodeGen/ubsan-trap-reason-negate-overflow.c
@@ -0,0 +1,12 @@
+// RUN: %clang -O0 -g -debug-info-kind=standalone -dwarf-version=5 -fsanitize=undefined \
+// RUN: -fsanitize-trap=undefined -emit-llvm -S -c %s -o - | FileCheck %s
+
+int negate_overflow()
+{
+ int x;
+ return -x;
+}
+
+// CHECK: call void @llvm.ubsantrap(i8 13) {{.*}}!dbg [[LOC:![0-9]+]]
+// CHECK: [[LOC]] = !DILocation(line: 0, scope: [[MSG:![0-9]+]], {{.+}})
+// CHECK: distinct !DISubprogram(name: "__clang_trap_msg$
\ No newline at end of file
diff --git a/clang/test/CodeGen/ubsan-trap-reason-nonnull-arg.c b/clang/test/CodeGen/ubsan-trap-reason-nonnull-arg.c
new file mode 100644
index 0000000000000..e648f91b86b27
--- /dev/null
+++ b/clang/test/CodeGen/ubsan-trap-reason-nonnull-arg.c
@@ -0,0 +1,17 @@
+// RUN: %clang -O0 -g -debug-info-kind=standalone -dwarf-version=5 -fsanitize=nonnull-attribute \
+// RUN: -fsanitize-trap=nonnull-attribute -emit-llvm -S -c %s -o - | FileCheck %s
+
+__attribute__((nonnull))
+void nonnull_arg(int *p) {
+ (void)p;
+}
+
+void trigger_nonnull_arg()
+{
+ nonnull_arg(0);
+}
+
+
+// CHECK: call void @llvm.ubsantrap(i8 16) {{.*}}!dbg [[LOC:![0-9]+]]
+// CHECK: [[LOC]] = !DILocation(line: 0, scope: [[MSG:![0-9]+]], {{.+}})
+// CHECK: distinct !DISubprogram(name: "__clang_trap_msg$
\ No newline at end of file
diff --git a/clang/test/CodeGen/ubsan-trap-reason-nonnull-return.c b/clang/test/CodeGen/ubsan-trap-reason-nonnull-return.c
new file mode 100644
index 0000000000000..9b14004d96a02
--- /dev/null
+++ b/clang/test/CodeGen/ubsan-trap-reason-nonnull-return.c
@@ -0,0 +1,15 @@
+// RUN: %clang -O0 -g -debug-info-kind=standalone -dwarf-version=5 -fsanitize=returns-nonnull-attribute \
+// RUN: -fsanitize-trap=returns-nonnull-attribute -emit-llvm -S -c %s -o - | FileCheck %s
+
+__attribute__((returns_nonnull))
+int* must_return_nonnull(int bad)
+{
+ if (bad)
+ return 0;
+ static int x = 1;
+ return &x;
+}
+
+// CHECK: call void @llvm.ubsantrap(i8 17) {{.*}}!dbg [[LOC:![0-9]+]]
+// CHECK: [[LOC]] = !DILocation(line: 0, scope: [[MSG:![0-9]+]], {{.+}})
+// CHECK: distinct !DISubprogram(name: "__clang_trap_msg$
\ No newline at end of file
diff --git a/clang/test/CodeGen/ubsan-trap-reason-nullability-arg.c b/clang/test/CodeGen/ubsan-trap-reason-nullability-arg.c
new file mode 100644
index 0000000000000..e0d6a79b27c02
--- /dev/null
+++ b/clang/test/CodeGen/ubsan-trap-reason-nullability-arg.c
@@ -0,0 +1,19 @@
+// RUN: %clang -O0 -g -debug-info-kind=standalone -dwarf-version=5 -fsanitize=nullability-arg \
+// RUN: -fsanitize-trap=nullability-arg -emit-llvm -S -c %s -o - | FileCheck %s
+
+#include <stddef.h>
+
+int nullability_arg(int* _Nonnull p)
+{
+ return *p;
+}
+
+int trigger_nullability_arg()
+{
+ return nullability_arg(NULL);
+}
+
+
+// CHECK: call void @llvm.ubsantrap(i8 14) {{.*}}!dbg [[LOC:![0-9]+]]
+// CHECK: [[LOC]] = !DILocation(line: 0, scope: [[MSG:![0-9]+]], {{.+}})
+// CHECK: distinct !DISubprogram(name: "__clang_trap_msg$
\ No newline at end of file
diff --git a/clang/test/CodeGen/ubsan-trap-reason-nullability-return.c b/clang/test/CodeGen/ubsan-trap-reason-nullability-return.c
new file mode 100644
index 0000000000000..e10fc5b225221
--- /dev/null
+++ b/clang/test/CodeGen/ubsan-trap-reason-nullability-return.c
@@ -0,0 +1,19 @@
+// RUN: %clang -O0 -g -debug-info-kind=standalone -dwarf-version=5 -fsanitize=nullability-return \
+// RUN: -fsanitize-trap=nullability-return -emit-llvm -S -c %s -o - | FileCheck %s
+
+#include <stdbool.h>
+#include <stddef.h>
+
+int* _Nonnull nullability_return(bool fail)
+{
+ if (fail)
+ return NULL;
+
+ static int x = 0;
+ return &x;
+}
+
+
+// CHECK: call void @llvm.ubsantrap(i8 15) {{.*}}!dbg [[LOC:![0-9]+]]
+// CHECK: [[LOC]] = !DILocation(line: 0, scope: [[MSG:![0-9]+]], {{.+}})
+// CHECK: distinct !DISubprogram(name: "__clang_trap_msg$
\ No newline at end of file
diff --git a/clang/test/CodeGen/ubsan-trap-reason-out-of-bounds.c b/clang/test/CodeGen/ubsan-trap-reason-out-of-bounds.c
new file mode 100644
index 0000000000000..9ed093fc528ed
--- /dev/null
+++ b/clang/test/CodeGen/ubsan-trap-reason-out-of-bounds.c
@@ -0,0 +1,12 @@
+// RUN: %clang -O0 -g -debug-info-kind=standalone -dwarf-version=5 -fsanitize=bounds \
+// RUN: -fsanitize-trap=bounds -emit-llvm -S -c %s -o - | FileCheck %s
+
+int out_of_bounds()
+{
+ int a[1] = {0};
+ return a[1];
+}
+
+// CHECK: call void @llvm.ubsantrap(i8 18) {{.*}}!dbg [[LOC:![0-9]+]]
+// CHECK: [[LOC]] = !DILocation(line: 0, scope: [[MSG:![0-9]+]], {{.+}})
+// CHECK: distinct !DISubprogram(name: "__clang_trap_msg$
\ No newline at end of file
diff --git a/clang/test/CodeGen/ubsan-trap-reason-pointer-overflow.c b/clang/test/CodeGen/ubsan-trap-reason-pointer-overflow.c
new file mode 100644
index 0000000000000..93ae42208520f
--- /dev/null
+++ b/clang/test/CodeGen/ubsan-trap-reason-pointer-overflow.c
@@ -0,0 +1,16 @@
+// RUN: %clang -O0 -g -debug-info-kind=standalone -dwarf-version=5 -fsanitize=pointer-overflow \
+// RUN: -fsanitize-trap=pointer-overflow -emit-llvm -S -c %s -o - | FileCheck %s
+
+#include <stddef.h>
+#include <stdint.h>
+
+int* pointer_overflow(void)
+{
+ int buf[4];
+ volatile size_t n = (SIZE_MAX / sizeof(int)) - 1;
+ return buf + n;
+}
+
+// CHECK: call void @llvm.ubsantrap(i8 19) {{.*}}!dbg [[LOC:![0-9]+]]
+// CHECK: [[LOC]] = !DILocation(line: 0, scope: [[MSG:![0-9]+]], {{.+}})
+// CHECK: distinct !DISubprogram(name: "__clang_trap_msg$
\ No newline at end of file
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
new file mode 100644
index 0000000000000..6f5aff7cd197a
--- /dev/null
+++ b/clang/test/CodeGen/ubsan-trap-reason-shift-out-of-bounds.c
@@ -0,0 +1,12 @@
+// RUN: %clang -O0 -g -debug-info-kind=standalone -dwarf-version=5 -fsanitize=shift \
+// RUN: -fsanitize-trap=shift -emi...
[truncated]
|
Forgot to mention missing test cases: |
@@ -4041,7 +4133,8 @@ void CodeGenFunction::EmitUnreachable(SourceLocation Loc) { | |||
|
|||
void CodeGenFunction::EmitTrapCheck(llvm::Value *Checked, | |||
SanitizerHandler CheckHandlerID, | |||
bool NoMerge) { | |||
bool NoMerge, StringRef Annotation, | |||
StringRef TrapMessage) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TrapMessage
parameter seems to not get passed from anywhere?
|
||
if (getDebugInfo() && !Category.empty()) { | ||
TrapLocation = getDebugInfo()->CreateTrapFailureMessageFor( | ||
TrapLocation, Category, TrapMessage); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Correct me if I'm wrong, but shouldn't TrapMessage
be what GetTrapMessageForHandler
provides, and Category
be something like "UBSan Trap"
?
The way the fake inline frame name gets constructed is:
__clang_trap_msg$<category>$<trap message>
Currently you are omitting the "" and putting the failure reason into the category. It would still technically work out with LLDB (it will display the category even if no message was provided), but it wouldn't be consistent with how __verbose_trap
is handled
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, you are correct on that. I didn't initially intend on having the TrapMessage
part there at all until I examined CreateTrapFailureMessageFor
which required it, which was why I left it like so. I think a possible approach could be to put the SanitizerHandler
's name as the category, and have the GetTrapMessageForHandler
deal with the TrapMessage
, but let me know if it would be preferable to have it more general with "UBSan Trap
" instead
|
||
// CHECK: call void @llvm.ubsantrap(i8 6) {{.*}}!dbg [[LOC:![0-9]+]] | ||
// CHECK: [[LOC]] = !DILocation(line: 0, scope: [[MSG:![0-9]+]], {{.+}}) | ||
// CHECK: distinct !DISubprogram(name: "__clang_trap_msg$ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lets check that the "category" part of the fake frame name is correct too
GSoC 2025
@delcypher @Michael137
Ran the clang test suite before and after changes, and some (~5) test cases failed after my changes:
clang/test/CodeGen/ubsan-trap-debugloc.c
clang/test/CodeGen/bounds-checking-debuginfo.c
clang/test/CodeGen/cfi-icall-normalize2-debuginfo.c
clang/test/CodeGen/cfi-icall-generalize-debuginfo.c
clang/test/Driver/clang_f_opts_withspaces.c
Still need to modify the hard-coded strings after further discussion