Skip to content

Commit 542052d

Browse files
committed
Only allow propagating integers.
1 parent b365b5f commit 542052d

File tree

2 files changed

+17
-10
lines changed

2 files changed

+17
-10
lines changed

compiler/rustc_mir_transform/src/const_prop.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ impl<'tcx> MirPass<'tcx> for ConstProp {
135135
FlatSet::Top
136136
};
137137

138-
if let FlatSet::Elem(value) = value {
138+
if let FlatSet::Elem(value) = value && value.can_const_prop() {
139139
collector.assignments.insert(location, value);
140140
}
141141
}

compiler/rustc_mir_transform/src/dataflow_const_prop.rs

+16-9
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,12 @@ impl<'tcx> std::fmt::Debug for ScalarTy<'tcx> {
354354
}
355355
}
356356

357+
impl<'tcx> ScalarTy<'tcx> {
358+
pub fn can_const_prop(&self) -> bool {
359+
self.0.try_to_int().is_ok()
360+
}
361+
}
362+
357363
impl<'a, 'm, 'tcx> ConstAnalysis<'a, 'm, 'tcx> {
358364
pub fn new(tcx: TyCtxt<'tcx>, body: &'a Body<'tcx>, map: &'m Map) -> Self {
359365
let param_env = tcx.param_env_reveal_all_normalized(body.source.def_id());
@@ -527,14 +533,10 @@ impl<'mir, 'tcx>
527533
// Don't overwrite the assignment if it already uses a constant (to keep the span).
528534
}
529535
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);
538540
}
539541
}
540542
_ => (),
@@ -560,6 +562,7 @@ impl<'tcx> MutVisitor<'tcx> for CollectAndPatch<'tcx> {
560562

561563
fn visit_statement(&mut self, statement: &mut Statement<'tcx>, location: Location) {
562564
if let Some(value) = self.assignments.get(&location) {
565+
assert!(value.can_const_prop(), "trying to propagate a pointer");
563566
match &mut statement.kind {
564567
StatementKind::Assign(box (_, rvalue)) => {
565568
if !matches!(rvalue, Rvalue::Use(Operand::Constant(_))) {
@@ -578,6 +581,7 @@ impl<'tcx> MutVisitor<'tcx> for CollectAndPatch<'tcx> {
578581
match operand {
579582
Operand::Copy(place) | Operand::Move(place) => {
580583
if let Some(value) = self.before_effect.get(&(location, *place)) {
584+
assert!(value.can_const_prop(), "trying to propagate a pointer");
581585
*operand = self.make_operand(value.clone());
582586
} else if !place.projection.is_empty() {
583587
self.super_operand(operand, location)
@@ -613,7 +617,9 @@ pub(crate) struct OperandCollector<'tcx, 'map, 'a> {
613617
impl<'tcx, 'map, 'a> Visitor<'tcx> for OperandCollector<'tcx, 'map, 'a> {
614618
fn visit_operand(&mut self, operand: &Operand<'tcx>, location: Location) {
615619
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+
{
617623
self.visitor.before_effect.insert((location, place), value);
618624
} else if !place.projection.is_empty() {
619625
// Try to propagate into `Index` projections.
@@ -625,6 +631,7 @@ impl<'tcx, 'map, 'a> Visitor<'tcx> for OperandCollector<'tcx, 'map, 'a> {
625631
fn visit_local(&mut self, local: Local, ctxt: PlaceContext, location: Location) {
626632
if let PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy | NonMutatingUseContext::Move) = ctxt
627633
&& let FlatSet::Elem(value) = self.state.get(local.into(), self.map)
634+
&& value.can_const_prop()
628635
{
629636
self.visitor.before_effect.insert((location, local.into()), value);
630637
}

0 commit comments

Comments
 (0)