@@ -354,6 +354,12 @@ impl<'tcx> std::fmt::Debug for ScalarTy<'tcx> {
354
354
}
355
355
}
356
356
357
+ impl<'tcx> ScalarTy<'tcx> {
358
+ pub fn can_const_prop(&self) -> bool {
359
+ self.0.try_to_int().is_ok()
360
+ }
361
+ }
362
+
357
363
impl<'a, 'm, 'tcx> ConstAnalysis<'a, 'm, 'tcx> {
358
364
pub fn new(tcx: TyCtxt<'tcx>, body: &'a Body<'tcx>, map: &'m Map) -> Self {
359
365
let param_env = tcx.param_env_reveal_all_normalized(body.source.def_id());
@@ -527,14 +533,10 @@ impl<'mir, 'tcx>
527
533
// Don't overwrite the assignment if it already uses a constant (to keep the span).
528
534
}
529
535
StatementKind::Assign(box (place, _)) => {
530
- match state.get(place.as_ref(), &results.analysis.0.map) {
531
- FlatSet::Top => (),
532
- FlatSet::Elem(value) => {
533
- self.assignments.insert(location, value);
534
- }
535
- FlatSet::Bottom => {
536
- // This assignment is either unreachable, or an uninitialized value is assigned.
537
- }
536
+ if let FlatSet::Elem(value) = state.get(place.as_ref(), results.analysis.0.map)
537
+ && value.can_const_prop()
538
+ {
539
+ self.assignments.insert(location, value);
538
540
}
539
541
}
540
542
_ => (),
@@ -560,6 +562,7 @@ impl<'tcx> MutVisitor<'tcx> for CollectAndPatch<'tcx> {
560
562
561
563
fn visit_statement(&mut self, statement: &mut Statement<'tcx>, location: Location) {
562
564
if let Some(value) = self.assignments.get(&location) {
565
+ assert!(value.can_const_prop(), "trying to propagate a pointer");
563
566
match &mut statement.kind {
564
567
StatementKind::Assign(box (_, rvalue)) => {
565
568
if !matches!(rvalue, Rvalue::Use(Operand::Constant(_))) {
@@ -578,6 +581,7 @@ impl<'tcx> MutVisitor<'tcx> for CollectAndPatch<'tcx> {
578
581
match operand {
579
582
Operand::Copy(place) | Operand::Move(place) => {
580
583
if let Some(value) = self.before_effect.get(&(location, *place)) {
584
+ assert!(value.can_const_prop(), "trying to propagate a pointer");
581
585
*operand = self.make_operand(value.clone());
582
586
} else if !place.projection.is_empty() {
583
587
self.super_operand(operand, location)
@@ -613,7 +617,9 @@ pub(crate) struct OperandCollector<'tcx, 'map, 'a> {
613
617
impl<'tcx, 'map, 'a> Visitor<'tcx> for OperandCollector<'tcx, 'map, 'a> {
614
618
fn visit_operand(&mut self, operand: &Operand<'tcx>, location: Location) {
615
619
if let Some(place) = operand.place() {
616
- if let FlatSet::Elem(value) = self.state.get(place.as_ref(), self.map) {
620
+ if let FlatSet::Elem(value) = self.state.get(place.as_ref(), self.map)
621
+ && value.can_const_prop()
622
+ {
617
623
self.visitor.before_effect.insert((location, place), value);
618
624
} else if !place.projection.is_empty() {
619
625
// Try to propagate into `Index` projections.
@@ -625,6 +631,7 @@ impl<'tcx, 'map, 'a> Visitor<'tcx> for OperandCollector<'tcx, 'map, 'a> {
625
631
fn visit_local(&mut self, local: Local, ctxt: PlaceContext, location: Location) {
626
632
if let PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy | NonMutatingUseContext::Move) = ctxt
627
633
&& let FlatSet::Elem(value) = self.state.get(local.into(), self.map)
634
+ && value.can_const_prop()
628
635
{
629
636
self.visitor.before_effect.insert((location, local.into()), value);
630
637
}
0 commit comments