Skip to content

is_flag_supported ignores Build::env overrides; gnu_debug_fp/gnu_debug_fp_auto fail on Windows hosts without a system cc (since #1845) #1859

Description

@MohammedAlkindi

Environment: Windows 11, rustup stable-x86_64-pc-windows-gnu, mingw-w64 gcc 16.2 on PATH as gcc.exe — no cc.exe (where cc finds nothing), no MSVC installed. I'd expect this to be a common shape for Windows contributors using rustup plus a mingw toolchain.

Symptom: on a fresh clone of main, cargo test --test test fails:

thread 'gnu_debug_fp' panicked at tests\test.rs:119:17:
didn't find "-mno-omit-leaf-frame-pointer" in ["-O2", "-ffunction-sections", "-fdata-sections",
"-fPIC", "-g", "-gdwarf-4", "-fno-omit-frame-pointer", "-m64", "-o",
"...\\db3b6bfb95261072-foo.o", "-c", "foo.c"]

gnu_debug_fp_auto fails the same way. This started when #1845 made -mno-omit-leaf-frame-pointer conditional on is_flag_supported. CI stays green, but for a reason that I think is itself a bug — see below.

Mechanism (traced with CC_ENABLE_DEBUG_OUTPUT=1):

The test framework only exposes the shim directory through Build::env:

// tests/support/mod.rs
.env("PATH", self.path())   // shim dir prepended

Build::env overrides are applied to the Tool's spawn environment at the end of try_get_compiler ("Do this last, to allow overwriting the other values above"), and the main compile honors them. But is_flag_supported_inner (src/lib.rs:1488) constructs a fresh Build for the probe and copies compiler / opt_level / debug / cpp / cuda / … — everything except self.env. So the probe resolves and spawns cc against the real process environment:

running: "cc" "-E" "...\detect_compiler_family.c"
cargo:warning=Compiler family detection failed due to error: ToolNotFound: failed to find tool "cc": program not found
running: "cc" "-O2" ... "-g" "-gdwarf-4" "-fno-omit-frame-pointer" "-m64" ... "-c" "foo.c"   <-- flag missing
exit code: 0

Consequences:

  • On a host with a system cc (every current CI runner), the probe silently uses that compiler rather than the shim — the test passes, but it is testing the host compiler's flag support.
  • On a host without one (this machine), the probe fails, is_flag_supported comes back false via .unwrap_or(false), the flag is silently dropped, and the test fails.
  • Outside the test suite, any user who configures a Build with .env(...) (say a PATH or CC override) gets flag probes that ignore those overrides — and since do not emit -mno-omit-leaf-frame-pointer if unsupported #1845 that can silently change which flags are emitted.

Why this isn't a PR yet: the small fix — copying self.env into the probe's Build

             if let Some(host) = &self.host {
                 cfg.host(host);
             }
+            // Pass along the custom env vars the user specified with
+            // `Build::env`, so that the probe resolves and spawns the
+            // compiler in the same environment as the real invocation.
+            for (key, val) in &self.env {
+                cfg.env(key, val);
+            }
             cfg.try_get_compiler()?

— does make the probe hit the shim, and the flag is then emitted (verified here: the main compile gains -mno-omit-leaf-frame-pointer). But the shim then records the probe invocation (the -c cwd fallback in cc-shim.rs anticipates exactly this), which shifts the out{N} indices, and gnu_debug_fp fails differently: cmd(0) now matches the probe's arguments instead of the main compile's. cc-shim.rs also documents that family detection "must keep failing", so the framework currently depends on probes and detection not seeing the shim. That seems like a design decision rather than a drive-by patch: should probes see the shim (then recordings/indices and family detection need explicit handling), should the framework pin probe results for tests, or should these tests avoid asserting probed flags? Happy to send a PR for whichever direction you prefer.

Related: #851 (env overrides dropped on the get_compiler path — same family of problem), #1632 (probe mechanics), #1844 / #1845 (the change that exposed this).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions