Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 026a080

Browse files
committedNov 1, 2024
remove const-support for align_offset
Operations like is_aligned would return actively wrong results at compile-time, i.e. calling it on the same pointer at compiletime and runtime could yield different results. That's no good. Instead of having hacks to make align_offset kind-of work in const-eval, just use const_eval_select in the few places where it makes sense, which also ensures those places are all aware they need to make sure the fallback behavior is consistent.
1 parent c8b8378 commit 026a080

File tree

16 files changed

+183
-1020
lines changed

16 files changed

+183
-1020
lines changed
 

‎compiler/rustc_const_eval/messages.ftl

-3
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
const_eval_address_space_full =
22
there are no more free addresses in the address space
33
4-
const_eval_align_offset_invalid_align =
5-
`align_offset` called with non-power-of-two align: {$target_align}
6-
74
const_eval_alignment_check_failed =
85
{$msg ->
96
[AccessedPtr] accessing memory

‎compiler/rustc_const_eval/src/const_eval/machine.rs

+6-82
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
11
use std::borrow::{Borrow, Cow};
22
use std::fmt;
33
use std::hash::Hash;
4-
use std::ops::ControlFlow;
54

65
use rustc_ast::Mutability;
76
use rustc_data_structures::fx::{FxHashMap, FxIndexMap, IndexEntry};
87
use rustc_hir::def_id::{DefId, LocalDefId};
98
use rustc_hir::{self as hir, CRATE_HIR_ID, LangItem};
109
use rustc_middle::mir::AssertMessage;
1110
use rustc_middle::query::TyCtxtAt;
12-
use rustc_middle::ty::layout::{FnAbiOf, TyAndLayout};
11+
use rustc_middle::ty::layout::TyAndLayout;
1312
use rustc_middle::ty::{self, Ty, TyCtxt};
1413
use rustc_middle::{bug, mir};
1514
use rustc_span::Span;
@@ -23,9 +22,9 @@ use crate::errors::{LongRunning, LongRunningWarn};
2322
use crate::fluent_generated as fluent;
2423
use crate::interpret::{
2524
self, AllocId, AllocRange, ConstAllocation, CtfeProvenance, FnArg, Frame, GlobalAlloc, ImmTy,
26-
InterpCx, InterpResult, MPlaceTy, OpTy, Pointer, PointerArithmetic, RangeSet, Scalar,
27-
StackPopCleanup, compile_time_machine, interp_ok, throw_exhaust, throw_inval, throw_ub,
28-
throw_ub_custom, throw_unsup, throw_unsup_format,
25+
InterpCx, InterpResult, MPlaceTy, OpTy, Pointer, RangeSet, Scalar, compile_time_machine,
26+
interp_ok, throw_exhaust, throw_inval, throw_ub, throw_ub_custom, throw_unsup,
27+
throw_unsup_format,
2928
};
3029

3130
/// When hitting this many interpreted terminators we emit a deny by default lint
@@ -227,8 +226,8 @@ impl<'tcx> CompileTimeInterpCx<'tcx> {
227226
&mut self,
228227
instance: ty::Instance<'tcx>,
229228
args: &[FnArg<'tcx>],
230-
dest: &MPlaceTy<'tcx>,
231-
ret: Option<mir::BasicBlock>,
229+
_dest: &MPlaceTy<'tcx>,
230+
_ret: Option<mir::BasicBlock>,
232231
) -> InterpResult<'tcx, Option<ty::Instance<'tcx>>> {
233232
let def_id = instance.def_id();
234233

@@ -260,85 +259,10 @@ impl<'tcx> CompileTimeInterpCx<'tcx> {
260259
);
261260

262261
return interp_ok(Some(new_instance));
263-
} else if self.tcx.is_lang_item(def_id, LangItem::AlignOffset) {
264-
let args = self.copy_fn_args(args);
265-
// For align_offset, we replace the function call if the pointer has no address.
266-
match self.align_offset(instance, &args, dest, ret)? {
267-
ControlFlow::Continue(()) => return interp_ok(Some(instance)),
268-
ControlFlow::Break(()) => return interp_ok(None),
269-
}
270262
}
271263
interp_ok(Some(instance))
272264
}
273265

274-
/// `align_offset(ptr, target_align)` needs special handling in const eval, because the pointer
275-
/// may not have an address.
276-
///
277-
/// If `ptr` does have a known address, then we return `Continue(())` and the function call should
278-
/// proceed as normal.
279-
///
280-
/// If `ptr` doesn't have an address, but its underlying allocation's alignment is at most
281-
/// `target_align`, then we call the function again with an dummy address relative to the
282-
/// allocation.
283-
///
284-
/// If `ptr` doesn't have an address and `target_align` is stricter than the underlying
285-
/// allocation's alignment, then we return `usize::MAX` immediately.
286-
fn align_offset(
287-
&mut self,
288-
instance: ty::Instance<'tcx>,
289-
args: &[OpTy<'tcx>],
290-
dest: &MPlaceTy<'tcx>,
291-
ret: Option<mir::BasicBlock>,
292-
) -> InterpResult<'tcx, ControlFlow<()>> {
293-
assert_eq!(args.len(), 2);
294-
295-
let ptr = self.read_pointer(&args[0])?;
296-
let target_align = self.read_scalar(&args[1])?.to_target_usize(self)?;
297-
298-
if !target_align.is_power_of_two() {
299-
throw_ub_custom!(
300-
fluent::const_eval_align_offset_invalid_align,
301-
target_align = target_align,
302-
);
303-
}
304-
305-
match self.ptr_try_get_alloc_id(ptr, 0) {
306-
Ok((alloc_id, offset, _extra)) => {
307-
let (_size, alloc_align, _kind) = self.get_alloc_info(alloc_id);
308-
309-
if target_align <= alloc_align.bytes() {
310-
// Extract the address relative to the allocation base that is definitely
311-
// sufficiently aligned and call `align_offset` again.
312-
let addr = ImmTy::from_uint(offset.bytes(), args[0].layout).into();
313-
let align = ImmTy::from_uint(target_align, args[1].layout).into();
314-
let fn_abi = self.fn_abi_of_instance(instance, ty::List::empty())?;
315-
316-
// Push the stack frame with our own adjusted arguments.
317-
self.init_stack_frame(
318-
instance,
319-
self.load_mir(instance.def, None)?,
320-
fn_abi,
321-
&[FnArg::Copy(addr), FnArg::Copy(align)],
322-
/* with_caller_location = */ false,
323-
dest,
324-
StackPopCleanup::Goto { ret, unwind: mir::UnwindAction::Unreachable },
325-
)?;
326-
interp_ok(ControlFlow::Break(()))
327-
} else {
328-
// Not alignable in const, return `usize::MAX`.
329-
let usize_max = Scalar::from_target_usize(self.target_usize_max(), self);
330-
self.write_scalar(usize_max, dest)?;
331-
self.return_to_block(ret)?;
332-
interp_ok(ControlFlow::Break(()))
333-
}
334-
}
335-
Err(_addr) => {
336-
// The pointer has an address, continue with function call.
337-
interp_ok(ControlFlow::Continue(()))
338-
}
339-
}
340-
}
341-
342266
/// See documentation on the `ptr_guaranteed_cmp` intrinsic.
343267
fn guaranteed_cmp(&mut self, a: Scalar, b: Scalar) -> InterpResult<'tcx, u8> {
344268
interp_ok(match (a, b) {

‎compiler/rustc_hir/src/lang_items.rs

-3
Original file line numberDiff line numberDiff line change
@@ -348,9 +348,6 @@ language_item_table! {
348348

349349
MaybeUninit, sym::maybe_uninit, maybe_uninit, Target::Union, GenericRequirement::None;
350350

351-
/// Align offset for stride != 1; must not panic.
352-
AlignOffset, sym::align_offset, align_offset_fn, Target::Fn, GenericRequirement::None;
353-
354351
Termination, sym::termination, termination, Target::Trait, GenericRequirement::None;
355352

356353
Try, sym::Try, try_trait, Target::Trait, GenericRequirement::None;

‎compiler/rustc_span/src/symbol.rs

-1
Original file line numberDiff line numberDiff line change
@@ -378,7 +378,6 @@ symbols! {
378378
aggregate_raw_ptr,
379379
alias,
380380
align,
381-
align_offset,
382381
alignment,
383382
all,
384383
alloc,

‎library/core/src/lib.rs

-2
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,6 @@
112112
#![feature(asm_experimental_arch)]
113113
#![feature(const_align_of_val)]
114114
#![feature(const_align_of_val_raw)]
115-
#![feature(const_align_offset)]
116115
#![feature(const_alloc_layout)]
117116
#![feature(const_arguments_as_str)]
118117
#![feature(const_array_into_iter_constructors)]
@@ -128,7 +127,6 @@
128127
#![feature(const_num_midpoint)]
129128
#![feature(const_option_ext)]
130129
#![feature(const_pin_2)]
131-
#![feature(const_pointer_is_aligned)]
132130
#![feature(const_ptr_is_null)]
133131
#![feature(const_ptr_sub_ptr)]
134132
#![feature(const_raw_ptr_comparison)]
There was a problem loading the remainder of the diff.

0 commit comments

Comments
 (0)
Failed to load comments.