Skip to content

Rollup of 8 pull requests #144313

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 24 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
ac87434
Implement support for explicit tail calls in the MIR block builders a…
xacrimon Jul 20, 2025
a96bd57
chore: clang-format
xacrimon Jul 20, 2025
205f4ca
tests: add ui fail/pass tests and llvm ir tail codegen tests
xacrimon Jul 21, 2025
3fac279
chore: fix typo
xacrimon Jul 21, 2025
bcaa795
removed tidy check on issues files
Kivooeo Jul 19, 2025
58537fb
Fix broken TLS destructors on 32-bit win7
roblabla Jul 20, 2025
b2f8b40
Don't ICE on non-TypeId metadata within TypeId
oli-obk Jul 21, 2025
55b5612
don't end lifetimes after call
xacrimon Jul 21, 2025
2cd84dc
recursion-no-tce.rs should be run-crash
xacrimon Jul 21, 2025
d424207
fix typo in codegen test
xacrimon Jul 21, 2025
dad96b1
Use serde for target spec json deserialize
Noratrieb Jul 20, 2025
e5a5062
add an error message if you attempt to pass indirect args via guarant…
xacrimon Jul 21, 2025
ecf34e1
use span_bug instead of bug
xacrimon Jul 21, 2025
c4eb077
Ensure we codegen and don't internalize the entrypoint
saethlin Jul 17, 2025
6e8762f
Use less HIR in check_private_in_public.
cjgillot Oct 1, 2023
3083d8f
generate elf symbol version in raw-dylib
usamoi Jul 20, 2025
79eee8a
Rollup merge of #144094 - saethlin:codegen-the-main-fn, r=petrochenkov
matthiaskrgr Jul 22, 2025
2d5dd25
Rollup merge of #144173 - Kivooeo:tidy_checks, r=jieyouxu
matthiaskrgr Jul 22, 2025
eccb34a
Rollup merge of #144218 - Noratrieb:target-spec-json-de-jank, r=fee1-…
matthiaskrgr Jul 22, 2025
cc11e25
Rollup merge of #144221 - usamoi:versym, r=bjorn3
matthiaskrgr Jul 22, 2025
83e6902
Rollup merge of #144232 - xacrimon:explicit-tail-call, r=oli-obk
matthiaskrgr Jul 22, 2025
c80de8a
Rollup merge of #144234 - roblabla:fix-win7-tls-dtors, r=ChrisDenton
matthiaskrgr Jul 22, 2025
22c5fce
Rollup merge of #144256 - oli-obk:type-id-ice, r=RalfJung
matthiaskrgr Jul 22, 2025
8f36601
Rollup merge of #144276 - cjgillot:no-hir-privacy, r=petrochenkov
matthiaskrgr Jul 22, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4563,7 +4563,10 @@ dependencies = [
"rustc_macros",
"rustc_serialize",
"rustc_span",
"serde",
"serde_derive",
"serde_json",
"serde_path_to_error",
"tracing",
]

Expand Down Expand Up @@ -4955,6 +4958,16 @@ dependencies = [
"serde",
]

[[package]]
name = "serde_path_to_error"
version = "0.1.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "59fab13f937fa393d08645bf3a84bdfe86e296747b506ada67bb15f10f218b2a"
dependencies = [
"itoa",
"serde",
]

[[package]]
name = "serde_spanned"
version = "0.6.9"
Expand Down
15 changes: 15 additions & 0 deletions compiler/rustc_codegen_gcc/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1742,6 +1742,21 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
call
}

fn tail_call(
&mut self,
_llty: Self::Type,
_fn_attrs: Option<&CodegenFnAttrs>,
_fn_abi: &FnAbi<'tcx, Ty<'tcx>>,
_llfn: Self::Value,
_args: &[Self::Value],
_funclet: Option<&Self::Funclet>,
_instance: Option<Instance<'tcx>>,
) {
bug!(
"Guaranteed tail calls with the 'become' keyword are not implemented in the GCC backend"
);
}

fn zext(&mut self, value: RValue<'gcc>, dest_typ: Type<'gcc>) -> RValue<'gcc> {
// FIXME(antoyo): this does not zero-extend.
self.gcc_int_cast(value, dest_typ)
Expand Down
26 changes: 25 additions & 1 deletion compiler/rustc_codegen_llvm/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ use rustc_codegen_ssa::mir::place::PlaceRef;
use rustc_codegen_ssa::traits::*;
use rustc_data_structures::small_c_str::SmallCStr;
use rustc_hir::def_id::DefId;
use rustc_middle::bug;
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs;
use rustc_middle::ty::layout::{
FnAbiError, FnAbiOfHelpers, FnAbiRequest, HasTypingEnv, LayoutError, LayoutOfHelpers,
Expand All @@ -24,7 +25,7 @@ use rustc_middle::ty::{self, Instance, Ty, TyCtxt};
use rustc_sanitizers::{cfi, kcfi};
use rustc_session::config::OptLevel;
use rustc_span::Span;
use rustc_target::callconv::FnAbi;
use rustc_target::callconv::{FnAbi, PassMode};
use rustc_target::spec::{HasTargetSpec, SanitizerSet, Target};
use smallvec::SmallVec;
use tracing::{debug, instrument};
Expand Down Expand Up @@ -1431,6 +1432,29 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
call
}

fn tail_call(
&mut self,
llty: Self::Type,
fn_attrs: Option<&CodegenFnAttrs>,
fn_abi: &FnAbi<'tcx, Ty<'tcx>>,
llfn: Self::Value,
args: &[Self::Value],
funclet: Option<&Self::Funclet>,
instance: Option<Instance<'tcx>>,
) {
let call = self.call(llty, fn_attrs, Some(fn_abi), llfn, args, funclet, instance);

match &fn_abi.ret.mode {
PassMode::Ignore | PassMode::Indirect { .. } => self.ret_void(),
PassMode::Direct(_) | PassMode::Pair { .. } => self.ret(call),
mode @ PassMode::Cast { .. } => {
bug!("Encountered `PassMode::{mode:?}` during codegen")
}
}

llvm::LLVMRustSetTailCallKind(call, llvm::TailCallKind::MustTail);
}

fn zext(&mut self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
unsafe { llvm::LLVMBuildZExt(self.llbuilder, val, dest_ty, UNNAMED) }
}
Expand Down
11 changes: 11 additions & 0 deletions compiler/rustc_codegen_llvm/src/llvm/ffi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,16 @@ pub(crate) enum ModuleFlagMergeBehavior {

// Consts for the LLVM CallConv type, pre-cast to usize.

#[derive(Copy, Clone, PartialEq, Debug)]
#[repr(C)]
#[allow(dead_code)]
pub(crate) enum TailCallKind {
None = 0,
Tail = 1,
MustTail = 2,
NoTail = 3,
}

/// LLVM CallingConv::ID. Should we wrap this?
///
/// See <https://github.com/llvm/llvm-project/blob/main/llvm/include/llvm/IR/CallingConv.h>
Expand Down Expand Up @@ -1186,6 +1196,7 @@ unsafe extern "C" {
pub(crate) safe fn LLVMIsGlobalConstant(GlobalVar: &Value) -> Bool;
pub(crate) safe fn LLVMSetGlobalConstant(GlobalVar: &Value, IsConstant: Bool);
pub(crate) safe fn LLVMSetTailCall(CallInst: &Value, IsTailCall: Bool);
pub(crate) safe fn LLVMRustSetTailCallKind(CallInst: &Value, Kind: TailCallKind);

// Operations on attributes
pub(crate) fn LLVMCreateStringAttribute(
Expand Down
97 changes: 78 additions & 19 deletions compiler/rustc_codegen_ssa/src/back/link/raw_dylib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use std::path::{Path, PathBuf};

use rustc_abi::Endian;
use rustc_data_structures::base_n::{CASE_INSENSITIVE, ToBaseN};
use rustc_data_structures::fx::FxIndexMap;
use rustc_data_structures::fx::{FxHashMap, FxIndexMap};
use rustc_data_structures::stable_hasher::StableHasher;
use rustc_hashes::Hash128;
use rustc_session::Session;
Expand Down Expand Up @@ -230,40 +230,66 @@ fn create_elf_raw_dylib_stub(sess: &Session, soname: &str, symbols: &[DllImport]
Endian::Little => object::Endianness::Little,
Endian::Big => object::Endianness::Big,
};

let mut stub = write::Writer::new(endianness, true, &mut stub_buf);

let mut vers = Vec::new();
let mut vers_map = FxHashMap::default();
let mut syms = Vec::new();

for symbol in symbols {
let symbol_name = symbol.name.as_str();
if let Some((name, version_name)) = symbol_name.split_once('@') {
assert!(!version_name.contains('@'));
let dynstr = stub.add_dynamic_string(name.as_bytes());
let ver = if let Some(&ver_id) = vers_map.get(version_name) {
ver_id
} else {
let id = vers.len();
vers_map.insert(version_name, id);
let dynstr = stub.add_dynamic_string(version_name.as_bytes());
vers.push((version_name, dynstr));
id
};
syms.push((name, dynstr, Some(ver)));
} else {
let dynstr = stub.add_dynamic_string(symbol_name.as_bytes());
syms.push((symbol_name, dynstr, None));
}
}

let soname = stub.add_dynamic_string(soname.as_bytes());

// These initial reservations don't reserve any bytes in the binary yet,
// they just allocate in the internal data structures.

// First, we crate the dynamic symbol table. It starts with a null symbol
// First, we create the dynamic symbol table. It starts with a null symbol
// and then all the symbols and their dynamic strings.
stub.reserve_null_dynamic_symbol_index();

let dynstrs = symbols
.iter()
.map(|sym| {
stub.reserve_dynamic_symbol_index();
(sym, stub.add_dynamic_string(sym.name.as_str().as_bytes()))
})
.collect::<Vec<_>>();

let soname = stub.add_dynamic_string(soname.as_bytes());
for _ in syms.iter() {
stub.reserve_dynamic_symbol_index();
}

// Reserve the sections.
// We have the minimal sections for a dynamic SO and .text where we point our dummy symbols to.
stub.reserve_shstrtab_section_index();
let text_section_name = stub.add_section_name(".text".as_bytes());
let text_section = stub.reserve_section_index();
stub.reserve_dynstr_section_index();
stub.reserve_dynsym_section_index();
stub.reserve_dynstr_section_index();
stub.reserve_gnu_versym_section_index();
stub.reserve_gnu_verdef_section_index();
stub.reserve_dynamic_section_index();

// These reservations now determine the actual layout order of the object file.
stub.reserve_file_header();
stub.reserve_shstrtab();
stub.reserve_section_headers();
stub.reserve_dynstr();
stub.reserve_dynsym();
stub.reserve_dynstr();
stub.reserve_gnu_versym();
stub.reserve_gnu_verdef(1 + vers.len(), 1 + vers.len());
stub.reserve_dynamic(2); // DT_SONAME, DT_NULL

// First write the ELF header with the arch information.
Expand Down Expand Up @@ -342,18 +368,17 @@ fn create_elf_raw_dylib_stub(sess: &Session, soname: &str, symbols: &[DllImport]
sh_addralign: 1,
sh_entsize: 0,
});
stub.write_dynstr_section_header(0);
stub.write_dynsym_section_header(0, 1);
stub.write_dynstr_section_header(0);
stub.write_gnu_versym_section_header(0);
stub.write_gnu_verdef_section_header(0);
stub.write_dynamic_section_header(0);

// .dynstr
stub.write_dynstr();

// .dynsym
stub.write_null_dynamic_symbol();
for (_, name) in dynstrs {
for (_name, dynstr, _ver) in syms.iter().copied() {
stub.write_dynamic_symbol(&write::Sym {
name: Some(name),
name: Some(dynstr),
st_info: (elf::STB_GLOBAL << 4) | elf::STT_NOTYPE,
st_other: elf::STV_DEFAULT,
section: Some(text_section),
Expand All @@ -363,10 +388,44 @@ fn create_elf_raw_dylib_stub(sess: &Session, soname: &str, symbols: &[DllImport]
});
}

// .dynstr
stub.write_dynstr();

// .gnu_version
stub.write_null_gnu_versym();
for (_name, _dynstr, ver) in syms.iter().copied() {
stub.write_gnu_versym(if let Some(ver) = ver {
assert!((2 + ver as u16) < elf::VERSYM_HIDDEN);
elf::VERSYM_HIDDEN | (2 + ver as u16)
} else {
1
});
}

// .gnu_version_d
stub.write_align_gnu_verdef();
stub.write_gnu_verdef(&write::Verdef {
version: elf::VER_DEF_CURRENT,
flags: elf::VER_FLG_BASE,
index: 1,
aux_count: 1,
name: soname,
});
for (ver, (_name, dynstr)) in vers.into_iter().enumerate() {
stub.write_gnu_verdef(&write::Verdef {
version: elf::VER_DEF_CURRENT,
flags: 0,
index: 2 + ver as u16,
aux_count: 1,
name: dynstr,
});
}

// .dynamic
// the DT_SONAME will be used by the linker to populate DT_NEEDED
// which the loader uses to find the library.
// DT_NULL terminates the .dynamic table.
stub.write_align_dynamic();
stub.write_dynamic_string(elf::DT_SONAME, soname);
stub.write_dynamic(elf::DT_NULL, 0);

Expand Down
Loading