Skip to content

Commit 8dd1d0c

Browse files
committed
Modify array-bounds sanitizer to improve debuggability
1 parent 72b8d25 commit 8dd1d0c

File tree

2 files changed

+35
-12
lines changed

2 files changed

+35
-12
lines changed

clang/lib/CodeGen/CGExpr.cpp

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,12 @@
5151
using namespace clang;
5252
using namespace CodeGen;
5353

54+
// Experiment to make sanitizers easier to debug
55+
static llvm::cl::opt<bool> ClSanitizeDebugDeoptimization(
56+
"ubsan-unique-traps", llvm::cl::Optional,
57+
llvm::cl::desc("Deoptimize traps for UBSAN so there is 1 trap per check"),
58+
llvm::cl::init(false));
59+
5460
//===--------------------------------------------------------------------===//
5561
// Miscellaneous Helper Methods
5662
//===--------------------------------------------------------------------===//
@@ -3553,17 +3559,28 @@ void CodeGenFunction::EmitTrapCheck(llvm::Value *Checked,
35533559
// check-type per function to save on code size.
35543560
if (TrapBBs.size() <= CheckHandlerID)
35553561
TrapBBs.resize(CheckHandlerID + 1);
3562+
35563563
llvm::BasicBlock *&TrapBB = TrapBBs[CheckHandlerID];
35573564

3558-
if (!CGM.getCodeGenOpts().OptimizationLevel || !TrapBB ||
3559-
(CurCodeDecl && CurCodeDecl->hasAttr<OptimizeNoneAttr>())) {
3565+
if (!ClSanitizeDebugDeoptimization &&
3566+
CGM.getCodeGenOpts().OptimizationLevel && TrapBB &&
3567+
(!CurCodeDecl || !CurCodeDecl->hasAttr<OptimizeNoneAttr>())) {
3568+
auto Call = TrapBB->begin();
3569+
assert(isa<llvm::CallInst>(Call) && "Expected call in trap BB");
3570+
3571+
Call->applyMergedLocation(Call->getDebugLoc(),
3572+
Builder.getCurrentDebugLocation());
3573+
Builder.CreateCondBr(Checked, Cont, TrapBB);
3574+
} else {
35603575
TrapBB = createBasicBlock("trap");
35613576
Builder.CreateCondBr(Checked, Cont, TrapBB);
35623577
EmitBlock(TrapBB);
35633578

3564-
llvm::CallInst *TrapCall =
3565-
Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::ubsantrap),
3566-
llvm::ConstantInt::get(CGM.Int8Ty, CheckHandlerID));
3579+
llvm::CallInst *TrapCall = Builder.CreateCall(
3580+
CGM.getIntrinsic(llvm::Intrinsic::ubsantrap),
3581+
llvm::ConstantInt::get(CGM.Int8Ty, ClSanitizeDebugDeoptimization
3582+
? TrapBB->getParent()->size()
3583+
: CheckHandlerID));
35673584

35683585
if (!CGM.getCodeGenOpts().TrapFuncName.empty()) {
35693586
auto A = llvm::Attribute::get(getLLVMContext(), "trap-func-name",
@@ -3573,13 +3590,6 @@ void CodeGenFunction::EmitTrapCheck(llvm::Value *Checked,
35733590
TrapCall->setDoesNotReturn();
35743591
TrapCall->setDoesNotThrow();
35753592
Builder.CreateUnreachable();
3576-
} else {
3577-
auto Call = TrapBB->begin();
3578-
assert(isa<llvm::CallInst>(Call) && "Expected call in trap BB");
3579-
3580-
Call->applyMergedLocation(Call->getDebugLoc(),
3581-
Builder.getCurrentDebugLocation());
3582-
Builder.CreateCondBr(Checked, Cont, TrapBB);
35833593
}
35843594

35853595
EmitBlock(Cont);

clang/test/CodeGen/bounds-checking.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
// RUN: %clang_cc1 -fsanitize=local-bounds -emit-llvm -triple x86_64-apple-darwin10 %s -o - | FileCheck %s
22
// RUN: %clang_cc1 -fsanitize=array-bounds -O -fsanitize-trap=array-bounds -emit-llvm -triple x86_64-apple-darwin10 -DNO_DYNAMIC %s -o - | FileCheck %s
3+
// RUN: %clang_cc1 -fsanitize=array-bounds -fsanitize-trap=array-bounds -O3 -mllvm -ubsan-unique-traps -emit-llvm -triple x86_64-apple-darwin10 %s -o - | FileCheck %s --check-prefixes=NOOPTARRAY
34
//
45
// REQUIRES: x86-registered-target
56

@@ -66,3 +67,15 @@ int f7(union U *u, int i) {
6667
// CHECK-NOT: @llvm.ubsantrap
6768
return u->c[i];
6869
}
70+
71+
72+
char B[10];
73+
char B2[10];
74+
// CHECK-LABEL: @f8
75+
void f8(int i, int k) {
76+
// NOOPTARRAY: call void @llvm.ubsantrap(i8 2)
77+
B[i] = '\0';
78+
79+
// NOOPTARRAY: call void @llvm.ubsantrap(i8 4)
80+
B2[k] = '\0';
81+
}

0 commit comments

Comments
 (0)