mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-01 23:12:02 +00:00
codegen: assume constants cannot fail to evaluate
also don't submit code to LLVM when the session has errors
This commit is contained in:
parent
4d0dd02ee0
commit
944237f6cd
@ -625,6 +625,11 @@ pub fn codegen_crate<B: ExtraBackendMethods>(
|
||||
*time += start_time.elapsed();
|
||||
module
|
||||
};
|
||||
// This will unwind if there are errors, which triggers our `AbortCodegenOnDrop`
|
||||
// guard. Unfortunately, just skipping the `submit_codegened_module_to_llvm` makes
|
||||
// compilation hang on post-monomorphization errors.
|
||||
tcx.sess.abort_if_errors();
|
||||
|
||||
submit_codegened_module_to_llvm(
|
||||
&backend,
|
||||
&ongoing_codegen.coordinator_send,
|
||||
|
@ -188,8 +188,11 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
|
||||
|
||||
fx.per_local_var_debug_info = fx.compute_per_local_var_debug_info(&mut bx);
|
||||
|
||||
// Evaluate all required consts; codegen later assumes that CTFE will never fail.
|
||||
let mut all_consts_ok = true;
|
||||
for const_ in &mir.required_consts {
|
||||
if let Err(err) = fx.eval_mir_constant(const_) {
|
||||
all_consts_ok = false;
|
||||
match err {
|
||||
// errored or at least linted
|
||||
ErrorHandled::Reported(ErrorReported) | ErrorHandled::Linted => {}
|
||||
@ -199,6 +202,11 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
|
||||
}
|
||||
}
|
||||
}
|
||||
if !all_consts_ok {
|
||||
// We leave the IR in some half-built state here, and rely on this code not even being
|
||||
// submitted to LLVM once an error was raised.
|
||||
return;
|
||||
}
|
||||
|
||||
let memory_locals = analyze::non_ssa_locals(&fx);
|
||||
|
||||
|
@ -6,9 +6,8 @@ use crate::glue;
|
||||
use crate::traits::*;
|
||||
use crate::MemFlags;
|
||||
|
||||
use rustc_errors::ErrorReported;
|
||||
use rustc_middle::mir;
|
||||
use rustc_middle::mir::interpret::{ConstValue, ErrorHandled, Pointer, Scalar};
|
||||
use rustc_middle::mir::interpret::{ConstValue, Pointer, Scalar};
|
||||
use rustc_middle::ty::layout::TyAndLayout;
|
||||
use rustc_middle::ty::Ty;
|
||||
use rustc_target::abi::{Abi, Align, LayoutOf, Size};
|
||||
@ -439,25 +438,9 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
}
|
||||
|
||||
mir::Operand::Constant(ref constant) => {
|
||||
self.eval_mir_constant_to_operand(bx, constant).unwrap_or_else(|err| {
|
||||
match err {
|
||||
// errored or at least linted
|
||||
ErrorHandled::Reported(ErrorReported) | ErrorHandled::Linted => {}
|
||||
ErrorHandled::TooGeneric => {
|
||||
bug!("codegen encountered polymorphic constant")
|
||||
}
|
||||
}
|
||||
// Allow RalfJ to sleep soundly knowing that even refactorings that remove
|
||||
// the above error (or silence it under some conditions) will not cause UB.
|
||||
bx.abort();
|
||||
// We still have to return an operand but it doesn't matter,
|
||||
// this code is unreachable.
|
||||
let ty = self.monomorphize(constant.literal.ty);
|
||||
let layout = bx.cx().layout_of(ty);
|
||||
bx.load_operand(PlaceRef::new_sized(
|
||||
bx.cx().const_undef(bx.cx().type_ptr_to(bx.cx().backend_type(layout))),
|
||||
layout,
|
||||
))
|
||||
// This cannot fail because we checked all required_consts in advance.
|
||||
self.eval_mir_constant_to_operand(bx, constant).unwrap_or_else(|_err| {
|
||||
span_bug!(constant.span, "erroneous constant not captured by required_consts")
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -511,6 +511,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
Constant(ref constant) => {
|
||||
let val =
|
||||
self.subst_from_current_frame_and_normalize_erasing_regions(constant.literal);
|
||||
// This can still fail:
|
||||
// * During ConstProp, with `TooGeneric` or since the `requried_consts` were not all
|
||||
// checked yet.
|
||||
// * During CTFE, since promoteds in `const`/`static` initializer bodies can fail.
|
||||
self.const_to_op(val, layout)?
|
||||
}
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user