about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_codegen_ssa/messages.ftl2
-rw-r--r--compiler/rustc_codegen_ssa/src/back/link.rs27
-rw-r--r--compiler/rustc_codegen_ssa/src/base.rs4
-rw-r--r--compiler/rustc_codegen_ssa/src/lib.rs1
-rwxr-xr-xtests/run-make/linker-warning/fake-linker.sh17
-rw-r--r--tests/run-make/linker-warning/rmake.rs19
-rw-r--r--tests/run-make/rust-lld-by-default-beta-stable/rmake.rs6
-rw-r--r--tests/run-make/rust-lld-by-default-nightly/rmake.rs17
-rw-r--r--tests/run-make/rust-lld-custom-target/rmake.rs7
-rw-r--r--tests/run-make/rust-lld/rmake.rs9
10 files changed, 82 insertions, 27 deletions
diff --git a/compiler/rustc_codegen_ssa/messages.ftl b/compiler/rustc_codegen_ssa/messages.ftl
index 484f467068a..ff49630de4c 100644
--- a/compiler/rustc_codegen_ssa/messages.ftl
+++ b/compiler/rustc_codegen_ssa/messages.ftl
@@ -183,6 +183,8 @@ codegen_ssa_linker_file_stem = couldn't extract file stem from specified linker
 codegen_ssa_linker_not_found = linker `{$linker_path}` not found
     .note = {$error}
 
+codegen_ssa_linker_output = {$inner}
+
 codegen_ssa_linker_unsupported_modifier = `as-needed` modifier not supported for current linker
 
 codegen_ssa_linking_failed = linking with `{$linker_path}` failed: {$exit_status}
diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs
index df35b5e8426..378b6a50f7f 100644
--- a/compiler/rustc_codegen_ssa/src/back/link.rs
+++ b/compiler/rustc_codegen_ssa/src/back/link.rs
@@ -18,6 +18,7 @@ use rustc_data_structures::temp_dir::MaybeTempDir;
 use rustc_errors::DiagCtxtHandle;
 use rustc_fs_util::{fix_windows_verbatim_for_gcc, try_canonicalize};
 use rustc_hir::def_id::{CrateNum, LOCAL_CRATE};
+use rustc_macros::Diagnostic;
 use rustc_metadata::fs::{METADATA_FILENAME, copy_to_stdout, emit_wrapper_file};
 use rustc_metadata::{find_native_static_library, walk_native_lib_search_dirs};
 use rustc_middle::bug;
@@ -749,6 +750,14 @@ fn link_dwarf_object(sess: &Session, cg_results: &CodegenResults, executable_out
     }
 }
 
+#[derive(Diagnostic)]
+#[diag(codegen_ssa_linker_output)]
+/// Translating this is kind of useless. We don't pass translation flags to the linker, so we'd just
+/// end up with inconsistent languages within the same diagnostic.
+struct LinkerOutput {
+    inner: String,
+}
+
 /// Create a dynamic library or executable.
 ///
 /// This will invoke the system linker/cc to create the resulting file. This links to all upstream
@@ -1028,8 +1037,22 @@ fn link_natively(
 
                 sess.dcx().abort_if_errors();
             }
-            info!("linker stderr:\n{}", escape_string(&prog.stderr));
-            info!("linker stdout:\n{}", escape_string(&prog.stdout));
+
+            if !prog.stderr.is_empty() {
+                // We already print `warning:` at the start of the diagnostic. Remove it from the linker output if present.
+                let stderr = escape_string(&prog.stderr);
+                debug!("original stderr: {stderr}");
+                let stderr = stderr
+                    .strip_prefix("warning: ")
+                    .unwrap_or(&stderr)
+                    .replace(": warning: ", ": ");
+                sess.dcx().emit_warn(LinkerOutput { inner: format!("linker stderr: {stderr}") });
+            }
+            if !prog.stdout.is_empty() && sess.opts.verbose {
+                sess.dcx().emit_warn(LinkerOutput {
+                    inner: format!("linker stdout: {}", escape_string(&prog.stdout)),
+                });
+            }
         }
         Err(e) => {
             let linker_not_found = e.kind() == io::ErrorKind::NotFound;
diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs
index 544578b29f1..f14396c517c 100644
--- a/compiler/rustc_codegen_ssa/src/base.rs
+++ b/compiler/rustc_codegen_ssa/src/base.rs
@@ -44,7 +44,8 @@ use crate::mir::operand::OperandValue;
 use crate::mir::place::PlaceRef;
 use crate::traits::*;
 use crate::{
-    CachedModuleCodegen, CompiledModule, CrateInfo, ModuleCodegen, ModuleKind, errors, meth, mir,
+    CachedModuleCodegen, CodegenLintLevels, CompiledModule, CrateInfo, ModuleCodegen, ModuleKind,
+    errors, meth, mir,
 };
 
 pub(crate) fn bin_op_to_icmp_predicate(op: BinOp, signed: bool) -> IntPredicate {
@@ -927,6 +928,7 @@ impl CrateInfo {
             dependency_formats: Lrc::clone(tcx.dependency_formats(())),
             windows_subsystem,
             natvis_debugger_visualizers: Default::default(),
+            lint_levels: CodegenLintLevels::from_tcx(tcx),
         };
 
         info.native_libraries.reserve(n_crates);
diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs
index 65c6067c740..332f2ffbc88 100644
--- a/compiler/rustc_codegen_ssa/src/lib.rs
+++ b/compiler/rustc_codegen_ssa/src/lib.rs
@@ -200,6 +200,7 @@ pub struct CrateInfo {
     pub dependency_formats: Lrc<Dependencies>,
     pub windows_subsystem: Option<String>,
     pub natvis_debugger_visualizers: BTreeSet<DebuggerVisualizerFile>,
+    pub lint_levels: CodegenLintLevels,
 }
 
 #[derive(Encodable, Decodable)]
diff --git a/tests/run-make/linker-warning/fake-linker.sh b/tests/run-make/linker-warning/fake-linker.sh
new file mode 100755
index 00000000000..ed4d472c3bf
--- /dev/null
+++ b/tests/run-make/linker-warning/fake-linker.sh
@@ -0,0 +1,17 @@
+#!/bin/sh
+
+code=0
+while ! [ $# = 0 ]; do
+    case "$1" in
+        run_make_info) echo "foo"
+            ;;
+        run_make_warn) echo "warning: bar" >&2
+            ;;
+        run_make_error) echo "error: baz" >&2; code=1
+            ;;
+        *) ;;   # rustc passes lots of args we don't care about
+    esac
+    shift
+done
+
+exit $code
diff --git a/tests/run-make/linker-warning/rmake.rs b/tests/run-make/linker-warning/rmake.rs
index 4d21c5ea569..d2bb12aafcb 100644
--- a/tests/run-make/linker-warning/rmake.rs
+++ b/tests/run-make/linker-warning/rmake.rs
@@ -10,6 +10,25 @@ fn main() {
     // first, compile our linker
     rustc().arg("fake-linker.rs").output("fake-linker").run();
 
+    // Run rustc with our fake linker, and make sure it shows warnings
+    let warnings = run_rustc().link_arg("run_make_warn").run();
+    warnings.assert_stderr_contains("warning: linker stderr: bar");
+
+    // Make sure it shows stdout, but only when --verbose is passed
+    run_rustc()
+        .link_arg("run_make_info")
+        .verbose()
+        .run()
+        .assert_stderr_contains("warning: linker stdout: foo");
+    run_rustc()
+        .link_arg("run_make_info")
+        .run()
+        .assert_stderr_not_contains("warning: linker stdout: foo");
+
+    // Make sure we short-circuit this new path if the linker exits with an error
+    // (so the diagnostic is less verbose)
+    run_rustc().link_arg("run_make_error").run_fail().assert_stderr_contains("note: error: baz");
+
     // Make sure we don't show the linker args unless `--verbose` is passed
     run_rustc()
         .link_arg("run_make_error")
diff --git a/tests/run-make/rust-lld-by-default-beta-stable/rmake.rs b/tests/run-make/rust-lld-by-default-beta-stable/rmake.rs
index 2417a4274e4..85860fc95b8 100644
--- a/tests/run-make/rust-lld-by-default-beta-stable/rmake.rs
+++ b/tests/run-make/rust-lld-by-default-beta-stable/rmake.rs
@@ -12,11 +12,7 @@ use run_make_support::rustc;
 fn main() {
     // A regular compilation should not use rust-lld by default. We'll check that by asking the
     // linker to display its version number with a link-arg.
-    let output = rustc()
-        .env("RUSTC_LOG", "rustc_codegen_ssa::back::link=info")
-        .link_arg("-Wl,-v")
-        .input("main.rs")
-        .run();
+    let output = rustc().verbose().link_arg("-Wl,-v").input("main.rs").run();
     assert!(
         !find_lld_version_in_logs(output.stderr_utf8()),
         "the LLD version string should not be present in the output logs:\n{}",
diff --git a/tests/run-make/rust-lld-by-default-nightly/rmake.rs b/tests/run-make/rust-lld-by-default-nightly/rmake.rs
index 02bbe8227f0..4026af83064 100644
--- a/tests/run-make/rust-lld-by-default-nightly/rmake.rs
+++ b/tests/run-make/rust-lld-by-default-nightly/rmake.rs
@@ -12,11 +12,7 @@ use run_make_support::rustc;
 fn main() {
     // A regular compilation should use rust-lld by default. We'll check that by asking the linker
     // to display its version number with a link-arg.
-    let output = rustc()
-        .env("RUSTC_LOG", "rustc_codegen_ssa::back::link=info")
-        .link_arg("-Wl,-v")
-        .input("main.rs")
-        .run();
+    let output = rustc().verbose().link_arg("-Wl,-v").input("main.rs").run();
     assert!(
         find_lld_version_in_logs(output.stderr_utf8()),
         "the LLD version string should be present in the output logs:\n{}",
@@ -24,12 +20,8 @@ fn main() {
     );
 
     // But it can still be disabled by turning the linker feature off.
-    let output = rustc()
-        .env("RUSTC_LOG", "rustc_codegen_ssa::back::link=info")
-        .link_arg("-Wl,-v")
-        .arg("-Zlinker-features=-lld")
-        .input("main.rs")
-        .run();
+    let output =
+        rustc().verbose().link_arg("-Wl,-v").arg("-Zlinker-features=-lld").input("main.rs").run();
     assert!(
         !find_lld_version_in_logs(output.stderr_utf8()),
         "the LLD version string should not be present in the output logs:\n{}",
@@ -38,6 +30,7 @@ fn main() {
 }
 
 fn find_lld_version_in_logs(stderr: String) -> bool {
-    let lld_version_re = Regex::new(r"^LLD [0-9]+\.[0-9]+\.[0-9]+").unwrap();
+    let lld_version_re =
+        Regex::new(r"^warning: linker stdout: LLD [0-9]+\.[0-9]+\.[0-9]+").unwrap();
     stderr.lines().any(|line| lld_version_re.is_match(line.trim()))
 }
diff --git a/tests/run-make/rust-lld-custom-target/rmake.rs b/tests/run-make/rust-lld-custom-target/rmake.rs
index a6f7c33793a..17468223306 100644
--- a/tests/run-make/rust-lld-custom-target/rmake.rs
+++ b/tests/run-make/rust-lld-custom-target/rmake.rs
@@ -15,7 +15,7 @@ fn main() {
     // Compile to a custom target spec with rust-lld enabled by default. We'll check that by asking
     // the linker to display its version number with a link-arg.
     let output = rustc()
-        .env("RUSTC_LOG", "rustc_codegen_ssa::back::link=info")
+        .verbose()
         .crate_type("cdylib")
         .target("custom-target.json")
         .link_arg("-Wl,-v")
@@ -29,7 +29,7 @@ fn main() {
 
     // But it can also be disabled via linker features.
     let output = rustc()
-        .env("RUSTC_LOG", "rustc_codegen_ssa::back::link=info")
+        .verbose()
         .crate_type("cdylib")
         .target("custom-target.json")
         .arg("-Zlinker-features=-lld")
@@ -44,6 +44,7 @@ fn main() {
 }
 
 fn find_lld_version_in_logs(stderr: String) -> bool {
-    let lld_version_re = Regex::new(r"^LLD [0-9]+\.[0-9]+\.[0-9]+").unwrap();
+    let lld_version_re =
+        Regex::new(r"^warning: linker stdout: LLD [0-9]+\.[0-9]+\.[0-9]+").unwrap();
     stderr.lines().any(|line| lld_version_re.is_match(line.trim()))
 }
diff --git a/tests/run-make/rust-lld/rmake.rs b/tests/run-make/rust-lld/rmake.rs
index 1f311af1ed5..732bc6f6ba2 100644
--- a/tests/run-make/rust-lld/rmake.rs
+++ b/tests/run-make/rust-lld/rmake.rs
@@ -14,10 +14,10 @@ fn main() {
     // Opt-in to lld and the self-contained linker, to link with rust-lld. We'll check that by
     // asking the linker to display its version number with a link-arg.
     let output = rustc()
-        .env("RUSTC_LOG", "rustc_codegen_ssa::back::link=info")
         .arg("-Zlinker-features=+lld")
         .arg("-Clink-self-contained=+linker")
         .arg("-Zunstable-options")
+        .verbose()
         .link_arg(linker_version_flag)
         .input("main.rs")
         .run();
@@ -29,8 +29,8 @@ fn main() {
 
     // It should not be used when we explicitly opt-out of lld.
     let output = rustc()
-        .env("RUSTC_LOG", "rustc_codegen_ssa::back::link=info")
         .link_arg(linker_version_flag)
+        .verbose()
         .arg("-Zlinker-features=-lld")
         .input("main.rs")
         .run();
@@ -43,8 +43,8 @@ fn main() {
     // While we're here, also check that the last linker feature flag "wins" when passed multiple
     // times to rustc.
     let output = rustc()
-        .env("RUSTC_LOG", "rustc_codegen_ssa::back::link=info")
         .link_arg(linker_version_flag)
+        .verbose()
         .arg("-Clink-self-contained=+linker")
         .arg("-Zunstable-options")
         .arg("-Zlinker-features=-lld")
@@ -60,6 +60,7 @@ fn main() {
 }
 
 fn find_lld_version_in_logs(stderr: String) -> bool {
-    let lld_version_re = Regex::new(r"^LLD [0-9]+\.[0-9]+\.[0-9]+").unwrap();
+    let lld_version_re =
+        Regex::new(r"^warning: linker stdout: LLD [0-9]+\.[0-9]+\.[0-9]+").unwrap();
     stderr.lines().any(|line| lld_version_re.is_match(line.trim()))
 }