Skip to content

Commit 8955686

Browse files
committed
interpret: track place alignment together with the type, not the value
1 parent ada8c80 commit 8955686

File tree

3 files changed

+117
-95
lines changed

3 files changed

+117
-95
lines changed

compiler/rustc_const_eval/src/interpret/eval_context.rs

+5-10
Original file line numberDiff line numberDiff line change
@@ -808,7 +808,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
808808
self.stack_mut().pop().expect("tried to pop a stack frame, but there were none");
809809

810810
if !unwinding {
811-
let op = self.access_local(&frame, mir::RETURN_PLACE, None)?;
811+
let op = self.local_to_op(&frame, mir::RETURN_PLACE, None)?;
812812
self.copy_op_transmute(&op, &frame.return_place)?;
813813
trace!("{:?}", self.dump_place(*frame.return_place));
814814
}
@@ -981,8 +981,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> std::fmt::Debug
981981
LocalValue::Live(Operand::Indirect(mplace)) => {
982982
write!(
983983
fmt,
984-
" by align({}){} ref {:?}:",
985-
mplace.align.bytes(),
984+
" by {} ref {:?}:",
986985
match mplace.meta {
987986
MemPlaceMeta::Meta(meta) => format!(" meta({:?})", meta),
988987
MemPlaceMeta::Poison | MemPlaceMeta::None => String::new(),
@@ -1011,13 +1010,9 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> std::fmt::Debug
10111010
write!(fmt, ": {:?}", self.ecx.dump_allocs(allocs.into_iter().flatten().collect()))
10121011
}
10131012
Place::Ptr(mplace) => match mplace.ptr.provenance.and_then(Provenance::get_alloc_id) {
1014-
Some(alloc_id) => write!(
1015-
fmt,
1016-
"by align({}) ref {:?}: {:?}",
1017-
mplace.align.bytes(),
1018-
mplace.ptr,
1019-
self.ecx.dump_alloc(alloc_id)
1020-
),
1013+
Some(alloc_id) => {
1014+
write!(fmt, "by ref {:?}: {:?}", mplace.ptr, self.ecx.dump_alloc(alloc_id))
1015+
}
10211016
ptr => write!(fmt, " integral by ref: {:?}", ptr),
10221017
},
10231018
}

compiler/rustc_const_eval/src/interpret/operand.rs

+22-15
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use rustc_middle::ty::layout::{LayoutOf, PrimitiveExt, TyAndLayout};
1010
use rustc_middle::ty::print::{FmtPrinter, PrettyPrinter, Printer};
1111
use rustc_middle::ty::{ConstInt, DelaySpanBugEmitted, Ty};
1212
use rustc_middle::{mir, ty};
13-
use rustc_target::abi::{self, Abi, HasDataLayout, Size, TagEncoding};
13+
use rustc_target::abi::{self, Abi, Align, HasDataLayout, Size, TagEncoding};
1414
use rustc_target::abi::{VariantIdx, Variants};
1515

1616
use super::{
@@ -177,10 +177,17 @@ pub enum Operand<Tag: Provenance = AllocId> {
177177
pub struct OpTy<'tcx, Tag: Provenance = AllocId> {
178178
op: Operand<Tag>, // Keep this private; it helps enforce invariants.
179179
pub layout: TyAndLayout<'tcx>,
180+
/// rustc does not have a proper way to represent the type of a field of a `repr(packed)` struct:
181+
/// it needs to have a different alignment than the field type would usually have.
182+
/// So we represent this here with a separate field that "overwrites" `layout.align`.
183+
/// This means `layout.align` should never be used for an `OpTy`!
184+
/// `None` means "alignment does not matter since this is a by-value operand"
185+
/// (`Operand::Immediate`).
186+
pub align: Option<Align>,
180187
}
181188

182189
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
183-
rustc_data_structures::static_assert_size!(OpTy<'_>, 80);
190+
rustc_data_structures::static_assert_size!(OpTy<'_>, 88);
184191

185192
impl<'tcx, Tag: Provenance> std::ops::Deref for OpTy<'tcx, Tag> {
186193
type Target = Operand<Tag>;
@@ -193,28 +200,28 @@ impl<'tcx, Tag: Provenance> std::ops::Deref for OpTy<'tcx, Tag> {
193200
impl<'tcx, Tag: Provenance> From<MPlaceTy<'tcx, Tag>> for OpTy<'tcx, Tag> {
194201
#[inline(always)]
195202
fn from(mplace: MPlaceTy<'tcx, Tag>) -> Self {
196-
OpTy { op: Operand::Indirect(*mplace), layout: mplace.layout }
203+
OpTy { op: Operand::Indirect(*mplace), layout: mplace.layout, align: Some(mplace.align) }
197204
}
198205
}
199206

200207
impl<'tcx, Tag: Provenance> From<&'_ MPlaceTy<'tcx, Tag>> for OpTy<'tcx, Tag> {
201208
#[inline(always)]
202209
fn from(mplace: &MPlaceTy<'tcx, Tag>) -> Self {
203-
OpTy { op: Operand::Indirect(**mplace), layout: mplace.layout }
210+
OpTy { op: Operand::Indirect(**mplace), layout: mplace.layout, align: Some(mplace.align) }
204211
}
205212
}
206213

207214
impl<'tcx, Tag: Provenance> From<&'_ mut MPlaceTy<'tcx, Tag>> for OpTy<'tcx, Tag> {
208215
#[inline(always)]
209216
fn from(mplace: &mut MPlaceTy<'tcx, Tag>) -> Self {
210-
OpTy { op: Operand::Indirect(**mplace), layout: mplace.layout }
217+
OpTy { op: Operand::Indirect(**mplace), layout: mplace.layout, align: Some(mplace.align) }
211218
}
212219
}
213220

214221
impl<'tcx, Tag: Provenance> From<ImmTy<'tcx, Tag>> for OpTy<'tcx, Tag> {
215222
#[inline(always)]
216223
fn from(val: ImmTy<'tcx, Tag>) -> Self {
217-
OpTy { op: Operand::Immediate(val.imm), layout: val.layout }
224+
OpTy { op: Operand::Immediate(val.imm), layout: val.layout, align: None }
218225
}
219226
}
220227

@@ -450,7 +457,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
450457
),
451458
};
452459

453-
Ok(OpTy { op: Operand::Immediate(field_val), layout: field_layout })
460+
Ok(OpTy { op: Operand::Immediate(field_val), layout: field_layout, align: None })
454461
}
455462

456463
pub fn operand_index(
@@ -522,7 +529,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
522529
///
523530
/// This is public because it is used by [priroda](https://github.com/oli-obk/priroda) to get an
524531
/// OpTy from a local
525-
pub fn access_local(
532+
pub fn local_to_op(
526533
&self,
527534
frame: &super::Frame<'mir, 'tcx, M::PointerTag, M::FrameExtra>,
528535
local: mir::Local,
@@ -535,7 +542,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
535542
} else {
536543
M::access_local(&self, frame, local)?
537544
};
538-
Ok(OpTy { op, layout })
545+
Ok(OpTy { op, layout, align: Some(layout.align.abi) })
539546
}
540547

541548
/// Every place can be read from, so we can turn them into an operand.
@@ -549,10 +556,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
549556
let op = match **place {
550557
Place::Ptr(mplace) => Operand::Indirect(mplace),
551558
Place::Local { frame, local } => {
552-
*self.access_local(&self.stack()[frame], local, None)?
559+
*self.local_to_op(&self.stack()[frame], local, None)?
553560
}
554561
};
555-
Ok(OpTy { op, layout: place.layout })
562+
Ok(OpTy { op, layout: place.layout, align: Some(place.align) })
556563
}
557564

558565
/// Evaluate a place with the goal of reading from it. This lets us sometimes
@@ -566,7 +573,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
566573
// here is not the entire place.
567574
let layout = if place.projection.is_empty() { layout } else { None };
568575

569-
let base_op = self.access_local(self.frame(), place.local, layout)?;
576+
let base_op = self.local_to_op(self.frame(), place.local, layout)?;
570577

571578
let op = place
572579
.projection
@@ -603,11 +610,11 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
603610
Constant(ref constant) => {
604611
let val =
605612
self.subst_from_current_frame_and_normalize_erasing_regions(constant.literal)?;
613+
606614
// This can still fail:
607615
// * During ConstProp, with `TooGeneric` or since the `required_consts` were not all
608616
// checked yet.
609617
// * During CTFE, since promoteds in `const`/`static` initializer bodies can fail.
610-
611618
self.mir_const_to_op(&val, layout)?
612619
}
613620
};
@@ -683,7 +690,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
683690
// We rely on mutability being set correctly in that allocation to prevent writes
684691
// where none should happen.
685692
let ptr = self.global_base_pointer(Pointer::new(id, offset))?;
686-
Operand::Indirect(MemPlace::from_ptr(ptr.into(), layout.align.abi))
693+
Operand::Indirect(MemPlace::from_ptr(ptr.into()))
687694
}
688695
ConstValue::Scalar(x) => Operand::Immediate(tag_scalar(x)?.into()),
689696
ConstValue::Slice { data, start, end } => {
@@ -700,7 +707,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
700707
))
701708
}
702709
};
703-
Ok(OpTy { op, layout })
710+
Ok(OpTy { op, layout, align: Some(layout.align.abi) })
704711
}
705712

706713
/// Read discriminant, return the runtime value as well as the variant index.

0 commit comments

Comments
 (0)