Rollup merge of #89370 - RalfJung:ctfe-aggregate-rvalue, r=oli-obk

CTFE: tweak aggregate rvalue handling

I have not looked at this code in ages... I think Miri does not even hit it, since (most?) aggregate rvalues are lowered somewhere in the MIR pipeline, but CTFE does hit it.

So this adds some extra sanity assertions, and removes a ZST special case -- ZST should only be special cased fairly late (when the actual memory access happens); e.g. `!` is a ZST and we still want `copy_op` to be called for it since it will perform validation (and raise UB, since `!` is never valid).
This commit is contained in:
Manish Goregaokar 2021-09-30 18:05:26 -07:00 committed by GitHub
commit 4661464961
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -197,12 +197,17 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
}
Aggregate(ref kind, ref operands) => {
// active_field_index is for union initialization.
let (dest, active_field_index) = match **kind {
mir::AggregateKind::Adt(adt_def, variant_index, _, _, active_field_index) => {
self.write_discriminant(variant_index, &dest)?;
if adt_def.is_enum() {
(self.place_downcast(&dest, variant_index)?, active_field_index)
assert!(active_field_index.is_none());
(self.place_downcast(&dest, variant_index)?, None)
} else {
if active_field_index.is_some() {
assert_eq!(operands.len(), 1);
}
(dest, active_field_index)
}
}
@ -211,14 +216,11 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
for (i, operand) in operands.iter().enumerate() {
let op = self.eval_operand(operand, None)?;
// Ignore zero-sized fields.
if !op.layout.is_zst() {
let field_index = active_field_index.unwrap_or(i);
let field_dest = self.place_field(&dest, field_index)?;
self.copy_op(&op, &field_dest)?;
}
}
}
Repeat(ref operand, _) => {
let src = self.eval_operand(operand, None)?;
@ -253,7 +255,6 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
}
Len(place) => {
// FIXME(CTFE): don't allow computing the length of arrays in const eval
let src = self.eval_place(place)?;
let mplace = self.force_allocation(&src)?;
let len = mplace.len(self)?;