@@ -1021,6 +1021,40 @@ impl Session {
10211021 || self . opts . debugging_opts . sanitizer . intersects ( SanitizerSet :: ADDRESS | SanitizerSet :: MEMORY )
10221022 }
10231023
1024+ pub fn link_dead_code ( & self ) -> bool {
1025+ match self . opts . cg . link_dead_code {
1026+ Some ( explicitly_set) => explicitly_set,
1027+ None => {
1028+ self . opts . debugging_opts . instrument_coverage
1029+ && !self . target . target . options . is_like_msvc
1030+ // Issue #76038: (rustc `-Clink-dead-code` causes MSVC linker to produce invalid
1031+ // binaries when LLVM InstrProf counters are enabled). As described by this issue,
1032+ // the "link dead code" option produces incorrect binaries when compiled and linked
1033+ // under MSVC. The resulting Rust programs typically crash with a segmentation
1034+ // fault, or produce an empty "*.profraw" file (profiling counter results normally
1035+ // generated during program exit).
1036+ //
1037+ // If not targeting MSVC, `-Z instrument-coverage` implies `-C link-dead-code`, so
1038+ // unexecuted code is still counted as zero, rather than be optimized out. Note that
1039+ // instrumenting dead code can be explicitly disabled with:
1040+ //
1041+ // `-Z instrument-coverage -C link-dead-code=no`.
1042+ //
1043+ // FIXME(richkadel): Investigate if `instrument-coverage` implementation can inject
1044+ // [zero counters](https://llvm.org/docs/CoverageMappingFormat.html#counter) in the
1045+ // coverage map when "dead code" is removed, rather than forcing `link-dead-code`.
1046+ // This may not be possible, however, if (as it seems to appear) the "dead code"
1047+ // that would otherwise not be linked is only identified as "dead" by the native
1048+ // linker. If that's the case, I believe it is too late for the Rust compiler to
1049+ // leverage any information it might be able to get from the linker regarding what
1050+ // code is dead, to be able to add those counters.
1051+ //
1052+ // On the other hand, if any Rust compiler passes are optimizing out dead code blocks
1053+ // we should inject "zero" counters for those code regions.
1054+ }
1055+ }
1056+ }
1057+
10241058 pub fn mark_attr_known ( & self , attr : & Attribute ) {
10251059 self . known_attrs . lock ( ) . mark ( attr)
10261060 }
@@ -1428,20 +1462,6 @@ fn validate_commandline_args_with_session_available(sess: &Session) {
14281462 ) ;
14291463 }
14301464
1431- // FIXME(richkadel): See `src/test/run-make-fulldeps/instrument-coverage/Makefile`. After
1432- // compiling with `-Zinstrument-coverage`, the resulting binary generates a segfault during
1433- // the program's exit process (likely while attempting to generate the coverage stats in
1434- // the "*.profraw" file). An investigation to resolve the problem on Windows is ongoing,
1435- // but until this is resolved, the option is disabled on Windows, and the test is skipped
1436- // when targeting `MSVC`.
1437- if sess. opts . debugging_opts . instrument_coverage && sess. target . target . options . is_like_msvc {
1438- sess. warn (
1439- "Rust source-based code coverage instrumentation (with `-Z instrument-coverage`) \
1440- is not yet supported on Windows when targeting MSVC. The resulting binaries will \
1441- still be instrumented for experimentation purposes, but may not execute correctly.",
1442- ) ;
1443- }
1444-
14451465 const ASAN_SUPPORTED_TARGETS : & [ & str ] = & [
14461466 "aarch64-fuchsia" ,
14471467 "aarch64-unknown-linux-gnu" ,
0 commit comments