Auto merge of #127995 - workingjubilee:say-turings-prayer, r=BoxyUwU
compiler: Never debug_assert in codegen In the name of Turing and his Hoarey heralds, assert our truths before creating a monster! The `rustc_codegen_llvm` and `rustc_codegen_ssa` crates are fairly critical for rustc's correctness. Small mistakes here can easily result in undefined behavior, since a "small mistake" can mean something like "link and execute the wrong code". We should probably run any and all asserts in these modules unconditionally on whether this is a "debug build", and damn the costs in performance. ...Especially because the costs in performance seem to be *nothing*. It is not clear how much correctness we gain here, but I'll take free correctness improvements.
This commit is contained in:
commit
28e684b470
16 changed files with 57 additions and 65 deletions
|
@ -330,7 +330,7 @@ impl<'ll> CodegenCx<'ll, '_> {
|
|||
|
||||
// If this assertion triggers, there's something wrong with commandline
|
||||
// argument validation.
|
||||
debug_assert!(
|
||||
assert!(
|
||||
!(self.tcx.sess.opts.cg.linker_plugin_lto.enabled()
|
||||
&& self.tcx.sess.target.is_like_windows
|
||||
&& self.tcx.sess.opts.cg.prefer_dynamic)
|
||||
|
|
|
@ -170,7 +170,7 @@ fn build_pointer_or_reference_di_node<'ll, 'tcx>(
|
|||
) -> DINodeCreationResult<'ll> {
|
||||
// The debuginfo generated by this function is only valid if `ptr_type` is really just
|
||||
// a (fat) pointer. Make sure it is not called for e.g. `Box<T, NonZSTAllocator>`.
|
||||
debug_assert_eq!(
|
||||
assert_eq!(
|
||||
cx.size_and_align_of(ptr_type),
|
||||
cx.size_and_align_of(Ty::new_mut_ptr(cx.tcx, pointee_type))
|
||||
);
|
||||
|
@ -185,7 +185,7 @@ fn build_pointer_or_reference_di_node<'ll, 'tcx>(
|
|||
match fat_pointer_kind(cx, pointee_type) {
|
||||
None => {
|
||||
// This is a thin pointer. Create a regular pointer type and give it the correct name.
|
||||
debug_assert_eq!(
|
||||
assert_eq!(
|
||||
(data_layout.pointer_size, data_layout.pointer_align.abi),
|
||||
cx.size_and_align_of(ptr_type),
|
||||
"ptr_type={ptr_type}, pointee_type={pointee_type}",
|
||||
|
@ -240,8 +240,8 @@ fn build_pointer_or_reference_di_node<'ll, 'tcx>(
|
|||
FatPtrKind::Slice => ("data_ptr", "length"),
|
||||
};
|
||||
|
||||
debug_assert_eq!(abi::FAT_PTR_ADDR, 0);
|
||||
debug_assert_eq!(abi::FAT_PTR_EXTRA, 1);
|
||||
assert_eq!(abi::FAT_PTR_ADDR, 0);
|
||||
assert_eq!(abi::FAT_PTR_EXTRA, 1);
|
||||
|
||||
// The data pointer type is a regular, thin pointer, regardless of whether this
|
||||
// is a slice or a trait object.
|
||||
|
@ -498,7 +498,7 @@ pub fn type_di_node<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, t: Ty<'tcx>) -> &'ll D
|
|||
}
|
||||
};
|
||||
|
||||
debug_assert_eq!(di_node_for_uid as *const _, di_node as *const _);
|
||||
assert_eq!(di_node_for_uid as *const _, di_node as *const _);
|
||||
} else {
|
||||
debug_context(cx).type_map.insert(unique_type_id, di_node);
|
||||
}
|
||||
|
@ -1060,7 +1060,7 @@ fn build_struct_type_di_node<'ll, 'tcx>(
|
|||
let ty::Adt(adt_def, _) = struct_type.kind() else {
|
||||
bug!("build_struct_type_di_node() called with non-struct-type: {:?}", struct_type);
|
||||
};
|
||||
debug_assert!(adt_def.is_struct());
|
||||
assert!(adt_def.is_struct());
|
||||
let containing_scope = get_namespace_for_item(cx, adt_def.did());
|
||||
let struct_type_and_layout = cx.layout_of(struct_type);
|
||||
let variant_def = adt_def.non_enum_variant();
|
||||
|
@ -1130,7 +1130,7 @@ fn build_upvar_field_di_nodes<'ll, 'tcx>(
|
|||
}
|
||||
};
|
||||
|
||||
debug_assert!(
|
||||
assert!(
|
||||
up_var_tys.iter().all(|t| t == cx.tcx.normalize_erasing_regions(ParamEnv::reveal_all(), t))
|
||||
);
|
||||
|
||||
|
|
|
@ -204,7 +204,7 @@ pub(super) fn build_enum_type_di_node<'ll, 'tcx>(
|
|||
let enum_type_and_layout = cx.layout_of(enum_type);
|
||||
let enum_type_name = compute_debuginfo_type_name(cx.tcx, enum_type, false);
|
||||
|
||||
debug_assert!(!wants_c_like_enum_debuginfo(enum_type_and_layout));
|
||||
assert!(!wants_c_like_enum_debuginfo(enum_type_and_layout));
|
||||
|
||||
type_map::build_type_with_children(
|
||||
cx,
|
||||
|
@ -279,7 +279,7 @@ pub(super) fn build_coroutine_di_node<'ll, 'tcx>(
|
|||
let coroutine_type_and_layout = cx.layout_of(coroutine_type);
|
||||
let coroutine_type_name = compute_debuginfo_type_name(cx.tcx, coroutine_type, false);
|
||||
|
||||
debug_assert!(!wants_c_like_enum_debuginfo(coroutine_type_and_layout));
|
||||
assert!(!wants_c_like_enum_debuginfo(coroutine_type_and_layout));
|
||||
|
||||
type_map::build_type_with_children(
|
||||
cx,
|
||||
|
@ -517,7 +517,7 @@ fn build_variant_struct_wrapper_type_di_node<'ll, 'tcx>(
|
|||
if is_128_bits {
|
||||
DiscrKind::Exact128(discr_val)
|
||||
} else {
|
||||
debug_assert_eq!(discr_val, discr_val as u64 as u128);
|
||||
assert_eq!(discr_val, discr_val as u64 as u128);
|
||||
DiscrKind::Exact(discr_val as u64)
|
||||
}
|
||||
}
|
||||
|
@ -526,8 +526,8 @@ fn build_variant_struct_wrapper_type_di_node<'ll, 'tcx>(
|
|||
if is_128_bits {
|
||||
DiscrKind::Range128(min, max)
|
||||
} else {
|
||||
debug_assert_eq!(min, min as u64 as u128);
|
||||
debug_assert_eq!(max, max as u64 as u128);
|
||||
assert_eq!(min, min as u64 as u128);
|
||||
assert_eq!(max, max as u64 as u128);
|
||||
DiscrKind::Range(min as u64, max as u64)
|
||||
}
|
||||
}
|
||||
|
@ -815,7 +815,7 @@ fn build_union_fields_for_direct_tag_enum_or_coroutine<'ll, 'tcx>(
|
|||
}
|
||||
}));
|
||||
|
||||
debug_assert_eq!(
|
||||
assert_eq!(
|
||||
cx.size_and_align_of(enum_type_and_layout.field(cx, tag_field).ty),
|
||||
cx.size_and_align_of(super::tag_base_type(cx, enum_type_and_layout))
|
||||
);
|
||||
|
|
|
@ -106,7 +106,7 @@ fn tag_base_type<'ll, 'tcx>(
|
|||
cx: &CodegenCx<'ll, 'tcx>,
|
||||
enum_type_and_layout: TyAndLayout<'tcx>,
|
||||
) -> Ty<'tcx> {
|
||||
debug_assert!(match enum_type_and_layout.ty.kind() {
|
||||
assert!(match enum_type_and_layout.ty.kind() {
|
||||
ty::Coroutine(..) => true,
|
||||
ty::Adt(adt_def, _) => adt_def.is_enum(),
|
||||
_ => false,
|
||||
|
@ -251,7 +251,7 @@ fn build_enum_variant_struct_type_di_node<'ll, 'tcx>(
|
|||
variant_layout: TyAndLayout<'tcx>,
|
||||
di_flags: DIFlags,
|
||||
) -> &'ll DIType {
|
||||
debug_assert_eq!(variant_layout.ty, enum_type_and_layout.ty);
|
||||
assert_eq!(variant_layout.ty, enum_type_and_layout.ty);
|
||||
|
||||
type_map::build_type_with_children(
|
||||
cx,
|
||||
|
|
|
@ -65,7 +65,7 @@ pub(super) fn build_enum_type_di_node<'ll, 'tcx>(
|
|||
|
||||
let visibility_flags = visibility_di_flags(cx, enum_adt_def.did(), enum_adt_def.did());
|
||||
|
||||
debug_assert!(!wants_c_like_enum_debuginfo(enum_type_and_layout));
|
||||
assert!(!wants_c_like_enum_debuginfo(enum_type_and_layout));
|
||||
|
||||
type_map::build_type_with_children(
|
||||
cx,
|
||||
|
@ -142,7 +142,7 @@ pub(super) fn build_coroutine_di_node<'ll, 'tcx>(
|
|||
let containing_scope = get_namespace_for_item(cx, coroutine_def_id);
|
||||
let coroutine_type_and_layout = cx.layout_of(coroutine_type);
|
||||
|
||||
debug_assert!(!wants_c_like_enum_debuginfo(coroutine_type_and_layout));
|
||||
assert!(!wants_c_like_enum_debuginfo(coroutine_type_and_layout));
|
||||
|
||||
let coroutine_type_name = compute_debuginfo_type_name(cx.tcx, coroutine_type, false);
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@ mod private {
|
|||
|
||||
/// A unique identifier for anything that we create a debuginfo node for.
|
||||
/// The types it contains are expected to already be normalized (which
|
||||
/// is debug_asserted in the constructors).
|
||||
/// is asserted in the constructors).
|
||||
///
|
||||
/// Note that there are some things that only show up in debuginfo, like
|
||||
/// the separate type descriptions for each enum variant. These get an ID
|
||||
|
@ -58,12 +58,12 @@ pub(super) enum UniqueTypeId<'tcx> {
|
|||
|
||||
impl<'tcx> UniqueTypeId<'tcx> {
|
||||
pub fn for_ty(tcx: TyCtxt<'tcx>, t: Ty<'tcx>) -> Self {
|
||||
debug_assert_eq!(t, tcx.normalize_erasing_regions(ParamEnv::reveal_all(), t));
|
||||
assert_eq!(t, tcx.normalize_erasing_regions(ParamEnv::reveal_all(), t));
|
||||
UniqueTypeId::Ty(t, private::HiddenZst)
|
||||
}
|
||||
|
||||
pub fn for_enum_variant_part(tcx: TyCtxt<'tcx>, enum_ty: Ty<'tcx>) -> Self {
|
||||
debug_assert_eq!(enum_ty, tcx.normalize_erasing_regions(ParamEnv::reveal_all(), enum_ty));
|
||||
assert_eq!(enum_ty, tcx.normalize_erasing_regions(ParamEnv::reveal_all(), enum_ty));
|
||||
UniqueTypeId::VariantPart(enum_ty, private::HiddenZst)
|
||||
}
|
||||
|
||||
|
@ -72,7 +72,7 @@ impl<'tcx> UniqueTypeId<'tcx> {
|
|||
enum_ty: Ty<'tcx>,
|
||||
variant_idx: VariantIdx,
|
||||
) -> Self {
|
||||
debug_assert_eq!(enum_ty, tcx.normalize_erasing_regions(ParamEnv::reveal_all(), enum_ty));
|
||||
assert_eq!(enum_ty, tcx.normalize_erasing_regions(ParamEnv::reveal_all(), enum_ty));
|
||||
UniqueTypeId::VariantStructType(enum_ty, variant_idx, private::HiddenZst)
|
||||
}
|
||||
|
||||
|
@ -81,7 +81,7 @@ impl<'tcx> UniqueTypeId<'tcx> {
|
|||
enum_ty: Ty<'tcx>,
|
||||
variant_idx: VariantIdx,
|
||||
) -> Self {
|
||||
debug_assert_eq!(enum_ty, tcx.normalize_erasing_regions(ParamEnv::reveal_all(), enum_ty));
|
||||
assert_eq!(enum_ty, tcx.normalize_erasing_regions(ParamEnv::reveal_all(), enum_ty));
|
||||
UniqueTypeId::VariantStructTypeCppLikeWrapper(enum_ty, variant_idx, private::HiddenZst)
|
||||
}
|
||||
|
||||
|
@ -90,11 +90,8 @@ impl<'tcx> UniqueTypeId<'tcx> {
|
|||
self_type: Ty<'tcx>,
|
||||
implemented_trait: Option<PolyExistentialTraitRef<'tcx>>,
|
||||
) -> Self {
|
||||
debug_assert_eq!(
|
||||
self_type,
|
||||
tcx.normalize_erasing_regions(ParamEnv::reveal_all(), self_type)
|
||||
);
|
||||
debug_assert_eq!(
|
||||
assert_eq!(self_type, tcx.normalize_erasing_regions(ParamEnv::reveal_all(), self_type));
|
||||
assert_eq!(
|
||||
implemented_trait,
|
||||
tcx.normalize_erasing_regions(ParamEnv::reveal_all(), implemented_trait)
|
||||
);
|
||||
|
@ -252,10 +249,7 @@ pub(super) fn build_type_with_children<'ll, 'tcx>(
|
|||
members: impl FnOnce(&CodegenCx<'ll, 'tcx>, &'ll DIType) -> SmallVec<&'ll DIType>,
|
||||
generics: impl FnOnce(&CodegenCx<'ll, 'tcx>) -> SmallVec<&'ll DIType>,
|
||||
) -> DINodeCreationResult<'ll> {
|
||||
debug_assert_eq!(
|
||||
debug_context(cx).type_map.di_node_for_unique_id(stub_info.unique_type_id),
|
||||
None
|
||||
);
|
||||
assert_eq!(debug_context(cx).type_map.di_node_for_unique_id(stub_info.unique_type_id), None);
|
||||
|
||||
debug_context(cx).type_map.insert(stub_info.unique_type_id, stub_info.metadata);
|
||||
|
||||
|
|
|
@ -81,7 +81,7 @@ pub(crate) fn fat_pointer_kind<'ll, 'tcx>(
|
|||
ty::Dynamic(..) => Some(FatPtrKind::Dyn),
|
||||
ty::Foreign(_) => {
|
||||
// Assert that pointers to foreign types really are thin:
|
||||
debug_assert_eq!(
|
||||
assert_eq!(
|
||||
cx.size_of(Ty::new_imm_ptr(cx.tcx, pointee_tail_ty)),
|
||||
cx.size_of(Ty::new_imm_ptr(cx.tcx, cx.tcx.types.u8))
|
||||
);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue