Skip to content

Commit 9e4495f

Browse files
committed
Auto merge of rust-lang#133697 - matthiaskrgr:rollup-jebttr8, r=matthiaskrgr
Rollup of 8 pull requests Successful merges: - rust-lang#128004 (codegen `#[naked]` functions using global asm) - rust-lang#132974 (Properly pass linker arguments that contain commas) - rust-lang#133403 (Make `adjust_fulfillment_errors` work with `HostEffectPredicate` and `const_conditions`) - rust-lang#133482 (Only error raw lifetime followed by `\'` in edition 2021+) - rust-lang#133595 (Do not emit `missing_doc_code_examples` rustdoc lint on module and a few other items) - rust-lang#133669 (Move some functions out of const_swap feature gate) - rust-lang#133674 (Fix chaining `carrying_add`s) - rust-lang#133691 (Check let source before suggesting annotation) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 6c76ed5 + 6f9f594 commit 9e4495f

File tree

89 files changed

+1344
-436
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

89 files changed

+1344
-436
lines changed

Diff for: compiler/rustc_attr/src/builtin.rs

+10-1
Original file line numberDiff line numberDiff line change
@@ -49,12 +49,21 @@ pub enum InlineAttr {
4949
Never,
5050
}
5151

52-
#[derive(Clone, Encodable, Decodable, Debug, PartialEq, Eq, HashStable_Generic)]
52+
#[derive(Copy, Clone, Encodable, Decodable, Debug, PartialEq, Eq, HashStable_Generic)]
5353
pub enum InstructionSetAttr {
5454
ArmA32,
5555
ArmT32,
5656
}
5757

58+
impl InstructionSetAttr {
59+
pub fn as_str(self) -> &'static str {
60+
match self {
61+
Self::ArmA32 => sym::a32.as_str(),
62+
Self::ArmT32 => sym::t32.as_str(),
63+
}
64+
}
65+
}
66+
5867
#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
5968
pub enum OptimizeAttr {
6069
None,

Diff for: compiler/rustc_codegen_gcc/src/asm.rs

+7
Original file line numberDiff line numberDiff line change
@@ -867,6 +867,13 @@ impl<'gcc, 'tcx> AsmCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
867867
template_str.push_str("\n.popsection");
868868
self.context.add_top_level_asm(None, &template_str);
869869
}
870+
871+
fn mangled_name(&self, instance: Instance<'tcx>) -> String {
872+
// TODO(@Amanieu): Additional mangling is needed on
873+
// some targets to add a leading underscore (Mach-O)
874+
// or byte count suffixes (x86 Windows).
875+
self.tcx.symbol_name(instance).name.to_string()
876+
}
870877
}
871878

872879
fn modifier_to_gcc(

Diff for: compiler/rustc_codegen_llvm/src/asm.rs

+8
Original file line numberDiff line numberDiff line change
@@ -442,6 +442,14 @@ impl<'tcx> AsmCodegenMethods<'tcx> for CodegenCx<'_, 'tcx> {
442442
);
443443
}
444444
}
445+
446+
fn mangled_name(&self, instance: Instance<'tcx>) -> String {
447+
let llval = self.get_fn(instance);
448+
llvm::build_string(|s| unsafe {
449+
llvm::LLVMRustGetMangledName(llval, s);
450+
})
451+
.expect("symbol is not valid UTF-8")
452+
}
445453
}
446454

447455
pub(crate) fn inline_asm_call<'ll>(

Diff for: compiler/rustc_codegen_llvm/src/attributes.rs

+3-11
Original file line numberDiff line numberDiff line change
@@ -395,17 +395,9 @@ pub(crate) fn llfn_attrs_from_instance<'ll, 'tcx>(
395395
to_add.push(MemoryEffects::None.create_attr(cx.llcx));
396396
}
397397
if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::NAKED) {
398-
to_add.push(AttributeKind::Naked.create_attr(cx.llcx));
399-
// HACK(jubilee): "indirect branch tracking" works by attaching prologues to functions.
400-
// And it is a module-level attribute, so the alternative is pulling naked functions into
401-
// new LLVM modules. Otherwise LLVM's "naked" functions come with endbr prefixes per
402-
// https://github.com/rust-lang/rust/issues/98768
403-
to_add.push(AttributeKind::NoCfCheck.create_attr(cx.llcx));
404-
if llvm_util::get_version() < (19, 0, 0) {
405-
// Prior to LLVM 19, branch-target-enforcement was disabled by setting the attribute to
406-
// the string "false". Now it is disabled by absence of the attribute.
407-
to_add.push(llvm::CreateAttrStringValue(cx.llcx, "branch-target-enforcement", "false"));
408-
}
398+
// do nothing; a naked function is converted into an extern function
399+
// and a global assembly block. LLVM's support for naked functions is
400+
// not used.
409401
} else {
410402
// Do not set sanitizer attributes for naked functions.
411403
to_add.extend(sanitize_attrs(cx, codegen_fn_attrs.no_sanitize));

Diff for: compiler/rustc_codegen_ssa/src/back/link.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1386,7 +1386,7 @@ fn link_sanitizer_runtime(
13861386
let filename = format!("rustc{channel}_rt.{name}");
13871387
let path = find_sanitizer_runtime(sess, &filename);
13881388
let rpath = path.to_str().expect("non-utf8 component in path");
1389-
linker.cc_args(&["-Wl,-rpath", "-Xlinker", rpath]);
1389+
linker.link_args(&["-rpath", rpath]);
13901390
linker.link_dylib_by_name(&filename, false, true);
13911391
} else if sess.target.is_like_msvc && flavor == LinkerFlavor::Msvc(Lld::No) && name == "asan" {
13921392
// MSVC provides the `/INFERASANLIBS` argument to automatically find the
@@ -2210,7 +2210,7 @@ fn add_rpath_args(
22102210
is_like_osx: sess.target.is_like_osx,
22112211
linker_is_gnu: sess.target.linker_flavor.is_gnu(),
22122212
};
2213-
cmd.cc_args(&rpath::get_rpath_flags(&rpath_config));
2213+
cmd.link_args(&rpath::get_rpath_linker_args(&rpath_config));
22142214
}
22152215
}
22162216

Diff for: compiler/rustc_codegen_ssa/src/back/linker.rs

+36-14
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ use super::command::Command;
2424
use super::symbol_export;
2525
use crate::errors;
2626

27+
#[cfg(test)]
28+
mod tests;
29+
2730
/// Disables non-English messages from localized linkers.
2831
/// Such messages may cause issues with text encoding on Windows (#35785)
2932
/// and prevent inspection of linker output in case of errors, which we occasionally do.
@@ -178,23 +181,42 @@ fn verbatim_args<L: Linker + ?Sized>(
178181
}
179182
l
180183
}
184+
/// Add underlying linker arguments to C compiler command, by wrapping them in
185+
/// `-Wl` or `-Xlinker`.
186+
fn convert_link_args_to_cc_args(cmd: &mut Command, args: impl IntoIterator<Item: AsRef<OsStr>>) {
187+
let mut combined_arg = OsString::from("-Wl");
188+
for arg in args {
189+
// If the argument itself contains a comma, we need to emit it
190+
// as `-Xlinker`, otherwise we can use `-Wl`.
191+
if arg.as_ref().as_encoded_bytes().contains(&b',') {
192+
// Emit current `-Wl` argument, if any has been built.
193+
if combined_arg != OsStr::new("-Wl") {
194+
cmd.arg(combined_arg);
195+
// Begin next `-Wl` argument.
196+
combined_arg = OsString::from("-Wl");
197+
}
198+
199+
// Emit `-Xlinker` argument.
200+
cmd.arg("-Xlinker");
201+
cmd.arg(arg);
202+
} else {
203+
// Append to `-Wl` argument.
204+
combined_arg.push(",");
205+
combined_arg.push(arg);
206+
}
207+
}
208+
// Emit final `-Wl` argument.
209+
if combined_arg != OsStr::new("-Wl") {
210+
cmd.arg(combined_arg);
211+
}
212+
}
181213
/// Arguments for the underlying linker.
182214
/// Add options to pass them through cc wrapper if `Linker` is a cc wrapper.
183-
fn link_args<L: Linker + ?Sized>(
184-
l: &mut L,
185-
args: impl IntoIterator<Item: AsRef<OsStr>, IntoIter: ExactSizeIterator>,
186-
) -> &mut L {
187-
let args = args.into_iter();
215+
fn link_args<L: Linker + ?Sized>(l: &mut L, args: impl IntoIterator<Item: AsRef<OsStr>>) -> &mut L {
188216
if !l.is_cc() {
189217
verbatim_args(l, args);
190-
} else if args.len() != 0 {
191-
// FIXME: Support arguments with commas, see `rpaths_to_flags` for the example.
192-
let mut combined_arg = OsString::from("-Wl");
193-
for arg in args {
194-
combined_arg.push(",");
195-
combined_arg.push(arg);
196-
}
197-
l.cmd().arg(combined_arg);
218+
} else {
219+
convert_link_args_to_cc_args(l.cmd(), args);
198220
}
199221
l
200222
}
@@ -224,7 +246,7 @@ macro_rules! generate_arg_methods {
224246
verbatim_args(self, iter::once(arg))
225247
}
226248
#[allow(unused)]
227-
pub(crate) fn link_args(&mut self, args: impl IntoIterator<Item: AsRef<OsStr>, IntoIter: ExactSizeIterator>) -> &mut Self {
249+
pub(crate) fn link_args(&mut self, args: impl IntoIterator<Item: AsRef<OsStr>>) -> &mut Self {
228250
link_args(self, args)
229251
}
230252
#[allow(unused)]

Diff for: compiler/rustc_codegen_ssa/src/back/linker/tests.rs

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
use super::*;
2+
3+
#[test]
4+
fn test_rpaths_to_args() {
5+
let mut cmd = Command::new("foo");
6+
convert_link_args_to_cc_args(&mut cmd, &["-rpath", "path1", "-rpath", "path2"]);
7+
assert_eq!(cmd.get_args(), [OsStr::new("-Wl,-rpath,path1,-rpath,path2")]);
8+
}
9+
10+
#[test]
11+
fn test_xlinker() {
12+
let mut cmd = Command::new("foo");
13+
convert_link_args_to_cc_args(&mut cmd, &[
14+
"arg1",
15+
"arg2",
16+
"arg3,with,comma",
17+
"arg4,with,comma",
18+
"arg5",
19+
"arg6,with,comma",
20+
]);
21+
22+
assert_eq!(cmd.get_args(), [
23+
OsStr::new("-Wl,arg1,arg2"),
24+
OsStr::new("-Xlinker"),
25+
OsStr::new("arg3,with,comma"),
26+
OsStr::new("-Xlinker"),
27+
OsStr::new("arg4,with,comma"),
28+
OsStr::new("-Wl,arg5"),
29+
OsStr::new("-Xlinker"),
30+
OsStr::new("arg6,with,comma"),
31+
]);
32+
}

Diff for: compiler/rustc_codegen_ssa/src/back/rpath.rs

+11-23
Original file line numberDiff line numberDiff line change
@@ -13,39 +13,27 @@ pub(super) struct RPathConfig<'a> {
1313
pub linker_is_gnu: bool,
1414
}
1515

16-
pub(super) fn get_rpath_flags(config: &RPathConfig<'_>) -> Vec<OsString> {
16+
pub(super) fn get_rpath_linker_args(config: &RPathConfig<'_>) -> Vec<OsString> {
1717
debug!("preparing the RPATH!");
1818

1919
let rpaths = get_rpaths(config);
20-
let mut flags = rpaths_to_flags(rpaths);
20+
let mut args = Vec::with_capacity(rpaths.len() * 2); // the minimum needed capacity
21+
22+
for rpath in rpaths {
23+
args.push("-rpath".into());
24+
args.push(rpath);
25+
}
2126

2227
if config.linker_is_gnu {
2328
// Use DT_RUNPATH instead of DT_RPATH if available
24-
flags.push("-Wl,--enable-new-dtags".into());
29+
args.push("--enable-new-dtags".into());
2530

2631
// Set DF_ORIGIN for substitute $ORIGIN
27-
flags.push("-Wl,-z,origin".into());
28-
}
29-
30-
flags
31-
}
32-
33-
fn rpaths_to_flags(rpaths: Vec<OsString>) -> Vec<OsString> {
34-
let mut ret = Vec::with_capacity(rpaths.len()); // the minimum needed capacity
35-
36-
for rpath in rpaths {
37-
if rpath.to_string_lossy().contains(',') {
38-
ret.push("-Wl,-rpath".into());
39-
ret.push("-Xlinker".into());
40-
ret.push(rpath);
41-
} else {
42-
let mut single_arg = OsString::from("-Wl,-rpath,");
43-
single_arg.push(rpath);
44-
ret.push(single_arg);
45-
}
32+
args.push("-z".into());
33+
args.push("origin".into());
4634
}
4735

48-
ret
36+
args
4937
}
5038

5139
fn get_rpaths(config: &RPathConfig<'_>) -> Vec<OsString> {

Diff for: compiler/rustc_codegen_ssa/src/back/rpath/tests.rs

+1-22
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,4 @@
1-
use std::ffi::OsString;
2-
use std::path::{Path, PathBuf};
3-
4-
use super::{RPathConfig, get_rpath_relative_to_output, minimize_rpaths, rpaths_to_flags};
5-
6-
#[test]
7-
fn test_rpaths_to_flags() {
8-
let flags = rpaths_to_flags(vec!["path1".into(), "path2".into()]);
9-
assert_eq!(flags, ["-Wl,-rpath,path1", "-Wl,-rpath,path2"]);
10-
}
1+
use super::*;
112

123
#[test]
134
fn test_minimize1() {
@@ -69,15 +60,3 @@ fn test_rpath_relative_issue_119571() {
6960
// Should not panic when lib only contains filename.
7061
let _ = get_rpath_relative_to_output(config, Path::new("libstd.so"));
7162
}
72-
73-
#[test]
74-
fn test_xlinker() {
75-
let args = rpaths_to_flags(vec!["a/normal/path".into(), "a,comma,path".into()]);
76-
77-
assert_eq!(args, vec![
78-
OsString::from("-Wl,-rpath,a/normal/path"),
79-
OsString::from("-Wl,-rpath"),
80-
OsString::from("-Xlinker"),
81-
OsString::from("a,comma,path")
82-
]);
83-
}

Diff for: compiler/rustc_codegen_ssa/src/codegen_attrs.rs

+7-4
Original file line numberDiff line numberDiff line change
@@ -542,6 +542,13 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
542542
}
543543
});
544544

545+
// naked function MUST NOT be inlined! This attribute is required for the rust compiler itself,
546+
// but not for the code generation backend because at that point the naked function will just be
547+
// a declaration, with a definition provided in global assembly.
548+
if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::NAKED) {
549+
codegen_fn_attrs.inline = InlineAttr::Never;
550+
}
551+
545552
codegen_fn_attrs.optimize = attrs.iter().fold(OptimizeAttr::None, |ia, attr| {
546553
if !attr.has_name(sym::optimize) {
547554
return ia;
@@ -626,10 +633,6 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
626633
}
627634
}
628635

629-
if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::NAKED) {
630-
codegen_fn_attrs.inline = InlineAttr::Never;
631-
}
632-
633636
// Weak lang items have the same semantics as "std internal" symbols in the
634637
// sense that they're preserved through all our LTO passes and only
635638
// strippable by the linker.

Diff for: compiler/rustc_codegen_ssa/src/mir/mod.rs

+6
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ mod coverageinfo;
2020
pub mod debuginfo;
2121
mod intrinsic;
2222
mod locals;
23+
mod naked_asm;
2324
pub mod operand;
2425
pub mod place;
2526
mod rvalue;
@@ -176,6 +177,11 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
176177
let fn_abi = cx.fn_abi_of_instance(instance, ty::List::empty());
177178
debug!("fn_abi: {:?}", fn_abi);
178179

180+
if cx.tcx().codegen_fn_attrs(instance.def_id()).flags.contains(CodegenFnAttrFlags::NAKED) {
181+
crate::mir::naked_asm::codegen_naked_asm::<Bx>(cx, &mir, instance);
182+
return;
183+
}
184+
179185
let debug_context = cx.create_function_debug_context(instance, fn_abi, llfn, mir);
180186

181187
let start_llbb = Bx::append_block(cx, llfn, "start");

0 commit comments

Comments
 (0)