Merge pull request #795 from rust-lang/sync_from_rust_2025_11_01
Sync from rust 2025/11/01
This commit is contained in:
commit
e785c50dad
12 changed files with 97 additions and 70 deletions
|
|
@ -603,7 +603,7 @@ impl<T: ?Sized + Unsize<U>, U: ?Sized, A: Allocator> CoerceUnsized<Box<U, A>> fo
|
|||
impl<T> Box<T> {
|
||||
pub fn new(val: T) -> Box<T> {
|
||||
unsafe {
|
||||
let size = intrinsics::size_of::<T>();
|
||||
let size = size_of::<T>();
|
||||
let ptr = libc::malloc(size);
|
||||
intrinsics::copy(&val as *const T as *const u8, ptr, size);
|
||||
Box(Unique { pointer: NonNull(ptr as *const T), _marker: PhantomData }, Global)
|
||||
|
|
@ -657,11 +657,11 @@ pub mod intrinsics {
|
|||
#[rustc_intrinsic]
|
||||
pub fn abort() -> !;
|
||||
#[rustc_intrinsic]
|
||||
pub fn size_of<T>() -> usize;
|
||||
pub const fn size_of<T>() -> usize;
|
||||
#[rustc_intrinsic]
|
||||
pub unsafe fn size_of_val<T: ?::Sized>(val: *const T) -> usize;
|
||||
#[rustc_intrinsic]
|
||||
pub fn align_of<T>() -> usize;
|
||||
pub const fn align_of<T>() -> usize;
|
||||
#[rustc_intrinsic]
|
||||
pub unsafe fn align_of_val<T: ?::Sized>(val: *const T) -> usize;
|
||||
#[rustc_intrinsic]
|
||||
|
|
@ -699,6 +699,24 @@ pub mod libc {
|
|||
}
|
||||
}
|
||||
|
||||
pub const fn size_of<T>() -> usize {
|
||||
<T as SizedTypeProperties>::SIZE
|
||||
}
|
||||
|
||||
pub const fn align_of<T>() -> usize {
|
||||
<T as SizedTypeProperties>::ALIGN
|
||||
}
|
||||
|
||||
trait SizedTypeProperties: Sized {
|
||||
#[lang = "mem_size_const"]
|
||||
const SIZE: usize = intrinsics::size_of::<Self>();
|
||||
|
||||
#[lang = "mem_align_const"]
|
||||
const ALIGN: usize = intrinsics::align_of::<Self>();
|
||||
}
|
||||
|
||||
impl<T> SizedTypeProperties for T {}
|
||||
|
||||
#[lang = "index"]
|
||||
pub trait Index<Idx: ?Sized> {
|
||||
type Output: ?Sized;
|
||||
|
|
|
|||
|
|
@ -90,8 +90,8 @@ fn start<T: Termination + 'static>(
|
|||
) -> isize {
|
||||
if argc == 3 {
|
||||
unsafe { puts(*argv); }
|
||||
unsafe { puts(*((argv as usize + intrinsics::size_of::<*const u8>()) as *const *const u8)); }
|
||||
unsafe { puts(*((argv as usize + 2 * intrinsics::size_of::<*const u8>()) as *const *const u8)); }
|
||||
unsafe { puts(*((argv as usize + size_of::<*const u8>()) as *const *const u8)); }
|
||||
unsafe { puts(*((argv as usize + 2 * size_of::<*const u8>()) as *const *const u8)); }
|
||||
}
|
||||
|
||||
main().report();
|
||||
|
|
@ -154,7 +154,7 @@ fn main() {
|
|||
let slice = &[0, 1] as &[i32];
|
||||
let slice_ptr = slice as *const [i32] as *const i32;
|
||||
|
||||
let align = intrinsics::align_of::<*const i32>();
|
||||
let align = align_of::<*const i32>();
|
||||
assert_eq!(slice_ptr as usize % align, 0);
|
||||
|
||||
//return;
|
||||
|
|
@ -195,8 +195,8 @@ fn main() {
|
|||
assert_eq!(intrinsics::size_of_val(a) as u8, 8);
|
||||
assert_eq!(intrinsics::size_of_val(&0u32) as u8, 4);
|
||||
|
||||
assert_eq!(intrinsics::align_of::<u16>() as u8, 2);
|
||||
assert_eq!(intrinsics::align_of_val(&a) as u8, intrinsics::align_of::<&str>() as u8);
|
||||
assert_eq!(align_of::<u16>() as u8, 2);
|
||||
assert_eq!(intrinsics::align_of_val(&a) as u8, align_of::<&str>() as u8);
|
||||
|
||||
let u8_needs_drop = const { intrinsics::needs_drop::<u8>() };
|
||||
assert!(!u8_needs_drop);
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
[toolchain]
|
||||
channel = "nightly-2025-09-30"
|
||||
channel = "nightly-2025-11-04"
|
||||
components = ["rust-src", "rustc-dev", "llvm-tools-preview"]
|
||||
|
|
|
|||
|
|
@ -2,8 +2,7 @@
|
|||
use gccjit::FnAttribute;
|
||||
use gccjit::{Context, FunctionType, RValue, ToRValue, Type};
|
||||
use rustc_ast::expand::allocator::{
|
||||
ALLOCATOR_METHODS, AllocatorKind, AllocatorTy, NO_ALLOC_SHIM_IS_UNSTABLE,
|
||||
alloc_error_handler_name, default_fn_name, global_fn_name,
|
||||
AllocatorMethod, AllocatorTy, NO_ALLOC_SHIM_IS_UNSTABLE, default_fn_name, global_fn_name,
|
||||
};
|
||||
use rustc_middle::bug;
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
|
|
@ -18,8 +17,7 @@ pub(crate) unsafe fn codegen(
|
|||
tcx: TyCtxt<'_>,
|
||||
mods: &mut GccContext,
|
||||
_module_name: &str,
|
||||
kind: AllocatorKind,
|
||||
alloc_error_handler_kind: AllocatorKind,
|
||||
methods: &[AllocatorMethod],
|
||||
) {
|
||||
let context = &mods.context;
|
||||
let usize = match tcx.sess.target.pointer_width {
|
||||
|
|
@ -31,45 +29,35 @@ pub(crate) unsafe fn codegen(
|
|||
let i8 = context.new_type::<i8>();
|
||||
let i8p = i8.make_pointer();
|
||||
|
||||
if kind == AllocatorKind::Default {
|
||||
for method in ALLOCATOR_METHODS {
|
||||
let mut types = Vec::with_capacity(method.inputs.len());
|
||||
for input in method.inputs.iter() {
|
||||
match input.ty {
|
||||
AllocatorTy::Layout => {
|
||||
types.push(usize);
|
||||
types.push(usize);
|
||||
}
|
||||
AllocatorTy::Ptr => types.push(i8p),
|
||||
AllocatorTy::Usize => types.push(usize),
|
||||
for method in methods {
|
||||
let mut types = Vec::with_capacity(method.inputs.len());
|
||||
for input in method.inputs.iter() {
|
||||
match input.ty {
|
||||
AllocatorTy::Layout => {
|
||||
types.push(usize);
|
||||
types.push(usize);
|
||||
}
|
||||
AllocatorTy::Ptr => types.push(i8p),
|
||||
AllocatorTy::Usize => types.push(usize),
|
||||
|
||||
AllocatorTy::ResultPtr | AllocatorTy::Unit => panic!("invalid allocator arg"),
|
||||
AllocatorTy::Never | AllocatorTy::ResultPtr | AllocatorTy::Unit => {
|
||||
panic!("invalid allocator arg")
|
||||
}
|
||||
}
|
||||
let output = match method.output {
|
||||
AllocatorTy::ResultPtr => Some(i8p),
|
||||
AllocatorTy::Unit => None,
|
||||
|
||||
AllocatorTy::Layout | AllocatorTy::Usize | AllocatorTy::Ptr => {
|
||||
panic!("invalid allocator output")
|
||||
}
|
||||
};
|
||||
let from_name = mangle_internal_symbol(tcx, &global_fn_name(method.name));
|
||||
let to_name = mangle_internal_symbol(tcx, &default_fn_name(method.name));
|
||||
|
||||
create_wrapper_function(tcx, context, &from_name, Some(&to_name), &types, output);
|
||||
}
|
||||
}
|
||||
let output = match method.output {
|
||||
AllocatorTy::ResultPtr => Some(i8p),
|
||||
AllocatorTy::Never | AllocatorTy::Unit => None,
|
||||
|
||||
// FIXME(bjorn3): Add noreturn attribute
|
||||
create_wrapper_function(
|
||||
tcx,
|
||||
context,
|
||||
&mangle_internal_symbol(tcx, "__rust_alloc_error_handler"),
|
||||
Some(&mangle_internal_symbol(tcx, alloc_error_handler_name(alloc_error_handler_kind))),
|
||||
&[usize, usize],
|
||||
None,
|
||||
);
|
||||
AllocatorTy::Layout | AllocatorTy::Usize | AllocatorTy::Ptr => {
|
||||
panic!("invalid allocator output")
|
||||
}
|
||||
};
|
||||
let from_name = mangle_internal_symbol(tcx, &global_fn_name(method.name));
|
||||
let to_name = mangle_internal_symbol(tcx, &default_fn_name(method.name));
|
||||
|
||||
create_wrapper_function(tcx, context, &from_name, Some(&to_name), &types, output);
|
||||
}
|
||||
|
||||
create_const_value_function(
|
||||
tcx,
|
||||
|
|
|
|||
27
src/asm.rs
27
src/asm.rs
|
|
@ -546,9 +546,16 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
|
|||
}
|
||||
|
||||
if !options.contains(InlineAsmOptions::PRESERVES_FLAGS) {
|
||||
// TODO(@Commeownist): I'm not 100% sure this one clobber is sufficient
|
||||
// on all architectures. For instance, what about FP stack?
|
||||
extended_asm.add_clobber("cc");
|
||||
match asm_arch {
|
||||
InlineAsmArch::PowerPC | InlineAsmArch::PowerPC64 => {
|
||||
// "cc" is cr0 on powerpc.
|
||||
}
|
||||
// TODO(@Commeownist): I'm not 100% sure this one clobber is sufficient
|
||||
// on all architectures. For instance, what about FP stack?
|
||||
_ => {
|
||||
extended_asm.add_clobber("cc");
|
||||
}
|
||||
}
|
||||
}
|
||||
if !options.contains(InlineAsmOptions::NOMEM) {
|
||||
extended_asm.add_clobber("memory");
|
||||
|
|
@ -698,6 +705,7 @@ fn reg_class_to_gcc(reg_class: InlineAsmRegClass) -> &'static str {
|
|||
InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::reg_nonzero) => "b",
|
||||
InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::freg) => "f",
|
||||
InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::vreg) => "v",
|
||||
InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::vsreg) => "wa",
|
||||
InlineAsmRegClass::PowerPC(
|
||||
PowerPCInlineAsmRegClass::cr
|
||||
| PowerPCInlineAsmRegClass::ctr
|
||||
|
|
@ -778,9 +786,9 @@ fn dummy_output_type<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, reg: InlineAsmRegCl
|
|||
InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::reg) => cx.type_i32(),
|
||||
InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::reg_nonzero) => cx.type_i32(),
|
||||
InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::freg) => cx.type_f64(),
|
||||
InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::vreg) => {
|
||||
cx.type_vector(cx.type_i32(), 4)
|
||||
}
|
||||
InlineAsmRegClass::PowerPC(
|
||||
PowerPCInlineAsmRegClass::vreg | PowerPCInlineAsmRegClass::vsreg,
|
||||
) => cx.type_vector(cx.type_i32(), 4),
|
||||
InlineAsmRegClass::PowerPC(
|
||||
PowerPCInlineAsmRegClass::cr
|
||||
| PowerPCInlineAsmRegClass::ctr
|
||||
|
|
@ -957,6 +965,13 @@ fn modifier_to_gcc(
|
|||
InlineAsmRegClass::LoongArch(_) => None,
|
||||
InlineAsmRegClass::Mips(_) => None,
|
||||
InlineAsmRegClass::Nvptx(_) => None,
|
||||
InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::vsreg) => {
|
||||
if modifier.is_none() {
|
||||
Some('x')
|
||||
} else {
|
||||
modifier
|
||||
}
|
||||
}
|
||||
InlineAsmRegClass::PowerPC(_) => None,
|
||||
InlineAsmRegClass::RiscV(RiscVInlineAsmRegClass::reg)
|
||||
| InlineAsmRegClass::RiscV(RiscVInlineAsmRegClass::freg) => None,
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ use rustc_codegen_ssa::traits::*;
|
|||
use rustc_codegen_ssa::{ModuleCodegen, ModuleKind, looks_like_rust_object_file};
|
||||
use rustc_data_structures::memmap::Mmap;
|
||||
use rustc_errors::DiagCtxtHandle;
|
||||
use rustc_log::tracing::info;
|
||||
use rustc_middle::bug;
|
||||
use rustc_middle::dep_graph::WorkProduct;
|
||||
use rustc_session::config::Lto;
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ use rustc_codegen_ssa::back::link::ensure_removed;
|
|||
use rustc_codegen_ssa::back::write::{BitcodeSection, CodegenContext, EmitObj, ModuleConfig};
|
||||
use rustc_codegen_ssa::{CompiledModule, ModuleCodegen};
|
||||
use rustc_fs_util::link_or_copy;
|
||||
use rustc_log::tracing::debug;
|
||||
use rustc_session::config::OutputType;
|
||||
use rustc_target::spec::SplitDebuginfo;
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ use rustc_codegen_ssa::traits::{
|
|||
BaseTypeCodegenMethods, ConstCodegenMethods, MiscCodegenMethods, StaticCodegenMethods,
|
||||
};
|
||||
use rustc_middle::mir::Mutability;
|
||||
use rustc_middle::mir::interpret::{ConstAllocation, GlobalAlloc, Scalar};
|
||||
use rustc_middle::mir::interpret::{ConstAllocation, GlobalAlloc, PointerArithmetic, Scalar};
|
||||
use rustc_middle::ty::layout::LayoutOf;
|
||||
|
||||
use crate::context::CodegenCx;
|
||||
|
|
@ -247,8 +247,8 @@ impl<'gcc, 'tcx> ConstCodegenMethods for CodegenCx<'gcc, 'tcx> {
|
|||
// This avoids generating a zero-sized constant value and actually needing a
|
||||
// real address at runtime.
|
||||
if alloc.inner().len() == 0 {
|
||||
assert_eq!(offset.bytes(), 0);
|
||||
let val = self.const_usize(alloc.inner().align.bytes());
|
||||
let val = alloc.inner().align.bytes().wrapping_add(offset.bytes());
|
||||
let val = self.const_usize(self.tcx.truncate_to_target_usize(val));
|
||||
return if matches!(layout.primitive(), Pointer(_)) {
|
||||
self.context.new_cast(None, val, ty)
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ use rustc_codegen_ssa::traits::{
|
|||
use rustc_hir::attrs::Linkage;
|
||||
use rustc_hir::def::DefKind;
|
||||
use rustc_hir::def_id::LOCAL_CRATE;
|
||||
use rustc_log::tracing::trace;
|
||||
use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs};
|
||||
use rustc_middle::mir::interpret::{
|
||||
self, ConstAllocation, ErrorHandled, Scalar as InterpScalar, read_target_uint,
|
||||
|
|
|
|||
|
|
@ -29,13 +29,24 @@ impl<'a, 'gcc, 'tcx> DebugInfoBuilderMethods for Builder<'a, 'gcc, 'tcx> {
|
|||
_variable_alloca: Self::Value,
|
||||
_direct_offset: Size,
|
||||
_indirect_offsets: &[Size],
|
||||
_fragment: Option<Range<Size>>,
|
||||
_fragment: &Option<Range<Size>>,
|
||||
) {
|
||||
// FIXME(tempdragon): Not sure if this is correct, probably wrong but still keep it here.
|
||||
#[cfg(feature = "master")]
|
||||
_variable_alloca.set_location(_dbg_loc);
|
||||
}
|
||||
|
||||
fn dbg_var_value(
|
||||
&mut self,
|
||||
_dbg_var: Self::DIVariable,
|
||||
_dbg_loc: Self::DILocation,
|
||||
_value: Self::Value,
|
||||
_direct_offset: Size,
|
||||
_indirect_offsets: &[Size],
|
||||
_fragment: &Option<Range<Size>>,
|
||||
) {
|
||||
}
|
||||
|
||||
fn insert_reference_to_gdb_debug_scripts_section_global(&mut self) {
|
||||
// TODO(antoyo): insert reference to gdb debug scripts section global.
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
#[cfg(feature = "master")]
|
||||
use gccjit::Context;
|
||||
use rustc_codegen_ssa::target_features;
|
||||
use rustc_data_structures::smallvec::{SmallVec, smallvec};
|
||||
use rustc_session::Session;
|
||||
use smallvec::{SmallVec, smallvec};
|
||||
|
||||
fn gcc_features_by_flags(sess: &Session, features: &mut Vec<String>) {
|
||||
target_features::retpoline_features_by_flags(sess, features);
|
||||
|
|
|
|||
16
src/lib.rs
16
src/lib.rs
|
|
@ -1,7 +1,5 @@
|
|||
/*
|
||||
* TODO(antoyo): implement equality in libgccjit based on https://zpz.github.io/blog/overloading-equality-operator-in-cpp-class-hierarchy/ (for type equality?)
|
||||
* TODO(antoyo): support #[inline] attributes.
|
||||
* TODO(antoyo): support LTO (gcc's equivalent to Full LTO is -flto -flto-partition=one — https://documentation.suse.com/sbp/all/html/SBP-GCC-10/index.html).
|
||||
* For Thin LTO, this might be helpful:
|
||||
// cspell:disable-next-line
|
||||
* In gcc 4.6 -fwhopr was removed and became default with -flto. The non-whopr path can still be executed via -flto-partition=none.
|
||||
|
|
@ -25,12 +23,6 @@
|
|||
#![deny(clippy::pattern_type_mismatch)]
|
||||
#![allow(clippy::needless_lifetimes, clippy::uninlined_format_args)]
|
||||
|
||||
// These crates are pulled from the sysroot because they are part of
|
||||
// rustc's public API, so we need to ensure version compatibility.
|
||||
extern crate smallvec;
|
||||
#[macro_use]
|
||||
extern crate tracing;
|
||||
|
||||
// The rustc crates we need
|
||||
extern crate rustc_abi;
|
||||
extern crate rustc_apfloat;
|
||||
|
|
@ -44,6 +36,7 @@ extern crate rustc_hir;
|
|||
extern crate rustc_index;
|
||||
#[cfg(feature = "master")]
|
||||
extern crate rustc_interface;
|
||||
extern crate rustc_log;
|
||||
extern crate rustc_macros;
|
||||
extern crate rustc_middle;
|
||||
extern crate rustc_session;
|
||||
|
|
@ -89,7 +82,7 @@ use back::lto::{ThinBuffer, ThinData};
|
|||
use gccjit::{CType, Context, OptimizationLevel};
|
||||
#[cfg(feature = "master")]
|
||||
use gccjit::{TargetInfo, Version};
|
||||
use rustc_ast::expand::allocator::AllocatorKind;
|
||||
use rustc_ast::expand::allocator::AllocatorMethod;
|
||||
use rustc_codegen_ssa::back::lto::{SerializedModule, ThinModule};
|
||||
use rustc_codegen_ssa::back::write::{
|
||||
CodegenContext, FatLtoInput, ModuleConfig, TargetMachineFactoryFn,
|
||||
|
|
@ -290,8 +283,7 @@ impl ExtraBackendMethods for GccCodegenBackend {
|
|||
&self,
|
||||
tcx: TyCtxt<'_>,
|
||||
module_name: &str,
|
||||
kind: AllocatorKind,
|
||||
alloc_error_handler_kind: AllocatorKind,
|
||||
methods: &[AllocatorMethod],
|
||||
) -> Self::Module {
|
||||
let lto_supported = self.lto_supported.load(Ordering::SeqCst);
|
||||
let mut mods = GccContext {
|
||||
|
|
@ -303,7 +295,7 @@ impl ExtraBackendMethods for GccCodegenBackend {
|
|||
};
|
||||
|
||||
unsafe {
|
||||
allocator::codegen(tcx, &mut mods, module_name, kind, alloc_error_handler_kind);
|
||||
allocator::codegen(tcx, &mut mods, module_name, methods);
|
||||
}
|
||||
mods
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue