diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs index da2a153d819f9..bd175e560c77a 100644 --- a/compiler/rustc_codegen_llvm/src/builder.rs +++ b/compiler/rustc_codegen_llvm/src/builder.rs @@ -1886,48 +1886,4 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> { ) { self.call_intrinsic("llvm.instrprof.increment", &[], &[fn_name, hash, num_counters, index]); } - - /// Emits a call to `llvm.instrprof.mcdc.parameters`. - /// - /// This doesn't produce any code directly, but is used as input by - /// the LLVM pass that handles coverage instrumentation. - /// - /// (See clang's [`CodeGenPGO::emitMCDCParameters`] for comparison.) - /// - /// [`CodeGenPGO::emitMCDCParameters`]: - /// https://github.com/rust-lang/llvm-project/blob/5399a24/clang/lib/CodeGen/CodeGenPGO.cpp#L1124 - #[instrument(level = "debug", skip(self))] - pub(crate) fn mcdc_parameters( - &mut self, - fn_name: &'ll Value, - hash: &'ll Value, - bitmap_bits: &'ll Value, - ) { - self.call_intrinsic("llvm.instrprof.mcdc.parameters", &[], &[fn_name, hash, bitmap_bits]); - } - - #[instrument(level = "debug", skip(self))] - pub(crate) fn mcdc_tvbitmap_update( - &mut self, - fn_name: &'ll Value, - hash: &'ll Value, - bitmap_index: &'ll Value, - mcdc_temp: &'ll Value, - ) { - let args = &[fn_name, hash, bitmap_index, mcdc_temp]; - self.call_intrinsic("llvm.instrprof.mcdc.tvbitmap.update", &[], args); - } - - #[instrument(level = "debug", skip(self))] - pub(crate) fn mcdc_condbitmap_reset(&mut self, mcdc_temp: &'ll Value) { - self.store(self.const_i32(0), mcdc_temp, self.tcx.data_layout.i32_align.abi); - } - - #[instrument(level = "debug", skip(self))] - pub(crate) fn mcdc_condbitmap_update(&mut self, cond_index: &'ll Value, mcdc_temp: &'ll Value) { - let align = self.tcx.data_layout.i32_align.abi; - let current_tv_index = self.load(self.cx.type_i32(), mcdc_temp, align); - let new_tv_index = self.add(current_tv_index, cond_index); - self.store(new_tv_index, mcdc_temp, align); - } } diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/ffi.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/ffi.rs index f6000e7284002..a4b60d420f3fb 100644 --- a/compiler/rustc_codegen_llvm/src/coverageinfo/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/coverageinfo/ffi.rs @@ -73,48 +73,6 @@ pub(crate) struct CounterExpression { pub(crate) rhs: Counter, } -pub(crate) mod mcdc { - use rustc_middle::mir::coverage::{ConditionId, ConditionInfo, DecisionInfo}; - - /// Must match the layout of `LLVMRustMCDCDecisionParameters`. - #[repr(C)] - #[derive(Clone, Copy, Debug, Default)] - pub(crate) struct DecisionParameters { - bitmap_idx: u32, - num_conditions: u16, - } - - type LLVMConditionId = i16; - - /// Must match the layout of `LLVMRustMCDCBranchParameters`. - #[repr(C)] - #[derive(Clone, Copy, Debug, Default)] - pub(crate) struct BranchParameters { - condition_id: LLVMConditionId, - condition_ids: [LLVMConditionId; 2], - } - - impl From for BranchParameters { - fn from(value: ConditionInfo) -> Self { - let to_llvm_cond_id = |cond_id: Option| { - cond_id.and_then(|id| LLVMConditionId::try_from(id.as_usize()).ok()).unwrap_or(-1) - }; - let ConditionInfo { condition_id, true_next_id, false_next_id } = value; - Self { - condition_id: to_llvm_cond_id(Some(condition_id)), - condition_ids: [to_llvm_cond_id(false_next_id), to_llvm_cond_id(true_next_id)], - } - } - } - - impl From for DecisionParameters { - fn from(info: DecisionInfo) -> Self { - let DecisionInfo { bitmap_idx, num_conditions } = info; - Self { bitmap_idx, num_conditions } - } - } -} - /// A span of source code coordinates to be embedded in coverage metadata. /// /// Must match the layout of `LLVMRustCoverageSpan`. @@ -148,26 +106,14 @@ pub(crate) struct Regions { pub(crate) code_regions: Vec, pub(crate) expansion_regions: Vec, pub(crate) branch_regions: Vec, - pub(crate) mcdc_branch_regions: Vec, - pub(crate) mcdc_decision_regions: Vec, } impl Regions { /// Returns true if none of this structure's tables contain any regions. pub(crate) fn has_no_regions(&self) -> bool { - let Self { - code_regions, - expansion_regions, - branch_regions, - mcdc_branch_regions, - mcdc_decision_regions, - } = self; - - code_regions.is_empty() - && expansion_regions.is_empty() - && branch_regions.is_empty() - && mcdc_branch_regions.is_empty() - && mcdc_decision_regions.is_empty() + let Self { code_regions, expansion_regions, branch_regions } = self; + + code_regions.is_empty() && expansion_regions.is_empty() && branch_regions.is_empty() } } @@ -195,21 +141,3 @@ pub(crate) struct BranchRegion { pub(crate) true_counter: Counter, pub(crate) false_counter: Counter, } - -/// Must match the layout of `LLVMRustCoverageMCDCBranchRegion`. -#[derive(Clone, Debug)] -#[repr(C)] -pub(crate) struct MCDCBranchRegion { - pub(crate) cov_span: CoverageSpan, - pub(crate) true_counter: Counter, - pub(crate) false_counter: Counter, - pub(crate) mcdc_branch_params: mcdc::BranchParameters, -} - -/// Must match the layout of `LLVMRustCoverageMCDCDecisionRegion`. -#[derive(Clone, Debug)] -#[repr(C)] -pub(crate) struct MCDCDecisionRegion { - pub(crate) cov_span: CoverageSpan, - pub(crate) mcdc_decision_params: mcdc::DecisionParameters, -} diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/llvm_cov.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/llvm_cov.rs index 907d6d41a1fb5..bc4f6bb6a82bc 100644 --- a/compiler/rustc_codegen_llvm/src/coverageinfo/llvm_cov.rs +++ b/compiler/rustc_codegen_llvm/src/coverageinfo/llvm_cov.rs @@ -63,13 +63,7 @@ pub(crate) fn write_function_mappings_to_buffer( expressions: &[ffi::CounterExpression], regions: &ffi::Regions, ) -> Vec { - let ffi::Regions { - code_regions, - expansion_regions, - branch_regions, - mcdc_branch_regions, - mcdc_decision_regions, - } = regions; + let ffi::Regions { code_regions, expansion_regions, branch_regions } = regions; // SAFETY: // - All types are FFI-compatible and have matching representations in Rust/C++. @@ -87,10 +81,6 @@ pub(crate) fn write_function_mappings_to_buffer( expansion_regions.len(), branch_regions.as_ptr(), branch_regions.len(), - mcdc_branch_regions.as_ptr(), - mcdc_branch_regions.len(), - mcdc_decision_regions.as_ptr(), - mcdc_decision_regions.len(), buffer, ) }) diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen/covfun.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen/covfun.rs index fd1e7f7f160ab..e0da8d368762b 100644 --- a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen/covfun.rs +++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen/covfun.rs @@ -140,8 +140,6 @@ fn fill_region_tables<'tcx>( code_regions, expansion_regions: _, // FIXME(Zalathar): Fill out support for expansion regions branch_regions, - mcdc_branch_regions, - mcdc_decision_regions, } = &mut covfun.regions; // For each counter/region pair in this function+file, convert it to a @@ -161,20 +159,6 @@ fn fill_region_tables<'tcx>( false_counter: counter_for_bcb(false_bcb), }); } - MappingKind::MCDCBranch { true_bcb, false_bcb, mcdc_params } => { - mcdc_branch_regions.push(ffi::MCDCBranchRegion { - cov_span, - true_counter: counter_for_bcb(true_bcb), - false_counter: counter_for_bcb(false_bcb), - mcdc_branch_params: ffi::mcdc::BranchParameters::from(mcdc_params), - }); - } - MappingKind::MCDCDecision(mcdc_decision_params) => { - mcdc_decision_regions.push(ffi::MCDCDecisionRegion { - cov_span, - mcdc_decision_params: ffi::mcdc::DecisionParameters::from(mcdc_decision_params), - }); - } } } } diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs index 119237abd6b8f..6a58f495c9d8f 100644 --- a/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs +++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs @@ -1,11 +1,10 @@ use std::cell::{OnceCell, RefCell}; use std::ffi::{CStr, CString}; -use rustc_abi::Size; use rustc_codegen_ssa::traits::{ - BuilderMethods, ConstCodegenMethods, CoverageInfoBuilderMethods, MiscCodegenMethods, + ConstCodegenMethods, CoverageInfoBuilderMethods, MiscCodegenMethods, }; -use rustc_data_structures::fx::{FxHashMap, FxIndexMap}; +use rustc_data_structures::fx::FxIndexMap; use rustc_middle::mir::coverage::CoverageKind; use rustc_middle::ty::Instance; use tracing::{debug, instrument}; @@ -28,34 +27,13 @@ pub(crate) struct CguCoverageContext<'ll, 'tcx> { /// symbol name, and `llvm-cov` will exit fatally if it can't resolve that /// hash back to an entry in the binary's `__llvm_prf_names` linker section. pub(crate) pgo_func_name_var_map: RefCell, &'ll llvm::Value>>, - pub(crate) mcdc_condition_bitmap_map: RefCell, Vec<&'ll llvm::Value>>>, covfun_section_name: OnceCell, } impl<'ll, 'tcx> CguCoverageContext<'ll, 'tcx> { pub(crate) fn new() -> Self { - Self { - pgo_func_name_var_map: Default::default(), - mcdc_condition_bitmap_map: Default::default(), - covfun_section_name: Default::default(), - } - } - - /// LLVM use a temp value to record evaluated mcdc test vector of each decision, which is - /// called condition bitmap. In order to handle nested decisions, several condition bitmaps can - /// be allocated for a function body. These values are named `mcdc.addr.{i}` and are a 32-bit - /// integers. They respectively hold the condition bitmaps for decisions with a depth of `i`. - fn try_get_mcdc_condition_bitmap( - &self, - instance: &Instance<'tcx>, - decision_depth: u16, - ) -> Option<&'ll llvm::Value> { - self.mcdc_condition_bitmap_map - .borrow() - .get(instance) - .and_then(|bitmap_map| bitmap_map.get(decision_depth as usize)) - .copied() // Dereference Option<&&Value> to Option<&Value> + Self { pgo_func_name_var_map: Default::default(), covfun_section_name: Default::default() } } /// Returns the list of instances considered "used" in this CGU, as @@ -105,38 +83,6 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> { } impl<'tcx> CoverageInfoBuilderMethods<'tcx> for Builder<'_, '_, 'tcx> { - fn init_coverage(&mut self, instance: Instance<'tcx>) { - let Some(function_coverage_info) = - self.tcx.instance_mir(instance.def).function_coverage_info.as_deref() - else { - return; - }; - - // If there are no MC/DC bitmaps to set up, return immediately. - if function_coverage_info.mcdc_bitmap_bits == 0 { - return; - } - - let fn_name = self.ensure_pgo_func_name_var(instance); - let hash = self.const_u64(function_coverage_info.function_source_hash); - let bitmap_bits = self.const_u32(function_coverage_info.mcdc_bitmap_bits as u32); - self.mcdc_parameters(fn_name, hash, bitmap_bits); - - // Create pointers named `mcdc.addr.{i}` to stack-allocated condition bitmaps. - let mut cond_bitmaps = vec![]; - for i in 0..function_coverage_info.mcdc_num_condition_bitmaps { - // MC/DC intrinsics will perform loads/stores that use the ABI default - // alignment for i32, so our variable declaration should match. - let align = self.tcx.data_layout.i32_align.abi; - let cond_bitmap = self.alloca(Size::from_bytes(4), align); - llvm::set_value_name(cond_bitmap, format!("mcdc.addr.{i}").as_bytes()); - self.store(self.const_i32(0), cond_bitmap, align); - cond_bitmaps.push(cond_bitmap); - } - - self.coverage_cx().mcdc_condition_bitmap_map.borrow_mut().insert(instance, cond_bitmaps); - } - #[instrument(level = "debug", skip(self))] fn add_coverage(&mut self, instance: Instance<'tcx>, kind: &CoverageKind) { // Our caller should have already taken care of inlining subtleties, @@ -153,7 +99,7 @@ impl<'tcx> CoverageInfoBuilderMethods<'tcx> for Builder<'_, '_, 'tcx> { // When that happens, we currently just discard those statements, so // the corresponding code will be undercounted. // FIXME(Zalathar): Find a better solution for mixed-coverage builds. - let Some(coverage_cx) = &bx.cx.coverage_cx else { return }; + let Some(_coverage_cx) = &bx.cx.coverage_cx else { return }; let Some(function_coverage_info) = bx.tcx.instance_mir(instance.def).function_coverage_info.as_deref() @@ -185,30 +131,6 @@ impl<'tcx> CoverageInfoBuilderMethods<'tcx> for Builder<'_, '_, 'tcx> { } // If a BCB doesn't have an associated physical counter, there's nothing to codegen. CoverageKind::VirtualCounter { .. } => {} - CoverageKind::CondBitmapUpdate { index, decision_depth } => { - let cond_bitmap = coverage_cx - .try_get_mcdc_condition_bitmap(&instance, decision_depth) - .expect("mcdc cond bitmap should have been allocated for updating"); - let cond_index = bx.const_i32(index as i32); - bx.mcdc_condbitmap_update(cond_index, cond_bitmap); - } - CoverageKind::TestVectorBitmapUpdate { bitmap_idx, decision_depth } => { - let cond_bitmap = - coverage_cx.try_get_mcdc_condition_bitmap(&instance, decision_depth).expect( - "mcdc cond bitmap should have been allocated for merging \ - into the global bitmap", - ); - assert!( - bitmap_idx as usize <= function_coverage_info.mcdc_bitmap_bits, - "bitmap index of the decision out of range" - ); - - let fn_name = bx.ensure_pgo_func_name_var(instance); - let hash = bx.const_u64(function_coverage_info.function_source_hash); - let bitmap_index = bx.const_u32(bitmap_idx); - bx.mcdc_tvbitmap_update(fn_name, hash, bitmap_index, cond_bitmap); - bx.mcdc_condbitmap_reset(cond_bitmap); - } } } } diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index 2443194ff4832..75d3d27f74e10 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -2056,10 +2056,6 @@ unsafe extern "C" { NumExpansionRegions: size_t, BranchRegions: *const crate::coverageinfo::ffi::BranchRegion, NumBranchRegions: size_t, - MCDCBranchRegions: *const crate::coverageinfo::ffi::MCDCBranchRegion, - NumMCDCBranchRegions: size_t, - MCDCDecisionRegions: *const crate::coverageinfo::ffi::MCDCDecisionRegion, - NumMCDCDecisionRegions: size_t, BufferOut: &RustString, ); diff --git a/compiler/rustc_codegen_ssa/src/mir/mod.rs b/compiler/rustc_codegen_ssa/src/mir/mod.rs index 50d0f91074450..06873313e2ecd 100644 --- a/compiler/rustc_codegen_ssa/src/mir/mod.rs +++ b/compiler/rustc_codegen_ssa/src/mir/mod.rs @@ -296,10 +296,6 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( // Apply debuginfo to the newly allocated locals. fx.debug_introduce_locals(&mut start_bx, consts_debug_info.unwrap_or_default()); - // If the backend supports coverage, and coverage is enabled for this function, - // do any necessary start-of-function codegen (e.g. locals for MC/DC bitmaps). - start_bx.init_coverage(instance); - // The builders will be created separately for each basic block at `codegen_block`. // So drop the builder of `start_llbb` to avoid having two at the same time. drop(start_bx); diff --git a/compiler/rustc_codegen_ssa/src/traits/coverageinfo.rs b/compiler/rustc_codegen_ssa/src/traits/coverageinfo.rs index 0b513dac50378..31482a53b6d41 100644 --- a/compiler/rustc_codegen_ssa/src/traits/coverageinfo.rs +++ b/compiler/rustc_codegen_ssa/src/traits/coverageinfo.rs @@ -2,11 +2,6 @@ use rustc_middle::mir::coverage::CoverageKind; use rustc_middle::ty::Instance; pub trait CoverageInfoBuilderMethods<'tcx> { - /// Performs any start-of-function codegen needed for coverage instrumentation. - /// - /// Can be a no-op in backends that don't support coverage instrumentation. - fn init_coverage(&mut self, _instance: Instance<'tcx>) {} - /// Handle the MIR coverage info in a backend-specific way. /// /// This can potentially be a no-op in backends that don't support diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index 86faab62d03a7..16474b231e042 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -777,7 +777,7 @@ fn test_unstable_options_tracking_hash() { tracked!( coverage_options, CoverageOptions { - level: CoverageLevel::Mcdc, + level: CoverageLevel::Branch, // (don't collapse test-only options onto the same line) discard_all_spans_in_codegen: true, } diff --git a/compiler/rustc_llvm/llvm-wrapper/CoverageMappingWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/CoverageMappingWrapper.cpp index 4695de8ea09a3..22e7c7a160ff5 100644 --- a/compiler/rustc_llvm/llvm-wrapper/CoverageMappingWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/CoverageMappingWrapper.cpp @@ -37,28 +37,6 @@ static coverage::Counter fromRust(LLVMRustCounter Counter) { report_fatal_error("Bad LLVMRustCounterKind!"); } -struct LLVMRustMCDCDecisionParameters { - uint32_t BitmapIdx; - uint16_t NumConditions; -}; - -struct LLVMRustMCDCBranchParameters { - int16_t ConditionID; - int16_t ConditionIDs[2]; -}; - -static coverage::mcdc::BranchParameters -fromRust(LLVMRustMCDCBranchParameters Params) { - return coverage::mcdc::BranchParameters( - Params.ConditionID, {Params.ConditionIDs[0], Params.ConditionIDs[1]}); -} - -static coverage::mcdc::DecisionParameters -fromRust(LLVMRustMCDCDecisionParameters Params) { - return coverage::mcdc::DecisionParameters(Params.BitmapIdx, - Params.NumConditions); -} - // Must match the layout of // `rustc_codegen_llvm::coverageinfo::ffi::CoverageSpan`. struct LLVMRustCoverageSpan { @@ -90,22 +68,6 @@ struct LLVMRustCoverageBranchRegion { LLVMRustCounter FalseCount; }; -// Must match the layout of -// `rustc_codegen_llvm::coverageinfo::ffi::MCDCBranchRegion`. -struct LLVMRustCoverageMCDCBranchRegion { - LLVMRustCoverageSpan Span; - LLVMRustCounter TrueCount; - LLVMRustCounter FalseCount; - LLVMRustMCDCBranchParameters MCDCBranchParams; -}; - -// Must match the layout of -// `rustc_codegen_llvm::coverageinfo::ffi::MCDCDecisionRegion`. -struct LLVMRustCoverageMCDCDecisionRegion { - LLVMRustCoverageSpan Span; - LLVMRustMCDCDecisionParameters MCDCDecisionParams; -}; - // FFI equivalent of enum `llvm::coverage::CounterExpression::ExprKind` // https://github.com/rust-lang/llvm-project/blob/ea6fa9c2/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h#L154 enum class LLVMRustCounterExprKind { @@ -159,10 +121,7 @@ extern "C" void LLVMRustCoverageWriteFunctionMappingsToBuffer( const LLVMRustCoverageExpansionRegion *ExpansionRegions, size_t NumExpansionRegions, const LLVMRustCoverageBranchRegion *BranchRegions, size_t NumBranchRegions, - const LLVMRustCoverageMCDCBranchRegion *MCDCBranchRegions, - size_t NumMCDCBranchRegions, - const LLVMRustCoverageMCDCDecisionRegion *MCDCDecisionRegions, - size_t NumMCDCDecisionRegions, RustStringRef BufferOut) { + RustStringRef BufferOut) { // Convert from FFI representation to LLVM representation. // Expressions: @@ -176,8 +135,8 @@ extern "C" void LLVMRustCoverageWriteFunctionMappingsToBuffer( } std::vector MappingRegions; - MappingRegions.reserve(NumCodeRegions + NumBranchRegions + - NumMCDCBranchRegions + NumMCDCDecisionRegions); + MappingRegions.reserve(NumCodeRegions + NumExpansionRegions + + NumBranchRegions); // Code regions: for (const auto &Region : ArrayRef(CodeRegions, NumCodeRegions)) { @@ -201,24 +160,6 @@ extern "C" void LLVMRustCoverageWriteFunctionMappingsToBuffer( Region.Span.LineEnd, Region.Span.ColumnEnd)); } - // MC/DC branch regions: - for (const auto &Region : ArrayRef(MCDCBranchRegions, NumMCDCBranchRegions)) { - MappingRegions.push_back(coverage::CounterMappingRegion::makeBranchRegion( - fromRust(Region.TrueCount), fromRust(Region.FalseCount), - Region.Span.FileID, Region.Span.LineStart, Region.Span.ColumnStart, - Region.Span.LineEnd, Region.Span.ColumnEnd, - fromRust(Region.MCDCBranchParams))); - } - - // MC/DC decision regions: - for (const auto &Region : - ArrayRef(MCDCDecisionRegions, NumMCDCDecisionRegions)) { - MappingRegions.push_back(coverage::CounterMappingRegion::makeDecisionRegion( - fromRust(Region.MCDCDecisionParams), Region.Span.FileID, - Region.Span.LineStart, Region.Span.ColumnStart, Region.Span.LineEnd, - Region.Span.ColumnEnd)); - } - // Write the converted expressions and mappings to a byte buffer. auto CoverageMappingWriter = coverage::CoverageMappingWriter( ArrayRef(VirtualFileMappingIDs, NumVirtualFileMappingIDs), diff --git a/compiler/rustc_middle/src/mir/coverage.rs b/compiler/rustc_middle/src/mir/coverage.rs index e26575b552ee1..fd4c64b9a61c2 100644 --- a/compiler/rustc_middle/src/mir/coverage.rs +++ b/compiler/rustc_middle/src/mir/coverage.rs @@ -50,25 +50,6 @@ rustc_index::newtype_index! { pub struct ExpressionId {} } -rustc_index::newtype_index! { - /// ID of a mcdc condition. Used by llvm to check mcdc coverage. - /// - /// Note for future: the max limit of 0xFFFF is probably too loose. Actually llvm does not - /// support decisions with too many conditions (7 and more at LLVM 18 while may be hundreds at 19) - /// and represents it with `int16_t`. This max value may be changed once we could - /// figure out an accurate limit. - #[derive(HashStable)] - #[encodable] - #[orderable] - #[max = 0xFFFF] - #[debug_format = "ConditionId({})"] - pub struct ConditionId {} -} - -impl ConditionId { - pub const START: Self = Self::from_usize(0); -} - /// Enum that can hold a constant zero value, the ID of an physical coverage /// counter, or the ID of a coverage-counter expression. #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord)] @@ -109,16 +90,6 @@ pub enum CoverageKind { /// During codegen, this might be lowered to `llvm.instrprof.increment` or /// to a no-op, depending on the outcome of counter-creation. VirtualCounter { bcb: BasicCoverageBlock }, - - /// Marks the point in MIR control flow represented by a evaluated condition. - /// - /// This is eventually lowered to instruments updating mcdc temp variables. - CondBitmapUpdate { index: u32, decision_depth: u16 }, - - /// Marks the point in MIR control flow represented by a evaluated decision. - /// - /// This is eventually lowered to `llvm.instrprof.mcdc.tvbitmap.update` in LLVM IR. - TestVectorBitmapUpdate { bitmap_idx: u32, decision_depth: u16 }, } impl Debug for CoverageKind { @@ -128,12 +99,6 @@ impl Debug for CoverageKind { SpanMarker => write!(fmt, "SpanMarker"), BlockMarker { id } => write!(fmt, "BlockMarker({:?})", id.index()), VirtualCounter { bcb } => write!(fmt, "VirtualCounter({bcb:?})"), - CondBitmapUpdate { index, decision_depth } => { - write!(fmt, "CondBitmapUpdate(index={:?}, depth={:?})", index, decision_depth) - } - TestVectorBitmapUpdate { bitmap_idx, decision_depth } => { - write!(fmt, "TestVectorUpdate({:?}, depth={:?})", bitmap_idx, decision_depth) - } } } } @@ -170,14 +135,6 @@ pub enum MappingKind { Code { bcb: BasicCoverageBlock }, /// Associates a branch region with separate counters for true and false. Branch { true_bcb: BasicCoverageBlock, false_bcb: BasicCoverageBlock }, - /// Associates a branch region with separate counters for true and false. - MCDCBranch { - true_bcb: BasicCoverageBlock, - false_bcb: BasicCoverageBlock, - mcdc_params: ConditionInfo, - }, - /// Associates a decision region with a bitmap and number of conditions. - MCDCDecision(DecisionInfo), } #[derive(Clone, Debug)] @@ -201,11 +158,6 @@ pub struct FunctionCoverageInfo { pub priority_list: Vec, pub mappings: Vec, - - pub mcdc_bitmap_bits: usize, - /// The depth of the deepest decision is used to know how many - /// temp condbitmaps should be allocated for the function. - pub mcdc_num_condition_bitmaps: usize, } /// Coverage information for a function, recorded during MIR building and @@ -222,10 +174,6 @@ pub struct CoverageInfoHi { /// data structures without having to scan the entire body first. pub num_block_markers: usize, pub branch_spans: Vec, - /// Branch spans generated by mcdc. Because of some limits mcdc builder give up generating - /// decisions including them so that they are handled as normal branch spans. - pub mcdc_degraded_branch_spans: Vec, - pub mcdc_spans: Vec<(MCDCDecisionSpan, Vec)>, } #[derive(Clone, Debug)] @@ -236,39 +184,6 @@ pub struct BranchSpan { pub false_marker: BlockMarkerId, } -#[derive(Copy, Clone, Debug)] -#[derive(TyEncodable, TyDecodable, Hash, HashStable)] -pub struct ConditionInfo { - pub condition_id: ConditionId, - pub true_next_id: Option, - pub false_next_id: Option, -} - -#[derive(Clone, Debug)] -#[derive(TyEncodable, TyDecodable, Hash, HashStable)] -pub struct MCDCBranchSpan { - pub span: Span, - pub condition_info: ConditionInfo, - pub true_marker: BlockMarkerId, - pub false_marker: BlockMarkerId, -} - -#[derive(Copy, Clone, Debug)] -#[derive(TyEncodable, TyDecodable, Hash, HashStable)] -pub struct DecisionInfo { - pub bitmap_idx: u32, - pub num_conditions: u16, -} - -#[derive(Clone, Debug)] -#[derive(TyEncodable, TyDecodable, Hash, HashStable)] -pub struct MCDCDecisionSpan { - pub span: Span, - pub end_markers: Vec, - pub decision_depth: u16, - pub num_conditions: usize, -} - /// Contains information needed during codegen, obtained by inspecting the /// function's MIR after MIR optimizations. /// diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs index ed067d491276f..84abcf550d28b 100644 --- a/compiler/rustc_middle/src/mir/pretty.rs +++ b/compiler/rustc_middle/src/mir/pretty.rs @@ -585,12 +585,7 @@ fn write_coverage_info_hi( coverage_info_hi: &coverage::CoverageInfoHi, w: &mut dyn io::Write, ) -> io::Result<()> { - let coverage::CoverageInfoHi { - num_block_markers: _, - branch_spans, - mcdc_degraded_branch_spans, - mcdc_spans, - } = coverage_info_hi; + let coverage::CoverageInfoHi { num_block_markers: _, branch_spans } = coverage_info_hi; // Only add an extra trailing newline if we printed at least one thing. let mut did_print = false; @@ -603,38 +598,6 @@ fn write_coverage_info_hi( did_print = true; } - for coverage::MCDCBranchSpan { span, true_marker, false_marker, .. } in - mcdc_degraded_branch_spans - { - writeln!( - w, - "{INDENT}coverage branch {{ true: {true_marker:?}, false: {false_marker:?} }} => {span:?}", - )?; - did_print = true; - } - - for ( - coverage::MCDCDecisionSpan { span, end_markers, decision_depth, num_conditions: _ }, - conditions, - ) in mcdc_spans - { - let num_conditions = conditions.len(); - writeln!( - w, - "{INDENT}coverage mcdc decision {{ num_conditions: {num_conditions:?}, end: {end_markers:?}, depth: {decision_depth:?} }} => {span:?}" - )?; - for coverage::MCDCBranchSpan { span, condition_info, true_marker, false_marker } in - conditions - { - writeln!( - w, - "{INDENT}coverage mcdc branch {{ condition_id: {:?}, true: {true_marker:?}, false: {false_marker:?} }} => {span:?}", - condition_info.condition_id - )?; - } - did_print = true; - } - if did_print { writeln!(w)?; } diff --git a/compiler/rustc_mir_build/messages.ftl b/compiler/rustc_mir_build/messages.ftl index 287639de663cb..83fbcb30dd941 100644 --- a/compiler/rustc_mir_build/messages.ftl +++ b/compiler/rustc_mir_build/messages.ftl @@ -121,8 +121,6 @@ mir_build_deref_raw_pointer_requires_unsafe_unsafe_op_in_unsafe_fn_allowed = .note = raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior .label = dereference of raw pointer -mir_build_exceeds_mcdc_condition_limit = number of conditions in decision ({$num_conditions}) exceeds limit ({$max_conditions}), so MC/DC analysis will not count this expression - mir_build_extern_static_requires_unsafe = use of extern static is unsafe and requires unsafe block .note = extern statics are not controlled by the Rust type system: invalid data, aliasing violations or data races will cause undefined behavior diff --git a/compiler/rustc_mir_build/src/builder/coverageinfo.rs b/compiler/rustc_mir_build/src/builder/coverageinfo.rs index aa43b273cff5c..14199c209217c 100644 --- a/compiler/rustc_mir_build/src/builder/coverageinfo.rs +++ b/compiler/rustc_mir_build/src/builder/coverageinfo.rs @@ -8,11 +8,8 @@ use rustc_middle::thir::{ExprId, ExprKind, Pat, Thir}; use rustc_middle::ty::TyCtxt; use rustc_span::def_id::LocalDefId; -use crate::builder::coverageinfo::mcdc::MCDCInfoBuilder; use crate::builder::{Builder, CFG}; -mod mcdc; - /// Collects coverage-related information during MIR building, to eventually be /// turned into a function's [`CoverageInfoHi`] when MIR building is complete. pub(crate) struct CoverageInfoBuilder { @@ -23,8 +20,6 @@ pub(crate) struct CoverageInfoBuilder { /// Present if branch coverage is enabled. branch_info: Option, - /// Present if MC/DC coverage is enabled. - mcdc_info: Option, } #[derive(Default)] @@ -83,7 +78,6 @@ impl CoverageInfoBuilder { nots: FxHashMap::default(), markers: BlockMarkerGen::default(), branch_info: tcx.sess.instrument_coverage_branch().then(BranchInfo::default), - mcdc_info: tcx.sess.instrument_coverage_mcdc().then(MCDCInfoBuilder::new), }) } @@ -135,26 +129,11 @@ impl CoverageInfoBuilder { fn register_two_way_branch<'tcx>( &mut self, - tcx: TyCtxt<'tcx>, cfg: &mut CFG<'tcx>, source_info: SourceInfo, true_block: BasicBlock, false_block: BasicBlock, ) { - // Separate path for handling branches when MC/DC is enabled. - if let Some(mcdc_info) = self.mcdc_info.as_mut() { - let inject_block_marker = - |source_info, block| self.markers.inject_block_marker(cfg, source_info, block); - mcdc_info.visit_evaluated_condition( - tcx, - source_info, - true_block, - false_block, - inject_block_marker, - ); - return; - } - // Bail out if branch coverage is not enabled. let Some(branch_info) = self.branch_info.as_mut() else { return }; @@ -169,23 +148,14 @@ impl CoverageInfoBuilder { } pub(crate) fn into_done(self) -> Box { - let Self { nots: _, markers: BlockMarkerGen { num_block_markers }, branch_info, mcdc_info } = - self; + let Self { nots: _, markers: BlockMarkerGen { num_block_markers }, branch_info } = self; let branch_spans = branch_info.map(|branch_info| branch_info.branch_spans).unwrap_or_default(); - let (mcdc_spans, mcdc_degraded_branch_spans) = - mcdc_info.map(MCDCInfoBuilder::into_done).unwrap_or_default(); - // For simplicity, always return an info struct (without Option), even // if there's nothing interesting in it. - Box::new(CoverageInfoHi { - num_block_markers, - branch_spans, - mcdc_degraded_branch_spans, - mcdc_spans, - }) + Box::new(CoverageInfoHi { num_block_markers, branch_spans }) } } @@ -238,14 +208,7 @@ impl<'tcx> Builder<'_, 'tcx> { mir::TerminatorKind::if_(mir::Operand::Copy(place), true_block, false_block), ); - // Separate path for handling branches when MC/DC is enabled. - coverage_info.register_two_way_branch( - self.tcx, - &mut self.cfg, - source_info, - true_block, - false_block, - ); + coverage_info.register_two_way_branch(&mut self.cfg, source_info, true_block, false_block); let join_block = self.cfg.start_new_block(); self.cfg.goto(true_block, source_info, join_block); @@ -276,13 +239,7 @@ impl<'tcx> Builder<'_, 'tcx> { let source_info = SourceInfo { span: self.thir[expr_id].span, scope: self.source_scope }; - coverage_info.register_two_way_branch( - self.tcx, - &mut self.cfg, - source_info, - then_block, - else_block, - ); + coverage_info.register_two_way_branch(&mut self.cfg, source_info, then_block, else_block); } /// If branch coverage is enabled, inject marker statements into `true_block` @@ -299,12 +256,6 @@ impl<'tcx> Builder<'_, 'tcx> { let Some(coverage_info) = self.coverage_info.as_mut() else { return }; let source_info = SourceInfo { span: pattern.span, scope: self.source_scope }; - coverage_info.register_two_way_branch( - self.tcx, - &mut self.cfg, - source_info, - true_block, - false_block, - ); + coverage_info.register_two_way_branch(&mut self.cfg, source_info, true_block, false_block); } } diff --git a/compiler/rustc_mir_build/src/builder/coverageinfo/mcdc.rs b/compiler/rustc_mir_build/src/builder/coverageinfo/mcdc.rs deleted file mode 100644 index 6b4871dc1fcc8..0000000000000 --- a/compiler/rustc_mir_build/src/builder/coverageinfo/mcdc.rs +++ /dev/null @@ -1,295 +0,0 @@ -use std::collections::VecDeque; - -use rustc_middle::bug; -use rustc_middle::mir::coverage::{ - BlockMarkerId, ConditionId, ConditionInfo, MCDCBranchSpan, MCDCDecisionSpan, -}; -use rustc_middle::mir::{BasicBlock, SourceInfo}; -use rustc_middle::thir::LogicalOp; -use rustc_middle::ty::TyCtxt; -use rustc_span::Span; - -use crate::builder::Builder; -use crate::errors::MCDCExceedsConditionLimit; - -/// LLVM uses `i16` to represent condition id. Hence `i16::MAX` is the hard limit for number of -/// conditions in a decision. -const MAX_CONDITIONS_IN_DECISION: usize = i16::MAX as usize; - -#[derive(Default)] -struct MCDCDecisionCtx { - /// To construct condition evaluation tree. - decision_stack: VecDeque, - processing_decision: Option, - conditions: Vec, -} - -struct MCDCState { - decision_ctx_stack: Vec, -} - -impl MCDCState { - fn new() -> Self { - Self { decision_ctx_stack: vec![MCDCDecisionCtx::default()] } - } - - /// Decision depth is given as a u16 to reduce the size of the `CoverageKind`, - /// as it is very unlikely that the depth ever reaches 2^16. - #[inline] - fn decision_depth(&self) -> u16 { - match u16::try_from(self.decision_ctx_stack.len()) - .expect( - "decision depth did not fit in u16, this is likely to be an instrumentation error", - ) - .checked_sub(1) - { - Some(d) => d, - None => bug!("Unexpected empty decision stack"), - } - } - - // At first we assign ConditionIds for each sub expression. - // If the sub expression is composite, re-assign its ConditionId to its LHS and generate a new ConditionId for its RHS. - // - // Example: "x = (A && B) || (C && D) || (D && F)" - // - // Visit Depth1: - // (A && B) || (C && D) || (D && F) - // ^-------LHS--------^ ^-RHS--^ - // ID=1 ID=2 - // - // Visit LHS-Depth2: - // (A && B) || (C && D) - // ^-LHS--^ ^-RHS--^ - // ID=1 ID=3 - // - // Visit LHS-Depth3: - // (A && B) - // LHS RHS - // ID=1 ID=4 - // - // Visit RHS-Depth3: - // (C && D) - // LHS RHS - // ID=3 ID=5 - // - // Visit RHS-Depth2: (D && F) - // LHS RHS - // ID=2 ID=6 - // - // Visit Depth1: - // (A && B) || (C && D) || (D && F) - // ID=1 ID=4 ID=3 ID=5 ID=2 ID=6 - // - // A node ID of '0' always means MC/DC isn't being tracked. - // - // If a "next" node ID is '0', it means it's the end of the test vector. - // - // As the compiler tracks expression in pre-order, we can ensure that condition info of parents are always properly assigned when their children are visited. - // - If the op is AND, the "false_next" of LHS and RHS should be the parent's "false_next". While "true_next" of the LHS is the RHS, the "true next" of RHS is the parent's "true_next". - // - If the op is OR, the "true_next" of LHS and RHS should be the parent's "true_next". While "false_next" of the LHS is the RHS, the "false next" of RHS is the parent's "false_next". - fn record_conditions(&mut self, op: LogicalOp, span: Span) { - let decision_depth = self.decision_depth(); - let Some(decision_ctx) = self.decision_ctx_stack.last_mut() else { - bug!("Unexpected empty decision_ctx_stack") - }; - let decision = match decision_ctx.processing_decision.as_mut() { - Some(decision) => { - decision.span = decision.span.to(span); - decision - } - None => decision_ctx.processing_decision.insert(MCDCDecisionSpan { - span, - num_conditions: 0, - end_markers: vec![], - decision_depth, - }), - }; - - let parent_condition = decision_ctx.decision_stack.pop_back().unwrap_or_else(|| { - assert_eq!( - decision.num_conditions, 0, - "decision stack must be empty only for empty decision" - ); - decision.num_conditions += 1; - ConditionInfo { - condition_id: ConditionId::START, - true_next_id: None, - false_next_id: None, - } - }); - let lhs_id = parent_condition.condition_id; - - let rhs_condition_id = ConditionId::from(decision.num_conditions); - decision.num_conditions += 1; - let (lhs, rhs) = match op { - LogicalOp::And => { - let lhs = ConditionInfo { - condition_id: lhs_id, - true_next_id: Some(rhs_condition_id), - false_next_id: parent_condition.false_next_id, - }; - let rhs = ConditionInfo { - condition_id: rhs_condition_id, - true_next_id: parent_condition.true_next_id, - false_next_id: parent_condition.false_next_id, - }; - (lhs, rhs) - } - LogicalOp::Or => { - let lhs = ConditionInfo { - condition_id: lhs_id, - true_next_id: parent_condition.true_next_id, - false_next_id: Some(rhs_condition_id), - }; - let rhs = ConditionInfo { - condition_id: rhs_condition_id, - true_next_id: parent_condition.true_next_id, - false_next_id: parent_condition.false_next_id, - }; - (lhs, rhs) - } - }; - // We visit expressions tree in pre-order, so place the left-hand side on the top. - decision_ctx.decision_stack.push_back(rhs); - decision_ctx.decision_stack.push_back(lhs); - } - - fn try_finish_decision( - &mut self, - span: Span, - true_marker: BlockMarkerId, - false_marker: BlockMarkerId, - degraded_branches: &mut Vec, - ) -> Option<(MCDCDecisionSpan, Vec)> { - let Some(decision_ctx) = self.decision_ctx_stack.last_mut() else { - bug!("Unexpected empty decision_ctx_stack") - }; - let Some(condition_info) = decision_ctx.decision_stack.pop_back() else { - let branch = MCDCBranchSpan { - span, - condition_info: ConditionInfo { - condition_id: ConditionId::START, - true_next_id: None, - false_next_id: None, - }, - true_marker, - false_marker, - }; - degraded_branches.push(branch); - return None; - }; - let Some(decision) = decision_ctx.processing_decision.as_mut() else { - bug!("Processing decision should have been created before any conditions are taken"); - }; - if condition_info.true_next_id.is_none() { - decision.end_markers.push(true_marker); - } - if condition_info.false_next_id.is_none() { - decision.end_markers.push(false_marker); - } - decision_ctx.conditions.push(MCDCBranchSpan { - span, - condition_info, - true_marker, - false_marker, - }); - - if decision_ctx.decision_stack.is_empty() { - let conditions = std::mem::take(&mut decision_ctx.conditions); - decision_ctx.processing_decision.take().map(|decision| (decision, conditions)) - } else { - None - } - } -} - -pub(crate) struct MCDCInfoBuilder { - degraded_spans: Vec, - mcdc_spans: Vec<(MCDCDecisionSpan, Vec)>, - state: MCDCState, -} - -impl MCDCInfoBuilder { - pub(crate) fn new() -> Self { - Self { degraded_spans: vec![], mcdc_spans: vec![], state: MCDCState::new() } - } - - pub(crate) fn visit_evaluated_condition( - &mut self, - tcx: TyCtxt<'_>, - source_info: SourceInfo, - true_block: BasicBlock, - false_block: BasicBlock, - mut inject_block_marker: impl FnMut(SourceInfo, BasicBlock) -> BlockMarkerId, - ) { - let true_marker = inject_block_marker(source_info, true_block); - let false_marker = inject_block_marker(source_info, false_block); - - // take_condition() returns Some for decision_result when the decision stack - // is empty, i.e. when all the conditions of the decision were instrumented, - // and the decision is "complete". - if let Some((decision, conditions)) = self.state.try_finish_decision( - source_info.span, - true_marker, - false_marker, - &mut self.degraded_spans, - ) { - let num_conditions = conditions.len(); - assert_eq!( - num_conditions, decision.num_conditions, - "final number of conditions is not correct" - ); - match num_conditions { - 0 => { - unreachable!("Decision with no condition is not expected"); - } - 1..=MAX_CONDITIONS_IN_DECISION => { - self.mcdc_spans.push((decision, conditions)); - } - _ => { - self.degraded_spans.extend(conditions); - - tcx.dcx().emit_warn(MCDCExceedsConditionLimit { - span: decision.span, - num_conditions, - max_conditions: MAX_CONDITIONS_IN_DECISION, - }); - } - } - } - } - - pub(crate) fn into_done( - self, - ) -> (Vec<(MCDCDecisionSpan, Vec)>, Vec) { - (self.mcdc_spans, self.degraded_spans) - } -} - -impl Builder<'_, '_> { - pub(crate) fn visit_coverage_branch_operation(&mut self, logical_op: LogicalOp, span: Span) { - if let Some(coverage_info) = self.coverage_info.as_mut() - && let Some(mcdc_info) = coverage_info.mcdc_info.as_mut() - { - mcdc_info.state.record_conditions(logical_op, span); - } - } - - pub(crate) fn mcdc_increment_depth_if_enabled(&mut self) { - if let Some(coverage_info) = self.coverage_info.as_mut() - && let Some(mcdc_info) = coverage_info.mcdc_info.as_mut() - { - mcdc_info.state.decision_ctx_stack.push(MCDCDecisionCtx::default()); - }; - } - - pub(crate) fn mcdc_decrement_depth_if_enabled(&mut self) { - if let Some(coverage_info) = self.coverage_info.as_mut() - && let Some(mcdc_info) = coverage_info.mcdc_info.as_mut() - && mcdc_info.state.decision_ctx_stack.pop().is_none() - { - bug!("Unexpected empty decision stack"); - }; - } -} diff --git a/compiler/rustc_mir_build/src/builder/expr/into.rs b/compiler/rustc_mir_build/src/builder/expr/into.rs index 82b883a99a11c..eb99c184bd296 100644 --- a/compiler/rustc_mir_build/src/builder/expr/into.rs +++ b/compiler/rustc_mir_build/src/builder/expr/into.rs @@ -159,8 +159,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let condition_scope = this.local_scope(); let source_info = this.source_info(expr.span); - this.visit_coverage_branch_operation(op, expr.span); - // We first evaluate the left-hand side of the predicate ... let (then_block, else_block) = this.in_if_then_scope(condition_scope, expr.span, |this| { diff --git a/compiler/rustc_mir_build/src/builder/matches/mod.rs b/compiler/rustc_mir_build/src/builder/matches/mod.rs index 2c29b8628417f..9cdfb86333089 100644 --- a/compiler/rustc_mir_build/src/builder/matches/mod.rs +++ b/compiler/rustc_mir_build/src/builder/matches/mod.rs @@ -125,15 +125,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let expr_span = expr.span; match expr.kind { - ExprKind::LogicalOp { op: op @ LogicalOp::And, lhs, rhs } => { - this.visit_coverage_branch_operation(op, expr_span); + ExprKind::LogicalOp { op: LogicalOp::And, lhs, rhs } => { let lhs_then_block = this.then_else_break_inner(block, lhs, args).into_block(); let rhs_then_block = this.then_else_break_inner(lhs_then_block, rhs, args).into_block(); rhs_then_block.unit() } - ExprKind::LogicalOp { op: op @ LogicalOp::Or, lhs, rhs } => { - this.visit_coverage_branch_operation(op, expr_span); + ExprKind::LogicalOp { op: LogicalOp::Or, lhs, rhs } => { let local_scope = this.local_scope(); let (lhs_success_block, failure_block) = this.in_if_then_scope(local_scope, expr_span, |this| { @@ -214,9 +212,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let temp_scope = args.temp_scope_override.unwrap_or_else(|| this.local_scope()); let mutability = Mutability::Mut; - // Increment the decision depth, in case we encounter boolean expressions - // further down. - this.mcdc_increment_depth_if_enabled(); let place = unpack!( block = this.as_temp( block, @@ -228,7 +223,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { mutability ) ); - this.mcdc_decrement_depth_if_enabled(); let operand = Operand::Move(Place::from(place)); diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs index 1a52c6c85cb6e..58c3de4a8b59c 100644 --- a/compiler/rustc_mir_build/src/errors.rs +++ b/compiler/rustc_mir_build/src/errors.rs @@ -975,15 +975,6 @@ pub(crate) struct NonEmptyNeverPattern<'tcx> { pub(crate) ty: Ty<'tcx>, } -#[derive(Diagnostic)] -#[diag(mir_build_exceeds_mcdc_condition_limit)] -pub(crate) struct MCDCExceedsConditionLimit { - #[primary_span] - pub(crate) span: Span, - pub(crate) num_conditions: usize, - pub(crate) max_conditions: usize, -} - #[derive(Diagnostic)] #[diag(mir_build_pattern_not_covered, code = E0005)] pub(crate) struct PatternNotCovered<'s, 'tcx> { diff --git a/compiler/rustc_mir_transform/messages.ftl b/compiler/rustc_mir_transform/messages.ftl index ae3062f07de9c..2e08f50e8a9aa 100644 --- a/compiler/rustc_mir_transform/messages.ftl +++ b/compiler/rustc_mir_transform/messages.ftl @@ -9,8 +9,6 @@ mir_transform_const_mut_borrow = taking a mutable reference to a `const` item .note2 = the mutable reference will refer to this temporary, not the original `const` item .note3 = mutable reference created due to call to this method -mir_transform_exceeds_mcdc_test_vector_limit = number of total test vectors in one function will exceed limit ({$max_num_test_vectors}) if this decision is instrumented, so MC/DC analysis ignores it - mir_transform_ffi_unwind_call = call to {$foreign -> [true] foreign function *[false] function pointer diff --git a/compiler/rustc_mir_transform/src/check_inline.rs b/compiler/rustc_mir_transform/src/check_inline.rs index af6da209081bf..8d28cb3ca003d 100644 --- a/compiler/rustc_mir_transform/src/check_inline.rs +++ b/compiler/rustc_mir_transform/src/check_inline.rs @@ -45,12 +45,6 @@ pub(super) fn is_inline_valid_on_fn<'tcx>( return Err("#[rustc_no_mir_inline]"); } - // FIXME(#127234): Coverage instrumentation currently doesn't handle inlined - // MIR correctly when Modified Condition/Decision Coverage is enabled. - if tcx.sess.instrument_coverage_mcdc() { - return Err("incompatible with MC/DC coverage"); - } - let ty = tcx.type_of(def_id); if match ty.instantiate_identity().kind() { ty::FnDef(..) => tcx.fn_sig(def_id).instantiate_identity().c_variadic(), diff --git a/compiler/rustc_mir_transform/src/coverage/mappings.rs b/compiler/rustc_mir_transform/src/coverage/mappings.rs index b0e24cf2bdb86..399978b5915a0 100644 --- a/compiler/rustc_mir_transform/src/coverage/mappings.rs +++ b/compiler/rustc_mir_transform/src/coverage/mappings.rs @@ -1,10 +1,5 @@ -use std::collections::BTreeSet; - -use rustc_data_structures::fx::FxIndexMap; use rustc_index::IndexVec; -use rustc_middle::mir::coverage::{ - BlockMarkerId, BranchSpan, ConditionId, ConditionInfo, CoverageInfoHi, CoverageKind, -}; +use rustc_middle::mir::coverage::{BlockMarkerId, BranchSpan, CoverageInfoHi, CoverageKind}; use rustc_middle::mir::{self, BasicBlock, StatementKind}; use rustc_middle::ty::TyCtxt; use rustc_span::Span; @@ -13,7 +8,6 @@ use crate::coverage::ExtractedHirInfo; use crate::coverage::graph::{BasicCoverageBlock, CoverageGraph}; use crate::coverage::spans::extract_refined_covspans; use crate::coverage::unexpand::unexpand_into_body_span; -use crate::errors::MCDCExceedsTestVectorLimit; /// Associates an ordinary executable code span with its corresponding BCB. #[derive(Debug)] @@ -22,9 +16,6 @@ pub(super) struct CodeMapping { pub(super) bcb: BasicCoverageBlock, } -/// This is separate from [`MCDCBranch`] to help prepare for larger changes -/// that will be needed for improved branch coverage in the future. -/// (See .) #[derive(Debug)] pub(super) struct BranchPair { pub(super) span: Span, @@ -32,40 +23,10 @@ pub(super) struct BranchPair { pub(super) false_bcb: BasicCoverageBlock, } -/// Associates an MC/DC branch span with condition info besides fields for normal branch. -#[derive(Debug)] -pub(super) struct MCDCBranch { - pub(super) span: Span, - pub(super) true_bcb: BasicCoverageBlock, - pub(super) false_bcb: BasicCoverageBlock, - pub(super) condition_info: ConditionInfo, - // Offset added to test vector idx if this branch is evaluated to true. - pub(super) true_index: usize, - // Offset added to test vector idx if this branch is evaluated to false. - pub(super) false_index: usize, -} - -/// Associates an MC/DC decision with its join BCBs. -#[derive(Debug)] -pub(super) struct MCDCDecision { - pub(super) span: Span, - pub(super) end_bcbs: BTreeSet, - pub(super) bitmap_idx: usize, - pub(super) num_test_vectors: usize, - pub(super) decision_depth: u16, -} - -// LLVM uses `i32` to index the bitmap. Thus `i32::MAX` is the hard limit for number of all test vectors -// in a function. -const MCDC_MAX_BITMAP_SIZE: usize = i32::MAX as usize; - #[derive(Default)] pub(super) struct ExtractedMappings { pub(super) code_mappings: Vec, pub(super) branch_pairs: Vec, - pub(super) mcdc_bitmap_bits: usize, - pub(super) mcdc_degraded_branches: Vec, - pub(super) mcdc_mappings: Vec<(MCDCDecision, Vec)>, } /// Extracts coverage-relevant spans from MIR, and associates them with @@ -78,32 +39,13 @@ pub(super) fn extract_all_mapping_info_from_mir<'tcx>( ) -> ExtractedMappings { let mut code_mappings = vec![]; let mut branch_pairs = vec![]; - let mut mcdc_bitmap_bits = 0; - let mut mcdc_degraded_branches = vec![]; - let mut mcdc_mappings = vec![]; // Extract ordinary code mappings from MIR statement/terminator spans. extract_refined_covspans(tcx, mir_body, hir_info, graph, &mut code_mappings); branch_pairs.extend(extract_branch_pairs(mir_body, hir_info, graph)); - extract_mcdc_mappings( - mir_body, - tcx, - hir_info.body_span, - graph, - &mut mcdc_bitmap_bits, - &mut mcdc_degraded_branches, - &mut mcdc_mappings, - ); - - ExtractedMappings { - code_mappings, - branch_pairs, - mcdc_bitmap_bits, - mcdc_degraded_branches, - mcdc_mappings, - } + ExtractedMappings { code_mappings, branch_pairs } } fn resolve_block_markers( @@ -127,12 +69,6 @@ fn resolve_block_markers( block_markers } -// FIXME: There is currently a lot of redundancy between -// `extract_branch_pairs` and `extract_mcdc_mappings`. This is needed so -// that they can each be modified without interfering with the other, but in -// the long term we should try to bring them together again when branch coverage -// and MC/DC coverage support are more mature. - pub(super) fn extract_branch_pairs( mir_body: &mir::Body<'_>, hir_info: &ExtractedHirInfo, @@ -162,175 +98,3 @@ pub(super) fn extract_branch_pairs( }) .collect::>() } - -pub(super) fn extract_mcdc_mappings( - mir_body: &mir::Body<'_>, - tcx: TyCtxt<'_>, - body_span: Span, - graph: &CoverageGraph, - mcdc_bitmap_bits: &mut usize, - mcdc_degraded_branches: &mut impl Extend, - mcdc_mappings: &mut impl Extend<(MCDCDecision, Vec)>, -) { - let Some(coverage_info_hi) = mir_body.coverage_info_hi.as_deref() else { return }; - - let block_markers = resolve_block_markers(coverage_info_hi, mir_body); - - let bcb_from_marker = |marker: BlockMarkerId| graph.bcb_from_bb(block_markers[marker]?); - - let check_branch_bcb = - |raw_span: Span, true_marker: BlockMarkerId, false_marker: BlockMarkerId| { - // For now, ignore any branch span that was introduced by - // expansion. This makes things like assert macros less noisy. - if !raw_span.ctxt().outer_expn_data().is_root() { - return None; - } - let span = unexpand_into_body_span(raw_span, body_span)?; - - let true_bcb = bcb_from_marker(true_marker)?; - let false_bcb = bcb_from_marker(false_marker)?; - Some((span, true_bcb, false_bcb)) - }; - - let to_mcdc_branch = |&mir::coverage::MCDCBranchSpan { - span: raw_span, - condition_info, - true_marker, - false_marker, - }| { - let (span, true_bcb, false_bcb) = check_branch_bcb(raw_span, true_marker, false_marker)?; - Some(MCDCBranch { - span, - true_bcb, - false_bcb, - condition_info, - true_index: usize::MAX, - false_index: usize::MAX, - }) - }; - - let mut get_bitmap_idx = |num_test_vectors: usize| -> Option { - let bitmap_idx = *mcdc_bitmap_bits; - let next_bitmap_bits = bitmap_idx.saturating_add(num_test_vectors); - (next_bitmap_bits <= MCDC_MAX_BITMAP_SIZE).then(|| { - *mcdc_bitmap_bits = next_bitmap_bits; - bitmap_idx - }) - }; - mcdc_degraded_branches - .extend(coverage_info_hi.mcdc_degraded_branch_spans.iter().filter_map(to_mcdc_branch)); - - mcdc_mappings.extend(coverage_info_hi.mcdc_spans.iter().filter_map(|(decision, branches)| { - if branches.len() == 0 { - return None; - } - let decision_span = unexpand_into_body_span(decision.span, body_span)?; - - let end_bcbs = decision - .end_markers - .iter() - .map(|&marker| bcb_from_marker(marker)) - .collect::>()?; - let mut branch_mappings: Vec<_> = branches.into_iter().filter_map(to_mcdc_branch).collect(); - if branch_mappings.len() != branches.len() { - mcdc_degraded_branches.extend(branch_mappings); - return None; - } - let num_test_vectors = calc_test_vectors_index(&mut branch_mappings); - let Some(bitmap_idx) = get_bitmap_idx(num_test_vectors) else { - tcx.dcx().emit_warn(MCDCExceedsTestVectorLimit { - span: decision_span, - max_num_test_vectors: MCDC_MAX_BITMAP_SIZE, - }); - mcdc_degraded_branches.extend(branch_mappings); - return None; - }; - // LLVM requires span of the decision contains all spans of its conditions. - // Usually the decision span meets the requirement well but in cases like macros it may not. - let span = branch_mappings - .iter() - .map(|branch| branch.span) - .reduce(|lhs, rhs| lhs.to(rhs)) - .map( - |joint_span| { - if decision_span.contains(joint_span) { decision_span } else { joint_span } - }, - ) - .expect("branch mappings are ensured to be non-empty as checked above"); - Some(( - MCDCDecision { - span, - end_bcbs, - bitmap_idx, - num_test_vectors, - decision_depth: decision.decision_depth, - }, - branch_mappings, - )) - })); -} - -// LLVM checks the executed test vector by accumulating indices of tested branches. -// We calculate number of all possible test vectors of the decision and assign indices -// to branches here. -// See [the rfc](https://discourse.llvm.org/t/rfc-coverage-new-algorithm-and-file-format-for-mc-dc/76798/) -// for more details about the algorithm. -// This function is mostly like [`TVIdxBuilder::TvIdxBuilder`](https://github.com/llvm/llvm-project/blob/d594d9f7f4dc6eb748b3261917db689fdc348b96/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp#L226) -fn calc_test_vectors_index(conditions: &mut Vec) -> usize { - let mut indegree_stats = IndexVec::::from_elem_n(0, conditions.len()); - // `num_paths` is `width` described at the llvm rfc, which indicates how many paths reaching the condition node. - let mut num_paths_stats = IndexVec::::from_elem_n(0, conditions.len()); - let mut next_conditions = conditions - .iter_mut() - .map(|branch| { - let ConditionInfo { condition_id, true_next_id, false_next_id } = branch.condition_info; - [true_next_id, false_next_id] - .into_iter() - .flatten() - .for_each(|next_id| indegree_stats[next_id] += 1); - (condition_id, branch) - }) - .collect::>(); - - let mut queue = - std::collections::VecDeque::from_iter(next_conditions.swap_remove(&ConditionId::START)); - num_paths_stats[ConditionId::START] = 1; - let mut decision_end_nodes = Vec::new(); - while let Some(branch) = queue.pop_front() { - let ConditionInfo { condition_id, true_next_id, false_next_id } = branch.condition_info; - let (false_index, true_index) = (&mut branch.false_index, &mut branch.true_index); - let this_paths_count = num_paths_stats[condition_id]; - // Note. First check the false next to ensure conditions are touched in same order with llvm-cov. - for (next, index) in [(false_next_id, false_index), (true_next_id, true_index)] { - if let Some(next_id) = next { - let next_paths_count = &mut num_paths_stats[next_id]; - *index = *next_paths_count; - *next_paths_count = next_paths_count.saturating_add(this_paths_count); - let next_indegree = &mut indegree_stats[next_id]; - *next_indegree -= 1; - if *next_indegree == 0 { - queue.push_back(next_conditions.swap_remove(&next_id).expect( - "conditions with non-zero indegree before must be in next_conditions", - )); - } - } else { - decision_end_nodes.push((this_paths_count, condition_id, index)); - } - } - } - assert!(next_conditions.is_empty(), "the decision tree has untouched nodes"); - let mut cur_idx = 0; - // LLVM hopes the end nodes are sorted in descending order by `num_paths` so that it can - // optimize bitmap size for decisions in tree form such as `a && b && c && d && ...`. - decision_end_nodes.sort_by_key(|(num_paths, _, _)| usize::MAX - *num_paths); - for (num_paths, condition_id, index) in decision_end_nodes { - assert_eq!( - num_paths, num_paths_stats[condition_id], - "end nodes should not be updated since they were visited" - ); - assert_eq!(*index, usize::MAX, "end nodes should not be assigned index before"); - *index = cur_idx; - cur_idx += num_paths; - } - cur_idx -} diff --git a/compiler/rustc_mir_transform/src/coverage/mod.rs b/compiler/rustc_mir_transform/src/coverage/mod.rs index f253d1662cac8..f6945a95a7c38 100644 --- a/compiler/rustc_mir_transform/src/coverage/mod.rs +++ b/compiler/rustc_mir_transform/src/coverage/mod.rs @@ -10,9 +10,7 @@ mod unexpand; use rustc_hir as hir; use rustc_hir::intravisit::{Visitor, walk_expr}; use rustc_middle::hir::nested_filter; -use rustc_middle::mir::coverage::{ - CoverageKind, DecisionInfo, FunctionCoverageInfo, Mapping, MappingKind, -}; +use rustc_middle::mir::coverage::{CoverageKind, FunctionCoverageInfo, Mapping, MappingKind}; use rustc_middle::mir::{self, BasicBlock, Statement, StatementKind, TerminatorKind}; use rustc_middle::ty::TyCtxt; use rustc_span::Span; @@ -95,14 +93,6 @@ fn instrument_function_for_coverage<'tcx>(tcx: TyCtxt<'tcx>, mir_body: &mut mir: // Inject coverage statements into MIR. inject_coverage_statements(mir_body, &graph); - inject_mcdc_statements(mir_body, &graph, &extracted_mappings); - - let mcdc_num_condition_bitmaps = extracted_mappings - .mcdc_mappings - .iter() - .map(|&(mappings::MCDCDecision { decision_depth, .. }, _)| decision_depth) - .max() - .map_or(0, |max| usize::from(max) + 1); mir_body.function_coverage_info = Some(Box::new(FunctionCoverageInfo { function_source_hash: hir_info.function_source_hash, @@ -111,9 +101,6 @@ fn instrument_function_for_coverage<'tcx>(tcx: TyCtxt<'tcx>, mir_body: &mut mir: priority_list, mappings, - - mcdc_bitmap_bits: extracted_mappings.mcdc_bitmap_bits, - mcdc_num_condition_bitmaps, })); } @@ -124,13 +111,7 @@ fn instrument_function_for_coverage<'tcx>(tcx: TyCtxt<'tcx>, mir_body: &mut mir: /// function can potentially be simplified even further. fn create_mappings(extracted_mappings: &ExtractedMappings) -> Vec { // Fully destructure the mappings struct to make sure we don't miss any kinds. - let ExtractedMappings { - code_mappings, - branch_pairs, - mcdc_bitmap_bits: _, - mcdc_degraded_branches, - mcdc_mappings, - } = extracted_mappings; + let ExtractedMappings { code_mappings, branch_pairs } = extracted_mappings; let mut mappings = Vec::new(); mappings.extend(code_mappings.iter().map( @@ -148,57 +129,6 @@ fn create_mappings(extracted_mappings: &ExtractedMappings) -> Vec { }, )); - // MCDC branch mappings are appended with their decisions in case decisions were ignored. - mappings.extend(mcdc_degraded_branches.iter().map( - |&mappings::MCDCBranch { - span, - true_bcb, - false_bcb, - condition_info: _, - true_index: _, - false_index: _, - }| { Mapping { kind: MappingKind::Branch { true_bcb, false_bcb }, span } }, - )); - - for (decision, branches) in mcdc_mappings { - // FIXME(#134497): Previously it was possible for some of these branch - // conversions to fail, in which case the remaining branches in the - // decision would be degraded to plain `MappingKind::Branch`. - // The changes in #134497 made that failure impossible, because the - // fallible step was deferred to codegen. But the corresponding code - // in codegen wasn't updated to detect the need for a degrade step. - let conditions = branches - .into_iter() - .map( - |&mappings::MCDCBranch { - span, - true_bcb, - false_bcb, - condition_info, - true_index: _, - false_index: _, - }| { - Mapping { - kind: MappingKind::MCDCBranch { - true_bcb, - false_bcb, - mcdc_params: condition_info, - }, - span, - } - }, - ) - .collect::>(); - - // LLVM requires end index for counter mapping regions. - let kind = MappingKind::MCDCDecision(DecisionInfo { - bitmap_idx: (decision.bitmap_idx + decision.num_test_vectors) as u32, - num_conditions: u16::try_from(conditions.len()).unwrap(), - }); - let span = decision.span; - mappings.extend(std::iter::once(Mapping { kind, span }).chain(conditions.into_iter())); - } - mappings } @@ -210,51 +140,6 @@ fn inject_coverage_statements<'tcx>(mir_body: &mut mir::Body<'tcx>, graph: &Cove } } -/// For each conditions inject statements to update condition bitmap after it has been evaluated. -/// For each decision inject statements to update test vector bitmap after it has been evaluated. -fn inject_mcdc_statements<'tcx>( - mir_body: &mut mir::Body<'tcx>, - graph: &CoverageGraph, - extracted_mappings: &ExtractedMappings, -) { - for (decision, conditions) in &extracted_mappings.mcdc_mappings { - // Inject test vector update first because `inject_statement` always insert new statement at head. - for &end in &decision.end_bcbs { - let end_bb = graph[end].leader_bb(); - inject_statement( - mir_body, - CoverageKind::TestVectorBitmapUpdate { - bitmap_idx: decision.bitmap_idx as u32, - decision_depth: decision.decision_depth, - }, - end_bb, - ); - } - - for &mappings::MCDCBranch { - span: _, - true_bcb, - false_bcb, - condition_info: _, - true_index, - false_index, - } in conditions - { - for (index, bcb) in [(false_index, false_bcb), (true_index, true_bcb)] { - let bb = graph[bcb].leader_bb(); - inject_statement( - mir_body, - CoverageKind::CondBitmapUpdate { - index: index as u32, - decision_depth: decision.decision_depth, - }, - bb, - ); - } - } - } -} - fn inject_statement(mir_body: &mut mir::Body<'_>, counter_kind: CoverageKind, bb: BasicBlock) { debug!(" injecting statement {counter_kind:?} for {bb:?}"); let data = &mut mir_body[bb]; diff --git a/compiler/rustc_mir_transform/src/coverage/query.rs b/compiler/rustc_mir_transform/src/coverage/query.rs index c195ca51540d0..63c550c27fe4e 100644 --- a/compiler/rustc_mir_transform/src/coverage/query.rs +++ b/compiler/rustc_mir_transform/src/coverage/query.rs @@ -111,11 +111,6 @@ fn coverage_ids_info<'tcx>( bcb_needs_counter.insert(true_bcb); bcb_needs_counter.insert(false_bcb); } - MappingKind::MCDCBranch { true_bcb, false_bcb, mcdc_params: _ } => { - bcb_needs_counter.insert(true_bcb); - bcb_needs_counter.insert(false_bcb); - } - MappingKind::MCDCDecision(_) => {} } } diff --git a/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs b/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs index 804cd8ab3f7d3..7985e1c079881 100644 --- a/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs +++ b/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs @@ -101,11 +101,7 @@ fn filtered_statement_span(statement: &Statement<'_>) -> Option { StatementKind::Coverage(CoverageKind::BlockMarker { .. }) => None, // These coverage statements should not exist prior to coverage instrumentation. - StatementKind::Coverage( - CoverageKind::VirtualCounter { .. } - | CoverageKind::CondBitmapUpdate { .. } - | CoverageKind::TestVectorBitmapUpdate { .. }, - ) => bug!( + StatementKind::Coverage(CoverageKind::VirtualCounter { .. }) => bug!( "Unexpected coverage statement found during coverage instrumentation: {statement:?}" ), } diff --git a/compiler/rustc_mir_transform/src/errors.rs b/compiler/rustc_mir_transform/src/errors.rs index cffa0183fa7a5..ad9635aae330d 100644 --- a/compiler/rustc_mir_transform/src/errors.rs +++ b/compiler/rustc_mir_transform/src/errors.rs @@ -117,14 +117,6 @@ pub(crate) struct FnItemRef { pub ident: Ident, } -#[derive(Diagnostic)] -#[diag(mir_transform_exceeds_mcdc_test_vector_limit)] -pub(crate) struct MCDCExceedsTestVectorLimit { - #[primary_span] - pub(crate) span: Span, - pub(crate) max_num_test_vectors: usize, -} - pub(crate) struct MustNotSupend<'a, 'tcx> { pub tcx: TyCtxt<'tcx>, pub yield_sp: Span, diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index cfeadf3c7595a..c665c85d1fea4 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -190,7 +190,7 @@ pub struct CoverageOptions { pub discard_all_spans_in_codegen: bool, } -/// Controls whether branch coverage or MC/DC coverage is enabled. +/// Controls whether branch coverage is enabled. #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Default)] pub enum CoverageLevel { /// Instrument for coverage at the MIR block level. @@ -214,9 +214,6 @@ pub enum CoverageLevel { /// instrumentation, so it might be removed in the future when MC/DC is /// sufficiently complete, or if it is making MC/DC changes difficult. Condition, - /// Instrument for MC/DC. Mostly a superset of condition coverage, but might - /// differ in some corner cases. - Mcdc, } // The different settings that the `-Z offload` flag can have. diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 880b08d444414..7c18fd8909808 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -755,7 +755,7 @@ mod desc { pub(crate) const parse_linker_flavor: &str = ::rustc_target::spec::LinkerFlavorCli::one_of(); pub(crate) const parse_dump_mono_stats: &str = "`markdown` (default) or `json`"; pub(crate) const parse_instrument_coverage: &str = parse_bool; - pub(crate) const parse_coverage_options: &str = "`block` | `branch` | `condition` | `mcdc`"; + pub(crate) const parse_coverage_options: &str = "`block` | `branch` | `condition`"; pub(crate) const parse_instrument_xray: &str = "either a boolean (`yes`, `no`, `on`, `off`, etc), or a comma separated list of settings: `always` or `never` (mutually exclusive), `ignore-loops`, `instruction-threshold=N`, `skip-entry`, `skip-exit`"; pub(crate) const parse_unpretty: &str = "`string` or `string=string`"; pub(crate) const parse_treat_err_as_bug: &str = "either no value or a non-negative number"; @@ -1458,7 +1458,6 @@ pub mod parse { "block" => slot.level = CoverageLevel::Block, "branch" => slot.level = CoverageLevel::Branch, "condition" => slot.level = CoverageLevel::Condition, - "mcdc" => slot.level = CoverageLevel::Mcdc, "discard-all-spans-in-codegen" => slot.discard_all_spans_in_codegen = true, _ => return false, } diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index b94636fea94e1..c6956cf5f23b5 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -354,11 +354,6 @@ impl Session { && self.opts.unstable_opts.coverage_options.level >= CoverageLevel::Condition } - pub fn instrument_coverage_mcdc(&self) -> bool { - self.instrument_coverage() - && self.opts.unstable_opts.coverage_options.level >= CoverageLevel::Mcdc - } - /// Provides direct access to the `CoverageOptions` struct, so that /// individual flags for debugging/testing coverage instrumetation don't /// need separate accessors. diff --git a/src/doc/unstable-book/src/compiler-flags/coverage-options.md b/src/doc/unstable-book/src/compiler-flags/coverage-options.md index 87a9a00b3c0f7..693a0a58b49ef 100644 --- a/src/doc/unstable-book/src/compiler-flags/coverage-options.md +++ b/src/doc/unstable-book/src/compiler-flags/coverage-options.md @@ -5,7 +5,7 @@ This option controls details of the coverage instrumentation performed by Multiple options can be passed, separated by commas. Valid options are: -- `block`, `branch`, `condition`, `mcdc`: +- `block`, `branch`, `condition`: Sets the level of coverage instrumentation. Setting the level will override any previously-specified level. - `block` (default): @@ -15,6 +15,3 @@ Multiple options can be passed, separated by commas. Valid options are: - `condition`: In addition to branch coverage, also instruments some boolean expressions as branches, even if they are not directly used as branch conditions. - - `mcdc`: - In addition to condition coverage, also enables MC/DC instrumentation. - (Branch coverage instrumentation may differ in some cases.) diff --git a/tests/coverage/mcdc/condition-limit.cov-map b/tests/coverage/mcdc/condition-limit.cov-map deleted file mode 100644 index ffee97cfbc50b..0000000000000 --- a/tests/coverage/mcdc/condition-limit.cov-map +++ /dev/null @@ -1,58 +0,0 @@ -Function name: condition_limit::accept_7_conditions -Raw bytes (192): 0x[01, 01, 08, 01, 05, 05, 09, 09, 0d, 0d, 11, 11, 15, 15, 19, 19, 1d, 01, 1d, 1b, 01, 06, 01, 00, 2c, 01, 01, 0a, 00, 0b, 01, 00, 0d, 00, 0e, 01, 00, 10, 00, 11, 01, 00, 13, 00, 14, 01, 00, 16, 00, 17, 01, 00, 19, 00, 1a, 01, 00, 1c, 00, 1d, 01, 00, 21, 00, 29, 01, 01, 08, 00, 09, 28, 08, 07, 00, 08, 00, 27, 30, 05, 02, 01, 07, 00, 00, 08, 00, 09, 05, 00, 0d, 00, 0e, 30, 09, 06, 07, 06, 00, 00, 0d, 00, 0e, 09, 00, 12, 00, 13, 30, 0d, 0a, 06, 05, 00, 00, 12, 00, 13, 0d, 00, 17, 00, 18, 30, 11, 0e, 05, 04, 00, 00, 17, 00, 18, 11, 00, 1c, 00, 1d, 30, 15, 12, 04, 03, 00, 00, 1c, 00, 1d, 15, 00, 21, 00, 22, 30, 19, 16, 03, 02, 00, 00, 21, 00, 22, 19, 00, 26, 00, 27, 30, 1d, 1a, 02, 00, 00, 00, 26, 00, 27, 1d, 00, 28, 02, 06, 1e, 02, 05, 00, 06, 01, 01, 01, 00, 02] -Number of files: 1 -- file 0 => $DIR/condition-limit.rs -Number of expressions: 8 -- expression 0 operands: lhs = Counter(0), rhs = Counter(1) -- expression 1 operands: lhs = Counter(1), rhs = Counter(2) -- expression 2 operands: lhs = Counter(2), rhs = Counter(3) -- expression 3 operands: lhs = Counter(3), rhs = Counter(4) -- expression 4 operands: lhs = Counter(4), rhs = Counter(5) -- expression 5 operands: lhs = Counter(5), rhs = Counter(6) -- expression 6 operands: lhs = Counter(6), rhs = Counter(7) -- expression 7 operands: lhs = Counter(0), rhs = Counter(7) -Number of file 0 mappings: 27 -- Code(Counter(0)) at (prev + 6, 1) to (start + 0, 44) -- Code(Counter(0)) at (prev + 1, 10) to (start + 0, 11) -- Code(Counter(0)) at (prev + 0, 13) to (start + 0, 14) -- Code(Counter(0)) at (prev + 0, 16) to (start + 0, 17) -- Code(Counter(0)) at (prev + 0, 19) to (start + 0, 20) -- Code(Counter(0)) at (prev + 0, 22) to (start + 0, 23) -- Code(Counter(0)) at (prev + 0, 25) to (start + 0, 26) -- Code(Counter(0)) at (prev + 0, 28) to (start + 0, 29) -- Code(Counter(0)) at (prev + 0, 33) to (start + 0, 41) -- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 9) -- MCDCDecision { bitmap_idx: 8, conditions_num: 7 } at (prev + 0, 8) to (start + 0, 39) -- MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 7, false_next_id: 0 } at (prev + 0, 8) to (start + 0, 9) - true = c1 - false = (c0 - c1) -- Code(Counter(1)) at (prev + 0, 13) to (start + 0, 14) -- MCDCBranch { true: Counter(2), false: Expression(1, Sub), condition_id: 7, true_next_id: 6, false_next_id: 0 } at (prev + 0, 13) to (start + 0, 14) - true = c2 - false = (c1 - c2) -- Code(Counter(2)) at (prev + 0, 18) to (start + 0, 19) -- MCDCBranch { true: Counter(3), false: Expression(2, Sub), condition_id: 6, true_next_id: 5, false_next_id: 0 } at (prev + 0, 18) to (start + 0, 19) - true = c3 - false = (c2 - c3) -- Code(Counter(3)) at (prev + 0, 23) to (start + 0, 24) -- MCDCBranch { true: Counter(4), false: Expression(3, Sub), condition_id: 5, true_next_id: 4, false_next_id: 0 } at (prev + 0, 23) to (start + 0, 24) - true = c4 - false = (c3 - c4) -- Code(Counter(4)) at (prev + 0, 28) to (start + 0, 29) -- MCDCBranch { true: Counter(5), false: Expression(4, Sub), condition_id: 4, true_next_id: 3, false_next_id: 0 } at (prev + 0, 28) to (start + 0, 29) - true = c5 - false = (c4 - c5) -- Code(Counter(5)) at (prev + 0, 33) to (start + 0, 34) -- MCDCBranch { true: Counter(6), false: Expression(5, Sub), condition_id: 3, true_next_id: 2, false_next_id: 0 } at (prev + 0, 33) to (start + 0, 34) - true = c6 - false = (c5 - c6) -- Code(Counter(6)) at (prev + 0, 38) to (start + 0, 39) -- MCDCBranch { true: Counter(7), false: Expression(6, Sub), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 38) to (start + 0, 39) - true = c7 - false = (c6 - c7) -- Code(Counter(7)) at (prev + 0, 40) to (start + 2, 6) -- Code(Expression(7, Sub)) at (prev + 2, 5) to (start + 0, 6) - = (c0 - c7) -- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) -Highest counter ID seen: c7 - diff --git a/tests/coverage/mcdc/condition-limit.coverage b/tests/coverage/mcdc/condition-limit.coverage deleted file mode 100644 index 04ccd6497c3d0..0000000000000 --- a/tests/coverage/mcdc/condition-limit.coverage +++ /dev/null @@ -1,55 +0,0 @@ - LL| |#![feature(coverage_attribute)] - LL| |//@ edition: 2021 - LL| |//@ compile-flags: -Zcoverage-options=mcdc - LL| |//@ llvm-cov-flags: --show-branches=count --show-mcdc - LL| | - LL| 2|fn accept_7_conditions(bool_arr: [bool; 7]) { - LL| 2| let [a, b, c, d, e, f, g] = bool_arr; - LL| 2| if a && b && c && d && e && f && g { - ^1 ^1 ^1 ^1 ^1 ^1 - ------------------ - | Branch (LL:8): [True: 1, False: 1] - | Branch (LL:13): [True: 1, False: 0] - | Branch (LL:18): [True: 1, False: 0] - | Branch (LL:23): [True: 1, False: 0] - | Branch (LL:28): [True: 1, False: 0] - | Branch (LL:33): [True: 1, False: 0] - | Branch (LL:38): [True: 1, False: 0] - ------------------ - |---> MC/DC Decision Region (LL:8) to (LL:39) - | - | Number of Conditions: 7 - | Condition C1 --> (LL:8) - | Condition C2 --> (LL:13) - | Condition C3 --> (LL:18) - | Condition C4 --> (LL:23) - | Condition C5 --> (LL:28) - | Condition C6 --> (LL:33) - | Condition C7 --> (LL:38) - | - | Executed MC/DC Test Vectors: - | - | C1, C2, C3, C4, C5, C6, C7 Result - | 1 { F, -, -, -, -, -, - = F } - | 2 { T, T, T, T, T, T, T = T } - | - | C1-Pair: covered: (1,2) - | C2-Pair: not covered - | C3-Pair: not covered - | C4-Pair: not covered - | C5-Pair: not covered - | C6-Pair: not covered - | C7-Pair: not covered - | MC/DC Coverage for Decision: 14.29% - | - ------------------ - LL| 1| core::hint::black_box("hello"); - LL| 1| } - LL| 2|} - LL| | - LL| |#[coverage(off)] - LL| |fn main() { - LL| | accept_7_conditions([false; 7]); - LL| | accept_7_conditions([true; 7]); - LL| |} - diff --git a/tests/coverage/mcdc/condition-limit.rs b/tests/coverage/mcdc/condition-limit.rs deleted file mode 100644 index 867636cdaed2a..0000000000000 --- a/tests/coverage/mcdc/condition-limit.rs +++ /dev/null @@ -1,17 +0,0 @@ -#![feature(coverage_attribute)] -//@ edition: 2021 -//@ compile-flags: -Zcoverage-options=mcdc -//@ llvm-cov-flags: --show-branches=count --show-mcdc - -fn accept_7_conditions(bool_arr: [bool; 7]) { - let [a, b, c, d, e, f, g] = bool_arr; - if a && b && c && d && e && f && g { - core::hint::black_box("hello"); - } -} - -#[coverage(off)] -fn main() { - accept_7_conditions([false; 7]); - accept_7_conditions([true; 7]); -} diff --git a/tests/coverage/mcdc/if.cov-map b/tests/coverage/mcdc/if.cov-map deleted file mode 100644 index dac1eb4c94bde..0000000000000 --- a/tests/coverage/mcdc/if.cov-map +++ /dev/null @@ -1,223 +0,0 @@ -Function name: if::mcdc_check_a -Raw bytes (67): 0x[01, 01, 03, 01, 05, 05, 09, 01, 09, 09, 01, 0e, 01, 00, 22, 01, 01, 08, 00, 09, 28, 03, 02, 00, 08, 00, 0e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 05, 00, 0d, 00, 0e, 30, 09, 06, 02, 00, 00, 00, 0d, 00, 0e, 09, 00, 0f, 02, 06, 0a, 02, 0c, 02, 06, 01, 03, 01, 00, 02] -Number of files: 1 -- file 0 => $DIR/if.rs -Number of expressions: 3 -- expression 0 operands: lhs = Counter(0), rhs = Counter(1) -- expression 1 operands: lhs = Counter(1), rhs = Counter(2) -- expression 2 operands: lhs = Counter(0), rhs = Counter(2) -Number of file 0 mappings: 9 -- Code(Counter(0)) at (prev + 14, 1) to (start + 0, 34) -- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 9) -- MCDCDecision { bitmap_idx: 3, conditions_num: 2 } at (prev + 0, 8) to (start + 0, 14) -- MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 8) to (start + 0, 9) - true = c1 - false = (c0 - c1) -- Code(Counter(1)) at (prev + 0, 13) to (start + 0, 14) -- MCDCBranch { true: Counter(2), false: Expression(1, Sub), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 13) to (start + 0, 14) - true = c2 - false = (c1 - c2) -- Code(Counter(2)) at (prev + 0, 15) to (start + 2, 6) -- Code(Expression(2, Sub)) at (prev + 2, 12) to (start + 2, 6) - = (c0 - c2) -- Code(Counter(0)) at (prev + 3, 1) to (start + 0, 2) -Highest counter ID seen: c2 - -Function name: if::mcdc_check_b -Raw bytes (67): 0x[01, 01, 03, 01, 05, 05, 09, 01, 09, 09, 01, 16, 01, 00, 22, 01, 01, 08, 00, 09, 28, 03, 02, 00, 08, 00, 0e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 05, 00, 0d, 00, 0e, 30, 09, 06, 02, 00, 00, 00, 0d, 00, 0e, 09, 00, 0f, 02, 06, 0a, 02, 0c, 02, 06, 01, 03, 01, 00, 02] -Number of files: 1 -- file 0 => $DIR/if.rs -Number of expressions: 3 -- expression 0 operands: lhs = Counter(0), rhs = Counter(1) -- expression 1 operands: lhs = Counter(1), rhs = Counter(2) -- expression 2 operands: lhs = Counter(0), rhs = Counter(2) -Number of file 0 mappings: 9 -- Code(Counter(0)) at (prev + 22, 1) to (start + 0, 34) -- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 9) -- MCDCDecision { bitmap_idx: 3, conditions_num: 2 } at (prev + 0, 8) to (start + 0, 14) -- MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 8) to (start + 0, 9) - true = c1 - false = (c0 - c1) -- Code(Counter(1)) at (prev + 0, 13) to (start + 0, 14) -- MCDCBranch { true: Counter(2), false: Expression(1, Sub), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 13) to (start + 0, 14) - true = c2 - false = (c1 - c2) -- Code(Counter(2)) at (prev + 0, 15) to (start + 2, 6) -- Code(Expression(2, Sub)) at (prev + 2, 12) to (start + 2, 6) - = (c0 - c2) -- Code(Counter(0)) at (prev + 3, 1) to (start + 0, 2) -Highest counter ID seen: c2 - -Function name: if::mcdc_check_both -Raw bytes (67): 0x[01, 01, 03, 01, 05, 05, 09, 01, 09, 09, 01, 1e, 01, 00, 25, 01, 01, 08, 00, 09, 28, 03, 02, 00, 08, 00, 0e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 05, 00, 0d, 00, 0e, 30, 09, 06, 02, 00, 00, 00, 0d, 00, 0e, 09, 00, 0f, 02, 06, 0a, 02, 0c, 02, 06, 01, 03, 01, 00, 02] -Number of files: 1 -- file 0 => $DIR/if.rs -Number of expressions: 3 -- expression 0 operands: lhs = Counter(0), rhs = Counter(1) -- expression 1 operands: lhs = Counter(1), rhs = Counter(2) -- expression 2 operands: lhs = Counter(0), rhs = Counter(2) -Number of file 0 mappings: 9 -- Code(Counter(0)) at (prev + 30, 1) to (start + 0, 37) -- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 9) -- MCDCDecision { bitmap_idx: 3, conditions_num: 2 } at (prev + 0, 8) to (start + 0, 14) -- MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 8) to (start + 0, 9) - true = c1 - false = (c0 - c1) -- Code(Counter(1)) at (prev + 0, 13) to (start + 0, 14) -- MCDCBranch { true: Counter(2), false: Expression(1, Sub), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 13) to (start + 0, 14) - true = c2 - false = (c1 - c2) -- Code(Counter(2)) at (prev + 0, 15) to (start + 2, 6) -- Code(Expression(2, Sub)) at (prev + 2, 12) to (start + 2, 6) - = (c0 - c2) -- Code(Counter(0)) at (prev + 3, 1) to (start + 0, 2) -Highest counter ID seen: c2 - -Function name: if::mcdc_check_neither -Raw bytes (67): 0x[01, 01, 03, 01, 05, 05, 09, 01, 09, 09, 01, 06, 01, 00, 28, 01, 01, 08, 00, 09, 28, 03, 02, 00, 08, 00, 0e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 05, 00, 0d, 00, 0e, 30, 09, 06, 02, 00, 00, 00, 0d, 00, 0e, 09, 00, 0f, 02, 06, 0a, 02, 0c, 02, 06, 01, 03, 01, 00, 02] -Number of files: 1 -- file 0 => $DIR/if.rs -Number of expressions: 3 -- expression 0 operands: lhs = Counter(0), rhs = Counter(1) -- expression 1 operands: lhs = Counter(1), rhs = Counter(2) -- expression 2 operands: lhs = Counter(0), rhs = Counter(2) -Number of file 0 mappings: 9 -- Code(Counter(0)) at (prev + 6, 1) to (start + 0, 40) -- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 9) -- MCDCDecision { bitmap_idx: 3, conditions_num: 2 } at (prev + 0, 8) to (start + 0, 14) -- MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 8) to (start + 0, 9) - true = c1 - false = (c0 - c1) -- Code(Counter(1)) at (prev + 0, 13) to (start + 0, 14) -- MCDCBranch { true: Counter(2), false: Expression(1, Sub), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 13) to (start + 0, 14) - true = c2 - false = (c1 - c2) -- Code(Counter(2)) at (prev + 0, 15) to (start + 2, 6) -- Code(Expression(2, Sub)) at (prev + 2, 12) to (start + 2, 6) - = (c0 - c2) -- Code(Counter(0)) at (prev + 3, 1) to (start + 0, 2) -Highest counter ID seen: c2 - -Function name: if::mcdc_check_not_tree_decision -Raw bytes (90): 0x[01, 01, 07, 01, 05, 01, 17, 05, 09, 05, 09, 17, 0d, 05, 09, 01, 0d, 0b, 01, 30, 01, 00, 3b, 28, 05, 03, 03, 08, 00, 15, 01, 00, 09, 00, 0a, 30, 05, 02, 01, 02, 03, 00, 09, 00, 0a, 02, 00, 0e, 00, 0f, 30, 09, 06, 03, 02, 00, 00, 0e, 00, 0f, 17, 00, 14, 00, 15, 30, 0d, 12, 02, 00, 00, 00, 14, 00, 15, 0d, 00, 16, 02, 06, 1a, 02, 0c, 02, 06, 01, 03, 01, 00, 02] -Number of files: 1 -- file 0 => $DIR/if.rs -Number of expressions: 7 -- expression 0 operands: lhs = Counter(0), rhs = Counter(1) -- expression 1 operands: lhs = Counter(0), rhs = Expression(5, Add) -- expression 2 operands: lhs = Counter(1), rhs = Counter(2) -- expression 3 operands: lhs = Counter(1), rhs = Counter(2) -- expression 4 operands: lhs = Expression(5, Add), rhs = Counter(3) -- expression 5 operands: lhs = Counter(1), rhs = Counter(2) -- expression 6 operands: lhs = Counter(0), rhs = Counter(3) -Number of file 0 mappings: 11 -- Code(Counter(0)) at (prev + 48, 1) to (start + 0, 59) -- MCDCDecision { bitmap_idx: 5, conditions_num: 3 } at (prev + 3, 8) to (start + 0, 21) -- Code(Counter(0)) at (prev + 0, 9) to (start + 0, 10) -- MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 2, false_next_id: 3 } at (prev + 0, 9) to (start + 0, 10) - true = c1 - false = (c0 - c1) -- Code(Expression(0, Sub)) at (prev + 0, 14) to (start + 0, 15) - = (c0 - c1) -- MCDCBranch { true: Counter(2), false: Expression(1, Sub), condition_id: 3, true_next_id: 2, false_next_id: 0 } at (prev + 0, 14) to (start + 0, 15) - true = c2 - false = (c0 - (c1 + c2)) -- Code(Expression(5, Add)) at (prev + 0, 20) to (start + 0, 21) - = (c1 + c2) -- MCDCBranch { true: Counter(3), false: Expression(4, Sub), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 20) to (start + 0, 21) - true = c3 - false = ((c1 + c2) - c3) -- Code(Counter(3)) at (prev + 0, 22) to (start + 2, 6) -- Code(Expression(6, Sub)) at (prev + 2, 12) to (start + 2, 6) - = (c0 - c3) -- Code(Counter(0)) at (prev + 3, 1) to (start + 0, 2) -Highest counter ID seen: c3 - -Function name: if::mcdc_check_tree_decision -Raw bytes (92): 0x[01, 01, 08, 01, 05, 05, 09, 05, 09, 05, 1f, 09, 0d, 09, 0d, 01, 1f, 09, 0d, 0b, 01, 26, 01, 00, 37, 01, 03, 08, 00, 09, 28, 04, 03, 00, 08, 00, 15, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 05, 00, 0e, 00, 0f, 30, 09, 0a, 02, 00, 03, 00, 0e, 00, 0f, 0a, 00, 13, 00, 14, 30, 0d, 0e, 03, 00, 00, 00, 13, 00, 14, 1f, 00, 16, 02, 06, 1a, 02, 0c, 02, 06, 01, 03, 01, 00, 02] -Number of files: 1 -- file 0 => $DIR/if.rs -Number of expressions: 8 -- expression 0 operands: lhs = Counter(0), rhs = Counter(1) -- expression 1 operands: lhs = Counter(1), rhs = Counter(2) -- expression 2 operands: lhs = Counter(1), rhs = Counter(2) -- expression 3 operands: lhs = Counter(1), rhs = Expression(7, Add) -- expression 4 operands: lhs = Counter(2), rhs = Counter(3) -- expression 5 operands: lhs = Counter(2), rhs = Counter(3) -- expression 6 operands: lhs = Counter(0), rhs = Expression(7, Add) -- expression 7 operands: lhs = Counter(2), rhs = Counter(3) -Number of file 0 mappings: 11 -- Code(Counter(0)) at (prev + 38, 1) to (start + 0, 55) -- Code(Counter(0)) at (prev + 3, 8) to (start + 0, 9) -- MCDCDecision { bitmap_idx: 4, conditions_num: 3 } at (prev + 0, 8) to (start + 0, 21) -- MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 8) to (start + 0, 9) - true = c1 - false = (c0 - c1) -- Code(Counter(1)) at (prev + 0, 14) to (start + 0, 15) -- MCDCBranch { true: Counter(2), false: Expression(2, Sub), condition_id: 2, true_next_id: 0, false_next_id: 3 } at (prev + 0, 14) to (start + 0, 15) - true = c2 - false = (c1 - c2) -- Code(Expression(2, Sub)) at (prev + 0, 19) to (start + 0, 20) - = (c1 - c2) -- MCDCBranch { true: Counter(3), false: Expression(3, Sub), condition_id: 3, true_next_id: 0, false_next_id: 0 } at (prev + 0, 19) to (start + 0, 20) - true = c3 - false = (c1 - (c2 + c3)) -- Code(Expression(7, Add)) at (prev + 0, 22) to (start + 2, 6) - = (c2 + c3) -- Code(Expression(6, Sub)) at (prev + 2, 12) to (start + 2, 6) - = (c0 - (c2 + c3)) -- Code(Counter(0)) at (prev + 3, 1) to (start + 0, 2) -Highest counter ID seen: c3 - -Function name: if::mcdc_nested_if -Raw bytes (139): 0x[01, 01, 0d, 01, 05, 01, 33, 05, 09, 05, 09, 05, 09, 05, 09, 33, 0d, 05, 09, 0d, 11, 33, 11, 05, 09, 01, 33, 05, 09, 11, 01, 3a, 01, 00, 2d, 01, 01, 08, 00, 09, 28, 03, 02, 00, 08, 00, 0e, 30, 05, 02, 01, 00, 02, 00, 08, 00, 09, 02, 00, 0d, 00, 0e, 30, 09, 2e, 02, 00, 00, 00, 0d, 00, 0e, 33, 01, 09, 00, 0c, 33, 00, 0d, 00, 15, 33, 01, 0c, 00, 0d, 28, 06, 02, 00, 0c, 00, 12, 30, 0d, 1a, 01, 02, 00, 00, 0c, 00, 0d, 0d, 00, 11, 00, 12, 30, 11, 22, 02, 00, 00, 00, 11, 00, 12, 11, 00, 13, 02, 0a, 26, 02, 09, 00, 0a, 2e, 01, 0c, 02, 06, 01, 03, 01, 00, 02] -Number of files: 1 -- file 0 => $DIR/if.rs -Number of expressions: 13 -- expression 0 operands: lhs = Counter(0), rhs = Counter(1) -- expression 1 operands: lhs = Counter(0), rhs = Expression(12, Add) -- expression 2 operands: lhs = Counter(1), rhs = Counter(2) -- expression 3 operands: lhs = Counter(1), rhs = Counter(2) -- expression 4 operands: lhs = Counter(1), rhs = Counter(2) -- expression 5 operands: lhs = Counter(1), rhs = Counter(2) -- expression 6 operands: lhs = Expression(12, Add), rhs = Counter(3) -- expression 7 operands: lhs = Counter(1), rhs = Counter(2) -- expression 8 operands: lhs = Counter(3), rhs = Counter(4) -- expression 9 operands: lhs = Expression(12, Add), rhs = Counter(4) -- expression 10 operands: lhs = Counter(1), rhs = Counter(2) -- expression 11 operands: lhs = Counter(0), rhs = Expression(12, Add) -- expression 12 operands: lhs = Counter(1), rhs = Counter(2) -Number of file 0 mappings: 17 -- Code(Counter(0)) at (prev + 58, 1) to (start + 0, 45) -- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 9) -- MCDCDecision { bitmap_idx: 3, conditions_num: 2 } at (prev + 0, 8) to (start + 0, 14) -- MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 0, false_next_id: 2 } at (prev + 0, 8) to (start + 0, 9) - true = c1 - false = (c0 - c1) -- Code(Expression(0, Sub)) at (prev + 0, 13) to (start + 0, 14) - = (c0 - c1) -- MCDCBranch { true: Counter(2), false: Expression(11, Sub), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 13) to (start + 0, 14) - true = c2 - false = (c0 - (c1 + c2)) -- Code(Expression(12, Add)) at (prev + 1, 9) to (start + 0, 12) - = (c1 + c2) -- Code(Expression(12, Add)) at (prev + 0, 13) to (start + 0, 21) - = (c1 + c2) -- Code(Expression(12, Add)) at (prev + 1, 12) to (start + 0, 13) - = (c1 + c2) -- MCDCDecision { bitmap_idx: 6, conditions_num: 2 } at (prev + 0, 12) to (start + 0, 18) -- MCDCBranch { true: Counter(3), false: Expression(6, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 12) to (start + 0, 13) - true = c3 - false = ((c1 + c2) - c3) -- Code(Counter(3)) at (prev + 0, 17) to (start + 0, 18) -- MCDCBranch { true: Counter(4), false: Expression(8, Sub), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 17) to (start + 0, 18) - true = c4 - false = (c3 - c4) -- Code(Counter(4)) at (prev + 0, 19) to (start + 2, 10) -- Code(Expression(9, Sub)) at (prev + 2, 9) to (start + 0, 10) - = ((c1 + c2) - c4) -- Code(Expression(11, Sub)) at (prev + 1, 12) to (start + 2, 6) - = (c0 - (c1 + c2)) -- Code(Counter(0)) at (prev + 3, 1) to (start + 0, 2) -Highest counter ID seen: c4 - diff --git a/tests/coverage/mcdc/if.coverage b/tests/coverage/mcdc/if.coverage deleted file mode 100644 index fda5525c472cb..0000000000000 --- a/tests/coverage/mcdc/if.coverage +++ /dev/null @@ -1,287 +0,0 @@ - LL| |#![feature(coverage_attribute)] - LL| |//@ edition: 2021 - LL| |//@ compile-flags: -Zcoverage-options=mcdc - LL| |//@ llvm-cov-flags: --show-branches=count --show-mcdc - LL| | - LL| 2|fn mcdc_check_neither(a: bool, b: bool) { - LL| 2| if a && b { - ^0 - ------------------ - | Branch (LL:8): [True: 0, False: 2] - | Branch (LL:13): [True: 0, False: 0] - ------------------ - |---> MC/DC Decision Region (LL:8) to (LL:14) - | - | Number of Conditions: 2 - | Condition C1 --> (LL:8) - | Condition C2 --> (LL:13) - | - | Executed MC/DC Test Vectors: - | - | C1, C2 Result - | 1 { F, - = F } - | - | C1-Pair: not covered - | C2-Pair: not covered - | MC/DC Coverage for Decision: 0.00% - | - ------------------ - LL| 0| say("a and b"); - LL| 2| } else { - LL| 2| say("not both"); - LL| 2| } - LL| 2|} - LL| | - LL| 2|fn mcdc_check_a(a: bool, b: bool) { - LL| 2| if a && b { - ^1 - ------------------ - | Branch (LL:8): [True: 1, False: 1] - | Branch (LL:13): [True: 1, False: 0] - ------------------ - |---> MC/DC Decision Region (LL:8) to (LL:14) - | - | Number of Conditions: 2 - | Condition C1 --> (LL:8) - | Condition C2 --> (LL:13) - | - | Executed MC/DC Test Vectors: - | - | C1, C2 Result - | 1 { F, - = F } - | 2 { T, T = T } - | - | C1-Pair: covered: (1,2) - | C2-Pair: not covered - | MC/DC Coverage for Decision: 50.00% - | - ------------------ - LL| 1| say("a and b"); - LL| 1| } else { - LL| 1| say("not both"); - LL| 1| } - LL| 2|} - LL| | - LL| 2|fn mcdc_check_b(a: bool, b: bool) { - LL| 2| if a && b { - ------------------ - | Branch (LL:8): [True: 2, False: 0] - | Branch (LL:13): [True: 1, False: 1] - ------------------ - |---> MC/DC Decision Region (LL:8) to (LL:14) - | - | Number of Conditions: 2 - | Condition C1 --> (LL:8) - | Condition C2 --> (LL:13) - | - | Executed MC/DC Test Vectors: - | - | C1, C2 Result - | 1 { T, F = F } - | 2 { T, T = T } - | - | C1-Pair: not covered - | C2-Pair: covered: (1,2) - | MC/DC Coverage for Decision: 50.00% - | - ------------------ - LL| 1| say("a and b"); - LL| 1| } else { - LL| 1| say("not both"); - LL| 1| } - LL| 2|} - LL| | - LL| 3|fn mcdc_check_both(a: bool, b: bool) { - LL| 3| if a && b { - ^2 - ------------------ - | Branch (LL:8): [True: 2, False: 1] - | Branch (LL:13): [True: 1, False: 1] - ------------------ - |---> MC/DC Decision Region (LL:8) to (LL:14) - | - | Number of Conditions: 2 - | Condition C1 --> (LL:8) - | Condition C2 --> (LL:13) - | - | Executed MC/DC Test Vectors: - | - | C1, C2 Result - | 1 { F, - = F } - | 2 { T, F = F } - | 3 { T, T = T } - | - | C1-Pair: covered: (1,3) - | C2-Pair: covered: (2,3) - | MC/DC Coverage for Decision: 100.00% - | - ------------------ - LL| 1| say("a and b"); - LL| 2| } else { - LL| 2| say("not both"); - LL| 2| } - LL| 3|} - LL| | - LL| 4|fn mcdc_check_tree_decision(a: bool, b: bool, c: bool) { - LL| | // This expression is intentionally written in a way - LL| | // where 100% branch coverage indicates 100% mcdc coverage. - LL| 4| if a && (b || c) { - ^3 ^2 - ------------------ - | Branch (LL:8): [True: 3, False: 1] - | Branch (LL:14): [True: 1, False: 2] - | Branch (LL:19): [True: 1, False: 1] - ------------------ - |---> MC/DC Decision Region (LL:8) to (LL:21) - | - | Number of Conditions: 3 - | Condition C1 --> (LL:8) - | Condition C2 --> (LL:14) - | Condition C3 --> (LL:19) - | - | Executed MC/DC Test Vectors: - | - | C1, C2, C3 Result - | 1 { F, -, - = F } - | 2 { T, F, F = F } - | 3 { T, F, T = T } - | 4 { T, T, - = T } - | - | C1-Pair: covered: (1,3) - | C2-Pair: covered: (2,4) - | C3-Pair: covered: (2,3) - | MC/DC Coverage for Decision: 100.00% - | - ------------------ - LL| 2| say("pass"); - LL| 2| } else { - LL| 2| say("reject"); - LL| 2| } - LL| 4|} - LL| | - LL| 4|fn mcdc_check_not_tree_decision(a: bool, b: bool, c: bool) { - LL| | // Contradict to `mcdc_check_tree_decision`, - LL| | // 100% branch coverage of this expression does not indicate 100% mcdc coverage. - LL| 4| if (a || b) && c { - ^1 - ------------------ - | Branch (LL:9): [True: 3, False: 1] - | Branch (LL:14): [True: 1, False: 0] - | Branch (LL:20): [True: 2, False: 2] - ------------------ - |---> MC/DC Decision Region (LL:8) to (LL:21) - | - | Number of Conditions: 3 - | Condition C1 --> (LL:9) - | Condition C2 --> (LL:14) - | Condition C3 --> (LL:20) - | - | Executed MC/DC Test Vectors: - | - | C1, C2, C3 Result - | 1 { T, -, F = F } - | 2 { F, T, T = T } - | 3 { T, -, T = T } - | - | C1-Pair: not covered - | C2-Pair: not covered - | C3-Pair: covered: (1,3) - | MC/DC Coverage for Decision: 33.33% - | - ------------------ - LL| 2| say("pass"); - LL| 2| } else { - LL| 2| say("reject"); - LL| 2| } - LL| 4|} - LL| | - LL| 3|fn mcdc_nested_if(a: bool, b: bool, c: bool) { - LL| 3| if a || b { - ^0 - ------------------ - | Branch (LL:8): [True: 3, False: 0] - | Branch (LL:13): [True: 0, False: 0] - ------------------ - |---> MC/DC Decision Region (LL:8) to (LL:14) - | - | Number of Conditions: 2 - | Condition C1 --> (LL:8) - | Condition C2 --> (LL:13) - | - | Executed MC/DC Test Vectors: - | - | C1, C2 Result - | 1 { T, - = T } - | - | C1-Pair: not covered - | C2-Pair: not covered - | MC/DC Coverage for Decision: 0.00% - | - ------------------ - LL| 3| say("a or b"); - LL| 3| if b && c { - ^2 - ------------------ - | Branch (LL:12): [True: 2, False: 1] - | Branch (LL:17): [True: 1, False: 1] - ------------------ - |---> MC/DC Decision Region (LL:12) to (LL:18) - | - | Number of Conditions: 2 - | Condition C1 --> (LL:12) - | Condition C2 --> (LL:17) - | - | Executed MC/DC Test Vectors: - | - | C1, C2 Result - | 1 { F, - = F } - | 2 { T, F = F } - | 3 { T, T = T } - | - | C1-Pair: covered: (1,3) - | C2-Pair: covered: (2,3) - | MC/DC Coverage for Decision: 100.00% - | - ------------------ - LL| 1| say("b and c"); - LL| 2| } - LL| 0| } else { - LL| 0| say("neither a nor b"); - LL| 0| } - LL| 3|} - LL| | - LL| |#[coverage(off)] - LL| |fn main() { - LL| | mcdc_check_neither(false, false); - LL| | mcdc_check_neither(false, true); - LL| | - LL| | mcdc_check_a(true, true); - LL| | mcdc_check_a(false, true); - LL| | - LL| | mcdc_check_b(true, true); - LL| | mcdc_check_b(true, false); - LL| | - LL| | mcdc_check_both(false, true); - LL| | mcdc_check_both(true, true); - LL| | mcdc_check_both(true, false); - LL| | - LL| | mcdc_check_tree_decision(false, true, true); - LL| | mcdc_check_tree_decision(true, true, false); - LL| | mcdc_check_tree_decision(true, false, false); - LL| | mcdc_check_tree_decision(true, false, true); - LL| | - LL| | mcdc_check_not_tree_decision(false, true, true); - LL| | mcdc_check_not_tree_decision(true, true, false); - LL| | mcdc_check_not_tree_decision(true, false, false); - LL| | mcdc_check_not_tree_decision(true, false, true); - LL| | - LL| | mcdc_nested_if(true, false, true); - LL| | mcdc_nested_if(true, true, true); - LL| | mcdc_nested_if(true, true, false); - LL| |} - LL| | - LL| |#[coverage(off)] - LL| |fn say(message: &str) { - LL| | core::hint::black_box(message); - LL| |} - diff --git a/tests/coverage/mcdc/if.rs b/tests/coverage/mcdc/if.rs deleted file mode 100644 index c4675f5d16725..0000000000000 --- a/tests/coverage/mcdc/if.rs +++ /dev/null @@ -1,102 +0,0 @@ -#![feature(coverage_attribute)] -//@ edition: 2021 -//@ compile-flags: -Zcoverage-options=mcdc -//@ llvm-cov-flags: --show-branches=count --show-mcdc - -fn mcdc_check_neither(a: bool, b: bool) { - if a && b { - say("a and b"); - } else { - say("not both"); - } -} - -fn mcdc_check_a(a: bool, b: bool) { - if a && b { - say("a and b"); - } else { - say("not both"); - } -} - -fn mcdc_check_b(a: bool, b: bool) { - if a && b { - say("a and b"); - } else { - say("not both"); - } -} - -fn mcdc_check_both(a: bool, b: bool) { - if a && b { - say("a and b"); - } else { - say("not both"); - } -} - -fn mcdc_check_tree_decision(a: bool, b: bool, c: bool) { - // This expression is intentionally written in a way - // where 100% branch coverage indicates 100% mcdc coverage. - if a && (b || c) { - say("pass"); - } else { - say("reject"); - } -} - -fn mcdc_check_not_tree_decision(a: bool, b: bool, c: bool) { - // Contradict to `mcdc_check_tree_decision`, - // 100% branch coverage of this expression does not indicate 100% mcdc coverage. - if (a || b) && c { - say("pass"); - } else { - say("reject"); - } -} - -fn mcdc_nested_if(a: bool, b: bool, c: bool) { - if a || b { - say("a or b"); - if b && c { - say("b and c"); - } - } else { - say("neither a nor b"); - } -} - -#[coverage(off)] -fn main() { - mcdc_check_neither(false, false); - mcdc_check_neither(false, true); - - mcdc_check_a(true, true); - mcdc_check_a(false, true); - - mcdc_check_b(true, true); - mcdc_check_b(true, false); - - mcdc_check_both(false, true); - mcdc_check_both(true, true); - mcdc_check_both(true, false); - - mcdc_check_tree_decision(false, true, true); - mcdc_check_tree_decision(true, true, false); - mcdc_check_tree_decision(true, false, false); - mcdc_check_tree_decision(true, false, true); - - mcdc_check_not_tree_decision(false, true, true); - mcdc_check_not_tree_decision(true, true, false); - mcdc_check_not_tree_decision(true, false, false); - mcdc_check_not_tree_decision(true, false, true); - - mcdc_nested_if(true, false, true); - mcdc_nested_if(true, true, true); - mcdc_nested_if(true, true, false); -} - -#[coverage(off)] -fn say(message: &str) { - core::hint::black_box(message); -} diff --git a/tests/coverage/mcdc/inlined_expressions.cov-map b/tests/coverage/mcdc/inlined_expressions.cov-map deleted file mode 100644 index d05ef368ba4af..0000000000000 --- a/tests/coverage/mcdc/inlined_expressions.cov-map +++ /dev/null @@ -1,21 +0,0 @@ -Function name: inlined_expressions::inlined_instance -Raw bytes (55): 0x[01, 01, 02, 01, 05, 05, 09, 07, 01, 07, 01, 00, 2e, 01, 01, 05, 00, 06, 28, 03, 02, 00, 05, 00, 0b, 30, 05, 02, 01, 02, 00, 00, 05, 00, 06, 05, 00, 0a, 00, 0b, 30, 09, 06, 02, 00, 00, 00, 0a, 00, 0b, 01, 01, 01, 00, 02] -Number of files: 1 -- file 0 => $DIR/inlined_expressions.rs -Number of expressions: 2 -- expression 0 operands: lhs = Counter(0), rhs = Counter(1) -- expression 1 operands: lhs = Counter(1), rhs = Counter(2) -Number of file 0 mappings: 7 -- Code(Counter(0)) at (prev + 7, 1) to (start + 0, 46) -- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 6) -- MCDCDecision { bitmap_idx: 3, conditions_num: 2 } at (prev + 0, 5) to (start + 0, 11) -- MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 5) to (start + 0, 6) - true = c1 - false = (c0 - c1) -- Code(Counter(1)) at (prev + 0, 10) to (start + 0, 11) -- MCDCBranch { true: Counter(2), false: Expression(1, Sub), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 10) to (start + 0, 11) - true = c2 - false = (c1 - c2) -- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) -Highest counter ID seen: c2 - diff --git a/tests/coverage/mcdc/inlined_expressions.coverage b/tests/coverage/mcdc/inlined_expressions.coverage deleted file mode 100644 index cfe398995e4e8..0000000000000 --- a/tests/coverage/mcdc/inlined_expressions.coverage +++ /dev/null @@ -1,40 +0,0 @@ - LL| |#![feature(coverage_attribute)] - LL| |//@ edition: 2021 - LL| |//@ compile-flags: -Zcoverage-options=mcdc -Copt-level=z -Cllvm-args=--inline-threshold=0 - LL| |//@ llvm-cov-flags: --show-branches=count --show-mcdc - LL| | - LL| |#[inline(always)] - LL| 3|fn inlined_instance(a: bool, b: bool) -> bool { - LL| 3| a && b - ^2 - ------------------ - | Branch (LL:5): [True: 2, False: 1] - | Branch (LL:10): [True: 1, False: 1] - ------------------ - |---> MC/DC Decision Region (LL:5) to (LL:11) - | - | Number of Conditions: 2 - | Condition C1 --> (LL:5) - | Condition C2 --> (LL:10) - | - | Executed MC/DC Test Vectors: - | - | C1, C2 Result - | 1 { F, - = F } - | 2 { T, F = F } - | 3 { T, T = T } - | - | C1-Pair: covered: (1,3) - | C2-Pair: covered: (2,3) - | MC/DC Coverage for Decision: 100.00% - | - ------------------ - LL| 3|} - LL| | - LL| |#[coverage(off)] - LL| |fn main() { - LL| | let _ = inlined_instance(true, false); - LL| | let _ = inlined_instance(false, true); - LL| | let _ = inlined_instance(true, true); - LL| |} - diff --git a/tests/coverage/mcdc/inlined_expressions.rs b/tests/coverage/mcdc/inlined_expressions.rs deleted file mode 100644 index 15d4260f6e2ce..0000000000000 --- a/tests/coverage/mcdc/inlined_expressions.rs +++ /dev/null @@ -1,16 +0,0 @@ -#![feature(coverage_attribute)] -//@ edition: 2021 -//@ compile-flags: -Zcoverage-options=mcdc -Copt-level=z -Cllvm-args=--inline-threshold=0 -//@ llvm-cov-flags: --show-branches=count --show-mcdc - -#[inline(always)] -fn inlined_instance(a: bool, b: bool) -> bool { - a && b -} - -#[coverage(off)] -fn main() { - let _ = inlined_instance(true, false); - let _ = inlined_instance(false, true); - let _ = inlined_instance(true, true); -} diff --git a/tests/coverage/mcdc/nested_if.cov-map b/tests/coverage/mcdc/nested_if.cov-map deleted file mode 100644 index 853cdf2c57608..0000000000000 --- a/tests/coverage/mcdc/nested_if.cov-map +++ /dev/null @@ -1,200 +0,0 @@ -Function name: nested_if::doubly_nested_if_in_condition -Raw bytes (175): 0x[01, 01, 0f, 01, 05, 05, 11, 05, 09, 05, 37, 09, 0d, 05, 09, 05, 1f, 09, 15, 15, 19, 05, 2b, 09, 19, 09, 0d, 05, 37, 09, 0d, 01, 11, 15, 01, 0e, 01, 00, 45, 01, 01, 08, 00, 09, 28, 09, 02, 00, 08, 00, 4e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 30, 11, 06, 02, 00, 00, 00, 0d, 00, 4e, 05, 00, 10, 00, 11, 28, 06, 02, 00, 10, 00, 36, 30, 09, 16, 01, 00, 02, 00, 10, 00, 11, 30, 0d, 32, 02, 00, 00, 00, 15, 00, 36, 16, 00, 18, 00, 19, 28, 03, 02, 00, 18, 00, 1e, 30, 15, 1a, 01, 02, 00, 00, 18, 00, 19, 15, 00, 1d, 00, 1e, 30, 19, 22, 02, 00, 00, 00, 1d, 00, 1e, 19, 00, 21, 00, 25, 26, 00, 2f, 00, 34, 37, 00, 39, 00, 3e, 32, 00, 48, 00, 4c, 11, 00, 4f, 02, 06, 3a, 02, 0c, 02, 06, 01, 03, 01, 00, 02] -Number of files: 1 -- file 0 => $DIR/nested_if.rs -Number of expressions: 15 -- expression 0 operands: lhs = Counter(0), rhs = Counter(1) -- expression 1 operands: lhs = Counter(1), rhs = Counter(4) -- expression 2 operands: lhs = Counter(1), rhs = Counter(2) -- expression 3 operands: lhs = Counter(1), rhs = Expression(13, Add) -- expression 4 operands: lhs = Counter(2), rhs = Counter(3) -- expression 5 operands: lhs = Counter(1), rhs = Counter(2) -- expression 6 operands: lhs = Counter(1), rhs = Expression(7, Add) -- expression 7 operands: lhs = Counter(2), rhs = Counter(5) -- expression 8 operands: lhs = Counter(5), rhs = Counter(6) -- expression 9 operands: lhs = Counter(1), rhs = Expression(10, Add) -- expression 10 operands: lhs = Counter(2), rhs = Counter(6) -- expression 11 operands: lhs = Counter(2), rhs = Counter(3) -- expression 12 operands: lhs = Counter(1), rhs = Expression(13, Add) -- expression 13 operands: lhs = Counter(2), rhs = Counter(3) -- expression 14 operands: lhs = Counter(0), rhs = Counter(4) -Number of file 0 mappings: 21 -- Code(Counter(0)) at (prev + 14, 1) to (start + 0, 69) -- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 9) -- MCDCDecision { bitmap_idx: 9, conditions_num: 2 } at (prev + 0, 8) to (start + 0, 78) -- MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 8) to (start + 0, 9) - true = c1 - false = (c0 - c1) -- MCDCBranch { true: Counter(4), false: Expression(1, Sub), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 13) to (start + 0, 78) - true = c4 - false = (c1 - c4) -- Code(Counter(1)) at (prev + 0, 16) to (start + 0, 17) -- MCDCDecision { bitmap_idx: 6, conditions_num: 2 } at (prev + 0, 16) to (start + 0, 54) -- MCDCBranch { true: Counter(2), false: Expression(5, Sub), condition_id: 1, true_next_id: 0, false_next_id: 2 } at (prev + 0, 16) to (start + 0, 17) - true = c2 - false = (c1 - c2) -- MCDCBranch { true: Counter(3), false: Expression(12, Sub), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 21) to (start + 0, 54) - true = c3 - false = (c1 - (c2 + c3)) -- Code(Expression(5, Sub)) at (prev + 0, 24) to (start + 0, 25) - = (c1 - c2) -- MCDCDecision { bitmap_idx: 3, conditions_num: 2 } at (prev + 0, 24) to (start + 0, 30) -- MCDCBranch { true: Counter(5), false: Expression(6, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 24) to (start + 0, 25) - true = c5 - false = (c1 - (c2 + c5)) -- Code(Counter(5)) at (prev + 0, 29) to (start + 0, 30) -- MCDCBranch { true: Counter(6), false: Expression(8, Sub), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 29) to (start + 0, 30) - true = c6 - false = (c5 - c6) -- Code(Counter(6)) at (prev + 0, 33) to (start + 0, 37) -- Code(Expression(9, Sub)) at (prev + 0, 47) to (start + 0, 52) - = (c1 - (c2 + c6)) -- Code(Expression(13, Add)) at (prev + 0, 57) to (start + 0, 62) - = (c2 + c3) -- Code(Expression(12, Sub)) at (prev + 0, 72) to (start + 0, 76) - = (c1 - (c2 + c3)) -- Code(Counter(4)) at (prev + 0, 79) to (start + 2, 6) -- Code(Expression(14, Sub)) at (prev + 2, 12) to (start + 2, 6) - = (c0 - c4) -- Code(Counter(0)) at (prev + 3, 1) to (start + 0, 2) -Highest counter ID seen: c6 - -Function name: nested_if::nested_if_in_condition -Raw bytes (123): 0x[01, 01, 0a, 01, 05, 05, 11, 05, 09, 05, 09, 05, 23, 09, 0d, 09, 0d, 05, 23, 09, 0d, 01, 11, 0f, 01, 06, 01, 00, 35, 01, 01, 08, 00, 09, 28, 06, 02, 00, 08, 00, 2e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 30, 11, 06, 02, 00, 00, 00, 0d, 00, 2e, 05, 00, 10, 00, 11, 28, 03, 02, 00, 10, 00, 16, 30, 09, 0e, 01, 00, 02, 00, 10, 00, 11, 0e, 00, 15, 00, 16, 30, 0d, 1e, 02, 00, 00, 00, 15, 00, 16, 23, 00, 19, 00, 1d, 1e, 00, 27, 00, 2c, 11, 00, 2f, 02, 06, 26, 02, 0c, 02, 06, 01, 03, 01, 00, 02] -Number of files: 1 -- file 0 => $DIR/nested_if.rs -Number of expressions: 10 -- expression 0 operands: lhs = Counter(0), rhs = Counter(1) -- expression 1 operands: lhs = Counter(1), rhs = Counter(4) -- expression 2 operands: lhs = Counter(1), rhs = Counter(2) -- expression 3 operands: lhs = Counter(1), rhs = Counter(2) -- expression 4 operands: lhs = Counter(1), rhs = Expression(8, Add) -- expression 5 operands: lhs = Counter(2), rhs = Counter(3) -- expression 6 operands: lhs = Counter(2), rhs = Counter(3) -- expression 7 operands: lhs = Counter(1), rhs = Expression(8, Add) -- expression 8 operands: lhs = Counter(2), rhs = Counter(3) -- expression 9 operands: lhs = Counter(0), rhs = Counter(4) -Number of file 0 mappings: 15 -- Code(Counter(0)) at (prev + 6, 1) to (start + 0, 53) -- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 9) -- MCDCDecision { bitmap_idx: 6, conditions_num: 2 } at (prev + 0, 8) to (start + 0, 46) -- MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 8) to (start + 0, 9) - true = c1 - false = (c0 - c1) -- MCDCBranch { true: Counter(4), false: Expression(1, Sub), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 13) to (start + 0, 46) - true = c4 - false = (c1 - c4) -- Code(Counter(1)) at (prev + 0, 16) to (start + 0, 17) -- MCDCDecision { bitmap_idx: 3, conditions_num: 2 } at (prev + 0, 16) to (start + 0, 22) -- MCDCBranch { true: Counter(2), false: Expression(3, Sub), condition_id: 1, true_next_id: 0, false_next_id: 2 } at (prev + 0, 16) to (start + 0, 17) - true = c2 - false = (c1 - c2) -- Code(Expression(3, Sub)) at (prev + 0, 21) to (start + 0, 22) - = (c1 - c2) -- MCDCBranch { true: Counter(3), false: Expression(7, Sub), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 21) to (start + 0, 22) - true = c3 - false = (c1 - (c2 + c3)) -- Code(Expression(8, Add)) at (prev + 0, 25) to (start + 0, 29) - = (c2 + c3) -- Code(Expression(7, Sub)) at (prev + 0, 39) to (start + 0, 44) - = (c1 - (c2 + c3)) -- Code(Counter(4)) at (prev + 0, 47) to (start + 2, 6) -- Code(Expression(9, Sub)) at (prev + 2, 12) to (start + 2, 6) - = (c0 - c4) -- Code(Counter(0)) at (prev + 3, 1) to (start + 0, 2) -Highest counter ID seen: c4 - -Function name: nested_if::nested_in_then_block_in_condition -Raw bytes (175): 0x[01, 01, 0f, 01, 05, 05, 19, 05, 09, 05, 09, 05, 37, 09, 0d, 09, 0d, 37, 11, 09, 0d, 11, 15, 37, 15, 09, 0d, 05, 37, 09, 0d, 01, 19, 15, 01, 21, 01, 00, 52, 01, 01, 08, 00, 09, 28, 09, 02, 00, 08, 00, 4b, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 30, 19, 06, 02, 00, 00, 00, 0d, 00, 4b, 05, 00, 10, 00, 11, 28, 03, 02, 00, 10, 00, 16, 30, 09, 0e, 01, 00, 02, 00, 10, 00, 11, 0e, 00, 15, 00, 16, 30, 0d, 32, 02, 00, 00, 00, 15, 00, 16, 37, 00, 1c, 00, 1d, 28, 06, 02, 00, 1c, 00, 22, 30, 11, 1e, 01, 02, 00, 00, 1c, 00, 1d, 11, 00, 21, 00, 22, 30, 15, 26, 02, 00, 00, 00, 21, 00, 22, 15, 00, 25, 00, 29, 2a, 00, 33, 00, 38, 32, 00, 44, 00, 49, 19, 00, 4c, 02, 06, 3a, 02, 0c, 02, 06, 01, 03, 01, 00, 02] -Number of files: 1 -- file 0 => $DIR/nested_if.rs -Number of expressions: 15 -- expression 0 operands: lhs = Counter(0), rhs = Counter(1) -- expression 1 operands: lhs = Counter(1), rhs = Counter(6) -- expression 2 operands: lhs = Counter(1), rhs = Counter(2) -- expression 3 operands: lhs = Counter(1), rhs = Counter(2) -- expression 4 operands: lhs = Counter(1), rhs = Expression(13, Add) -- expression 5 operands: lhs = Counter(2), rhs = Counter(3) -- expression 6 operands: lhs = Counter(2), rhs = Counter(3) -- expression 7 operands: lhs = Expression(13, Add), rhs = Counter(4) -- expression 8 operands: lhs = Counter(2), rhs = Counter(3) -- expression 9 operands: lhs = Counter(4), rhs = Counter(5) -- expression 10 operands: lhs = Expression(13, Add), rhs = Counter(5) -- expression 11 operands: lhs = Counter(2), rhs = Counter(3) -- expression 12 operands: lhs = Counter(1), rhs = Expression(13, Add) -- expression 13 operands: lhs = Counter(2), rhs = Counter(3) -- expression 14 operands: lhs = Counter(0), rhs = Counter(6) -Number of file 0 mappings: 21 -- Code(Counter(0)) at (prev + 33, 1) to (start + 0, 82) -- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 9) -- MCDCDecision { bitmap_idx: 9, conditions_num: 2 } at (prev + 0, 8) to (start + 0, 75) -- MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 8) to (start + 0, 9) - true = c1 - false = (c0 - c1) -- MCDCBranch { true: Counter(6), false: Expression(1, Sub), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 13) to (start + 0, 75) - true = c6 - false = (c1 - c6) -- Code(Counter(1)) at (prev + 0, 16) to (start + 0, 17) -- MCDCDecision { bitmap_idx: 3, conditions_num: 2 } at (prev + 0, 16) to (start + 0, 22) -- MCDCBranch { true: Counter(2), false: Expression(3, Sub), condition_id: 1, true_next_id: 0, false_next_id: 2 } at (prev + 0, 16) to (start + 0, 17) - true = c2 - false = (c1 - c2) -- Code(Expression(3, Sub)) at (prev + 0, 21) to (start + 0, 22) - = (c1 - c2) -- MCDCBranch { true: Counter(3), false: Expression(12, Sub), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 21) to (start + 0, 22) - true = c3 - false = (c1 - (c2 + c3)) -- Code(Expression(13, Add)) at (prev + 0, 28) to (start + 0, 29) - = (c2 + c3) -- MCDCDecision { bitmap_idx: 6, conditions_num: 2 } at (prev + 0, 28) to (start + 0, 34) -- MCDCBranch { true: Counter(4), false: Expression(7, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 28) to (start + 0, 29) - true = c4 - false = ((c2 + c3) - c4) -- Code(Counter(4)) at (prev + 0, 33) to (start + 0, 34) -- MCDCBranch { true: Counter(5), false: Expression(9, Sub), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 33) to (start + 0, 34) - true = c5 - false = (c4 - c5) -- Code(Counter(5)) at (prev + 0, 37) to (start + 0, 41) -- Code(Expression(10, Sub)) at (prev + 0, 51) to (start + 0, 56) - = ((c2 + c3) - c5) -- Code(Expression(12, Sub)) at (prev + 0, 68) to (start + 0, 73) - = (c1 - (c2 + c3)) -- Code(Counter(6)) at (prev + 0, 76) to (start + 2, 6) -- Code(Expression(14, Sub)) at (prev + 2, 12) to (start + 2, 6) - = (c0 - c6) -- Code(Counter(0)) at (prev + 3, 1) to (start + 0, 2) -Highest counter ID seen: c6 - -Function name: nested_if::nested_single_condition_decision -Raw bytes (88): 0x[01, 01, 05, 01, 05, 05, 0d, 05, 09, 05, 09, 01, 0d, 0c, 01, 16, 01, 00, 36, 01, 04, 08, 00, 09, 28, 03, 02, 00, 08, 00, 29, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 30, 0d, 06, 02, 00, 00, 00, 0d, 00, 29, 05, 00, 10, 00, 11, 20, 09, 0e, 00, 10, 00, 11, 09, 00, 14, 00, 19, 0e, 00, 23, 00, 27, 0d, 00, 2a, 02, 06, 12, 02, 0c, 02, 06, 01, 03, 01, 00, 02] -Number of files: 1 -- file 0 => $DIR/nested_if.rs -Number of expressions: 5 -- expression 0 operands: lhs = Counter(0), rhs = Counter(1) -- expression 1 operands: lhs = Counter(1), rhs = Counter(3) -- expression 2 operands: lhs = Counter(1), rhs = Counter(2) -- expression 3 operands: lhs = Counter(1), rhs = Counter(2) -- expression 4 operands: lhs = Counter(0), rhs = Counter(3) -Number of file 0 mappings: 12 -- Code(Counter(0)) at (prev + 22, 1) to (start + 0, 54) -- Code(Counter(0)) at (prev + 4, 8) to (start + 0, 9) -- MCDCDecision { bitmap_idx: 3, conditions_num: 2 } at (prev + 0, 8) to (start + 0, 41) -- MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 8) to (start + 0, 9) - true = c1 - false = (c0 - c1) -- MCDCBranch { true: Counter(3), false: Expression(1, Sub), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 13) to (start + 0, 41) - true = c3 - false = (c1 - c3) -- Code(Counter(1)) at (prev + 0, 16) to (start + 0, 17) -- Branch { true: Counter(2), false: Expression(3, Sub) } at (prev + 0, 16) to (start + 0, 17) - true = c2 - false = (c1 - c2) -- Code(Counter(2)) at (prev + 0, 20) to (start + 0, 25) -- Code(Expression(3, Sub)) at (prev + 0, 35) to (start + 0, 39) - = (c1 - c2) -- Code(Counter(3)) at (prev + 0, 42) to (start + 2, 6) -- Code(Expression(4, Sub)) at (prev + 2, 12) to (start + 2, 6) - = (c0 - c3) -- Code(Counter(0)) at (prev + 3, 1) to (start + 0, 2) -Highest counter ID seen: c3 - diff --git a/tests/coverage/mcdc/nested_if.coverage b/tests/coverage/mcdc/nested_if.coverage deleted file mode 100644 index 8b5179b34fee5..0000000000000 --- a/tests/coverage/mcdc/nested_if.coverage +++ /dev/null @@ -1,257 +0,0 @@ - LL| |#![feature(coverage_attribute)] - LL| |//@ edition: 2021 - LL| |//@ compile-flags: -Zcoverage-options=mcdc - LL| |//@ llvm-cov-flags: --show-branches=count --show-mcdc - LL| | - LL| 4|fn nested_if_in_condition(a: bool, b: bool, c: bool) { - LL| 4| if a && if b || c { true } else { false } { - ^3 ^2 ^2 ^1 - ------------------ - | Branch (LL:8): [True: 3, False: 1] - | Branch (LL:13): [True: 2, False: 1] - | Branch (LL:16): [True: 1, False: 2] - | Branch (LL:21): [True: 1, False: 1] - ------------------ - |---> MC/DC Decision Region (LL:8) to (LL:46) - | - | Number of Conditions: 2 - | Condition C1 --> (LL:8) - | Condition C2 --> (LL:13) - | - | Executed MC/DC Test Vectors: - | - | C1, C2 Result - | 1 { F, - = F } - | 2 { T, F = F } - | 3 { T, T = T } - | - | C1-Pair: covered: (1,3) - | C2-Pair: covered: (2,3) - | MC/DC Coverage for Decision: 100.00% - | - |---> MC/DC Decision Region (LL:16) to (LL:22) - | - | Number of Conditions: 2 - | Condition C1 --> (LL:16) - | Condition C2 --> (LL:21) - | - | Executed MC/DC Test Vectors: - | - | C1, C2 Result - | 1 { F, F = F } - | 2 { F, T = T } - | 3 { T, - = T } - | - | C1-Pair: covered: (1,3) - | C2-Pair: covered: (1,2) - | MC/DC Coverage for Decision: 100.00% - | - ------------------ - LL| 2| say("yes"); - LL| 2| } else { - LL| 2| say("no"); - LL| 2| } - LL| 4|} - LL| | - LL| 4|fn doubly_nested_if_in_condition(a: bool, b: bool, c: bool, d: bool) { - LL| 4| if a && if b || if c && d { true } else { false } { false } else { true } { - ^3 ^2 ^1 ^1 ^1 ^2 ^1 - ------------------ - | Branch (LL:8): [True: 3, False: 1] - | Branch (LL:13): [True: 1, False: 2] - | Branch (LL:16): [True: 1, False: 2] - | Branch (LL:21): [True: 1, False: 1] - | Branch (LL:24): [True: 1, False: 1] - | Branch (LL:29): [True: 1, False: 0] - ------------------ - |---> MC/DC Decision Region (LL:8) to (LL:78) - | - | Number of Conditions: 2 - | Condition C1 --> (LL:8) - | Condition C2 --> (LL:13) - | - | Executed MC/DC Test Vectors: - | - | C1, C2 Result - | 1 { F, - = F } - | 2 { T, F = F } - | 3 { T, T = T } - | - | C1-Pair: covered: (1,3) - | C2-Pair: covered: (2,3) - | MC/DC Coverage for Decision: 100.00% - | - |---> MC/DC Decision Region (LL:16) to (LL:54) - | - | Number of Conditions: 2 - | Condition C1 --> (LL:16) - | Condition C2 --> (LL:21) - | - | Executed MC/DC Test Vectors: - | - | C1, C2 Result - | 1 { F, F = F } - | 2 { F, T = T } - | 3 { T, - = T } - | - | C1-Pair: covered: (1,3) - | C2-Pair: covered: (1,2) - | MC/DC Coverage for Decision: 100.00% - | - |---> MC/DC Decision Region (LL:24) to (LL:30) - | - | Number of Conditions: 2 - | Condition C1 --> (LL:24) - | Condition C2 --> (LL:29) - | - | Executed MC/DC Test Vectors: - | - | C1, C2 Result - | 1 { F, - = F } - | 2 { T, T = T } - | - | C1-Pair: covered: (1,2) - | C2-Pair: not covered - | MC/DC Coverage for Decision: 50.00% - | - ------------------ - LL| 1| say("yes"); - LL| 3| } else { - LL| 3| say("no"); - LL| 3| } - LL| 4|} - LL| | - LL| 3|fn nested_single_condition_decision(a: bool, b: bool) { - LL| | // Decision with only 1 decision should not be instrumented by MCDC because - LL| | // branch-coverage is equivalent to MCDC coverage in this case, and we don't - LL| | // want to waste bitmap space for this. - LL| 3| if a && if b { false } else { true } { - ^2 ^1 ^1 - ------------------ - | Branch (LL:8): [True: 2, False: 1] - | Branch (LL:13): [True: 1, False: 1] - | Branch (LL:16): [True: 1, False: 1] - ------------------ - |---> MC/DC Decision Region (LL:8) to (LL:41) - | - | Number of Conditions: 2 - | Condition C1 --> (LL:8) - | Condition C2 --> (LL:13) - | - | Executed MC/DC Test Vectors: - | - | C1, C2 Result - | 1 { F, - = F } - | 2 { T, F = F } - | 3 { T, T = T } - | - | C1-Pair: covered: (1,3) - | C2-Pair: covered: (2,3) - | MC/DC Coverage for Decision: 100.00% - | - ------------------ - LL| 1| say("yes"); - LL| 2| } else { - LL| 2| say("no"); - LL| 2| } - LL| 3|} - LL| | - LL| 7|fn nested_in_then_block_in_condition(a: bool, b: bool, c: bool, d: bool, e: bool) { - LL| 7| if a && if b || c { if d && e { true } else { false } } else { false } { - ^6 ^5 ^5 ^2 ^1 ^4 ^1 - ------------------ - | Branch (LL:8): [True: 6, False: 1] - | Branch (LL:13): [True: 1, False: 5] - | Branch (LL:16): [True: 1, False: 5] - | Branch (LL:21): [True: 4, False: 1] - | Branch (LL:28): [True: 2, False: 3] - | Branch (LL:33): [True: 1, False: 1] - ------------------ - |---> MC/DC Decision Region (LL:8) to (LL:75) - | - | Number of Conditions: 2 - | Condition C1 --> (LL:8) - | Condition C2 --> (LL:13) - | - | Executed MC/DC Test Vectors: - | - | C1, C2 Result - | 1 { F, - = F } - | 2 { T, F = F } - | 3 { T, T = T } - | - | C1-Pair: covered: (1,3) - | C2-Pair: covered: (2,3) - | MC/DC Coverage for Decision: 100.00% - | - |---> MC/DC Decision Region (LL:16) to (LL:22) - | - | Number of Conditions: 2 - | Condition C1 --> (LL:16) - | Condition C2 --> (LL:21) - | - | Executed MC/DC Test Vectors: - | - | C1, C2 Result - | 1 { F, F = F } - | 2 { F, T = T } - | 3 { T, - = T } - | - | C1-Pair: covered: (1,3) - | C2-Pair: covered: (1,2) - | MC/DC Coverage for Decision: 100.00% - | - |---> MC/DC Decision Region (LL:28) to (LL:34) - | - | Number of Conditions: 2 - | Condition C1 --> (LL:28) - | Condition C2 --> (LL:33) - | - | Executed MC/DC Test Vectors: - | - | C1, C2 Result - | 1 { F, - = F } - | 2 { T, F = F } - | 3 { T, T = T } - | - | C1-Pair: covered: (1,3) - | C2-Pair: covered: (2,3) - | MC/DC Coverage for Decision: 100.00% - | - ------------------ - LL| 1| say("yes"); - LL| 6| } else { - LL| 6| say("no"); - LL| 6| } - LL| 7|} - LL| | - LL| |#[coverage(off)] - LL| |fn main() { - LL| | nested_if_in_condition(true, false, false); - LL| | nested_if_in_condition(true, true, true); - LL| | nested_if_in_condition(true, false, true); - LL| | nested_if_in_condition(false, true, true); - LL| | - LL| | doubly_nested_if_in_condition(true, false, false, true); - LL| | doubly_nested_if_in_condition(true, true, true, true); - LL| | doubly_nested_if_in_condition(true, false, true, true); - LL| | doubly_nested_if_in_condition(false, true, true, true); - LL| | - LL| | nested_single_condition_decision(true, true); - LL| | nested_single_condition_decision(true, false); - LL| | nested_single_condition_decision(false, false); - LL| | - LL| | nested_in_then_block_in_condition(false, false, false, false, false); - LL| | nested_in_then_block_in_condition(true, false, false, false, false); - LL| | nested_in_then_block_in_condition(true, true, false, false, false); - LL| | nested_in_then_block_in_condition(true, false, true, false, false); - LL| | nested_in_then_block_in_condition(true, false, true, true, false); - LL| | nested_in_then_block_in_condition(true, false, true, false, true); - LL| | nested_in_then_block_in_condition(true, false, true, true, true); - LL| |} - LL| | - LL| |#[coverage(off)] - LL| |fn say(message: &str) { - LL| | core::hint::black_box(message); - LL| |} - diff --git a/tests/coverage/mcdc/nested_if.rs b/tests/coverage/mcdc/nested_if.rs deleted file mode 100644 index db02aece33c9d..0000000000000 --- a/tests/coverage/mcdc/nested_if.rs +++ /dev/null @@ -1,69 +0,0 @@ -#![feature(coverage_attribute)] -//@ edition: 2021 -//@ compile-flags: -Zcoverage-options=mcdc -//@ llvm-cov-flags: --show-branches=count --show-mcdc - -fn nested_if_in_condition(a: bool, b: bool, c: bool) { - if a && if b || c { true } else { false } { - say("yes"); - } else { - say("no"); - } -} - -fn doubly_nested_if_in_condition(a: bool, b: bool, c: bool, d: bool) { - if a && if b || if c && d { true } else { false } { false } else { true } { - say("yes"); - } else { - say("no"); - } -} - -fn nested_single_condition_decision(a: bool, b: bool) { - // Decision with only 1 decision should not be instrumented by MCDC because - // branch-coverage is equivalent to MCDC coverage in this case, and we don't - // want to waste bitmap space for this. - if a && if b { false } else { true } { - say("yes"); - } else { - say("no"); - } -} - -fn nested_in_then_block_in_condition(a: bool, b: bool, c: bool, d: bool, e: bool) { - if a && if b || c { if d && e { true } else { false } } else { false } { - say("yes"); - } else { - say("no"); - } -} - -#[coverage(off)] -fn main() { - nested_if_in_condition(true, false, false); - nested_if_in_condition(true, true, true); - nested_if_in_condition(true, false, true); - nested_if_in_condition(false, true, true); - - doubly_nested_if_in_condition(true, false, false, true); - doubly_nested_if_in_condition(true, true, true, true); - doubly_nested_if_in_condition(true, false, true, true); - doubly_nested_if_in_condition(false, true, true, true); - - nested_single_condition_decision(true, true); - nested_single_condition_decision(true, false); - nested_single_condition_decision(false, false); - - nested_in_then_block_in_condition(false, false, false, false, false); - nested_in_then_block_in_condition(true, false, false, false, false); - nested_in_then_block_in_condition(true, true, false, false, false); - nested_in_then_block_in_condition(true, false, true, false, false); - nested_in_then_block_in_condition(true, false, true, true, false); - nested_in_then_block_in_condition(true, false, true, false, true); - nested_in_then_block_in_condition(true, false, true, true, true); -} - -#[coverage(off)] -fn say(message: &str) { - core::hint::black_box(message); -} diff --git a/tests/coverage/mcdc/non_control_flow.cov-map b/tests/coverage/mcdc/non_control_flow.cov-map deleted file mode 100644 index f06bc2ed8168e..0000000000000 --- a/tests/coverage/mcdc/non_control_flow.cov-map +++ /dev/null @@ -1,186 +0,0 @@ -Function name: non_control_flow::assign_3 -Raw bytes (89): 0x[01, 01, 04, 01, 05, 01, 0b, 05, 09, 09, 0d, 0c, 01, 15, 01, 00, 27, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 28, 04, 03, 00, 0d, 00, 18, 30, 05, 02, 01, 00, 02, 00, 0d, 00, 0e, 02, 00, 12, 00, 13, 30, 09, 06, 02, 03, 00, 00, 12, 00, 13, 09, 00, 17, 00, 18, 30, 0d, 0e, 03, 00, 00, 00, 17, 00, 18, 01, 01, 05, 00, 0e, 01, 00, 0f, 00, 10, 01, 01, 01, 00, 02] -Number of files: 1 -- file 0 => $DIR/non_control_flow.rs -Number of expressions: 4 -- expression 0 operands: lhs = Counter(0), rhs = Counter(1) -- expression 1 operands: lhs = Counter(0), rhs = Expression(2, Add) -- expression 2 operands: lhs = Counter(1), rhs = Counter(2) -- expression 3 operands: lhs = Counter(2), rhs = Counter(3) -Number of file 0 mappings: 12 -- Code(Counter(0)) at (prev + 21, 1) to (start + 0, 39) -- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 10) -- Code(Counter(0)) at (prev + 0, 13) to (start + 0, 14) -- MCDCDecision { bitmap_idx: 4, conditions_num: 3 } at (prev + 0, 13) to (start + 0, 24) -- MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 0, false_next_id: 2 } at (prev + 0, 13) to (start + 0, 14) - true = c1 - false = (c0 - c1) -- Code(Expression(0, Sub)) at (prev + 0, 18) to (start + 0, 19) - = (c0 - c1) -- MCDCBranch { true: Counter(2), false: Expression(1, Sub), condition_id: 2, true_next_id: 3, false_next_id: 0 } at (prev + 0, 18) to (start + 0, 19) - true = c2 - false = (c0 - (c1 + c2)) -- Code(Counter(2)) at (prev + 0, 23) to (start + 0, 24) -- MCDCBranch { true: Counter(3), false: Expression(3, Sub), condition_id: 3, true_next_id: 0, false_next_id: 0 } at (prev + 0, 23) to (start + 0, 24) - true = c3 - false = (c2 - c3) -- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14) -- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 16) -- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) -Highest counter ID seen: c3 - -Function name: non_control_flow::assign_3_bis -Raw bytes (91): 0x[01, 01, 05, 01, 05, 05, 09, 01, 09, 01, 13, 09, 0d, 0c, 01, 1a, 01, 00, 2b, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 28, 05, 03, 00, 0d, 00, 18, 30, 05, 02, 01, 03, 02, 00, 0d, 00, 0e, 05, 00, 12, 00, 13, 30, 09, 06, 03, 00, 02, 00, 12, 00, 13, 0a, 00, 17, 00, 18, 30, 0d, 0e, 02, 00, 00, 00, 17, 00, 18, 01, 01, 05, 00, 0e, 01, 00, 0f, 00, 10, 01, 01, 01, 00, 02] -Number of files: 1 -- file 0 => $DIR/non_control_flow.rs -Number of expressions: 5 -- expression 0 operands: lhs = Counter(0), rhs = Counter(1) -- expression 1 operands: lhs = Counter(1), rhs = Counter(2) -- expression 2 operands: lhs = Counter(0), rhs = Counter(2) -- expression 3 operands: lhs = Counter(0), rhs = Expression(4, Add) -- expression 4 operands: lhs = Counter(2), rhs = Counter(3) -Number of file 0 mappings: 12 -- Code(Counter(0)) at (prev + 26, 1) to (start + 0, 43) -- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 10) -- Code(Counter(0)) at (prev + 0, 13) to (start + 0, 14) -- MCDCDecision { bitmap_idx: 5, conditions_num: 3 } at (prev + 0, 13) to (start + 0, 24) -- MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 3, false_next_id: 2 } at (prev + 0, 13) to (start + 0, 14) - true = c1 - false = (c0 - c1) -- Code(Counter(1)) at (prev + 0, 18) to (start + 0, 19) -- MCDCBranch { true: Counter(2), false: Expression(1, Sub), condition_id: 3, true_next_id: 0, false_next_id: 2 } at (prev + 0, 18) to (start + 0, 19) - true = c2 - false = (c1 - c2) -- Code(Expression(2, Sub)) at (prev + 0, 23) to (start + 0, 24) - = (c0 - c2) -- MCDCBranch { true: Counter(3), false: Expression(3, Sub), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 23) to (start + 0, 24) - true = c3 - false = (c0 - (c2 + c3)) -- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14) -- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 16) -- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) -Highest counter ID seen: c3 - -Function name: non_control_flow::assign_and -Raw bytes (70): 0x[01, 01, 02, 01, 05, 05, 09, 0a, 01, 0b, 01, 00, 20, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 28, 03, 02, 00, 0d, 00, 13, 30, 05, 02, 01, 02, 00, 00, 0d, 00, 0e, 05, 00, 12, 00, 13, 30, 09, 06, 02, 00, 00, 00, 12, 00, 13, 01, 01, 05, 00, 0e, 01, 00, 0f, 00, 10, 01, 01, 01, 00, 02] -Number of files: 1 -- file 0 => $DIR/non_control_flow.rs -Number of expressions: 2 -- expression 0 operands: lhs = Counter(0), rhs = Counter(1) -- expression 1 operands: lhs = Counter(1), rhs = Counter(2) -Number of file 0 mappings: 10 -- Code(Counter(0)) at (prev + 11, 1) to (start + 0, 32) -- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 10) -- Code(Counter(0)) at (prev + 0, 13) to (start + 0, 14) -- MCDCDecision { bitmap_idx: 3, conditions_num: 2 } at (prev + 0, 13) to (start + 0, 19) -- MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 13) to (start + 0, 14) - true = c1 - false = (c0 - c1) -- Code(Counter(1)) at (prev + 0, 18) to (start + 0, 19) -- MCDCBranch { true: Counter(2), false: Expression(1, Sub), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 18) to (start + 0, 19) - true = c2 - false = (c1 - c2) -- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14) -- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 16) -- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) -Highest counter ID seen: c2 - -Function name: non_control_flow::assign_or -Raw bytes (72): 0x[01, 01, 03, 01, 05, 01, 0b, 05, 09, 0a, 01, 10, 01, 00, 1f, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 28, 03, 02, 00, 0d, 00, 13, 30, 05, 02, 01, 00, 02, 00, 0d, 00, 0e, 02, 00, 12, 00, 13, 30, 09, 06, 02, 00, 00, 00, 12, 00, 13, 01, 01, 05, 00, 0e, 01, 00, 0f, 00, 10, 01, 01, 01, 00, 02] -Number of files: 1 -- file 0 => $DIR/non_control_flow.rs -Number of expressions: 3 -- expression 0 operands: lhs = Counter(0), rhs = Counter(1) -- expression 1 operands: lhs = Counter(0), rhs = Expression(2, Add) -- expression 2 operands: lhs = Counter(1), rhs = Counter(2) -Number of file 0 mappings: 10 -- Code(Counter(0)) at (prev + 16, 1) to (start + 0, 31) -- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 10) -- Code(Counter(0)) at (prev + 0, 13) to (start + 0, 14) -- MCDCDecision { bitmap_idx: 3, conditions_num: 2 } at (prev + 0, 13) to (start + 0, 19) -- MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 0, false_next_id: 2 } at (prev + 0, 13) to (start + 0, 14) - true = c1 - false = (c0 - c1) -- Code(Expression(0, Sub)) at (prev + 0, 18) to (start + 0, 19) - = (c0 - c1) -- MCDCBranch { true: Counter(2), false: Expression(1, Sub), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 18) to (start + 0, 19) - true = c2 - false = (c0 - (c1 + c2)) -- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14) -- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 16) -- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) -Highest counter ID seen: c2 - -Function name: non_control_flow::foo -Raw bytes (24): 0x[01, 01, 00, 04, 01, 24, 01, 00, 18, 01, 01, 05, 00, 0e, 01, 00, 0f, 00, 10, 01, 01, 01, 00, 02] -Number of files: 1 -- file 0 => $DIR/non_control_flow.rs -Number of expressions: 0 -Number of file 0 mappings: 4 -- Code(Counter(0)) at (prev + 36, 1) to (start + 0, 24) -- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14) -- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 16) -- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) -Highest counter ID seen: c0 - -Function name: non_control_flow::func_call -Raw bytes (60): 0x[01, 01, 02, 01, 05, 05, 09, 08, 01, 28, 01, 00, 1f, 01, 01, 05, 00, 08, 01, 00, 09, 00, 0a, 28, 03, 02, 00, 09, 00, 0f, 30, 05, 02, 01, 02, 00, 00, 09, 00, 0a, 05, 00, 0e, 00, 0f, 30, 09, 06, 02, 00, 00, 00, 0e, 00, 0f, 01, 01, 01, 00, 02] -Number of files: 1 -- file 0 => $DIR/non_control_flow.rs -Number of expressions: 2 -- expression 0 operands: lhs = Counter(0), rhs = Counter(1) -- expression 1 operands: lhs = Counter(1), rhs = Counter(2) -Number of file 0 mappings: 8 -- Code(Counter(0)) at (prev + 40, 1) to (start + 0, 31) -- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 8) -- Code(Counter(0)) at (prev + 0, 9) to (start + 0, 10) -- MCDCDecision { bitmap_idx: 3, conditions_num: 2 } at (prev + 0, 9) to (start + 0, 15) -- MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 9) to (start + 0, 10) - true = c1 - false = (c0 - c1) -- Code(Counter(1)) at (prev + 0, 14) to (start + 0, 15) -- MCDCBranch { true: Counter(2), false: Expression(1, Sub), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 14) to (start + 0, 15) - true = c2 - false = (c1 - c2) -- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) -Highest counter ID seen: c2 - -Function name: non_control_flow::right_comb_tree -Raw bytes (121): 0x[01, 01, 05, 01, 05, 05, 09, 09, 0d, 0d, 11, 11, 15, 10, 01, 1f, 01, 00, 40, 01, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 28, 06, 05, 00, 0d, 00, 2a, 30, 05, 02, 01, 02, 00, 00, 0d, 00, 0e, 05, 00, 13, 00, 14, 30, 09, 06, 02, 03, 00, 00, 13, 00, 14, 09, 00, 19, 00, 1a, 30, 0d, 0a, 03, 04, 00, 00, 19, 00, 1a, 0d, 00, 1f, 00, 20, 30, 11, 0e, 04, 05, 00, 00, 1f, 00, 20, 11, 00, 24, 00, 27, 30, 15, 12, 05, 00, 00, 00, 24, 00, 27, 01, 01, 05, 00, 0e, 01, 00, 0f, 00, 10, 01, 01, 01, 00, 02] -Number of files: 1 -- file 0 => $DIR/non_control_flow.rs -Number of expressions: 5 -- expression 0 operands: lhs = Counter(0), rhs = Counter(1) -- expression 1 operands: lhs = Counter(1), rhs = Counter(2) -- expression 2 operands: lhs = Counter(2), rhs = Counter(3) -- expression 3 operands: lhs = Counter(3), rhs = Counter(4) -- expression 4 operands: lhs = Counter(4), rhs = Counter(5) -Number of file 0 mappings: 16 -- Code(Counter(0)) at (prev + 31, 1) to (start + 0, 64) -- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 10) -- Code(Counter(0)) at (prev + 0, 13) to (start + 0, 14) -- MCDCDecision { bitmap_idx: 6, conditions_num: 5 } at (prev + 0, 13) to (start + 0, 42) -- MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 13) to (start + 0, 14) - true = c1 - false = (c0 - c1) -- Code(Counter(1)) at (prev + 0, 19) to (start + 0, 20) -- MCDCBranch { true: Counter(2), false: Expression(1, Sub), condition_id: 2, true_next_id: 3, false_next_id: 0 } at (prev + 0, 19) to (start + 0, 20) - true = c2 - false = (c1 - c2) -- Code(Counter(2)) at (prev + 0, 25) to (start + 0, 26) -- MCDCBranch { true: Counter(3), false: Expression(2, Sub), condition_id: 3, true_next_id: 4, false_next_id: 0 } at (prev + 0, 25) to (start + 0, 26) - true = c3 - false = (c2 - c3) -- Code(Counter(3)) at (prev + 0, 31) to (start + 0, 32) -- MCDCBranch { true: Counter(4), false: Expression(3, Sub), condition_id: 4, true_next_id: 5, false_next_id: 0 } at (prev + 0, 31) to (start + 0, 32) - true = c4 - false = (c3 - c4) -- Code(Counter(4)) at (prev + 0, 36) to (start + 0, 39) -- MCDCBranch { true: Counter(5), false: Expression(4, Sub), condition_id: 5, true_next_id: 0, false_next_id: 0 } at (prev + 0, 36) to (start + 0, 39) - true = c5 - false = (c4 - c5) -- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14) -- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 16) -- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) -Highest counter ID seen: c5 - diff --git a/tests/coverage/mcdc/non_control_flow.coverage b/tests/coverage/mcdc/non_control_flow.coverage deleted file mode 100644 index 419d40bb6f993..0000000000000 --- a/tests/coverage/mcdc/non_control_flow.coverage +++ /dev/null @@ -1,224 +0,0 @@ - LL| |#![feature(coverage_attribute)] - LL| |//@ edition: 2021 - LL| |//@ compile-flags: -Zcoverage-options=mcdc - LL| |//@ llvm-cov-flags: --show-branches=count --show-mcdc - LL| | - LL| |// This test ensures that boolean expressions that are not inside control flow - LL| |// decisions are correctly instrumented. - LL| | - LL| |use core::hint::black_box; - LL| | - LL| 3|fn assign_and(a: bool, b: bool) { - LL| 3| let x = a && b; - ^2 - ------------------ - | Branch (LL:13): [True: 2, False: 1] - | Branch (LL:18): [True: 1, False: 1] - ------------------ - |---> MC/DC Decision Region (LL:13) to (LL:19) - | - | Number of Conditions: 2 - | Condition C1 --> (LL:13) - | Condition C2 --> (LL:18) - | - | Executed MC/DC Test Vectors: - | - | C1, C2 Result - | 1 { F, - = F } - | 2 { T, F = F } - | 3 { T, T = T } - | - | C1-Pair: covered: (1,3) - | C2-Pair: covered: (2,3) - | MC/DC Coverage for Decision: 100.00% - | - ------------------ - LL| 3| black_box(x); - LL| 3|} - LL| | - LL| 3|fn assign_or(a: bool, b: bool) { - LL| 3| let x = a || b; - ^1 - ------------------ - | Branch (LL:13): [True: 2, False: 1] - | Branch (LL:18): [True: 0, False: 1] - ------------------ - |---> MC/DC Decision Region (LL:13) to (LL:19) - | - | Number of Conditions: 2 - | Condition C1 --> (LL:13) - | Condition C2 --> (LL:18) - | - | Executed MC/DC Test Vectors: - | - | C1, C2 Result - | 1 { F, F = F } - | 2 { T, - = T } - | - | C1-Pair: covered: (1,2) - | C2-Pair: not covered - | MC/DC Coverage for Decision: 50.00% - | - ------------------ - LL| 3| black_box(x); - LL| 3|} - LL| | - LL| 4|fn assign_3(a: bool, b: bool, c: bool) { - LL| 4| let x = a || b && c; - ^2 ^1 - ------------------ - | Branch (LL:13): [True: 2, False: 2] - | Branch (LL:18): [True: 1, False: 1] - | Branch (LL:23): [True: 1, False: 0] - ------------------ - |---> MC/DC Decision Region (LL:13) to (LL:24) - | - | Number of Conditions: 3 - | Condition C1 --> (LL:13) - | Condition C2 --> (LL:18) - | Condition C3 --> (LL:23) - | - | Executed MC/DC Test Vectors: - | - | C1, C2, C3 Result - | 1 { F, F, - = F } - | 2 { F, T, T = T } - | 3 { T, -, - = T } - | - | C1-Pair: covered: (1,3) - | C2-Pair: covered: (1,2) - | C3-Pair: not covered - | MC/DC Coverage for Decision: 66.67% - | - ------------------ - LL| 4| black_box(x); - LL| 4|} - LL| | - LL| 4|fn assign_3_bis(a: bool, b: bool, c: bool) { - LL| 4| let x = a && b || c; - ^2 ^3 - ------------------ - | Branch (LL:13): [True: 2, False: 2] - | Branch (LL:18): [True: 1, False: 1] - | Branch (LL:23): [True: 2, False: 1] - ------------------ - |---> MC/DC Decision Region (LL:13) to (LL:24) - | - | Number of Conditions: 3 - | Condition C1 --> (LL:13) - | Condition C2 --> (LL:18) - | Condition C3 --> (LL:23) - | - | Executed MC/DC Test Vectors: - | - | C1, C2, C3 Result - | 1 { T, F, F = F } - | 2 { F, -, T = T } - | 3 { T, T, - = T } - | - | C1-Pair: not covered - | C2-Pair: covered: (1,3) - | C3-Pair: not covered - | MC/DC Coverage for Decision: 33.33% - | - ------------------ - LL| 4| black_box(x); - LL| 4|} - LL| | - LL| 3|fn right_comb_tree(a: bool, b: bool, c: bool, d: bool, e: bool) { - LL| 3| let x = a && (b && (c && (d && (e)))); - ^2 ^1 ^1 ^1 - ------------------ - | Branch (LL:13): [True: 2, False: 1] - | Branch (LL:19): [True: 1, False: 1] - | Branch (LL:25): [True: 1, False: 0] - | Branch (LL:31): [True: 1, False: 0] - | Branch (LL:36): [True: 1, False: 0] - ------------------ - |---> MC/DC Decision Region (LL:13) to (LL:42) - | - | Number of Conditions: 5 - | Condition C1 --> (LL:13) - | Condition C2 --> (LL:19) - | Condition C3 --> (LL:25) - | Condition C4 --> (LL:31) - | Condition C5 --> (LL:36) - | - | Executed MC/DC Test Vectors: - | - | C1, C2, C3, C4, C5 Result - | 1 { F, -, -, -, - = F } - | 2 { T, F, -, -, - = F } - | 3 { T, T, T, T, T = T } - | - | C1-Pair: covered: (1,3) - | C2-Pair: covered: (2,3) - | C3-Pair: not covered - | C4-Pair: not covered - | C5-Pair: not covered - | MC/DC Coverage for Decision: 40.00% - | - ------------------ - LL| 3| black_box(x); - LL| 3|} - LL| | - LL| 3|fn foo(a: bool) -> bool { - LL| 3| black_box(a) - LL| 3|} - LL| | - LL| 3|fn func_call(a: bool, b: bool) { - LL| 3| foo(a && b); - ^2 - ------------------ - | Branch (LL:9): [True: 2, False: 1] - | Branch (LL:14): [True: 1, False: 1] - ------------------ - |---> MC/DC Decision Region (LL:9) to (LL:15) - | - | Number of Conditions: 2 - | Condition C1 --> (LL:9) - | Condition C2 --> (LL:14) - | - | Executed MC/DC Test Vectors: - | - | C1, C2 Result - | 1 { F, - = F } - | 2 { T, F = F } - | 3 { T, T = T } - | - | C1-Pair: covered: (1,3) - | C2-Pair: covered: (2,3) - | MC/DC Coverage for Decision: 100.00% - | - ------------------ - LL| 3|} - LL| | - LL| |#[coverage(off)] - LL| |fn main() { - LL| | assign_and(true, false); - LL| | assign_and(true, true); - LL| | assign_and(false, false); - LL| | - LL| | assign_or(true, false); - LL| | assign_or(true, true); - LL| | assign_or(false, false); - LL| | - LL| | assign_3(true, false, false); - LL| | assign_3(true, true, false); - LL| | assign_3(false, false, true); - LL| | assign_3(false, true, true); - LL| | - LL| | assign_3_bis(true, false, false); - LL| | assign_3_bis(true, true, false); - LL| | assign_3_bis(false, false, true); - LL| | assign_3_bis(false, true, true); - LL| | - LL| | right_comb_tree(false, false, false, true, true); - LL| | right_comb_tree(true, false, false, true, true); - LL| | right_comb_tree(true, true, true, true, true); - LL| | - LL| | func_call(true, false); - LL| | func_call(true, true); - LL| | func_call(false, false); - LL| |} - diff --git a/tests/coverage/mcdc/non_control_flow.rs b/tests/coverage/mcdc/non_control_flow.rs deleted file mode 100644 index 863bb8a5756d2..0000000000000 --- a/tests/coverage/mcdc/non_control_flow.rs +++ /dev/null @@ -1,71 +0,0 @@ -#![feature(coverage_attribute)] -//@ edition: 2021 -//@ compile-flags: -Zcoverage-options=mcdc -//@ llvm-cov-flags: --show-branches=count --show-mcdc - -// This test ensures that boolean expressions that are not inside control flow -// decisions are correctly instrumented. - -use core::hint::black_box; - -fn assign_and(a: bool, b: bool) { - let x = a && b; - black_box(x); -} - -fn assign_or(a: bool, b: bool) { - let x = a || b; - black_box(x); -} - -fn assign_3(a: bool, b: bool, c: bool) { - let x = a || b && c; - black_box(x); -} - -fn assign_3_bis(a: bool, b: bool, c: bool) { - let x = a && b || c; - black_box(x); -} - -fn right_comb_tree(a: bool, b: bool, c: bool, d: bool, e: bool) { - let x = a && (b && (c && (d && (e)))); - black_box(x); -} - -fn foo(a: bool) -> bool { - black_box(a) -} - -fn func_call(a: bool, b: bool) { - foo(a && b); -} - -#[coverage(off)] -fn main() { - assign_and(true, false); - assign_and(true, true); - assign_and(false, false); - - assign_or(true, false); - assign_or(true, true); - assign_or(false, false); - - assign_3(true, false, false); - assign_3(true, true, false); - assign_3(false, false, true); - assign_3(false, true, true); - - assign_3_bis(true, false, false); - assign_3_bis(true, true, false); - assign_3_bis(false, false, true); - assign_3_bis(false, true, true); - - right_comb_tree(false, false, false, true, true); - right_comb_tree(true, false, false, true, true); - right_comb_tree(true, true, true, true, true); - - func_call(true, false); - func_call(true, true); - func_call(false, false); -} diff --git a/tests/ui/instrument-coverage/coverage-options.bad.stderr b/tests/ui/instrument-coverage/coverage-options.bad.stderr index 4a272cf97fb00..a7ea721659b63 100644 --- a/tests/ui/instrument-coverage/coverage-options.bad.stderr +++ b/tests/ui/instrument-coverage/coverage-options.bad.stderr @@ -1,2 +1,2 @@ -error: incorrect value `bad` for unstable option `coverage-options` - `block` | `branch` | `condition` | `mcdc` was expected +error: incorrect value `bad` for unstable option `coverage-options` - `block` | `branch` | `condition` was expected diff --git a/tests/ui/instrument-coverage/coverage-options.rs b/tests/ui/instrument-coverage/coverage-options.rs index c3eae9625da98..ead2e3221d8cb 100644 --- a/tests/ui/instrument-coverage/coverage-options.rs +++ b/tests/ui/instrument-coverage/coverage-options.rs @@ -1,4 +1,4 @@ -//@ revisions: block branch condition mcdc bad +//@ revisions: block branch condition bad //@ compile-flags -Cinstrument-coverage -Zno-profiler-runtime //@ [block] check-pass @@ -10,9 +10,6 @@ //@ [condition] check-pass //@ [condition] compile-flags: -Zcoverage-options=condition -//@ [mcdc] check-pass -//@ [mcdc] compile-flags: -Zcoverage-options=mcdc - //@ [bad] check-fail //@ [bad] compile-flags: -Zcoverage-options=bad diff --git a/tests/ui/instrument-coverage/mcdc-condition-limit.rs b/tests/ui/instrument-coverage/mcdc-condition-limit.rs deleted file mode 100644 index 74707ba2e670d..0000000000000 --- a/tests/ui/instrument-coverage/mcdc-condition-limit.rs +++ /dev/null @@ -1,22 +0,0 @@ -//@ edition: 2021 -//@ revisions: good -//@ check-pass -//@ compile-flags: -Cinstrument-coverage -Zcoverage-options=mcdc -Zno-profiler-runtime - -// Check that we emit some kind of diagnostic when MC/DC instrumentation sees -// code that exceeds the limit of 6 conditions per decision, and falls back -// to only instrumenting that code for branch coverage. -// -// See also `tests/coverage/mcdc/condition-limit.rs`, which tests the actual -// effect on instrumentation. -// -// (The limit is enforced in `compiler/rustc_mir_build/src/build/coverageinfo/mcdc.rs`.) - -#[cfg(good)] -fn main() { - // 7 conditions is allowed, so no diagnostic. - let [a, b, c, d, e, f, g] = <[bool; 7]>::default(); - if a && b && c && d && e && f && g { - core::hint::black_box("hello"); - } -}