diff options
| author | Ralf Jung <post@ralfj.de> | 2024-02-10 15:26:55 +0100 |
|---|---|---|
| committer | Ralf Jung <post@ralfj.de> | 2024-02-10 15:33:58 +0100 |
| commit | 18ed966ab565fab3344dd7dad96e4490f99a1a13 (patch) | |
| tree | b07ec7a6c3db4e055fe09f9d7a12e522f815c67d /compiler/rustc_const_eval/src | |
| parent | 0809f78c190eb9fdf36353d423147827610f33c9 (diff) | |
interpret/write_discriminant: when encoding niched variant, ensure the stored value matches
Diffstat (limited to 'compiler/rustc_const_eval/src')
| -rw-r--r-- | compiler/rustc_const_eval/src/errors.rs | 6 | ||||
| -rw-r--r-- | compiler/rustc_const_eval/src/interpret/discriminant.rs | 8 |
2 files changed, 14 insertions, 0 deletions
diff --git a/compiler/rustc_const_eval/src/errors.rs b/compiler/rustc_const_eval/src/errors.rs index 4d2b1ba3eec..c8fdb06d291 100644 --- a/compiler/rustc_const_eval/src/errors.rs +++ b/compiler/rustc_const_eval/src/errors.rs @@ -509,6 +509,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, } @@ -597,6 +600,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()); diff --git a/compiler/rustc_const_eval/src/interpret/discriminant.rs b/compiler/rustc_const_eval/src/interpret/discriminant.rs index bb8c17cf779..e951a77611c 100644 --- a/compiler/rustc_const_eval/src/interpret/discriminant.rs +++ b/compiler/rustc_const_eval/src/interpret/discriminant.rs @@ -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 }); + } } } } |
