]> granicus.if.org Git - llvm/commitdiff
[sancov] Instrument reachable blocks that end in unreachable
authorReid Kleckner <rnk@google.com>
Thu, 28 Feb 2019 22:54:30 +0000 (22:54 +0000)
committerReid Kleckner <rnk@google.com>
Thu, 28 Feb 2019 22:54:30 +0000 (22:54 +0000)
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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@355152 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/Instrumentation/SanitizerCoverage.cpp
test/Instrumentation/SanitizerCoverage/tracing.ll

index 21ad41c47f63049919d8115724103a841bc8ff1a..40151bc5d784fa8a5c923dfbe16832b7948d955e 100644 (file)
@@ -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<UnreachableInst>(BB->getTerminator()))
+  if (isa<UnreachableInst>(BB->getFirstNonPHIOrDbgOrLifetime()))
     return false;
 
   // Don't insert coverage into blocks without a valid insertion point
index 2982f95cc8fdd6a582770b8ecf29778f69dfd67b..7bf8cf7e18e6e241cd2cf7cef3e9faddbbe8b5cf 100644 (file)
@@ -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*))