about summary refs log tree commit diff
path: root/compiler/rustc_mir/src/transform/coverage/query.rs
diff options
context:
space:
mode:
authorRich Kadel <richkadel@google.com>2020-11-30 23:58:08 -0800
committerRich Kadel <richkadel@google.com>2020-12-03 09:50:10 -0800
commitdef932ca865b86a5057517d8a0e27c0ca72a0815 (patch)
treea3d66579631508cc930e3fa4bf245dd724cb4d71 /compiler/rustc_mir/src/transform/coverage/query.rs
parentf6c9c1a576ba485ad5bd072d9fd8e52c9a043788 (diff)
downloadrust-def932ca865b86a5057517d8a0e27c0ca72a0815.tar.gz
rust-def932ca865b86a5057517d8a0e27c0ca72a0815.zip
Combination of commits
Fixes multiple issue with counters, with simplification

  Includes a change to the implicit else span in ast_lowering, so coverage
  of the implicit else no longer spans the `then` block.

  Adds coverage for unused closures and async function bodies.

  Fixes: #78542

Adding unreachable regions for known MIR missing from coverage map

Cleaned up PR commits, and removed link-dead-code requirement and tests

  Coverage no longer depends on Issue #76038 (`-C link-dead-code` is
  no longer needed or enforced, so MSVC can use the same tests as
  Linux and MacOS now)

Restrict adding unreachable regions to covered files

  Improved the code that adds coverage for uncalled functions (with MIR
  but not-codegenned) to avoid generating coverage in files not already
  included in the files with covered functions.

Resolved last known issue requiring --emit llvm-ir workaround

  Fixed bugs in how unreachable code spans were added.
Diffstat (limited to 'compiler/rustc_mir/src/transform/coverage/query.rs')
-rw-r--r--compiler/rustc_mir/src/transform/coverage/query.rs37
1 files changed, 36 insertions, 1 deletions
diff --git a/compiler/rustc_mir/src/transform/coverage/query.rs b/compiler/rustc_mir/src/transform/coverage/query.rs
index e86bb96d29c..aa34ae70ef1 100644
--- a/compiler/rustc_mir/src/transform/coverage/query.rs
+++ b/compiler/rustc_mir/src/transform/coverage/query.rs
@@ -1,6 +1,8 @@
+use super::*;
+
 use rustc_middle::mir::coverage::*;
 use rustc_middle::mir::visit::Visitor;
-use rustc_middle::mir::{Coverage, CoverageInfo, Location};
+use rustc_middle::mir::{self, Coverage, CoverageInfo, Location};
 use rustc_middle::ty::query::Providers;
 use rustc_middle::ty::TyCtxt;
 use rustc_span::def_id::DefId;
@@ -9,6 +11,8 @@ use rustc_span::def_id::DefId;
 /// counter) and `FunctionCoverage::new()` (to extract the coverage map metadata from the MIR).
 pub(crate) fn provide(providers: &mut Providers) {
     providers.coverageinfo = |tcx, def_id| coverageinfo_from_mir(tcx, def_id);
+    providers.covered_file_name = |tcx, def_id| covered_file_name(tcx, def_id);
+    providers.covered_code_regions = |tcx, def_id| covered_code_regions(tcx, def_id);
 }
 
 /// The `num_counters` argument to `llvm.instrprof.increment` is the max counter_id + 1, or in
@@ -123,3 +127,34 @@ fn coverageinfo_from_mir<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> CoverageInfo
 
     coverage_visitor.info
 }
+
+fn covered_file_name<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Option<Symbol> {
+    let mir_body = tcx.optimized_mir(def_id);
+    for bb_data in mir_body.basic_blocks().iter() {
+        for statement in bb_data.statements.iter() {
+            if let StatementKind::Coverage(box ref coverage) = statement.kind {
+                if let Some(code_region) = coverage.code_region.as_ref() {
+                    return Some(code_region.file_name);
+                }
+            }
+        }
+    }
+    None
+}
+
+fn covered_code_regions<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Vec<&'tcx CodeRegion> {
+    let mir_body: &'tcx mir::Body<'tcx> = tcx.optimized_mir(def_id);
+    mir_body
+        .basic_blocks()
+        .iter()
+        .map(|data| {
+            data.statements.iter().filter_map(|statement| match statement.kind {
+                StatementKind::Coverage(box ref coverage) => {
+                    coverage.code_region.as_ref() // may be None
+                }
+                _ => None,
+            })
+        })
+        .flatten()
+        .collect()
+}