Skip to content

Commit 9669e57

Browse files
committed
Auto merge of #2793 - RalfJung:rustup, r=RalfJung
Rustup
2 parents 610dbcb + d1a2425 commit 9669e57

File tree

125 files changed

+2459
-804
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

125 files changed

+2459
-804
lines changed

compiler/rustc_codegen_cranelift/src/base.rs

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -347,7 +347,12 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) {
347347
}
348348
TerminatorKind::Assert { cond, expected, msg, target, cleanup: _ } => {
349349
if !fx.tcx.sess.overflow_checks() {
350-
if let mir::AssertKind::OverflowNeg(_) = *msg {
350+
let overflow_not_to_check = match msg {
351+
AssertKind::OverflowNeg(..) => true,
352+
AssertKind::Overflow(op, ..) => op.is_checkable(),
353+
_ => false,
354+
};
355+
if overflow_not_to_check {
351356
let target = fx.get_block(*target);
352357
fx.bcx.ins().jump(target, &[]);
353358
continue;
@@ -567,15 +572,7 @@ fn codegen_stmt<'tcx>(
567572
let lhs = codegen_operand(fx, &lhs_rhs.0);
568573
let rhs = codegen_operand(fx, &lhs_rhs.1);
569574

570-
let res = if !fx.tcx.sess.overflow_checks() {
571-
let val =
572-
crate::num::codegen_int_binop(fx, bin_op, lhs, rhs).load_scalar(fx);
573-
let is_overflow = fx.bcx.ins().iconst(types::I8, 0);
574-
CValue::by_val_pair(val, is_overflow, lval.layout())
575-
} else {
576-
crate::num::codegen_checked_int_binop(fx, bin_op, lhs, rhs)
577-
};
578-
575+
let res = crate::num::codegen_checked_int_binop(fx, bin_op, lhs, rhs);
579576
lval.write_cvalue(fx, res);
580577
}
581578
Rvalue::UnaryOp(un_op, ref operand) => {

compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -493,20 +493,6 @@ fn codegen_regular_intrinsic_call<'tcx>(
493493
let res = crate::num::codegen_int_binop(fx, bin_op, x, y);
494494
ret.write_cvalue(fx, res);
495495
}
496-
sym::add_with_overflow | sym::sub_with_overflow | sym::mul_with_overflow => {
497-
intrinsic_args!(fx, args => (x, y); intrinsic);
498-
499-
assert_eq!(x.layout().ty, y.layout().ty);
500-
let bin_op = match intrinsic {
501-
sym::add_with_overflow => BinOp::Add,
502-
sym::sub_with_overflow => BinOp::Sub,
503-
sym::mul_with_overflow => BinOp::Mul,
504-
_ => unreachable!(),
505-
};
506-
507-
let res = crate::num::codegen_checked_int_binop(fx, bin_op, x, y);
508-
ret.write_cvalue(fx, res);
509-
}
510496
sym::saturating_add | sym::saturating_sub => {
511497
intrinsic_args!(fx, args => (lhs, rhs); intrinsic);
512498

compiler/rustc_codegen_llvm/src/type_of.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,7 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyAndLayout<'tcx> {
329329
) -> &'a Type {
330330
// HACK(eddyb) special-case fat pointers until LLVM removes
331331
// pointee types, to avoid bitcasting every `OperandRef::deref`.
332-
match self.ty.kind() {
332+
match *self.ty.kind() {
333333
ty::Ref(..) | ty::RawPtr(_) => {
334334
return self.field(cx, index).llvm_type(cx);
335335
}
@@ -339,6 +339,11 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyAndLayout<'tcx> {
339339
let ptr_ty = cx.tcx.mk_mut_ptr(self.ty.boxed_ty());
340340
return cx.layout_of(ptr_ty).scalar_pair_element_llvm_type(cx, index, immediate);
341341
}
342+
// `dyn* Trait` has the same ABI as `*mut dyn Trait`
343+
ty::Dynamic(bounds, region, ty::DynStar) => {
344+
let ptr_ty = cx.tcx.mk_mut_ptr(cx.tcx.mk_dynamic(bounds, region, ty::Dyn));
345+
return cx.layout_of(ptr_ty).scalar_pair_element_llvm_type(cx, index, immediate);
346+
}
342347
_ => {}
343348
}
344349

compiler/rustc_codegen_ssa/src/base.rs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ use rustc_session::Session;
3939
use rustc_span::symbol::sym;
4040
use rustc_span::Symbol;
4141
use rustc_span::{DebuggerVisualizerFile, DebuggerVisualizerType};
42-
use rustc_target::abi::{Align, Size, VariantIdx};
42+
use rustc_target::abi::{Align, VariantIdx};
4343

4444
use std::collections::BTreeSet;
4545
use std::time::{Duration, Instant};
@@ -273,12 +273,13 @@ pub fn cast_to_dyn_star<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
273273
matches!(dst_ty.kind(), ty::Dynamic(_, _, ty::DynStar)),
274274
"destination type must be a dyn*"
275275
);
276-
// FIXME(dyn-star): this is probably not the best way to check if this is
277-
// a pointer, and really we should ensure that the value is a suitable
278-
// pointer earlier in the compilation process.
279-
let src = match src_ty_and_layout.pointee_info_at(bx.cx(), Size::ZERO) {
280-
Some(_) => bx.ptrtoint(src, bx.cx().type_isize()),
281-
None => bx.bitcast(src, bx.type_isize()),
276+
// FIXME(dyn-star): We can remove this when all supported LLVMs use opaque ptrs only.
277+
let unit_ptr = bx.cx().type_ptr_to(bx.cx().type_struct(&[], false));
278+
let src = match bx.cx().type_kind(bx.cx().backend_type(src_ty_and_layout)) {
279+
TypeKind::Pointer => bx.pointercast(src, unit_ptr),
280+
TypeKind::Integer => bx.inttoptr(src, unit_ptr),
281+
// FIXME(dyn-star): We probably have to do a bitcast first, then inttoptr.
282+
kind => bug!("unexpected TypeKind for left-hand side of `dyn*` cast: {kind:?}"),
282283
};
283284
(src, unsized_info(bx, src_ty_and_layout.ty, dst_ty, old_info))
284285
}

compiler/rustc_codegen_ssa/src/mir/block.rs

Lines changed: 85 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -452,86 +452,84 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
452452
args1 = [place.llval];
453453
&args1[..]
454454
};
455-
let (drop_fn, fn_abi) = match ty.kind() {
456-
// FIXME(eddyb) perhaps move some of this logic into
457-
// `Instance::resolve_drop_in_place`?
458-
ty::Dynamic(_, _, ty::Dyn) => {
459-
// IN THIS ARM, WE HAVE:
460-
// ty = *mut (dyn Trait)
461-
// which is: exists<T> ( *mut T, Vtable<T: Trait> )
462-
// args[0] args[1]
463-
//
464-
// args = ( Data, Vtable )
465-
// |
466-
// v
467-
// /-------\
468-
// | ... |
469-
// \-------/
470-
//
471-
let virtual_drop = Instance {
472-
def: ty::InstanceDef::Virtual(drop_fn.def_id(), 0),
473-
substs: drop_fn.substs,
474-
};
475-
debug!("ty = {:?}", ty);
476-
debug!("drop_fn = {:?}", drop_fn);
477-
debug!("args = {:?}", args);
478-
let fn_abi = bx.fn_abi_of_instance(virtual_drop, ty::List::empty());
479-
let vtable = args[1];
480-
// Truncate vtable off of args list
481-
args = &args[..1];
482-
(
483-
meth::VirtualIndex::from_index(ty::COMMON_VTABLE_ENTRIES_DROPINPLACE)
484-
.get_fn(bx, vtable, ty, &fn_abi),
485-
fn_abi,
486-
)
487-
}
488-
ty::Dynamic(_, _, ty::DynStar) => {
489-
// IN THIS ARM, WE HAVE:
490-
// ty = *mut (dyn* Trait)
491-
// which is: *mut exists<T: sizeof(T) == sizeof(usize)> (T, Vtable<T: Trait>)
492-
//
493-
// args = [ * ]
494-
// |
495-
// v
496-
// ( Data, Vtable )
497-
// |
498-
// v
499-
// /-------\
500-
// | ... |
501-
// \-------/
502-
//
503-
//
504-
// WE CAN CONVERT THIS INTO THE ABOVE LOGIC BY DOING
505-
//
506-
// data = &(*args[0]).0 // gives a pointer to Data above (really the same pointer)
507-
// vtable = (*args[0]).1 // loads the vtable out
508-
// (data, vtable) // an equivalent Rust `*mut dyn Trait`
509-
//
510-
// SO THEN WE CAN USE THE ABOVE CODE.
511-
let virtual_drop = Instance {
512-
def: ty::InstanceDef::Virtual(drop_fn.def_id(), 0),
513-
substs: drop_fn.substs,
514-
};
515-
debug!("ty = {:?}", ty);
516-
debug!("drop_fn = {:?}", drop_fn);
517-
debug!("args = {:?}", args);
518-
let fn_abi = bx.fn_abi_of_instance(virtual_drop, ty::List::empty());
519-
let data = args[0];
520-
let data_ty = bx.cx().backend_type(place.layout);
521-
let vtable_ptr =
522-
bx.gep(data_ty, data, &[bx.cx().const_i32(0), bx.cx().const_i32(1)]);
523-
let vtable = bx.load(bx.type_i8p(), vtable_ptr, abi::Align::ONE);
524-
// Truncate vtable off of args list
525-
args = &args[..1];
526-
debug!("args' = {:?}", args);
527-
(
528-
meth::VirtualIndex::from_index(ty::COMMON_VTABLE_ENTRIES_DROPINPLACE)
529-
.get_fn(bx, vtable, ty, &fn_abi),
530-
fn_abi,
531-
)
532-
}
533-
_ => (bx.get_fn_addr(drop_fn), bx.fn_abi_of_instance(drop_fn, ty::List::empty())),
534-
};
455+
let (drop_fn, fn_abi) =
456+
match ty.kind() {
457+
// FIXME(eddyb) perhaps move some of this logic into
458+
// `Instance::resolve_drop_in_place`?
459+
ty::Dynamic(_, _, ty::Dyn) => {
460+
// IN THIS ARM, WE HAVE:
461+
// ty = *mut (dyn Trait)
462+
// which is: exists<T> ( *mut T, Vtable<T: Trait> )
463+
// args[0] args[1]
464+
//
465+
// args = ( Data, Vtable )
466+
// |
467+
// v
468+
// /-------\
469+
// | ... |
470+
// \-------/
471+
//
472+
let virtual_drop = Instance {
473+
def: ty::InstanceDef::Virtual(drop_fn.def_id(), 0),
474+
substs: drop_fn.substs,
475+
};
476+
debug!("ty = {:?}", ty);
477+
debug!("drop_fn = {:?}", drop_fn);
478+
debug!("args = {:?}", args);
479+
let fn_abi = bx.fn_abi_of_instance(virtual_drop, ty::List::empty());
480+
let vtable = args[1];
481+
// Truncate vtable off of args list
482+
args = &args[..1];
483+
(
484+
meth::VirtualIndex::from_index(ty::COMMON_VTABLE_ENTRIES_DROPINPLACE)
485+
.get_fn(bx, vtable, ty, &fn_abi),
486+
fn_abi,
487+
)
488+
}
489+
ty::Dynamic(_, _, ty::DynStar) => {
490+
// IN THIS ARM, WE HAVE:
491+
// ty = *mut (dyn* Trait)
492+
// which is: *mut exists<T: sizeof(T) == sizeof(usize)> (T, Vtable<T: Trait>)
493+
//
494+
// args = [ * ]
495+
// |
496+
// v
497+
// ( Data, Vtable )
498+
// |
499+
// v
500+
// /-------\
501+
// | ... |
502+
// \-------/
503+
//
504+
//
505+
// WE CAN CONVERT THIS INTO THE ABOVE LOGIC BY DOING
506+
//
507+
// data = &(*args[0]).0 // gives a pointer to Data above (really the same pointer)
508+
// vtable = (*args[0]).1 // loads the vtable out
509+
// (data, vtable) // an equivalent Rust `*mut dyn Trait`
510+
//
511+
// SO THEN WE CAN USE THE ABOVE CODE.
512+
let virtual_drop = Instance {
513+
def: ty::InstanceDef::Virtual(drop_fn.def_id(), 0),
514+
substs: drop_fn.substs,
515+
};
516+
debug!("ty = {:?}", ty);
517+
debug!("drop_fn = {:?}", drop_fn);
518+
debug!("args = {:?}", args);
519+
let fn_abi = bx.fn_abi_of_instance(virtual_drop, ty::List::empty());
520+
let meta_ptr = place.project_field(bx, 1);
521+
let meta = bx.load_operand(meta_ptr);
522+
// Truncate vtable off of args list
523+
args = &args[..1];
524+
debug!("args' = {:?}", args);
525+
(
526+
meth::VirtualIndex::from_index(ty::COMMON_VTABLE_ENTRIES_DROPINPLACE)
527+
.get_fn(bx, meta.immediate(), ty, &fn_abi),
528+
fn_abi,
529+
)
530+
}
531+
_ => (bx.get_fn_addr(drop_fn), bx.fn_abi_of_instance(drop_fn, ty::List::empty())),
532+
};
535533
helper.do_call(
536534
self,
537535
bx,
@@ -565,11 +563,13 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
565563
// with #[rustc_inherit_overflow_checks] and inlined from
566564
// another crate (mostly core::num generic/#[inline] fns),
567565
// while the current crate doesn't use overflow checks.
568-
// NOTE: Unlike binops, negation doesn't have its own
569-
// checked operation, just a comparison with the minimum
570-
// value, so we have to check for the assert message.
571-
if !bx.check_overflow() {
572-
if let AssertKind::OverflowNeg(_) = *msg {
566+
if !bx.cx().check_overflow() {
567+
let overflow_not_to_check = match msg {
568+
AssertKind::OverflowNeg(..) => true,
569+
AssertKind::Overflow(op, ..) => op.is_checkable(),
570+
_ => false,
571+
};
572+
if overflow_not_to_check {
573573
const_cond = Some(expected);
574574
}
575575
}

compiler/rustc_codegen_ssa/src/mir/intrinsic.rs

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -218,9 +218,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
218218
args[1].val.unaligned_volatile_store(bx, dst);
219219
return;
220220
}
221-
sym::add_with_overflow
222-
| sym::sub_with_overflow
223-
| sym::mul_with_overflow
224221
| sym::unchecked_div
225222
| sym::unchecked_rem
226223
| sym::unchecked_shl
@@ -232,28 +229,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
232229
let ty = arg_tys[0];
233230
match int_type_width_signed(ty, bx.tcx()) {
234231
Some((_width, signed)) => match name {
235-
sym::add_with_overflow
236-
| sym::sub_with_overflow
237-
| sym::mul_with_overflow => {
238-
let op = match name {
239-
sym::add_with_overflow => OverflowOp::Add,
240-
sym::sub_with_overflow => OverflowOp::Sub,
241-
sym::mul_with_overflow => OverflowOp::Mul,
242-
_ => bug!(),
243-
};
244-
let (val, overflow) =
245-
bx.checked_binop(op, ty, args[0].immediate(), args[1].immediate());
246-
// Convert `i1` to a `bool`, and write it to the out parameter
247-
let val = bx.from_immediate(val);
248-
let overflow = bx.from_immediate(overflow);
249-
250-
let dest = result.project_field(bx, 0);
251-
bx.store(val, dest.llval, dest.align);
252-
let dest = result.project_field(bx, 1);
253-
bx.store(overflow, dest.llval, dest.align);
254-
255-
return;
256-
}
257232
sym::exact_div => {
258233
if signed {
259234
bx.exactsdiv(args[0].immediate(), args[1].immediate())

compiler/rustc_codegen_ssa/src/mir/rvalue.rs

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -652,15 +652,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
652652
rhs: Bx::Value,
653653
input_ty: Ty<'tcx>,
654654
) -> OperandValue<Bx::Value> {
655-
// This case can currently arise only from functions marked
656-
// with #[rustc_inherit_overflow_checks] and inlined from
657-
// another crate (mostly core::num generic/#[inline] fns),
658-
// while the current crate doesn't use overflow checks.
659-
if !bx.cx().check_overflow() {
660-
let val = self.codegen_scalar_binop(bx, op, lhs, rhs, input_ty);
661-
return OperandValue::Pair(val, bx.cx().const_bool(false));
662-
}
663-
664655
let (val, of) = match op {
665656
// These are checked using intrinsics
666657
mir::BinOp::Add | mir::BinOp::Sub | mir::BinOp::Mul => {

compiler/rustc_const_eval/src/interpret/intrinsics.rs

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -210,19 +210,6 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
210210
let out_val = numeric_intrinsic(intrinsic_name, bits, kind);
211211
self.write_scalar(out_val, dest)?;
212212
}
213-
sym::add_with_overflow | sym::sub_with_overflow | sym::mul_with_overflow => {
214-
let lhs = self.read_immediate(&args[0])?;
215-
let rhs = self.read_immediate(&args[1])?;
216-
let bin_op = match intrinsic_name {
217-
sym::add_with_overflow => BinOp::Add,
218-
sym::sub_with_overflow => BinOp::Sub,
219-
sym::mul_with_overflow => BinOp::Mul,
220-
_ => bug!(),
221-
};
222-
self.binop_with_overflow(
223-
bin_op, /*force_overflow_checks*/ true, &lhs, &rhs, dest,
224-
)?;
225-
}
226213
sym::saturating_add | sym::saturating_sub => {
227214
let l = self.read_immediate(&args[0])?;
228215
let r = self.read_immediate(&args[1])?;

compiler/rustc_const_eval/src/interpret/machine.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -147,8 +147,9 @@ pub trait Machine<'mir, 'tcx>: Sized {
147147
true
148148
}
149149

150-
/// Whether CheckedBinOp MIR statements should actually check for overflow.
151-
fn checked_binop_checks_overflow(_ecx: &InterpCx<'mir, 'tcx, Self>) -> bool;
150+
/// Whether Assert(OverflowNeg) and Assert(Overflow) MIR terminators should actually
151+
/// check for overflow.
152+
fn ignore_checkable_overflow_assertions(_ecx: &InterpCx<'mir, 'tcx, Self>) -> bool;
152153

153154
/// Entry point for obtaining the MIR of anything that should get evaluated.
154155
/// So not just functions and shims, but also const/static initializers, anonymous
@@ -466,8 +467,8 @@ pub macro compile_time_machine(<$mir: lifetime, $tcx: lifetime>) {
466467
}
467468

468469
#[inline(always)]
469-
fn checked_binop_checks_overflow(_ecx: &InterpCx<$mir, $tcx, Self>) -> bool {
470-
true
470+
fn ignore_checkable_overflow_assertions(_ecx: &InterpCx<$mir, $tcx, Self>) -> bool {
471+
false
471472
}
472473

473474
#[inline(always)]

0 commit comments

Comments
 (0)