Skip to content

Commit 0451b74

Browse files
authored
Merge pull request rust-lang#108 from oli-obk/packd
implement packed struct field access
2 parents 29afc84 + 74d1a9a commit 0451b74

File tree

8 files changed

+191
-70
lines changed

8 files changed

+191
-70
lines changed

Cargo.lock

+46-55
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/eval_context.rs

+12
Original file line numberDiff line numberDiff line change
@@ -443,6 +443,10 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
443443
match *dest_layout {
444444
Univariant { ref variant, .. } => {
445445
let offsets = variant.offsets.iter().map(|s| s.bytes());
446+
if variant.packed {
447+
let ptr = self.force_allocation(dest)?.to_ptr_and_extra().0;
448+
self.memory.mark_packed(ptr, variant.stride().bytes());
449+
}
446450
self.assign_fields(dest, offsets, operands)?;
447451
}
448452

@@ -460,6 +464,10 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
460464
if let mir::AggregateKind::Adt(adt_def, variant, _, _) = *kind {
461465
let discr_val = adt_def.variants[variant].disr_val.to_u128_unchecked();
462466
let discr_size = discr.size().bytes();
467+
if variants[variant].packed {
468+
let ptr = self.force_allocation(dest)?.to_ptr_and_extra().0;
469+
self.memory.mark_packed(ptr, variants[variant].stride().bytes());
470+
}
463471

464472
self.assign_discr_and_fields(
465473
dest,
@@ -496,6 +504,10 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
496504

497505
StructWrappedNullablePointer { nndiscr, ref nonnull, ref discrfield, .. } => {
498506
if let mir::AggregateKind::Adt(_, variant, _, _) = *kind {
507+
if nonnull.packed {
508+
let ptr = self.force_allocation(dest)?.to_ptr_and_extra().0;
509+
self.memory.mark_packed(ptr, nonnull.stride().bytes());
510+
}
499511
if nndiscr == variant as u64 {
500512
let offsets = nonnull.offsets.iter().map(|s| s.bytes());
501513
self.assign_fields(dest, offsets, operands)?;

src/lvalue.rs

+13-5
Original file line numberDiff line numberDiff line change
@@ -173,13 +173,15 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
173173
let field = field.index();
174174

175175
use rustc::ty::layout::Layout::*;
176-
let offset = match *base_layout {
177-
Univariant { ref variant, .. } => variant.offsets[field],
176+
let (offset, packed) = match *base_layout {
177+
Univariant { ref variant, .. } => {
178+
(variant.offsets[field], variant.packed)
179+
},
178180

179181
General { ref variants, .. } => {
180182
if let LvalueExtra::DowncastVariant(variant_idx) = base_extra {
181183
// +1 for the discriminant, which is field 0
182-
variants[variant_idx].offsets[field + 1]
184+
(variants[variant_idx].offsets[field + 1], variants[variant_idx].packed)
183185
} else {
184186
bug!("field access on enum had no variant index");
185187
}
@@ -191,7 +193,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
191193
}
192194

193195
StructWrappedNullablePointer { ref nonnull, .. } => {
194-
nonnull.offsets[field]
196+
(nonnull.offsets[field], nonnull.packed)
195197
}
196198

197199
UntaggedUnion { .. } => return Ok(base),
@@ -200,13 +202,19 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
200202
let field = field as u64;
201203
assert!(field < count);
202204
let elem_size = element.size(&self.tcx.data_layout).bytes();
203-
Size::from_bytes(field * elem_size)
205+
(Size::from_bytes(field * elem_size), false)
204206
}
205207

206208
_ => bug!("field access on non-product type: {:?}", base_layout),
207209
};
208210

209211
let ptr = base_ptr.offset(offset.bytes());
212+
213+
if packed {
214+
let size = self.type_size(field_ty)?.expect("packed struct must be sized");
215+
self.memory.mark_packed(ptr, size);
216+
}
217+
210218
let extra = if self.type_is_sized(field_ty) {
211219
LvalueExtra::None
212220
} else {

0 commit comments

Comments
 (0)