Skip to content

Commit 0cf31b4

Browse files
author
Anthony Tran
committed
Added Trap messages in debug info
1 parent 02d2a16 commit 0cf31b4

22 files changed

+379
-4
lines changed

clang/lib/CodeGen/CGExpr.cpp

Lines changed: 114 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,98 @@ enum VariableTypeDescriptorKind : uint16_t {
8585
// Miscellaneous Helper Methods
8686
//===--------------------------------------------------------------------===//
8787

88+
static llvm::StringRef GetTrapMessageForHandler(SanitizerHandler ID) {
89+
switch (ID) {
90+
case SanitizerHandler::AddOverflow:
91+
return "The addition of two signed integers resulted in overflow.";
92+
93+
case SanitizerHandler::BuiltinUnreachable:
94+
return "_builtin_unreachable encountered.";
95+
96+
case SanitizerHandler::CFICheckFail:
97+
return "Control flow integrity check failed.";
98+
99+
case SanitizerHandler::DivremOverflow: // Unsure
100+
return "stub";
101+
102+
case SanitizerHandler::DynamicTypeCacheMiss: // Unsure
103+
return "Data requested for dynamic type not found in cache memory.";
104+
105+
case SanitizerHandler::FloatCastOverflow: // Pasted from LLVM docs, maybe
106+
// something better to put here.
107+
return "Conversion to, from, or between floating-point types which would "
108+
"overflow the destination.";
109+
110+
case SanitizerHandler::FunctionTypeMismatch:
111+
return "Function called with arguments of a different data type than "
112+
"expected";
113+
114+
case SanitizerHandler::ImplicitConversion:
115+
return "Implicit conversion occurred.";
116+
117+
case SanitizerHandler::InvalidBuiltin:
118+
return "Built-in function or keyword not recognized.";
119+
120+
case SanitizerHandler::InvalidObjCCast:
121+
return "Invalid Objective-C cast.";
122+
123+
case SanitizerHandler::LoadInvalidValue:
124+
return "stub";
125+
126+
case SanitizerHandler::MissingReturn:
127+
return "Function is missing a return.";
128+
129+
case SanitizerHandler::MulOverflow:
130+
return "The multiplication of two signed integers resulted in overflow.";
131+
132+
case SanitizerHandler::NegateOverflow:
133+
return "Underflow/negative overflow occurred.";
134+
135+
case SanitizerHandler::
136+
NullabilityArg: // Next 4 pasted from
137+
// https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html
138+
return "Passing null as a function parameter which is annotated with "
139+
"_Nonnull";
140+
141+
case SanitizerHandler::NullabilityReturn:
142+
return "Returning null from a function with a return type annotated with "
143+
"_Nonnull";
144+
145+
case SanitizerHandler::NonnullArg:
146+
return "Passing null as a function parameter which is declared to never be "
147+
"null";
148+
149+
case SanitizerHandler::NonnullReturn:
150+
return "Returning null pointer from a function which is declared to never "
151+
"be null";
152+
153+
case SanitizerHandler::OutOfBounds:
154+
return "Out of bounds -- memory accessed outside of expected boundaries.";
155+
156+
case SanitizerHandler::PointerOverflow:
157+
return "stub";
158+
159+
case SanitizerHandler::ShiftOutOfBounds:
160+
return "Bit shift attempted to move bits beyond boundaries of data type's "
161+
"bit size.";
162+
163+
case SanitizerHandler::SubOverflow:
164+
return "The subtraction of two signed integers resulted in overflow.";
165+
166+
case SanitizerHandler::TypeMismatch:
167+
return "Type mismatch -- value type used does not match type expected.";
168+
169+
case SanitizerHandler::AlignmentAssumption: // Help on bottom 2
170+
return "stub";
171+
172+
case SanitizerHandler::VLABoundNotPositive:
173+
return "stub";
174+
175+
default:
176+
return "";
177+
}
178+
}
179+
88180
/// CreateTempAlloca - This creates a alloca and inserts it into the entry
89181
/// block.
90182
RawAddress
@@ -4041,7 +4133,8 @@ void CodeGenFunction::EmitUnreachable(SourceLocation Loc) {
40414133

40424134
void CodeGenFunction::EmitTrapCheck(llvm::Value *Checked,
40434135
SanitizerHandler CheckHandlerID,
4044-
bool NoMerge) {
4136+
bool NoMerge, StringRef Annotation,
4137+
StringRef TrapMessage) {
40454138
llvm::BasicBlock *Cont = createBasicBlock("cont");
40464139

40474140
// If we're optimizing, collapse all calls to trap down to just one per
@@ -4051,6 +4144,14 @@ void CodeGenFunction::EmitTrapCheck(llvm::Value *Checked,
40514144

40524145
llvm::BasicBlock *&TrapBB = TrapBBs[CheckHandlerID];
40534146

4147+
llvm::DILocation *TrapLocation = Builder.getCurrentDebugLocation();
4148+
llvm::StringRef Category = GetTrapMessageForHandler(CheckHandlerID);
4149+
4150+
if (getDebugInfo() && !Category.empty()) {
4151+
TrapLocation = getDebugInfo()->CreateTrapFailureMessageFor(
4152+
TrapLocation, Category, TrapMessage);
4153+
}
4154+
40544155
NoMerge = NoMerge || !CGM.getCodeGenOpts().OptimizationLevel ||
40554156
(CurCodeDecl && CurCodeDecl->hasAttr<OptimizeNoneAttr>());
40564157

@@ -4059,8 +4160,16 @@ void CodeGenFunction::EmitTrapCheck(llvm::Value *Checked,
40594160
auto Call = TrapBB->begin();
40604161
assert(isa<llvm::CallInst>(Call) && "Expected call in trap BB");
40614162

4062-
Call->applyMergedLocation(Call->getDebugLoc(),
4063-
Builder.getCurrentDebugLocation());
4163+
// Call->applyMergedLocation(Call->getDebugLoc(),
4164+
// Builder.getCurrentDebugLocation());
4165+
Call->applyMergedLocation(Call->getDebugLoc(), TrapLocation);
4166+
4167+
auto Unreachable = ++TrapBB->begin();
4168+
if (isa<llvm::UnreachableInst>(Unreachable)) {
4169+
Unreachable->applyMergedLocation(Unreachable->getDebugLoc(),
4170+
TrapLocation);
4171+
}
4172+
40644173
Builder.CreateCondBr(Checked, Cont, TrapBB,
40654174
MDHelper.createLikelyBranchWeights());
40664175
} else {
@@ -4069,6 +4178,8 @@ void CodeGenFunction::EmitTrapCheck(llvm::Value *Checked,
40694178
MDHelper.createLikelyBranchWeights());
40704179
EmitBlock(TrapBB);
40714180

4181+
ApplyDebugLocation applyTrapDI(*this, TrapLocation);
4182+
40724183
llvm::CallInst *TrapCall =
40734184
Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::ubsantrap),
40744185
llvm::ConstantInt::get(CGM.Int8Ty, CheckHandlerID));

clang/lib/CodeGen/CodeGenFunction.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5287,7 +5287,8 @@ class CodeGenFunction : public CodeGenTypeCache {
52875287
/// Create a basic block that will call the trap intrinsic, and emit a
52885288
/// conditional branch to it, for the -ftrapv checks.
52895289
void EmitTrapCheck(llvm::Value *Checked, SanitizerHandler CheckHandlerID,
5290-
bool NoMerge = false);
5290+
bool NoMerge = false, StringRef Annotation = "",
5291+
StringRef TrapMessage = "");
52915292

52925293
/// Emit a call to trap or debugtrap and attach function attribute
52935294
/// "trap-func-name" if specified.
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// RUN: %clang -O0 -g -debug-info-kind=standalone -dwarf-version=5 -fsanitize=undefined \
2+
// RUN: -fsanitize-trap=undefined -emit-llvm -S -c %s -o - | FileCheck %s
3+
4+
int add_overflow(int a, int b) {
5+
return a + b;
6+
}
7+
8+
// CHECK: call void @llvm.ubsantrap(i8 0) {{.*}}!dbg [[LOC:![0-9]+]]
9+
// CHECK: [[LOC]] = !DILocation(line: 0, scope: [[MSG:![0-9]+]], {{.+}})
10+
// CHECK: distinct !DISubprogram(name: "__clang_trap_msg$
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// RUN: %clang -O0 -g -debug-info-kind=standalone -dwarf-version=5 -fsanitize=unreachable \
2+
// RUN: -fsanitize-trap=unreachable -emit-llvm -S -c %s -o - | FileCheck %s
3+
4+
int call_builtin_unreachable()
5+
{
6+
__builtin_unreachable();
7+
}
8+
9+
10+
// CHECK: call void @llvm.ubsantrap(i8 1) {{.*}}!dbg [[LOC:![0-9]+]]
11+
// CHECK: [[LOC]] = !DILocation(line: 0, scope: [[MSG:![0-9]+]], {{.+}})
12+
// CHECK: distinct !DISubprogram(name: "__clang_trap_msg$
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// RUN: %clang -O0 -g -debug-info-kind=standalone -dwarf-version=5 -fsanitize=undefined \
2+
// RUN: -fsanitize-trap=undefined -emit-llvm -S -c %s -o - | FileCheck %s
3+
4+
int div_rem_overflow(int a, int b) {
5+
return a / b;
6+
}
7+
8+
// CHECK: call void @llvm.ubsantrap(i8 3) {{.*}}!dbg [[LOC:![0-9]+]]
9+
// CHECK: [[LOC]] = !DILocation(line: 0, scope: [[MSG:![0-9]+]], {{.+}})
10+
// CHECK: distinct !DISubprogram(name: "__clang_trap_msg$
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -O0 -debug-info-kind=standalone -dwarf-version=5 -fsanitize=float-cast-overflow \
2+
// RUN: -fsanitize-trap=float-cast-overflow -emit-llvm %s -o - | FileCheck %s
3+
4+
int f(float x) {
5+
return (int)x;
6+
}
7+
8+
// CHECK: call void @llvm.ubsantrap(i8 5) {{.*}}!dbg [[LOC:![0-9]+]]
9+
// CHECK: [[LOC]] = !DILocation(line: 0, scope: [[MSG:![0-9]+]], {{.+}})
10+
// CHECK: distinct !DISubprogram(name: "__clang_trap_msg$
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// RUN: %clang -O0 -g -debug-info-kind=standalone -dwarf-version=5 -fsanitize=undefined \
2+
// RUN: -fsanitize-trap=undefined -emit-llvm -S -c %s -o - | FileCheck %s
3+
4+
void target() { }
5+
6+
int function_type_mismatch() {
7+
int (*fp_int)(int);
8+
9+
fp_int = (int (*)(int))(void *)target;
10+
11+
return fp_int(42);
12+
}
13+
14+
// CHECK: call void @llvm.ubsantrap(i8 6) {{.*}}!dbg [[LOC:![0-9]+]]
15+
// CHECK: [[LOC]] = !DILocation(line: 0, scope: [[MSG:![0-9]+]], {{.+}})
16+
// CHECK: distinct !DISubprogram(name: "__clang_trap_msg$
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// RUN: %clang -O0 -g -debug-info-kind=standalone -dwarf-version=5 -fsanitize=implicit-conversion \
2+
// RUN: -fsanitize-trap=implicit-conversion -emit-llvm -S -c %s -o - | FileCheck %s
3+
4+
unsigned long long big;
5+
6+
unsigned implicit_conversion()
7+
{
8+
return big;
9+
}
10+
11+
// CHECK: call void @llvm.ubsantrap(i8 7) {{.*}}!dbg [[LOC:![0-9]+]]
12+
// CHECK: [[LOC]] = !DILocation(line: 0, scope: [[MSG:![0-9]+]], {{.+}})
13+
// CHECK: distinct !DISubprogram(name: "__clang_trap_msg$
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// RUN: %clang -O0 -g -debug-info-kind=standalone -dwarf-version=5 -fsanitize=builtin \
2+
// RUN: -fsanitize-trap=builtin -emit-llvm -S -c %s -o - | FileCheck %s
3+
4+
unsigned invalid_builtin(unsigned x)
5+
{
6+
return __builtin_clz(x);
7+
}
8+
9+
10+
// CHECK: call void @llvm.ubsantrap(i8 8) {{.*}}!dbg [[LOC:![0-9]+]]
11+
// CHECK: [[LOC]] = !DILocation(line: 0, scope: [[MSG:![0-9]+]], {{.+}})
12+
// CHECK: distinct !DISubprogram(name: "__clang_trap_msg$
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// RUN: %clang -O0 -g -debug-info-kind=standalone -dwarf-version=5 -fsanitize=undefined \
2+
// RUN: -fsanitize-trap=undefined -emit-llvm -S -c %s -o - | FileCheck %s
3+
#include <stdbool.h>
4+
5+
unsigned char bad_byte;
6+
7+
bool load_invalid_value()
8+
{
9+
return *((bool *)&bad_byte);
10+
}
11+
12+
13+
// CHECK: call void @llvm.ubsantrap(i8 10) {{.*}}!dbg [[LOC:![0-9]+]]
14+
// CHECK: [[LOC]] = !DILocation(line: 0, scope: [[MSG:![0-9]+]], {{.+}})
15+
// CHECK: distinct !DISubprogram(name: "__clang_trap_msg$

0 commit comments

Comments
 (0)