Skip to content

Commit 67bcaa9

Browse files
committed
Auto merge of #153968 - jyn514:jyn/linker-warn-by-default, r=mati865
linker-messages is warn-by-default again cc #136096 I ended up keeping it a lint and adding an option for lints to ignore `-Dwarnings` (there was already a lint that did that actually, it was just hard-coded in rustc_middle instead of in rustc_lint_defs like I'd expect). This allows people to actually see the warnings without them failing the build in CI.
2 parents 0164cc1 + 4e99b68 commit 67bcaa9

11 files changed

Lines changed: 129 additions & 18 deletions

File tree

compiler/rustc_codegen_ssa/src/back/link.rs

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -692,6 +692,15 @@ fn is_windows_gnu_ld(sess: &Session) -> bool {
692692
sess.target.is_like_windows
693693
&& !sess.target.is_like_msvc
694694
&& matches!(flavor, LinkerFlavor::Gnu(_, Lld::No))
695+
&& sess.target.options.cfg_abi != CfgAbi::Llvm
696+
}
697+
698+
fn is_windows_gnu_clang(sess: &Session) -> bool {
699+
let (_, flavor) = linker_and_flavor(sess);
700+
sess.target.is_like_windows
701+
&& !sess.target.is_like_msvc
702+
&& matches!(flavor, LinkerFlavor::Gnu(Cc::Yes, Lld::No))
703+
&& sess.target.options.cfg_abi == CfgAbi::Llvm
695704
}
696705

697706
fn report_linker_output(sess: &Session, levels: CodegenLintLevels, stdout: &[u8], stderr: &[u8]) {
@@ -720,9 +729,10 @@ fn report_linker_output(sess: &Session, levels: CodegenLintLevels, stdout: &[u8]
720729
escaped_stdout = for_each(&stdout, |line, output| {
721730
// Hide some progress messages from link.exe that we don't care about.
722731
// See https://github.com/chromium/chromium/blob/bfa41e41145ffc85f041384280caf2949bb7bd72/build/toolchain/win/tool_wrapper.py#L144-L146
723-
if line.starts_with(" Creating library")
724-
|| line.starts_with("Generating code")
725-
|| line.starts_with("Finished generating code")
732+
let trimmed = line.trim_start();
733+
if trimmed.starts_with("Creating library")
734+
|| trimmed.starts_with("Generating code")
735+
|| trimmed.starts_with("Finished generating code")
726736
{
727737
linker_info += line;
728738
linker_info += "\r\n";
@@ -781,7 +791,18 @@ fn report_linker_output(sess: &Session, levels: CodegenLintLevels, stdout: &[u8]
781791
*output += "\n"
782792
}
783793
});
784-
}
794+
} else if is_windows_gnu_clang(sess) {
795+
info!("inferred Windows Clang (GNU ABI)");
796+
escaped_stderr = for_each(&stderr, |line, output| {
797+
if line.contains("argument unused during compilation: '-nolibc'") {
798+
linker_info += line;
799+
linker_info += "\n";
800+
} else {
801+
*output += line;
802+
*output += "\n"
803+
}
804+
});
805+
};
785806

786807
let lint_msg = |msg| {
787808
emit_lint_base(
@@ -805,10 +826,10 @@ fn report_linker_output(sess: &Session, levels: CodegenLintLevels, stdout: &[u8]
805826
.strip_prefix("Warning: ")
806827
.unwrap_or(&escaped_stderr)
807828
.replace(": warning: ", ": ");
808-
lint_msg(format!("linker stderr: {escaped_stderr}"));
829+
lint_msg(format!("linker stderr: {}", escaped_stderr.trim_end()));
809830
}
810831
if !escaped_stdout.is_empty() {
811-
lint_msg(format!("linker stdout: {}", escaped_stdout))
832+
lint_msg(format!("linker stdout: {}", escaped_stdout.trim_end()))
812833
}
813834
if !linker_info.is_empty() {
814835
lint_info(linker_info);

compiler/rustc_lint_defs/src/builtin.rs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,11 @@ declare_lint! {
193193
reason: fcw!(FutureReleaseError #81670),
194194
report_in_deps: true,
195195
};
196+
// We exempt `FORBIDDEN_LINT_GROUPS` from `-Dwarnings` because it specifically
197+
// triggers in cases (like #80988) where you have `forbid(warnings)`,
198+
// and so if we turned that into an error, it'd defeat the purpose of the
199+
// future compatibility warning.
200+
ignore_deny_warnings
196201
}
197202

198203
declare_lint! {
@@ -4073,8 +4078,12 @@ declare_lint! {
40734078
/// and actionable warning of similar quality to our other diagnostics. See this tracking
40744079
/// issue for more details: <https://github.com/rust-lang/rust/issues/136096>.
40754080
pub LINKER_MESSAGES,
4076-
Allow,
4077-
"warnings emitted at runtime by the target-specific linker program"
4081+
Warn,
4082+
"warnings emitted at runtime by the target-specific linker program",
4083+
// Linker messages don't live up to the high standard people expect of rustc's errors.
4084+
// Prevent `-D warnings` from applying to it.
4085+
// It's still possible to pass `-D linker-messages` specifically.
4086+
ignore_deny_warnings
40784087
}
40794088

40804089
declare_lint! {

compiler/rustc_lint_defs/src/lib.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,9 @@ pub struct Lint {
343343
/// `true` if this lint should not be filtered out under any circustamces
344344
/// (e.g. the unknown_attributes lint)
345345
pub eval_always: bool,
346+
347+
/// `true` if this lint is unaffected by `-D warnings`
348+
pub ignore_deny_warnings: bool,
346349
}
347350

348351
/// Extra information for a future incompatibility lint.
@@ -558,6 +561,7 @@ impl Lint {
558561
feature_gate: None,
559562
crate_level_only: false,
560563
eval_always: false,
564+
ignore_deny_warnings: false,
561565
}
562566
}
563567

compiler/rustc_middle/src/lint.rs

Lines changed: 36 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,9 @@ use rustc_hir::{HirId, ItemLocalId};
77
use rustc_lint_defs::EditionFcw;
88
use rustc_macros::{Decodable, Encodable, HashStable};
99
use rustc_session::Session;
10-
use rustc_session::lint::builtin::{self, FORBIDDEN_LINT_GROUPS};
11-
use rustc_session::lint::{FutureIncompatibilityReason, Level, Lint, LintExpectationId, LintId};
10+
use rustc_session::lint::{
11+
FutureIncompatibilityReason, Level, Lint, LintExpectationId, LintId, builtin,
12+
};
1213
use rustc_span::{DUMMY_SP, ExpnKind, Span, Symbol, kw};
1314
use tracing::instrument;
1415

@@ -89,17 +90,30 @@ pub fn reveal_actual_level(
8990
level.unwrap_or_else(|| (lint.lint.default_level(sess.edition()), None));
9091

9192
// If we're about to issue a warning, check at the last minute for any
92-
// directives against the warnings "lint". If, for example, there's an
93+
// directives against the `warnings` lint group. If, for example, there's an
9394
// `allow(warnings)` in scope then we want to respect that instead.
94-
//
95-
// We exempt `FORBIDDEN_LINT_GROUPS` from this because it specifically
96-
// triggers in cases (like #80988) where you have `forbid(warnings)`,
97-
// and so if we turned that into an error, it'd defeat the purpose of the
98-
// future compatibility warning.
99-
if level == Level::Warn && lint != LintId::of(FORBIDDEN_LINT_GROUPS) {
95+
if level == Level::Warn {
10096
let (warnings_level, warnings_src) = probe_for_lint_level(LintId::of(builtin::WARNINGS));
10197
if let Some((configured_warning_level, configured_lint_id)) = warnings_level {
102-
if configured_warning_level != Level::Warn {
98+
let respect_warnings_lint_group = match configured_warning_level {
99+
// -Wwarnings is a no-op.
100+
Level::Warn => false,
101+
// Some warnings cannot be denied from the `warnings` lint group, only individually.
102+
Level::Deny | Level::Forbid => !lint.lint.ignore_deny_warnings,
103+
// All warnings respect -Awarnings.
104+
Level::Allow => true,
105+
// Not sure what the right behavior is here, but, sure, why not.
106+
// See tests/ui/lint/rfc-2383-lint-reason/expect_warnings.rs.
107+
Level::Expect => true,
108+
Level::ForceWarn => {
109+
sess.dcx().span_delayed_bug(
110+
warnings_src.span(),
111+
"cannot --force-warn the `warnings` lint group",
112+
);
113+
false
114+
}
115+
};
116+
if respect_warnings_lint_group {
103117
level = configured_warning_level;
104118
lint_id = configured_lint_id;
105119
*src = warnings_src;
@@ -291,6 +305,18 @@ fn explain_lint_level_source(
291305
}
292306
}
293307
}
308+
309+
if let Some(warnings_group) = sess
310+
.opts
311+
.lint_opts
312+
.iter()
313+
.find_map(|(opt, level)| (opt == "warnings").then_some(level))
314+
.copied()
315+
&& warnings_group >= Level::Deny
316+
&& level < warnings_group
317+
{
318+
err.note_once(format!("the `{name}` lint ignores `-D warnings`"));
319+
}
294320
}
295321

296322
/// The innermost function for emitting lints implementing the [`trait@Diagnostic`] trait.

src/bootstrap/src/core/builder/cargo.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,10 @@ impl Cargo {
344344
self.rustflags.arg("-Clink-arg=-gz");
345345
}
346346

347+
// Ignore linker warnings for now. These are complicated to fix and don't affect the build.
348+
// FIXME: we should really investigate these...
349+
self.rustflags.arg("-Alinker-messages");
350+
347351
// Throughout the build Cargo can execute a number of build scripts
348352
// compiling C/C++ code and we need to pass compilers, archivers, flags, etc
349353
// obtained previously to those build scripts.

src/tools/compiletest/src/directives/directive_names.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ pub(crate) const KNOWN_DIRECTIVE_NAMES: &[&str] = &[
143143
"ignore-x86_64",
144144
"ignore-x86_64-apple-darwin",
145145
"ignore-x86_64-pc-windows-gnu",
146+
"ignore-x86_64-pc-windows-gnullvm",
146147
"ignore-x86_64-unknown-linux-gnu",
147148
"incremental",
148149
"known-bug",
@@ -268,6 +269,7 @@ pub(crate) const KNOWN_DIRECTIVE_NAMES: &[&str] = &[
268269
"only-x86_64-apple-darwin",
269270
"only-x86_64-fortanix-unknown-sgx",
270271
"only-x86_64-pc-windows-gnu",
272+
"only-x86_64-pc-windows-gnullvm",
271273
"only-x86_64-pc-windows-msvc",
272274
"only-x86_64-unknown-linux-gnu",
273275
"pp-exact",
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
error: linker stderr: bar
2+
|
3+
= note: requested on the command line with `-D linker-messages`
4+
5+
error: aborting due to 1 previous error
6+
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
warning: linker stderr: bar
2+
|
3+
= note: requested on the command line with `-W linker-messages`
4+
= note: the `linker_messages` lint ignores `-D warnings`
5+
6+
warning: 1 warning emitted
7+

tests/run-make/linker-warning/rmake.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,19 @@ fn main() {
3737
.run()
3838
.assert_stderr_contains("warning: linker stdout: foo");
3939

40+
// Make sure it respects `-D linker-messages`
41+
let out = run_rustc().link_arg("run_make_warn").arg("-Dlinker-messages").run_fail();
42+
out.assert_stderr_contains("error: linker stderr: bar");
43+
diff()
44+
.expected_file("deny-linker-lint.txt")
45+
.actual_text("(linker warning)", out.stderr())
46+
.run();
47+
48+
// Make sure that linker warnings don't fail the build when `-D warnings` is present.
49+
let out = run_rustc().link_arg("run_make_warn").arg("-Dwarnings").run();
50+
out.assert_stderr_contains("warning: linker stderr: bar");
51+
diff().expected_file("deny-warnings.txt").actual_text("(linker warning)", out.stderr()).run();
52+
4053
// Make sure we short-circuit this new path if the linker exits with an error
4154
// (so the diagnostic is less verbose)
4255
run_rustc().link_arg("run_make_error").run_fail().assert_stderr_contains("note: error: baz");
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
//@ build-pass
2+
//@ only-x86_64-pc-windows-gnullvm
3+
#![allow(linker_messages)]
4+
#![warn(linker_info)]
5+
6+
//~? WARN argument unused
7+
8+
fn main() {}

0 commit comments

Comments
 (0)