From 611c956c78fc9f95bd8af1f9b0567669959d1efe Mon Sep 17 00:00:00 2001 From: dianqk Date: Mon, 8 Dec 2025 21:57:05 +0800 Subject: [PATCH] test: Add test for 146133 Even if a crate is marked as #![no_builtins], we can still generate bitcode for rlib, but we cannot emit bitcode to the linker in rustc's LTO. --- .../no-builtins-linker-plugin-lto/main.rs | 3 ++ .../no_builtins.rs | 4 ++ .../no-builtins-linker-plugin-lto/rmake.rs | 53 +++++++++++++++++++ 3 files changed, 60 insertions(+) create mode 100644 tests/run-make/no-builtins-linker-plugin-lto/main.rs create mode 100644 tests/run-make/no-builtins-linker-plugin-lto/no_builtins.rs create mode 100644 tests/run-make/no-builtins-linker-plugin-lto/rmake.rs diff --git a/tests/run-make/no-builtins-linker-plugin-lto/main.rs b/tests/run-make/no-builtins-linker-plugin-lto/main.rs new file mode 100644 index 0000000000000..f96605be89499 --- /dev/null +++ b/tests/run-make/no-builtins-linker-plugin-lto/main.rs @@ -0,0 +1,3 @@ +fn main() { + no_builtins::foo(); +} diff --git a/tests/run-make/no-builtins-linker-plugin-lto/no_builtins.rs b/tests/run-make/no-builtins-linker-plugin-lto/no_builtins.rs new file mode 100644 index 0000000000000..a56c1d6b41334 --- /dev/null +++ b/tests/run-make/no-builtins-linker-plugin-lto/no_builtins.rs @@ -0,0 +1,4 @@ +#![no_builtins] + +#[inline(never)] +pub fn foo() {} diff --git a/tests/run-make/no-builtins-linker-plugin-lto/rmake.rs b/tests/run-make/no-builtins-linker-plugin-lto/rmake.rs new file mode 100644 index 0000000000000..7133085677377 --- /dev/null +++ b/tests/run-make/no-builtins-linker-plugin-lto/rmake.rs @@ -0,0 +1,53 @@ +//@ only-x86_64-unknown-linux-gnu + +use std::fs; +use std::path::Path; + +use run_make_support::{cwd, has_extension, llvm_ar, llvm_bcanalyzer, rust_lib_name, rustc}; + +// A regression test for #146133. + +fn main() { + // Compile a `#![no_builtins]` rlib crate with `-Clinker-plugin-lto`. + // It is acceptable to generate bitcode for rlib, so there is no need to check something. + rustc().input("no_builtins.rs").crate_type("rlib").linker_plugin_lto("on").run(); + + // Checks that rustc's LTO doesn't emit any bitcode to the linker. + let stdout = rustc() + .input("main.rs") + .extern_("no_builtins", rust_lib_name("no_builtins")) + .lto("thin") + .print("link-args") + .arg("-Csave-temps") + .arg("-Clinker-features=-lld") + .run() + .stdout_utf8(); + for object in stdout + .split_whitespace() + .map(|s| s.trim_matches('"')) + .filter(|path| has_extension(path, "rlib") || has_extension(path, "o")) + { + let object_path = if !fs::exists(object).unwrap() { + cwd().join(object) + } else { + Path::new(object).to_path_buf() + }; + if has_extension(object, "rlib") { + let ar_stdout = llvm_ar().arg("t").arg(&object_path).run().stdout_utf8(); + llvm_ar().extract().arg(&object_path).run(); + for object in ar_stdout.split_whitespace().filter(|o| has_extension(o, "o")) { + let object_path = cwd().join(object); + not_bitcode(&object_path); + } + } else { + not_bitcode(&object_path); + } + } +} + +fn not_bitcode(object: &Path) { + llvm_bcanalyzer() + .input(object) + .run_fail() + .assert_stderr_contains("llvm-bcanalyzer: Invalid record at top-level"); +}