From d2f21b85ed464877456295579b39147ae6b59b8b Mon Sep 17 00:00:00 2001 From: Reuben Cruise Date: Mon, 1 Sep 2025 16:53:50 +0100 Subject: [PATCH 01/15] Adds AArch64 GCS support - Adds option to rustc config to enable GCS - Passes `guarded-control-stack` flag to llvm if enabled --- compiler/rustc_codegen_llvm/src/attributes.rs | 5 ++++- compiler/rustc_codegen_llvm/src/context.rs | 9 ++++++++- compiler/rustc_interface/src/tests.rs | 3 ++- compiler/rustc_session/src/config.rs | 1 + compiler/rustc_session/src/options.rs | 3 ++- .../src/compiler-flags/branch-protection.md | 1 + 6 files changed, 18 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/attributes.rs b/compiler/rustc_codegen_llvm/src/attributes.rs index 5affb26483aad..6f3e3a4f2ae0f 100644 --- a/compiler/rustc_codegen_llvm/src/attributes.rs +++ b/compiler/rustc_codegen_llvm/src/attributes.rs @@ -392,13 +392,16 @@ pub(crate) fn llfn_attrs_from_instance<'ll, 'tcx>( to_add.extend(sanitize_attrs(cx, codegen_fn_attrs.no_sanitize)); // For non-naked functions, set branch protection attributes on aarch64. - if let Some(BranchProtection { bti, pac_ret }) = + if let Some(BranchProtection { bti, pac_ret, gcs }) = cx.sess().opts.unstable_opts.branch_protection { assert!(cx.sess().target.arch == "aarch64"); if bti { to_add.push(llvm::CreateAttrString(cx.llcx, "branch-target-enforcement")); } + if gcs { + to_add.push(llvm::CreateAttrString(cx.llcx, "guarded-control-stack")); + } if let Some(PacRet { leaf, pc, key }) = pac_ret { if pc { to_add.push(llvm::CreateAttrString(cx.llcx, "branch-protection-pauth-lr")); diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs index 4fd6110ac4a11..fbf92cffcf552 100644 --- a/compiler/rustc_codegen_llvm/src/context.rs +++ b/compiler/rustc_codegen_llvm/src/context.rs @@ -386,7 +386,8 @@ pub(crate) unsafe fn create_module<'ll>( ); } - if let Some(BranchProtection { bti, pac_ret }) = sess.opts.unstable_opts.branch_protection { + if let Some(BranchProtection { bti, pac_ret, gcs }) = sess.opts.unstable_opts.branch_protection + { if sess.target.arch == "aarch64" { llvm::add_module_flag_u32( llmod, @@ -419,6 +420,12 @@ pub(crate) unsafe fn create_module<'ll>( "sign-return-address-with-bkey", u32::from(pac_opts.key == PAuthKey::B), ); + llvm::add_module_flag_u32( + llmod, + llvm::ModuleFlagMergeBehavior::Min, + "guarded-control-stack", + gcs.into(), + ); } else { bug!( "branch-protection used on non-AArch64 target; \ diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index 7730bddc0f12d..800f5efee41bf 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -772,7 +772,8 @@ fn test_unstable_options_tracking_hash() { branch_protection, Some(BranchProtection { bti: true, - pac_ret: Some(PacRet { leaf: true, pc: true, key: PAuthKey::B }) + pac_ret: Some(PacRet { leaf: true, pc: true, key: PAuthKey::B }), + gcs: true, }) ); tracked!(codegen_backend, Some("abc".to_string())); diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 9793d8091e2ab..990a7af882e83 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -1613,6 +1613,7 @@ pub struct PacRet { pub struct BranchProtection { pub bti: bool, pub pac_ret: Option, + pub gcs: bool, } pub(crate) const fn default_lib_output() -> CrateType { diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 6d5be2d92cd2a..ef543e00031c8 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -799,7 +799,7 @@ mod desc { pub(crate) const parse_polonius: &str = "either no value or `legacy` (the default), or `next`"; pub(crate) const parse_stack_protector: &str = "one of (`none` (default), `basic`, `strong`, or `all`)"; - pub(crate) const parse_branch_protection: &str = "a `,` separated combination of `bti`, `pac-ret`, followed by a combination of `pc`, `b-key`, or `leaf`"; + pub(crate) const parse_branch_protection: &str = "a `,` separated combination of `bti`, `gcs`, `pac-ret`, (optionally with `pc`, `b-key`, `leaf` if `pac-ret` is set)"; pub(crate) const parse_proc_macro_execution_strategy: &str = "one of supported execution strategies (`same-thread`, or `cross-thread`)"; pub(crate) const parse_remap_path_scope: &str = @@ -1836,6 +1836,7 @@ pub mod parse { Some(pac) => pac.pc = true, _ => return false, }, + "gcs" => slot.gcs = true, _ => return false, }; } diff --git a/src/doc/unstable-book/src/compiler-flags/branch-protection.md b/src/doc/unstable-book/src/compiler-flags/branch-protection.md index f0cc44a07f30d..c15567dcac2ee 100644 --- a/src/doc/unstable-book/src/compiler-flags/branch-protection.md +++ b/src/doc/unstable-book/src/compiler-flags/branch-protection.md @@ -13,6 +13,7 @@ It takes some combination of the following values, separated by a `,`. - `leaf` - Enable pointer authentication for all functions, including leaf functions. - `b-key` - Sign return addresses with key B, instead of the default key A. - `bti` - Enable branch target identification. +- `gcs` - Enable guarded control stack support. `leaf`, `b-key` and `pc` are only valid if `pac-ret` was previously specified. For example, `-Z branch-protection=bti,pac-ret,leaf` is valid, but From d80db5b814f594f2e1ecea2e375990287ba4d4df Mon Sep 17 00:00:00 2001 From: Jens Reidel Date: Mon, 8 Sep 2025 20:20:03 +0200 Subject: [PATCH 02/15] tests/codegen-llvm: Make rust-abi-arch-specific-adjustment portable This test currently only runs on RISC-V and loongarch hosts, but assumes that the host target is the -gnu target. By using minicore, we can run this test on all host targets, regardless of architecture, as long as the LLVM components are built. This also fixes this test on musl hosts of these architectures. Signed-off-by: Jens Reidel --- tests/codegen-llvm/rust-abi-arch-specific-adjustment.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tests/codegen-llvm/rust-abi-arch-specific-adjustment.rs b/tests/codegen-llvm/rust-abi-arch-specific-adjustment.rs index 561f081c700ea..ffff4b359947d 100644 --- a/tests/codegen-llvm/rust-abi-arch-specific-adjustment.rs +++ b/tests/codegen-llvm/rust-abi-arch-specific-adjustment.rs @@ -1,15 +1,19 @@ +//@ add-core-stubs //@ compile-flags: -Copt-level=3 -C no-prepopulate-passes //@ revisions: riscv64 loongarch64 -//@[riscv64] only-riscv64 //@[riscv64] compile-flags: --target riscv64gc-unknown-linux-gnu //@[riscv64] needs-llvm-components: riscv -//@[loongarch64] only-loongarch64 //@[loongarch64] compile-flags: --target loongarch64-unknown-linux-gnu //@[loongarch64] needs-llvm-components: loongarch #![crate_type = "lib"] +#![feature(no_core)] +#![no_core] + +extern crate minicore; +use minicore::*; #[no_mangle] // riscv64: define noundef i8 @arg_attr_u8(i8 noundef zeroext %x) From 8ecda4b7f866d77d4a87c5b5bc601d4078841093 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 10 Sep 2025 12:05:53 +0200 Subject: [PATCH 03/15] interpret: fix overlapping aggregate initialization --- .../rustc_const_eval/src/interpret/place.rs | 2 +- .../rustc_const_eval/src/interpret/step.rs | 16 +++++++++++++--- .../fail/both_borrows/issue-miri-1050-1.rs | 2 ++ .../fail/both_borrows/issue-miri-1050-2.rs | 2 ++ .../return_invalid_shr.stack.stderr | 2 +- .../return_invalid_shr.tree.stderr | 2 +- .../return_invalid_shr_option.stack.stderr | 2 +- .../return_invalid_shr_option.tree.stderr | 2 +- .../return_invalid_shr_tuple.stack.stderr | 2 +- .../return_invalid_shr_tuple.tree.stderr | 2 +- .../fail/overlapping_assignment_aggregate.rs | 18 ++++++++++++++++++ .../overlapping_assignment_aggregate.stderr | 15 +++++++++++++++ .../miri/tests/fail/validity/nonzero.stderr | 2 +- ...overlapping_assignment_aggregate_scalar.rs | 19 +++++++++++++++++++ 14 files changed, 77 insertions(+), 11 deletions(-) create mode 100644 src/tools/miri/tests/fail/overlapping_assignment_aggregate.rs create mode 100644 src/tools/miri/tests/fail/overlapping_assignment_aggregate.stderr create mode 100644 src/tools/miri/tests/pass/overlapping_assignment_aggregate_scalar.rs diff --git a/compiler/rustc_const_eval/src/interpret/place.rs b/compiler/rustc_const_eval/src/interpret/place.rs index a86fdf80f601a..cd34892f029cf 100644 --- a/compiler/rustc_const_eval/src/interpret/place.rs +++ b/compiler/rustc_const_eval/src/interpret/place.rs @@ -858,7 +858,7 @@ where /// Also, if you use this you are responsible for validating that things get copied at the /// right type. #[instrument(skip(self), level = "trace")] - fn copy_op_no_validate( + pub(super) fn copy_op_no_validate( &mut self, src: &impl Projectable<'tcx, M::Provenance>, dest: &impl Writeable<'tcx, M::Provenance>, diff --git a/compiler/rustc_const_eval/src/interpret/step.rs b/compiler/rustc_const_eval/src/interpret/step.rs index 23d362de308f3..46950d60f8c78 100644 --- a/compiler/rustc_const_eval/src/interpret/step.rs +++ b/compiler/rustc_const_eval/src/interpret/step.rs @@ -310,7 +310,6 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { operands: &IndexSlice>, dest: &PlaceTy<'tcx, M::Provenance>, ) -> InterpResult<'tcx> { - self.write_uninit(dest)?; // make sure all the padding ends up as uninit let (variant_index, variant_dest, active_field_index) = match *kind { mir::AggregateKind::Adt(_, variant_index, _, _, active_field_index) => { let variant_dest = self.project_downcast(dest, variant_index)?; @@ -346,9 +345,20 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { let field_index = active_field_index.unwrap_or(field_index); let field_dest = self.project_field(&variant_dest, field_index)?; let op = self.eval_operand(operand, Some(field_dest.layout))?; - self.copy_op(&op, &field_dest)?; + // We validate manually below so we don't have to do it here. + self.copy_op_no_validate(&op, &field_dest, /*allow_transmute*/ false)?; } - self.write_discriminant(variant_index, dest) + self.write_discriminant(variant_index, dest)?; + // Validate that the entire thing is valid, and reset padding that might be in between the + // fields. + if M::enforce_validity(self, dest.layout()) { + self.validate_operand( + dest, + M::enforce_validity_recursively(self, dest.layout()), + /*reset_provenance_and_padding*/ true, + )?; + } + interp_ok(()) } /// Repeats `operand` into the destination. `dest` must have array type, and that type diff --git a/src/tools/miri/tests/fail/both_borrows/issue-miri-1050-1.rs b/src/tools/miri/tests/fail/both_borrows/issue-miri-1050-1.rs index dd7dae9cecf91..d907c5de79700 100644 --- a/src/tools/miri/tests/fail/both_borrows/issue-miri-1050-1.rs +++ b/src/tools/miri/tests/fail/both_borrows/issue-miri-1050-1.rs @@ -1,4 +1,6 @@ //@revisions: stack tree +// Ensure this even hits the aliasing model +//@compile-flags: -Zmiri-disable-validation //@[tree]compile-flags: -Zmiri-tree-borrows //@error-in-other-file: pointer not dereferenceable diff --git a/src/tools/miri/tests/fail/both_borrows/issue-miri-1050-2.rs b/src/tools/miri/tests/fail/both_borrows/issue-miri-1050-2.rs index 5c947e6414258..b54f27bb8b23e 100644 --- a/src/tools/miri/tests/fail/both_borrows/issue-miri-1050-2.rs +++ b/src/tools/miri/tests/fail/both_borrows/issue-miri-1050-2.rs @@ -1,4 +1,6 @@ //@revisions: stack tree +// Ensure this even hits the aliasing model +//@compile-flags: -Zmiri-disable-validation //@[tree]compile-flags: -Zmiri-tree-borrows //@error-in-other-file: is a dangling pointer use std::ptr::NonNull; diff --git a/src/tools/miri/tests/fail/both_borrows/return_invalid_shr.stack.stderr b/src/tools/miri/tests/fail/both_borrows/return_invalid_shr.stack.stderr index d52143500c46a..7c4fe74870121 100644 --- a/src/tools/miri/tests/fail/both_borrows/return_invalid_shr.stack.stderr +++ b/src/tools/miri/tests/fail/both_borrows/return_invalid_shr.stack.stderr @@ -11,7 +11,7 @@ help: was created by a SharedReadOnly retag at offsets [0x4..0x8] | LL | let ret = unsafe { &(*xraw).1 }; | ^^^^^^^^^^ -help: was later invalidated at offsets [0x0..0x8] by a write access +help: was later invalidated at offsets [0x4..0x8] by a write access --> tests/fail/both_borrows/return_invalid_shr.rs:LL:CC | LL | unsafe { *xraw = (42, 23) }; // unfreeze diff --git a/src/tools/miri/tests/fail/both_borrows/return_invalid_shr.tree.stderr b/src/tools/miri/tests/fail/both_borrows/return_invalid_shr.tree.stderr index ee0f313d980da..a8e3553aae2c2 100644 --- a/src/tools/miri/tests/fail/both_borrows/return_invalid_shr.tree.stderr +++ b/src/tools/miri/tests/fail/both_borrows/return_invalid_shr.tree.stderr @@ -12,7 +12,7 @@ help: the accessed tag was created here, in the initial state Frozen | LL | let ret = unsafe { &(*xraw).1 }; | ^^^^^^^^^^ -help: the accessed tag later transitioned to Disabled due to a foreign write access at offsets [0x0..0x8] +help: the accessed tag later transitioned to Disabled due to a foreign write access at offsets [0x4..0x8] --> tests/fail/both_borrows/return_invalid_shr.rs:LL:CC | LL | unsafe { *xraw = (42, 23) }; // unfreeze diff --git a/src/tools/miri/tests/fail/both_borrows/return_invalid_shr_option.stack.stderr b/src/tools/miri/tests/fail/both_borrows/return_invalid_shr_option.stack.stderr index d66c8eeb1af69..8411437ea4c97 100644 --- a/src/tools/miri/tests/fail/both_borrows/return_invalid_shr_option.stack.stderr +++ b/src/tools/miri/tests/fail/both_borrows/return_invalid_shr_option.stack.stderr @@ -14,7 +14,7 @@ help: was created by a SharedReadOnly retag at offsets [0x4..0x8] | LL | let ret = Some(unsafe { &(*xraw).1 }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ -help: was later invalidated at offsets [0x0..0x8] by a write access +help: was later invalidated at offsets [0x4..0x8] by a write access --> tests/fail/both_borrows/return_invalid_shr_option.rs:LL:CC | LL | unsafe { *xraw = (42, 23) }; // unfreeze diff --git a/src/tools/miri/tests/fail/both_borrows/return_invalid_shr_option.tree.stderr b/src/tools/miri/tests/fail/both_borrows/return_invalid_shr_option.tree.stderr index 16110e5b062cc..39da45ad6db4d 100644 --- a/src/tools/miri/tests/fail/both_borrows/return_invalid_shr_option.tree.stderr +++ b/src/tools/miri/tests/fail/both_borrows/return_invalid_shr_option.tree.stderr @@ -12,7 +12,7 @@ help: the accessed tag was created here, in the initial state Frozen | LL | let ret = Some(unsafe { &(*xraw).1 }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ -help: the accessed tag later transitioned to Disabled due to a foreign write access at offsets [0x0..0x8] +help: the accessed tag later transitioned to Disabled due to a foreign write access at offsets [0x4..0x8] --> tests/fail/both_borrows/return_invalid_shr_option.rs:LL:CC | LL | unsafe { *xraw = (42, 23) }; // unfreeze diff --git a/src/tools/miri/tests/fail/both_borrows/return_invalid_shr_tuple.stack.stderr b/src/tools/miri/tests/fail/both_borrows/return_invalid_shr_tuple.stack.stderr index 727b52ec72965..a7c422aa73f2c 100644 --- a/src/tools/miri/tests/fail/both_borrows/return_invalid_shr_tuple.stack.stderr +++ b/src/tools/miri/tests/fail/both_borrows/return_invalid_shr_tuple.stack.stderr @@ -14,7 +14,7 @@ help: was created by a SharedReadOnly retag at offsets [0x4..0x8] | LL | let ret = (unsafe { &(*xraw).1 },); | ^^^^^^^^^^^^^^^^^^^^^^^^ -help: was later invalidated at offsets [0x0..0x8] by a write access +help: was later invalidated at offsets [0x4..0x8] by a write access --> tests/fail/both_borrows/return_invalid_shr_tuple.rs:LL:CC | LL | unsafe { *xraw = (42, 23) }; // unfreeze diff --git a/src/tools/miri/tests/fail/both_borrows/return_invalid_shr_tuple.tree.stderr b/src/tools/miri/tests/fail/both_borrows/return_invalid_shr_tuple.tree.stderr index f93698f570ee4..66b03e57905e9 100644 --- a/src/tools/miri/tests/fail/both_borrows/return_invalid_shr_tuple.tree.stderr +++ b/src/tools/miri/tests/fail/both_borrows/return_invalid_shr_tuple.tree.stderr @@ -12,7 +12,7 @@ help: the accessed tag was created here, in the initial state Frozen | LL | let ret = (unsafe { &(*xraw).1 },); | ^^^^^^^^^^^^^^^^^^^^^^^^ -help: the accessed tag later transitioned to Disabled due to a foreign write access at offsets [0x0..0x8] +help: the accessed tag later transitioned to Disabled due to a foreign write access at offsets [0x4..0x8] --> tests/fail/both_borrows/return_invalid_shr_tuple.rs:LL:CC | LL | unsafe { *xraw = (42, 23) }; // unfreeze diff --git a/src/tools/miri/tests/fail/overlapping_assignment_aggregate.rs b/src/tools/miri/tests/fail/overlapping_assignment_aggregate.rs new file mode 100644 index 0000000000000..8d7b1946242c0 --- /dev/null +++ b/src/tools/miri/tests/fail/overlapping_assignment_aggregate.rs @@ -0,0 +1,18 @@ +//! This is like `pass/overlapping_assignment_aggregate_scalar.rs` but with a non-scalar +//! type, and that makes it definite UB. +#![feature(custom_mir, core_intrinsics)] +#![allow(internal_features)] + +use std::intrinsics::mir::*; + +#[custom_mir(dialect = "runtime")] +fn main() { + mir! { + let _1: ([u8; 1],); + { + _1.0 = [0_u8; 1]; + _1 = (_1.0, ); //~ERROR: overlapping ranges + Return() + } + } +} diff --git a/src/tools/miri/tests/fail/overlapping_assignment_aggregate.stderr b/src/tools/miri/tests/fail/overlapping_assignment_aggregate.stderr new file mode 100644 index 0000000000000..f2a6d326b718b --- /dev/null +++ b/src/tools/miri/tests/fail/overlapping_assignment_aggregate.stderr @@ -0,0 +1,15 @@ +error: Undefined Behavior: `copy_nonoverlapping` called on overlapping ranges + --> tests/fail/overlapping_assignment_aggregate.rs:LL:CC + | +LL | _1 = (_1.0, ); + | ^^^^^^^^^^^^^ Undefined Behavior occurred here + | + = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior + = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information + = note: BACKTRACE: + = note: inside `main` at tests/fail/overlapping_assignment_aggregate.rs:LL:CC + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error + diff --git a/src/tools/miri/tests/fail/validity/nonzero.stderr b/src/tools/miri/tests/fail/validity/nonzero.stderr index 0c3a35d6b9fa6..7be3ef46639ca 100644 --- a/src/tools/miri/tests/fail/validity/nonzero.stderr +++ b/src/tools/miri/tests/fail/validity/nonzero.stderr @@ -2,7 +2,7 @@ error: Undefined Behavior: constructing invalid value: encountered 0, but expect --> tests/fail/validity/nonzero.rs:LL:CC | LL | let _x = Some(unsafe { NonZero(0) }); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ Undefined Behavior occurred here + | ^^^^^^^^^^ Undefined Behavior occurred here | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/src/tools/miri/tests/pass/overlapping_assignment_aggregate_scalar.rs b/src/tools/miri/tests/pass/overlapping_assignment_aggregate_scalar.rs new file mode 100644 index 0000000000000..0cb2f7642424e --- /dev/null +++ b/src/tools/miri/tests/pass/overlapping_assignment_aggregate_scalar.rs @@ -0,0 +1,19 @@ +#![feature(custom_mir, core_intrinsics)] +#![allow(internal_features)] + +use std::intrinsics::mir::*; + +#[custom_mir(dialect = "runtime")] +fn main() { + mir! { + let _1: (u8,); + { + _1.0 = 0_u8; + // This is a scalar type, so overlap is (for now) not UB. + // However, we used to treat such overlapping assignments incorrectly + // (see ). + _1 = (_1.0, ); + Return() + } + } +} From 72225060edefb6ae4014c671e9953f9822ddff7a Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 10 Sep 2025 14:27:43 +0200 Subject: [PATCH 04/15] clarify current MIR semantics re: overlapping assignment and double-check that we match it in codegen --- compiler/rustc_codegen_ssa/src/mir/rvalue.rs | 11 ++++++++++- compiler/rustc_middle/src/mir/syntax.rs | 8 +++++--- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs index f6f2e3f2a3a3c..f8755874014d3 100644 --- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs +++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs @@ -1,5 +1,5 @@ use itertools::Itertools as _; -use rustc_abi::{self as abi, FIRST_VARIANT}; +use rustc_abi::{self as abi, BackendRepr, FIRST_VARIANT}; use rustc_middle::ty::adjustment::PointerCoercion; use rustc_middle::ty::layout::{HasTyCtxt, HasTypingEnv, LayoutOf, TyAndLayout}; use rustc_middle::ty::{self, Instance, Ty, TyCtxt}; @@ -25,6 +25,15 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { match *rvalue { mir::Rvalue::Use(ref operand) => { let cg_operand = self.codegen_operand(bx, operand); + // Crucially, we do *not* use `OperandValue::Ref` for types with + // `BackendRepr::Scalar | BackendRepr::ScalarPair`. This ensures we match the MIR + // semantics regarding when assignment operators allow overlap of LHS and RHS. + if matches!( + cg_operand.layout.backend_repr, + BackendRepr::Scalar(..) | BackendRepr::ScalarPair(..), + ) { + debug_assert!(!matches!(cg_operand.val, OperandValue::Ref(..))); + } // FIXME: consider not copying constants through stack. (Fixable by codegen'ing // constants into `OperandValue::Ref`; why don’t we do that yet if we don’t?) cg_operand.val.store(bx, dest); diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs index 3b8def67f92d7..d402ea4b04f9c 100644 --- a/compiler/rustc_middle/src/mir/syntax.rs +++ b/compiler/rustc_middle/src/mir/syntax.rs @@ -327,9 +327,11 @@ pub enum StatementKind<'tcx> { /// interesting for optimizations? Do we want to allow such optimizations? /// /// **Needs clarification**: We currently require that the LHS place not overlap with any place - /// read as part of computation of the RHS for some rvalues (generally those not producing - /// primitives). This requirement is under discussion in [#68364]. As a part of this discussion, - /// it is also unclear in what order the components are evaluated. + /// read as part of computation of the RHS for some rvalues. This requirement is under + /// discussion in [#68364]. Specifically, overlap is permitted only for assignments of a type + /// with `BackendRepr::Scalar | BackendRepr::ScalarPair` where all the scalar fields are + /// [`Scalar::Initialized`][rustc_abi::Scalar::Initialized]. As a part of this discussion, it is + /// also unclear in what order the components are evaluated. /// /// [#68364]: https://github.com/rust-lang/rust/issues/68364 /// From 16c720645cac29e71cc897374bb462fab42a8682 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Sun, 14 Sep 2025 14:37:10 +1000 Subject: [PATCH 05/15] Note some previous attempts to change the Default impl for `[T; 0]` --- library/core/src/array/mod.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/library/core/src/array/mod.rs b/library/core/src/array/mod.rs index d14419a23a1d8..d713e575b58d3 100644 --- a/library/core/src/array/mod.rs +++ b/library/core/src/array/mod.rs @@ -472,6 +472,11 @@ impl SpecArrayClone for T { // The Default impls cannot be done with const generics because `[T; 0]` doesn't // require Default to be implemented, and having different impl blocks for // different numbers isn't supported yet. +// +// Trying to improve the `[T; 0]` situation has proven to be difficult. +// Please see these issues for more context on past attempts and crater runs: +// - https://github.com/rust-lang/rust/issues/61415 +// - https://github.com/rust-lang/rust/pull/145457 macro_rules! array_impl_default { {$n:expr, $t:ident $($ts:ident)*} => { From 7791178805c1bccd2696c123ba5e5e4c896cf7d6 Mon Sep 17 00:00:00 2001 From: Lucas Baumann Date: Sun, 14 Sep 2025 12:11:58 +0200 Subject: [PATCH 06/15] fix 404 link --- src/doc/rustc/src/target-tier-policy.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustc/src/target-tier-policy.md b/src/doc/rustc/src/target-tier-policy.md index 28d3dc32a63ee..f6b78eed24fc4 100644 --- a/src/doc/rustc/src/target-tier-policy.md +++ b/src/doc/rustc/src/target-tier-policy.md @@ -701,4 +701,4 @@ RFC process, with approval by the compiler and infra teams. Any such proposal will be communicated widely to the Rust community, both when initially proposed and before being dropped from a stable release. -[MCP]: https://forge.rust-lang.org/compiler/mcp.html +[MCP]: https://forge.rust-lang.org/compiler/proposals-and-stabilization.html#how-do-i-submit-an-mcp From ce859d7713dbca1b2a3dff17ccc4d4a0598bffbf Mon Sep 17 00:00:00 2001 From: Sidney Cammeresi Date: Sun, 14 Sep 2025 08:06:11 -0700 Subject: [PATCH 07/15] Switch `std::vec::PeekMut::pop` from self to this parameter. Since PeekMut implements Deref, it shouldn't have any methods of its own. See also: `std::collections::binary_heap::PeekMut::pop` --- .mailmap | 1 + library/alloc/src/vec/peek_mut.rs | 4 ++-- library/alloctests/tests/vec.rs | 4 ++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/.mailmap b/.mailmap index 6e3eed1226e0c..0f7bc5e38bd10 100644 --- a/.mailmap +++ b/.mailmap @@ -609,6 +609,7 @@ Shohei Wada Shotaro Yamada Shotaro Yamada Shyam Sundar B +Sidney Cammeresi Simon Barber-Dueck Simon BD Simon Sapin Simonas Kazlauskas Simonas Kazlauskas diff --git a/library/alloc/src/vec/peek_mut.rs b/library/alloc/src/vec/peek_mut.rs index c0dd941ed3933..caeaf2799d733 100644 --- a/library/alloc/src/vec/peek_mut.rs +++ b/library/alloc/src/vec/peek_mut.rs @@ -29,9 +29,9 @@ impl<'a, T> PeekMut<'a, T> { /// Removes the peeked value from the vector and returns it. #[unstable(feature = "vec_peek_mut", issue = "122742")] - pub fn pop(self) -> T { + pub fn pop(this: Self) -> T { // SAFETY: PeekMut is only constructed if the vec is non-empty - unsafe { self.vec.pop().unwrap_unchecked() } + unsafe { this.vec.pop().unwrap_unchecked() } } } diff --git a/library/alloctests/tests/vec.rs b/library/alloctests/tests/vec.rs index 00f640cd17ea4..404eb49e1ea9c 100644 --- a/library/alloctests/tests/vec.rs +++ b/library/alloctests/tests/vec.rs @@ -15,7 +15,7 @@ use std::ops::Bound::*; use std::panic::{AssertUnwindSafe, catch_unwind}; use std::rc::Rc; use std::sync::atomic::{AtomicU32, Ordering}; -use std::vec::{Drain, IntoIter}; +use std::vec::{Drain, IntoIter, PeekMut}; use crate::testing::macros::struct_with_counted_drop; @@ -2647,7 +2647,7 @@ fn test_peek_mut() { assert_eq!(*p, 2); *p = 0; assert_eq!(*p, 0); - p.pop(); + PeekMut::pop(p); assert_eq!(vec.len(), 1); } else { unreachable!() From 572b42346482472736723fe433b417fe32a01800 Mon Sep 17 00:00:00 2001 From: Alan Somers Date: Sun, 14 Sep 2025 11:33:11 -0600 Subject: [PATCH 08/15] On FreeBSD, use readdir instead of readdir_r readdir_r has the same problems on FreeBSD as it does on other platforms: it assumes a fixed NAME_MAX. And readdir has the same thread-safety guarantee as it does on other platforms: it's safe as long as only one thread tries to read from the directory stream at a given time. Furthermore, readdir_r is likely to be removed for FreeBSD 16, so we should stop using it now. --- library/std/src/sys/fs/unix.rs | 120 +++++++++++++++++---------------- 1 file changed, 63 insertions(+), 57 deletions(-) diff --git a/library/std/src/sys/fs/unix.rs b/library/std/src/sys/fs/unix.rs index dfd6ce56a7682..33a1e7ff5e40e 100644 --- a/library/std/src/sys/fs/unix.rs +++ b/library/std/src/sys/fs/unix.rs @@ -21,29 +21,31 @@ use libc::fstatat as fstatat64; #[cfg(any(all(target_os = "linux", not(target_env = "musl")), target_os = "hurd"))] use libc::fstatat64; #[cfg(any( + target_os = "aix", target_os = "android", - target_os = "solaris", + target_os = "freebsd", target_os = "fuchsia", - target_os = "redox", target_os = "illumos", - target_os = "aix", target_os = "nto", + target_os = "redox", + target_os = "solaris", target_os = "vita", all(target_os = "linux", target_env = "musl"), ))] use libc::readdir as readdir64; #[cfg(not(any( + target_os = "aix", target_os = "android", - target_os = "linux", - target_os = "solaris", + target_os = "freebsd", + target_os = "fuchsia", + target_os = "hurd", target_os = "illumos", target_os = "l4re", - target_os = "fuchsia", - target_os = "redox", - target_os = "aix", + target_os = "linux", target_os = "nto", + target_os = "redox", + target_os = "solaris", target_os = "vita", - target_os = "hurd", )))] use libc::readdir_r as readdir64_r; #[cfg(any(all(target_os = "linux", not(target_env = "musl")), target_os = "hurd"))] @@ -271,16 +273,17 @@ unsafe impl Send for Dir {} unsafe impl Sync for Dir {} #[cfg(any( + target_os = "aix", target_os = "android", - target_os = "linux", - target_os = "solaris", - target_os = "illumos", + target_os = "freebsd", target_os = "fuchsia", - target_os = "redox", - target_os = "aix", + target_os = "hurd", + target_os = "illumos", + target_os = "linux", target_os = "nto", + target_os = "redox", + target_os = "solaris", target_os = "vita", - target_os = "hurd", ))] pub struct DirEntry { dir: Arc, @@ -295,16 +298,17 @@ pub struct DirEntry { // we're not using the immediate `d_name` on these targets. Keeping this as an // `entry` field in `DirEntry` helps reduce the `cfg` boilerplate elsewhere. #[cfg(any( + target_os = "aix", target_os = "android", - target_os = "linux", - target_os = "solaris", - target_os = "illumos", + target_os = "freebsd", target_os = "fuchsia", - target_os = "redox", - target_os = "aix", + target_os = "hurd", + target_os = "illumos", + target_os = "linux", target_os = "nto", + target_os = "redox", + target_os = "solaris", target_os = "vita", - target_os = "hurd", ))] struct dirent64_min { d_ino: u64, @@ -319,16 +323,17 @@ struct dirent64_min { } #[cfg(not(any( + target_os = "aix", target_os = "android", - target_os = "linux", - target_os = "solaris", - target_os = "illumos", + target_os = "freebsd", target_os = "fuchsia", - target_os = "redox", - target_os = "aix", + target_os = "hurd", + target_os = "illumos", + target_os = "linux", target_os = "nto", + target_os = "redox", + target_os = "solaris", target_os = "vita", - target_os = "hurd", )))] pub struct DirEntry { dir: Arc, @@ -698,16 +703,17 @@ impl Iterator for ReadDir { type Item = io::Result; #[cfg(any( + target_os = "aix", target_os = "android", - target_os = "linux", - target_os = "solaris", + target_os = "freebsd", target_os = "fuchsia", - target_os = "redox", + target_os = "hurd", target_os = "illumos", - target_os = "aix", + target_os = "linux", target_os = "nto", + target_os = "redox", + target_os = "solaris", target_os = "vita", - target_os = "hurd", ))] fn next(&mut self) -> Option> { use crate::sys::os::{errno, set_errno}; @@ -768,6 +774,9 @@ impl Iterator for ReadDir { // only access those bytes. #[cfg(not(target_os = "vita"))] let entry = dirent64_min { + #[cfg(target_os = "freebsd")] + d_ino: (*entry_ptr).d_fileno, + #[cfg(not(target_os = "freebsd"))] d_ino: (*entry_ptr).d_ino as u64, #[cfg(not(any( target_os = "solaris", @@ -791,16 +800,17 @@ impl Iterator for ReadDir { } #[cfg(not(any( + target_os = "aix", target_os = "android", - target_os = "linux", - target_os = "solaris", + target_os = "freebsd", target_os = "fuchsia", - target_os = "redox", + target_os = "hurd", target_os = "illumos", - target_os = "aix", + target_os = "linux", target_os = "nto", + target_os = "redox", + target_os = "solaris", target_os = "vita", - target_os = "hurd", )))] fn next(&mut self) -> Option> { if self.end_of_stream { @@ -970,36 +980,32 @@ impl DirEntry { } #[cfg(any( - target_os = "linux", + target_os = "aix", + target_os = "android", target_os = "cygwin", target_os = "emscripten", - target_os = "android", - target_os = "solaris", - target_os = "illumos", - target_os = "haiku", - target_os = "l4re", - target_os = "fuchsia", - target_os = "redox", - target_os = "vxworks", target_os = "espidf", + target_os = "freebsd", + target_os = "fuchsia", + target_os = "haiku", target_os = "horizon", - target_os = "vita", - target_os = "aix", - target_os = "nto", target_os = "hurd", + target_os = "illumos", + target_os = "l4re", + target_os = "linux", + target_os = "nto", + target_os = "redox", target_os = "rtems", + target_os = "solaris", + target_os = "vita", + target_os = "vxworks", target_vendor = "apple", ))] pub fn ino(&self) -> u64 { self.entry.d_ino as u64 } - #[cfg(any( - target_os = "freebsd", - target_os = "openbsd", - target_os = "netbsd", - target_os = "dragonfly" - ))] + #[cfg(any(target_os = "openbsd", target_os = "netbsd", target_os = "dragonfly"))] pub fn ino(&self) -> u64 { self.entry.d_fileno as u64 } @@ -1014,7 +1020,6 @@ impl DirEntry { #[cfg(any( target_os = "netbsd", target_os = "openbsd", - target_os = "freebsd", target_os = "dragonfly", target_vendor = "apple", ))] @@ -1030,7 +1035,6 @@ impl DirEntry { #[cfg(not(any( target_os = "netbsd", target_os = "openbsd", - target_os = "freebsd", target_os = "dragonfly", target_vendor = "apple", )))] @@ -1040,6 +1044,7 @@ impl DirEntry { #[cfg(not(any( target_os = "android", + target_os = "freebsd", target_os = "linux", target_os = "solaris", target_os = "illumos", @@ -1055,6 +1060,7 @@ impl DirEntry { } #[cfg(any( target_os = "android", + target_os = "freebsd", target_os = "linux", target_os = "solaris", target_os = "illumos", From 927c4c03194da284404985747c2cad25fa1f5066 Mon Sep 17 00:00:00 2001 From: Jules Bertholet Date: Sun, 14 Sep 2025 17:55:33 -0400 Subject: [PATCH 09/15] Fix typo in error message --- compiler/rustc_middle/messages.ftl | 2 +- tests/ui/consts/const_refs_to_static_fail.stderr | 2 +- tests/ui/consts/const_refs_to_static_fail_invalid.stderr | 4 ++-- .../ui/consts/miri_unleashed/const_refers_to_static.stderr | 2 +- .../const_refers_to_static_cross_crate.stderr | 6 +++--- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_middle/messages.ftl b/compiler/rustc_middle/messages.ftl index 69adb2fe3919f..279ab9a9d8fbe 100644 --- a/compiler/rustc_middle/messages.ftl +++ b/compiler/rustc_middle/messages.ftl @@ -84,7 +84,7 @@ middle_failed_writing_file = # Note: We only mention patterns here since the error can only occur with references, and those # are forbidden in const generics. middle_invalid_const_in_valtree = constant {$global_const_id} cannot be used as pattern - .note = constants that reference mutable or external memory cannot be used as pattern + .note = constants that reference mutable or external memory cannot be used as patterns middle_layout_cycle = a cycle occurred during layout computation diff --git a/tests/ui/consts/const_refs_to_static_fail.stderr b/tests/ui/consts/const_refs_to_static_fail.stderr index c567b3e0ce1f4..2bb6d2b8fef7c 100644 --- a/tests/ui/consts/const_refs_to_static_fail.stderr +++ b/tests/ui/consts/const_refs_to_static_fail.stderr @@ -16,7 +16,7 @@ error: constant BAD_PATTERN cannot be used as pattern LL | BAD_PATTERN => {}, | ^^^^^^^^^^^ | - = note: constants that reference mutable or external memory cannot be used as pattern + = note: constants that reference mutable or external memory cannot be used as patterns error: aborting due to 3 previous errors diff --git a/tests/ui/consts/const_refs_to_static_fail_invalid.stderr b/tests/ui/consts/const_refs_to_static_fail_invalid.stderr index f9088c318a621..226a9de285dc3 100644 --- a/tests/ui/consts/const_refs_to_static_fail_invalid.stderr +++ b/tests/ui/consts/const_refs_to_static_fail_invalid.stderr @@ -15,7 +15,7 @@ error: constant extern_::C cannot be used as pattern LL | C => {} | ^ | - = note: constants that reference mutable or external memory cannot be used as pattern + = note: constants that reference mutable or external memory cannot be used as patterns error: constant mutable::C cannot be used as pattern --> $DIR/const_refs_to_static_fail_invalid.rs:42:9 @@ -23,7 +23,7 @@ error: constant mutable::C cannot be used as pattern LL | C => {} | ^ | - = note: constants that reference mutable or external memory cannot be used as pattern + = note: constants that reference mutable or external memory cannot be used as patterns error: aborting due to 3 previous errors diff --git a/tests/ui/consts/miri_unleashed/const_refers_to_static.stderr b/tests/ui/consts/miri_unleashed/const_refers_to_static.stderr index 6b70a211a72cc..5b8797c511627 100644 --- a/tests/ui/consts/miri_unleashed/const_refers_to_static.stderr +++ b/tests/ui/consts/miri_unleashed/const_refers_to_static.stderr @@ -22,7 +22,7 @@ error: constant REF_INTERIOR_MUT cannot be used as pattern LL | REF_INTERIOR_MUT => {}, | ^^^^^^^^^^^^^^^^ | - = note: constants that reference mutable or external memory cannot be used as pattern + = note: constants that reference mutable or external memory cannot be used as patterns warning: skipping const checks | diff --git a/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.stderr b/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.stderr index d753506cc94e3..c2b730375f2c2 100644 --- a/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.stderr +++ b/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.stderr @@ -10,7 +10,7 @@ error: constant SLICE_MUT cannot be used as pattern LL | SLICE_MUT => true, | ^^^^^^^^^ | - = note: constants that reference mutable or external memory cannot be used as pattern + = note: constants that reference mutable or external memory cannot be used as patterns error: constant U8_MUT cannot be used as pattern --> $DIR/const_refers_to_static_cross_crate.rs:44:9 @@ -18,7 +18,7 @@ error: constant U8_MUT cannot be used as pattern LL | U8_MUT => true, | ^^^^^^ | - = note: constants that reference mutable or external memory cannot be used as pattern + = note: constants that reference mutable or external memory cannot be used as patterns error: constant U8_MUT2 cannot be used as pattern --> $DIR/const_refers_to_static_cross_crate.rs:53:9 @@ -26,7 +26,7 @@ error: constant U8_MUT2 cannot be used as pattern LL | U8_MUT2 => true, | ^^^^^^^ | - = note: constants that reference mutable or external memory cannot be used as pattern + = note: constants that reference mutable or external memory cannot be used as patterns error: aborting due to 4 previous errors From b92ad97f1d8d458de880daea3826d8db30717a0e Mon Sep 17 00:00:00 2001 From: binarycat Date: Sun, 14 Sep 2025 18:26:29 -0500 Subject: [PATCH 10/15] bootstrap.py: disable incremental build for bootstrap in CI --- src/bootstrap/bootstrap.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py index 2ece53eb0cc99..e017cfe6aefbf 100644 --- a/src/bootstrap/bootstrap.py +++ b/src/bootstrap/bootstrap.py @@ -1039,6 +1039,9 @@ def build_bootstrap_cmd(self, env): # See also: . if "CARGO_BUILD_TARGET" in env: del env["CARGO_BUILD_TARGET"] + # if in CI, don't use incremental build when building bootstrap. + if "GITHUB_ACTIONS" in env: + env["CARGO_INCREMENTAL"] = "0" env["CARGO_TARGET_DIR"] = build_dir env["RUSTC"] = self.rustc() env["LD_LIBRARY_PATH"] = ( From 5ebdec5ac2908b0bae42adbe451beeadbe8fa5de Mon Sep 17 00:00:00 2001 From: Tsukasa OI Date: Mon, 15 Sep 2025 02:16:34 +0000 Subject: [PATCH 11/15] rustc_codegen_llvm: Adjust RISC-V inline assembly's clobber list Despite that the `fflags` register (representing floating point exception flags) is stated as a flag register in the reference, it's not in the default clobber list of the RISC-V inline assembly and it would be better to fix it. --- compiler/rustc_codegen_llvm/src/asm.rs | 1 + tests/codegen-llvm/asm/riscv-clobbers.rs | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_codegen_llvm/src/asm.rs b/compiler/rustc_codegen_llvm/src/asm.rs index 38c1d3b53e87c..b79176e909818 100644 --- a/compiler/rustc_codegen_llvm/src/asm.rs +++ b/compiler/rustc_codegen_llvm/src/asm.rs @@ -240,6 +240,7 @@ impl<'ll, 'tcx> AsmBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { } InlineAsmArch::RiscV32 | InlineAsmArch::RiscV64 => { constraints.extend_from_slice(&[ + "~{fflags}".to_string(), "~{vtype}".to_string(), "~{vl}".to_string(), "~{vxsat}".to_string(), diff --git a/tests/codegen-llvm/asm/riscv-clobbers.rs b/tests/codegen-llvm/asm/riscv-clobbers.rs index e55b6731098e7..0f235ddcdcc85 100644 --- a/tests/codegen-llvm/asm/riscv-clobbers.rs +++ b/tests/codegen-llvm/asm/riscv-clobbers.rs @@ -17,7 +17,7 @@ extern crate minicore; use minicore::*; // CHECK-LABEL: @flags_clobber -// CHECK: call void asm sideeffect "", "~{vtype},~{vl},~{vxsat},~{vxrm}"() +// CHECK: call void asm sideeffect "", "~{fflags},~{vtype},~{vl},~{vxsat},~{vxrm}"() #[no_mangle] pub unsafe fn flags_clobber() { asm!("", options(nostack, nomem)); From 8265748da82be9909909930b191ead719cc760eb Mon Sep 17 00:00:00 2001 From: Maksim Bondarenkov Date: Mon, 15 Sep 2025 11:07:07 +0300 Subject: [PATCH 12/15] opt-dist: don't set `RUST_LOG=collector=debug` see [Zulip discussion](https://rust-lang.zulipchat.com/#narrow/channel/122651-general/topic/opt-dist.3A.20do.20not.20set.20RUST_LOG.3Dcollector.3Ddebug.20forcefully) --- src/tools/opt-dist/src/training.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/tools/opt-dist/src/training.rs b/src/tools/opt-dist/src/training.rs index 4f9352d11b12c..b3e95e087e3f1 100644 --- a/src/tools/opt-dist/src/training.rs +++ b/src/tools/opt-dist/src/training.rs @@ -39,7 +39,6 @@ fn init_compiler_benchmarks( "--exact-match", crates.join(",").as_str(), ]) - .env("RUST_LOG", "collector=debug") .env("RUSTC", env.rustc_stage_0().as_str()) .env("RUSTC_BOOTSTRAP", "1") .workdir(&env.rustc_perf_dir()); From 3a57d28e6d29fd4ae594bd0e20de77819a7e3680 Mon Sep 17 00:00:00 2001 From: Reuben Cruise Date: Tue, 2 Sep 2025 16:13:51 +0100 Subject: [PATCH 13/15] Extends branch protection tests to include GCS --- tests/assembly-llvm/aarch64-pointer-auth.rs | 5 ++++- tests/codegen-llvm/branch-protection.rs | 6 +++++- .../run-make/pointer-auth-link-with-c-lto-clang/rmake.rs | 6 +++--- tests/run-make/pointer-auth-link-with-c/rmake.rs | 8 ++++---- .../branch-protection-missing-pac-ret.BADFLAGS.stderr | 2 +- .../branch-protection-missing-pac-ret.BADFLAGSPC.stderr | 2 +- 6 files changed, 18 insertions(+), 11 deletions(-) diff --git a/tests/assembly-llvm/aarch64-pointer-auth.rs b/tests/assembly-llvm/aarch64-pointer-auth.rs index 56a26df469f35..0ac347b069e33 100644 --- a/tests/assembly-llvm/aarch64-pointer-auth.rs +++ b/tests/assembly-llvm/aarch64-pointer-auth.rs @@ -1,10 +1,12 @@ // Test that PAC instructions are emitted when branch-protection is specified. //@ add-core-stubs -//@ revisions: PACRET PAUTHLR_NOP PAUTHLR +//@ revisions: GCS PACRET PAUTHLR_NOP PAUTHLR //@ assembly-output: emit-asm //@ needs-llvm-components: aarch64 //@ compile-flags: --target aarch64-unknown-linux-gnu +//@ min-llvm-version: 21 +//@ [GCS] compile-flags: -Z branch-protection=gcs //@ [PACRET] compile-flags: -Z branch-protection=pac-ret,leaf //@ [PAUTHLR_NOP] compile-flags: -Z branch-protection=pac-ret,pc,leaf //@ [PAUTHLR] compile-flags: -C target-feature=+pauth-lr -Z branch-protection=pac-ret,pc,leaf @@ -17,6 +19,7 @@ extern crate minicore; use minicore::*; +// GCS: .aeabi_attribute 2, 1 // Tag_Feature_GCS // PACRET: hint #25 // PACRET: hint #29 // PAUTHLR_NOP: hint #25 diff --git a/tests/codegen-llvm/branch-protection.rs b/tests/codegen-llvm/branch-protection.rs index d67e494cc0d65..f92259c941cef 100644 --- a/tests/codegen-llvm/branch-protection.rs +++ b/tests/codegen-llvm/branch-protection.rs @@ -1,9 +1,10 @@ // Test that the correct module flags are emitted with different branch protection flags. //@ add-core-stubs -//@ revisions: BTI PACRET LEAF BKEY PAUTHLR PAUTHLR_BKEY PAUTHLR_LEAF PAUTHLR_BTI NONE +//@ revisions: BTI GCS PACRET LEAF BKEY PAUTHLR PAUTHLR_BKEY PAUTHLR_LEAF PAUTHLR_BTI NONE //@ needs-llvm-components: aarch64 //@ [BTI] compile-flags: -Z branch-protection=bti +//@ [GCS] compile-flags: -Z branch-protection=gcs //@ [PACRET] compile-flags: -Z branch-protection=pac-ret //@ [LEAF] compile-flags: -Z branch-protection=pac-ret,leaf //@ [BKEY] compile-flags: -Z branch-protection=pac-ret,b-key @@ -32,6 +33,9 @@ pub fn test() {} // BTI: !"sign-return-address-all", i32 0 // BTI: !"sign-return-address-with-bkey", i32 0 +// GCS: attributes [[ATTR]] = {{.*}} "guarded-control-stack" +// GCS: !"guarded-control-stack", i32 1 + // PACRET: attributes [[ATTR]] = {{.*}} "sign-return-address"="non-leaf" // PACRET-SAME: "sign-return-address-key"="a_key" // PACRET: !"branch-target-enforcement", i32 0 diff --git a/tests/run-make/pointer-auth-link-with-c-lto-clang/rmake.rs b/tests/run-make/pointer-auth-link-with-c-lto-clang/rmake.rs index 0a2186b095389..b0c2af46eaca9 100644 --- a/tests/run-make/pointer-auth-link-with-c-lto-clang/rmake.rs +++ b/tests/run-make/pointer-auth-link-with-c-lto-clang/rmake.rs @@ -1,7 +1,7 @@ // `-Z branch protection` is an unstable compiler feature which adds pointer-authentication // code (PAC), a useful hashing measure for verifying that pointers have not been modified. // This test checks that compilation and execution is successful when this feature is activated, -// with some of its possible extra arguments (bti, pac-ret, leaf) when doing LTO. +// with some of its possible extra arguments (bti, gcs, pac-ret, leaf) when doing LTO. // See https://github.com/rust-lang/rust/pull/88354 //@ needs-force-clang-based-tests @@ -19,7 +19,7 @@ fn main() { clang() .arg("-v") .lto("thin") - .arg("-mbranch-protection=bti+pac-ret+b-key+leaf") + .arg("-mbranch-protection=bti+gcs+pac-ret+b-key+leaf") .arg("-c") .out_exe("test.o") .input("test.c") @@ -30,7 +30,7 @@ fn main() { .opt_level("2") .linker(&env_var("CLANG")) .link_arg("-fuse-ld=lld") - .arg("-Zbranch-protection=bti,pac-ret,leaf") + .arg("-Zbranch-protection=bti,gcs,pac-ret,leaf") .input("test.rs") .output("test.bin") .run(); diff --git a/tests/run-make/pointer-auth-link-with-c/rmake.rs b/tests/run-make/pointer-auth-link-with-c/rmake.rs index a4d7454e5755a..0f4ad7e418ea0 100644 --- a/tests/run-make/pointer-auth-link-with-c/rmake.rs +++ b/tests/run-make/pointer-auth-link-with-c/rmake.rs @@ -1,7 +1,7 @@ // `-Z branch protection` is an unstable compiler feature which adds pointer-authentication // code (PAC), a useful hashing measure for verifying that pointers have not been modified. // This test checks that compilation and execution is successful when this feature is activated, -// with some of its possible extra arguments (bti, pac-ret, pc, leaf, b-key). +// with some of its possible extra arguments (bti, gcs, pac-ret, pc, leaf, b-key). // See https://github.com/rust-lang/rust/pull/88354 //@ only-aarch64 @@ -13,17 +13,17 @@ use run_make_support::{build_native_static_lib, cc, is_windows_msvc, llvm_ar, ru fn main() { build_native_static_lib("test"); - rustc().arg("-Zbranch-protection=bti,pac-ret,leaf").input("test.rs").run(); + rustc().arg("-Zbranch-protection=bti,gcs,pac-ret,leaf").input("test.rs").run(); run("test"); cc().arg("-v") .arg("-c") .out_exe("test") .input("test.c") - .arg("-mbranch-protection=bti+pac-ret+leaf") + .arg("-mbranch-protection=bti+gcs+pac-ret+leaf") .run(); let obj_file = if is_windows_msvc() { "test.obj" } else { "test" }; llvm_ar().obj_to_ar().output_input("libtest.a", &obj_file).run(); - rustc().arg("-Zbranch-protection=bti,pac-ret,leaf").input("test.rs").run(); + rustc().arg("-Zbranch-protection=bti,gcs,pac-ret,leaf").input("test.rs").run(); run("test"); // FIXME: +pc was only recently added to LLVM diff --git a/tests/ui/invalid-compile-flags/branch-protection-missing-pac-ret.BADFLAGS.stderr b/tests/ui/invalid-compile-flags/branch-protection-missing-pac-ret.BADFLAGS.stderr index dae08119dbc68..277111a41f29c 100644 --- a/tests/ui/invalid-compile-flags/branch-protection-missing-pac-ret.BADFLAGS.stderr +++ b/tests/ui/invalid-compile-flags/branch-protection-missing-pac-ret.BADFLAGS.stderr @@ -1,2 +1,2 @@ -error: incorrect value `leaf` for unstable option `branch-protection` - a `,` separated combination of `bti`, `pac-ret`, followed by a combination of `pc`, `b-key`, or `leaf` was expected +error: incorrect value `leaf` for unstable option `branch-protection` - a `,` separated combination of `bti`, `gcs`, `pac-ret`, (optionally with `pc`, `b-key`, `leaf` if `pac-ret` is set) was expected diff --git a/tests/ui/invalid-compile-flags/branch-protection-missing-pac-ret.BADFLAGSPC.stderr b/tests/ui/invalid-compile-flags/branch-protection-missing-pac-ret.BADFLAGSPC.stderr index 13f79e94674b2..e1ade01d2fe76 100644 --- a/tests/ui/invalid-compile-flags/branch-protection-missing-pac-ret.BADFLAGSPC.stderr +++ b/tests/ui/invalid-compile-flags/branch-protection-missing-pac-ret.BADFLAGSPC.stderr @@ -1,2 +1,2 @@ -error: incorrect value `pc` for unstable option `branch-protection` - a `,` separated combination of `bti`, `pac-ret`, followed by a combination of `pc`, `b-key`, or `leaf` was expected +error: incorrect value `pc` for unstable option `branch-protection` - a `,` separated combination of `bti`, `gcs`, `pac-ret`, (optionally with `pc`, `b-key`, `leaf` if `pac-ret` is set) was expected From dbb94e76ab25004718e6d548f93ea36d409da865 Mon Sep 17 00:00:00 2001 From: Reuben Cruise Date: Wed, 10 Sep 2025 15:40:27 +0100 Subject: [PATCH 14/15] Updates arch64 llvm-19 CI to use GCC15 GCS support was added to GCC in version 15, thus the rmake test for this patch requires GCC15 --- src/ci/docker/host-aarch64/aarch64-gnu-llvm-19/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ci/docker/host-aarch64/aarch64-gnu-llvm-19/Dockerfile b/src/ci/docker/host-aarch64/aarch64-gnu-llvm-19/Dockerfile index e73fbe506f788..4726e6fc84585 100644 --- a/src/ci/docker/host-aarch64/aarch64-gnu-llvm-19/Dockerfile +++ b/src/ci/docker/host-aarch64/aarch64-gnu-llvm-19/Dockerfile @@ -4,7 +4,7 @@ ARG DEBIAN_FRONTEND=noninteractive RUN apt-get update && apt-get install -y --no-install-recommends \ bzip2 \ - g++ \ + g++-15 \ make \ ninja-build \ file \ From c92dee244dcca49c1eed99a768749e433f17e112 Mon Sep 17 00:00:00 2001 From: Boxy Uwu Date: Wed, 10 Sep 2025 11:27:36 +0100 Subject: [PATCH 15/15] Add relnotes 1.90 --- RELEASES.md | 126 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 126 insertions(+) diff --git a/RELEASES.md b/RELEASES.md index 33abe45ce4629..2b65d070d5fd1 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1,3 +1,129 @@ +Version 1.90 (2025-09-18) +========================== + + + +Language +-------- +- [Split up the `unknown_or_malformed_diagnostic_attributes` lint](https://github.com/rust-lang/rust/pull/140717). This lint has been split up into four finer-grained lints, with `unknown_or_malformed_diagnostic_attributes` now being the lint group that contains these lints: + 1. `unknown_diagnostic_attributes`: unknown to the current compiler + 2. `misplaced_diagnostic_attributes`: placed on the wrong item + 3. `malformed_diagnostic_attributes`: malformed attribute syntax or options + 4. `malformed_diagnostic_format_literals`: malformed format string literal +- [Allow constants whose final value has references to mutable/external memory, but reject such constants as patterns](https://github.com/rust-lang/rust/pull/140942) +- [Allow volatile access to non-Rust memory, including address 0](https://github.com/rust-lang/rust/pull/141260) + + + + +Compiler +-------- +- [Use `lld` by default on `x86_64-unknown-linux-gnu`](https://github.com/rust-lang/rust/pull/140525). +- [Tier 3 `musl` targets now link dynamically by default](https://github.com/rust-lang/rust/pull/144410). Affected targets: + - `mips64-unknown-linux-muslabi64` + - `powerpc64-unknown-linux-musl` + - `powerpc-unknown-linux-musl` + - `powerpc-unknown-linux-muslspe` + - `riscv32gc-unknown-linux-musl` + - `s390x-unknown-linux-musl` + - `thumbv7neon-unknown-linux-musleabihf` + + + + +Platform Support +---------------- +- [Demote `x86_64-apple-darwin` to Tier 2 with host tools](https://github.com/rust-lang/rust/pull/145252) + + +Refer to Rust's [platform support page][platform-support-doc] +for more information on Rust's tiered platform support. + +[platform-support-doc]: https://doc.rust-lang.org/rustc/platform-support.html + + + +Libraries +--------- +- [Stabilize `u*::{checked,overflowing,saturating,wrapping}_sub_signed`](https://github.com/rust-lang/rust/issues/126043) +- [Allow comparisons between `CStr`, `CString`, and `Cow`](https://github.com/rust-lang/rust/pull/137268) +- [Remove some unsized tuple impls since unsized tuples can't be constructed](https://github.com/rust-lang/rust/pull/138340) +- [Set `MSG_NOSIGNAL` for `UnixStream`](https://github.com/rust-lang/rust/pull/140005) +- [`proc_macro::Ident::new` now supports `$crate`.](https://github.com/rust-lang/rust/pull/141996) +- [Guarantee the pointer returned from `Thread::into_raw` has at least 8 bytes of alignment](https://github.com/rust-lang/rust/pull/143859) + + + + +Stabilized APIs +--------------- + +- [`u{n}::checked_sub_signed`](https://doc.rust-lang.org/stable/std/primitive.usize.html#method.checked_sub_signed) +- [`u{n}::overflowing_sub_signed`](https://doc.rust-lang.org/stable/std/primitive.usize.html#method.overflowing_sub_signed) +- [`u{n}::saturating_sub_signed`](https://doc.rust-lang.org/stable/std/primitive.usize.html#method.saturating_sub_signed) +- [`u{n}::wrapping_sub_signed`](https://doc.rust-lang.org/stable/std/primitive.usize.html#method.wrapping_sub_signed) +- [`impl Copy for IntErrorKind`](https://doc.rust-lang.org/stable/std/num/enum.IntErrorKind.html#impl-Copy-for-IntErrorKind) +- [`impl Hash for IntErrorKind`](https://doc.rust-lang.org/stable/std/num/enum.IntErrorKind.html#impl-Hash-for-IntErrorKind) +- [`impl PartialEq<&CStr> for CStr`](https://doc.rust-lang.org/stable/std/ffi/struct.CStr.html#impl-PartialEq%3C%26CStr%3E-for-CStr) +- [`impl PartialEq for CStr`](https://doc.rust-lang.org/stable/std/ffi/struct.CStr.html#impl-PartialEq%3CCString%3E-for-CStr) +- [`impl PartialEq> for CStr`](https://doc.rust-lang.org/stable/std/ffi/struct.CStr.html#impl-PartialEq%3CCow%3C'_,+CStr%3E%3E-for-CStr) +- [`impl PartialEq<&CStr> for CString`](https://doc.rust-lang.org/stable/std/ffi/struct.CString.html#impl-PartialEq%3C%26CStr%3E-for-CString) +- [`impl PartialEq for CString`](https://doc.rust-lang.org/stable/std/ffi/struct.CString.html#impl-PartialEq%3CCStr%3E-for-CString) +- [`impl PartialEq> for CString`](https://doc.rust-lang.org/stable/std/ffi/struct.CString.html#impl-PartialEq%3CCow%3C'_,+CStr%3E%3E-for-CString) +- [`impl PartialEq<&CStr> for Cow`](https://doc.rust-lang.org/stable/std/borrow/enum.Cow.html#impl-PartialEq%3C%26CStr%3E-for-Cow%3C'_,+CStr%3E) +- [`impl PartialEq for Cow`](https://doc.rust-lang.org/stable/std/borrow/enum.Cow.html#impl-PartialEq%3CCStr%3E-for-Cow%3C'_,+CStr%3E) +- [`impl PartialEq for Cow`](https://doc.rust-lang.org/stable/std/borrow/enum.Cow.html#impl-PartialEq%3CCString%3E-for-Cow%3C'_,+CStr%3E) + + +These previously stable APIs are now stable in const contexts: + +- [`<[T]>::reverse`](https://doc.rust-lang.org/stable/std/primitive.slice.html#method.reverse) +- [`f32::floor`](https://doc.rust-lang.org/stable/std/primitive.f32.html#method.floor) +- [`f32::ceil`](https://doc.rust-lang.org/stable/std/primitive.f32.html#method.ceil) +- [`f32::trunc`](https://doc.rust-lang.org/stable/std/primitive.f32.html#method.trunc) +- [`f32::fract`](https://doc.rust-lang.org/stable/std/primitive.f32.html#method.fract) +- [`f32::round`](https://doc.rust-lang.org/stable/std/primitive.f32.html#method.round) +- [`f32::round_ties_even`](https://doc.rust-lang.org/stable/std/primitive.f32.html#method.round_ties_even) +- [`f64::floor`](https://doc.rust-lang.org/stable/std/primitive.f64.html#method.floor) +- [`f64::ceil`](https://doc.rust-lang.org/stable/std/primitive.f64.html#method.ceil) +- [`f64::trunc`](https://doc.rust-lang.org/stable/std/primitive.f64.html#method.trunc) +- [`f64::fract`](https://doc.rust-lang.org/stable/std/primitive.f64.html#method.fract) +- [`f64::round`](https://doc.rust-lang.org/stable/std/primitive.f64.html#method.round) +- [`f64::round_ties_even`](https://doc.rust-lang.org/stable/std/primitive.f64.html#method.round_ties_even) + + + + +Cargo +----- +- [Add `http.proxy-cainfo` config for proxy certs](https://github.com/rust-lang/cargo/pull/15374/) +- [Use `gix` for `cargo package`](https://github.com/rust-lang/cargo/pull/15534/) +- [feat(publish): Stabilize multi-package publishing](https://github.com/rust-lang/cargo/pull/15636/) + + + +Rustdoc +----- +- [Add ways to collapse all impl blocks](https://github.com/rust-lang/rust/pull/141663). Previously the "Summary" button and "-" keyboard shortcut would never collapse `impl` blocks, now they do when shift is held +- [Display unsafe attributes with `unsafe()` wrappers](https://github.com/rust-lang/rust/pull/143662) + + + + +Compatibility Notes +------------------- +- [Use `lld` by default on `x86_64-unknown-linux-gnu`](https://github.com/rust-lang/rust/pull/140525). + See also . +- [Make `core::iter::Fuse`'s `Default` impl construct `I::default()` internally as promised in the docs instead of always being empty](https://github.com/rust-lang/rust/pull/140985) +- [Set `MSG_NOSIGNAL` for `UnixStream`](https://github.com/rust-lang/rust/pull/140005) + This may change program behavior but results in the same behavior as other primitives (e.g., stdout, network sockets). + Programs relying on signals to terminate them should update handling of sockets to handle errors on write by exiting. +- [On Unix `std::env::home_dir` will use the fallback if the `HOME` environment variable is empty](https://github.com/rust-lang/rust/pull/141840) +- We now [reject unsupported `extern "{abi}"`s consistently in all positions](https://github.com/rust-lang/rust/pull/142134). This primarily affects the use of implementing traits on an `extern "{abi}"` function pointer, like `extern "stdcall" fn()`, on a platform that doesn't support that, like aarch64-unknown-linux-gnu. Direct usage of these unsupported ABI strings by declaring or defining functions was already rejected, so this is only a change for consistency. +- [const-eval: error when initializing a static writes to that static](https://github.com/rust-lang/rust/pull/143084) +- [Check that the `proc_macro_derive` macro has correct arguments when applied to the crate root](https://github.com/rust-lang/rust/pull/143607) + + Version 1.89.0 (2025-08-07) ==========================