From 701593f1dbff225e39f8a25cfd2bfbc3f246f296 Mon Sep 17 00:00:00 2001 From: Reid Kleckner Date: Thu, 28 Feb 2019 22:54:30 +0000 Subject: [PATCH] [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 --- .../Instrumentation/SanitizerCoverage.cpp | 6 ++--- .../Instrumentation/SanitizerCoverage/tracing.ll | 27 ++++++++++++++++++++++ 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp b/llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp index 21ad41c..40151bc 100644 --- a/llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp +++ b/llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp @@ -454,12 +454,12 @@ static bool shouldInstrumentBlock(const Function &F, const BasicBlock *BB, const DominatorTree *DT, const PostDominatorTree *PDT, const SanitizerCoverageOptions &Options) { - // Don't insert coverage for unreachable blocks: we will never call - // __sanitizer_cov() for them, so counting them in + // Don't insert coverage for blocks containing nothing but unreachable: we + // will never call __sanitizer_cov() for them, so counting them in // NumberOfInstrumentedBlocks() might complicate calculation of code coverage // percentage. Also, unreachable instructions frequently have no debug // locations. - if (isa(BB->getTerminator())) + if (isa(BB->getFirstNonPHIOrDbgOrLifetime())) return false; // Don't insert coverage into blocks without a valid insertion point diff --git a/llvm/test/Instrumentation/SanitizerCoverage/tracing.ll b/llvm/test/Instrumentation/SanitizerCoverage/tracing.ll index 2982f95..7bf8cf7 100644 --- a/llvm/test/Instrumentation/SanitizerCoverage/tracing.ll +++ b/llvm/test/Instrumentation/SanitizerCoverage/tracing.ll @@ -23,6 +23,19 @@ entry: ret void } +declare void @longjmp(i8*) noreturn + +; We expect three coverage points here for each BB. +define void @cond_longjmp(i1 %cond, i8* %jmp_buf) sanitize_address { +entry: + br i1 %cond, label %lj, label %done +done: + ret void +lj: + call void @longjmp(i8* %jmp_buf) + unreachable +} + ; CHECK_PC-LABEL: define void @foo ; CHECK_PC: call void @__sanitizer_cov_trace_pc @@ -31,6 +44,13 @@ entry: ; CHECK_PC-NOT: call void @__sanitizer_cov_trace_pc ; CHECK_PC: ret void ; CHECK_PC-NOT: call void @__sanitizer_cov_module_init +; CHECK_PC-LABEL: @cond_longjmp +; CHECK_PC: call void @__sanitizer_cov_trace_pc +; CHECK_PC: call void @__sanitizer_cov_trace_pc +; CHECK_PC: ret void +; CHECK_PC: call void @__sanitizer_cov_trace_pc +; CHECK_PC: call void @longjmp +; CHECK_PC: unreachable ; CHECK_PC_GUARD: section "__sancov_guards", comdat($foo), align 4 ; CHECK_PC_GUARD-LABEL: define void @foo @@ -42,6 +62,13 @@ entry: ; CHECK_PC_GUARD-LABEL: @external_bar ; CHECK_PC_GUARD-NOT: call void @__sanitizer_cov_trace_pc ; CHECK_PC_GUARD: ret void +; CHECK_PC_GUARD-LABEL: @cond_longjmp +; CHECK_PC_GUARD: call void @__sanitizer_cov_trace_pc_guard +; CHECK_PC_GUARD: call void @__sanitizer_cov_trace_pc_guard +; CHECK_PC_GUARD: ret void +; CHECK_PC_GUARD: call void @__sanitizer_cov_trace_pc_guard +; CHECK_PC_GUARD: call void @longjmp +; CHECK_PC_GUARD: unreachable ; 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*)) -- 2.7.4