Use the correct place for enum variants.
This commit is contained in:
parent
7213eaa1c0
commit
efb468866e
2 changed files with 18 additions and 8 deletions
|
@ -134,18 +134,21 @@ impl<'tcx> ValueAnalysis<'tcx> for ConstAnalysis<'_, 'tcx> {
|
||||||
AggregateKind::Adt(def_id, variant_index, ..) => {
|
AggregateKind::Adt(def_id, variant_index, ..) => {
|
||||||
match self.tcx.def_kind(def_id) {
|
match self.tcx.def_kind(def_id) {
|
||||||
DefKind::Struct => (Some(target_idx), None),
|
DefKind::Struct => (Some(target_idx), None),
|
||||||
DefKind::Enum => (Some(target_idx), Some(variant_index)),
|
DefKind::Enum => (
|
||||||
|
self.map.apply(target_idx, TrackElem::Variant(variant_index)),
|
||||||
|
Some(variant_index),
|
||||||
|
),
|
||||||
_ => (None, None),
|
_ => (None, None),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => (None, None),
|
_ => (None, None),
|
||||||
};
|
};
|
||||||
if let Some(target) = variant_target {
|
if let Some(variant_target_idx) = variant_target {
|
||||||
for (field_index, operand) in operands.iter().enumerate() {
|
for (field_index, operand) in operands.iter().enumerate() {
|
||||||
if let Some(field) = self
|
if let Some(field) = self.map().apply(
|
||||||
.map()
|
variant_target_idx,
|
||||||
.apply(target, TrackElem::Field(Field::from_usize(field_index)))
|
TrackElem::Field(Field::from_usize(field_index)),
|
||||||
{
|
) {
|
||||||
let result = self.handle_operand(operand, state);
|
let result = self.handle_operand(operand, state);
|
||||||
state.insert_idx(field, result, self.map());
|
state.insert_idx(field, result, self.map());
|
||||||
}
|
}
|
||||||
|
@ -154,6 +157,11 @@ impl<'tcx> ValueAnalysis<'tcx> for ConstAnalysis<'_, 'tcx> {
|
||||||
if let Some(variant_index) = variant_index
|
if let Some(variant_index) = variant_index
|
||||||
&& let Some(discr_idx) = self.map().apply(target_idx, TrackElem::Discriminant)
|
&& let Some(discr_idx) = self.map().apply(target_idx, TrackElem::Discriminant)
|
||||||
{
|
{
|
||||||
|
// We are assigning the discriminant as part of an aggregate.
|
||||||
|
// This discriminant can only alias a variant field's value if the operand
|
||||||
|
// had an invalid value for that type.
|
||||||
|
// Using invalid values is UB, so we are allowed to perform the assignment
|
||||||
|
// without extra flooding.
|
||||||
let enum_ty = target.ty(self.local_decls, self.tcx).ty;
|
let enum_ty = target.ty(self.local_decls, self.tcx).ty;
|
||||||
if let Some(discr_val) = self.eval_discriminant(enum_ty, variant_index) {
|
if let Some(discr_val) = self.eval_discriminant(enum_ty, variant_index) {
|
||||||
state.insert_value_idx(discr_idx, FlatSet::Elem(discr_val), &self.map);
|
state.insert_value_idx(discr_idx, FlatSet::Elem(discr_val), &self.map);
|
||||||
|
|
|
@ -45,8 +45,10 @@
|
||||||
|
|
||||||
bb3: {
|
bb3: {
|
||||||
StorageLive(_4); // scope 1 at $DIR/enum.rs:+2:29: +2:30
|
StorageLive(_4); // scope 1 at $DIR/enum.rs:+2:29: +2:30
|
||||||
_4 = ((_1 as V1).0: i32); // scope 1 at $DIR/enum.rs:+2:29: +2:30
|
- _4 = ((_1 as V1).0: i32); // scope 1 at $DIR/enum.rs:+2:29: +2:30
|
||||||
_2 = _4; // scope 3 at $DIR/enum.rs:+2:35: +2:36
|
- _2 = _4; // scope 3 at $DIR/enum.rs:+2:35: +2:36
|
||||||
|
+ _4 = const 0_i32; // scope 1 at $DIR/enum.rs:+2:29: +2:30
|
||||||
|
+ _2 = const 0_i32; // scope 3 at $DIR/enum.rs:+2:35: +2:36
|
||||||
StorageDead(_4); // scope 1 at $DIR/enum.rs:+2:35: +2:36
|
StorageDead(_4); // scope 1 at $DIR/enum.rs:+2:35: +2:36
|
||||||
goto -> bb4; // scope 1 at $DIR/enum.rs:+2:35: +2:36
|
goto -> bb4; // scope 1 at $DIR/enum.rs:+2:35: +2:36
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue