Skip to content

Commit 701593f

Browse files
committedFeb 28, 2019
[sancov] Instrument reachable blocks that end in unreachable
Summary: These sorts of blocks often contain calls to noreturn functions, like longjmp, throw, or trap. If they don't end the program, they are "interesting" from the perspective of sanitizer coverage, so we should instrument them. This was discussed in https://reviews.llvm.org/D57982. Reviewers: kcc, vitalybuka Subscribers: llvm-commits, craig.topper, efriedma, morehouse, hiraditya Tags: #llvm Differential Revision: https://reviews.llvm.org/D58740 llvm-svn: 355152
1 parent ac136cd commit 701593f

File tree

2 files changed

+30
-3
lines changed

2 files changed

+30
-3
lines changed
 

‎llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -454,12 +454,12 @@ static bool shouldInstrumentBlock(const Function &F, const BasicBlock *BB,
454454
const DominatorTree *DT,
455455
const PostDominatorTree *PDT,
456456
const SanitizerCoverageOptions &Options) {
457-
// Don't insert coverage for unreachable blocks: we will never call
458-
// __sanitizer_cov() for them, so counting them in
457+
// Don't insert coverage for blocks containing nothing but unreachable: we
458+
// will never call __sanitizer_cov() for them, so counting them in
459459
// NumberOfInstrumentedBlocks() might complicate calculation of code coverage
460460
// percentage. Also, unreachable instructions frequently have no debug
461461
// locations.
462-
if (isa<UnreachableInst>(BB->getTerminator()))
462+
if (isa<UnreachableInst>(BB->getFirstNonPHIOrDbgOrLifetime()))
463463
return false;
464464

465465
// Don't insert coverage into blocks without a valid insertion point

‎llvm/test/Instrumentation/SanitizerCoverage/tracing.ll

+27
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,19 @@ entry:
2323
ret void
2424
}
2525

26+
declare void @longjmp(i8*) noreturn
27+
28+
; We expect three coverage points here for each BB.
29+
define void @cond_longjmp(i1 %cond, i8* %jmp_buf) sanitize_address {
30+
entry:
31+
br i1 %cond, label %lj, label %done
32+
done:
33+
ret void
34+
lj:
35+
call void @longjmp(i8* %jmp_buf)
36+
unreachable
37+
}
38+
2639

2740
; CHECK_PC-LABEL: define void @foo
2841
; CHECK_PC: call void @__sanitizer_cov_trace_pc
@@ -31,6 +44,13 @@ entry:
3144
; CHECK_PC-NOT: call void @__sanitizer_cov_trace_pc
3245
; CHECK_PC: ret void
3346
; CHECK_PC-NOT: call void @__sanitizer_cov_module_init
47+
; CHECK_PC-LABEL: @cond_longjmp
48+
; CHECK_PC: call void @__sanitizer_cov_trace_pc
49+
; CHECK_PC: call void @__sanitizer_cov_trace_pc
50+
; CHECK_PC: ret void
51+
; CHECK_PC: call void @__sanitizer_cov_trace_pc
52+
; CHECK_PC: call void @longjmp
53+
; CHECK_PC: unreachable
3454

3555
; CHECK_PC_GUARD: section "__sancov_guards", comdat($foo), align 4
3656
; CHECK_PC_GUARD-LABEL: define void @foo
@@ -42,6 +62,13 @@ entry:
4262
; CHECK_PC_GUARD-LABEL: @external_bar
4363
; CHECK_PC_GUARD-NOT: call void @__sanitizer_cov_trace_pc
4464
; CHECK_PC_GUARD: ret void
65+
; CHECK_PC_GUARD-LABEL: @cond_longjmp
66+
; CHECK_PC_GUARD: call void @__sanitizer_cov_trace_pc_guard
67+
; CHECK_PC_GUARD: call void @__sanitizer_cov_trace_pc_guard
68+
; CHECK_PC_GUARD: ret void
69+
; CHECK_PC_GUARD: call void @__sanitizer_cov_trace_pc_guard
70+
; CHECK_PC_GUARD: call void @longjmp
71+
; CHECK_PC_GUARD: unreachable
4572

4673
; CHECK_PC_GUARD: call void @__sanitizer_cov_trace_pc_guard_init(i32* bitcast (i32** @__start___sancov_guards to i32*), i32* bitcast (i32** @__stop___sancov_guards to i32*))
4774

0 commit comments

Comments
 (0)
Please sign in to comment.