1
Fork 0

Rollup merge of #120882 - RalfJung:set-discriminant, r=compiler-errors

interpret/write_discriminant: when encoding niched variant, ensure the stored value matches

Cc https://github.com/rust-lang/unsafe-code-guidelines/issues/487
This commit is contained in:
Matthias Krüger 2024-02-11 01:37:55 +01:00 committed by GitHub
commit e82e087582
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 71 additions and 0 deletions

View file

@ -497,6 +497,9 @@ impl<'a> ReportErrorExt for UndefinedBehaviorInfo<'a> {
ScalarSizeMismatch(_) => const_eval_scalar_size_mismatch,
UninhabitedEnumVariantWritten(_) => const_eval_uninhabited_enum_variant_written,
UninhabitedEnumVariantRead(_) => const_eval_uninhabited_enum_variant_read,
InvalidNichedEnumVariantWritten { .. } => {
const_eval_invalid_niched_enum_variant_written
}
AbiMismatchArgument { .. } => const_eval_incompatible_types,
AbiMismatchReturn { .. } => const_eval_incompatible_return_types,
}
@ -585,6 +588,9 @@ impl<'a> ReportErrorExt for UndefinedBehaviorInfo<'a> {
builder.arg("target_size", info.target_size);
builder.arg("data_size", info.data_size);
}
InvalidNichedEnumVariantWritten { enum_ty } => {
builder.arg("ty", enum_ty.to_string());
}
AbiMismatchArgument { caller_ty, callee_ty }
| AbiMismatchReturn { caller_ty, callee_ty } => {
builder.arg("caller_ty", caller_ty.to_string());

View file

@ -85,6 +85,14 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
// Write result.
let niche_dest = self.project_field(dest, tag_field)?;
self.write_immediate(*tag_val, &niche_dest)?;
} else {
// The untagged variant is implicitly encoded simply by having a value that is
// outside the niche variants. But what if the data stored here does not
// actually encode this variant? That would be bad! So let's double-check...
let actual_variant = self.read_discriminant(&dest.to_op(self)?)?;
if actual_variant != variant_index {
throw_ub!(InvalidNichedEnumVariantWritten { enum_ty: dest.layout().ty });
}
}
}
}