diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs index 51baa2aafb7..ff65726c837 100644 --- a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs +++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs @@ -26,6 +26,11 @@ use tracing::debug; /// undocumented details in Clang's implementation (that may or may not be important) were also /// replicated for Rust's Coverage Map. pub fn finalize<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>) { + // Ensure LLVM supports Coverage Map Version 4 (encoded as a zero-based value: 3). + // If not, the LLVM Version must be less than 11. + let version = coverageinfo::mapping_version(); + assert_eq!(version, 3, "rustc option `-Z instrument-coverage` requires LLVM 11 or higher."); + let function_coverage_map = match cx.coverage_context() { Some(ctx) => ctx.take_function_coverage_map(), None => return, @@ -68,7 +73,7 @@ pub fn finalize<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>) { let filenames_ref = coverageinfo::hash_bytes(filenames_buffer); // Generate the LLVM IR representation of the coverage map and store it in a well-known global - let cov_data_val = mapgen.generate_coverage_map(cx, filenames_size, filenames_val); + let cov_data_val = mapgen.generate_coverage_map(cx, version, filenames_size, filenames_val); for (mangled_function_name, function_source_hash, coverage_mapping_buffer) in function_data { save_function_record( @@ -159,21 +164,18 @@ impl CoverageMapGenerator { fn generate_coverage_map( self, cx: &CodegenCx<'ll, 'tcx>, + version: u32, filenames_size: usize, filenames_val: &'ll llvm::Value, ) -> &'ll llvm::Value { - debug!( - "cov map: filenames_size = {}, 0-based version = {}", - filenames_size, - coverageinfo::mapping_version() - ); + debug!("cov map: filenames_size = {}, 0-based version = {}", filenames_size, version); // Create the coverage data header (Note, fields 0 and 2 are now always zero, // as of `llvm::coverage::CovMapVersion::Version4`.) let zero_was_n_records_val = cx.const_u32(0); let filenames_size_val = cx.const_u32(filenames_size as u32); let zero_was_coverage_size_val = cx.const_u32(0); - let version_val = cx.const_u32(coverageinfo::mapping_version()); + let version_val = cx.const_u32(version); let cov_data_header_val = cx.const_struct( &[zero_was_n_records_val, filenames_size_val, zero_was_coverage_size_val, version_val], /*packed=*/ false, diff --git a/compiler/rustc_llvm/llvm-wrapper/CoverageMappingWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/CoverageMappingWrapper.cpp index 2b76cd5849d..25badc3f4e1 100644 --- a/compiler/rustc_llvm/llvm-wrapper/CoverageMappingWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/CoverageMappingWrapper.cpp @@ -73,8 +73,7 @@ extern "C" void LLVMRustCoverageWriteFuncSectionNameToString(LLVMModuleRef M, RustStringRef Str) { #if LLVM_VERSION_GE(11, 0) WriteSectionNameToString(M, IPSK_covfun, Str); -#else - report_fatal_error("rustc option `-Z instrument-coverage` requires LLVM 11 or higher."); +// else do nothing; the `Version` check will abort codegen on the Rust side #endif } @@ -88,6 +87,6 @@ extern "C" uint32_t LLVMRustCoverageMappingVersion() { #if LLVM_VERSION_GE(11, 0) return coverage::CovMapVersion::Version4; #else - report_fatal_error("rustc option `-Z instrument-coverage` requires LLVM 11 or higher."); + return coverage::CovMapVersion::Version3; #endif }