Auto merge of #38989 - arielb1:constant-mir-overflow2, r=eddyb
fix function arguments in constant promotion we can't create the target block until *after* we promote the arguments - otherwise the arguments will be promoted into the target block. oops. Fixes #38985. This is a regression introduced in the beta-nominated #38833, so beta-nominating this one too (sorry @brson). r? @eddyb
This commit is contained in:
commit
513d942a7e
@ -237,7 +237,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
|
|||||||
self.visit_rvalue(&mut rvalue, loc);
|
self.visit_rvalue(&mut rvalue, loc);
|
||||||
self.assign(new_temp, rvalue, source_info.span);
|
self.assign(new_temp, rvalue, source_info.span);
|
||||||
} else {
|
} else {
|
||||||
let mut terminator = if self.keep_original {
|
let terminator = if self.keep_original {
|
||||||
self.source[loc.block].terminator().clone()
|
self.source[loc.block].terminator().clone()
|
||||||
} else {
|
} else {
|
||||||
let terminator = self.source[loc.block].terminator_mut();
|
let terminator = self.source[loc.block].terminator_mut();
|
||||||
@ -255,28 +255,30 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let last = self.promoted.basic_blocks().last().unwrap();
|
match terminator.kind {
|
||||||
let new_target = self.new_block();
|
|
||||||
|
|
||||||
terminator.kind = match terminator.kind {
|
|
||||||
TerminatorKind::Call { mut func, mut args, .. } => {
|
TerminatorKind::Call { mut func, mut args, .. } => {
|
||||||
self.visit_operand(&mut func, loc);
|
self.visit_operand(&mut func, loc);
|
||||||
for arg in &mut args {
|
for arg in &mut args {
|
||||||
self.visit_operand(arg, loc);
|
self.visit_operand(arg, loc);
|
||||||
}
|
}
|
||||||
TerminatorKind::Call {
|
|
||||||
func: func,
|
let last = self.promoted.basic_blocks().last().unwrap();
|
||||||
args: args,
|
let new_target = self.new_block();
|
||||||
cleanup: None,
|
|
||||||
destination: Some((Lvalue::Local(new_temp), new_target))
|
*self.promoted[last].terminator_mut() = Terminator {
|
||||||
}
|
kind: TerminatorKind::Call {
|
||||||
|
func: func,
|
||||||
|
args: args,
|
||||||
|
cleanup: None,
|
||||||
|
destination: Some((Lvalue::Local(new_temp), new_target))
|
||||||
|
},
|
||||||
|
..terminator
|
||||||
|
};
|
||||||
}
|
}
|
||||||
ref kind => {
|
ref kind => {
|
||||||
span_bug!(terminator.source_info.span, "{:?} not promotable", kind);
|
span_bug!(terminator.source_info.span, "{:?} not promotable", kind);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
*self.promoted[last].terminator_mut() = terminator;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
self.keep_original = old_keep_original;
|
self.keep_original = old_keep_original;
|
||||||
|
@ -14,7 +14,14 @@ const fn foo() -> i64 {
|
|||||||
3
|
3
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const fn bar(x: i64) -> i64 {
|
||||||
|
x*2
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let val = &(foo() % 2);
|
let val = &(foo() % 2);
|
||||||
assert_eq!(*val, 1);
|
assert_eq!(*val, 1);
|
||||||
|
|
||||||
|
let val2 = &(bar(1+1) % 3);
|
||||||
|
assert_eq!(*val2, 1);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user