Fix pointer value punning.

Seems this doesn't trigger error on LLVM 15, but let's fix it for better compatibility.
This commit is contained in:
Charles Lew 2022-09-10 19:42:51 +08:00
parent db9d86b58d
commit 1cbbd2aa61
2 changed files with 27 additions and 1 deletions

View File

@ -166,6 +166,11 @@ pub fn unsized_info<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
if let Some(entry_idx) = vptr_entry_idx {
let ptr_ty = cx.type_i8p();
let ptr_align = cx.tcx().data_layout.pointer_align.abi;
let vtable_ptr_ty = cx.scalar_pair_element_backend_type(
cx.layout_of(cx.tcx().mk_mut_ptr(target)),
1,
true,
);
let llvtable = bx.pointercast(old_info, bx.type_ptr_to(ptr_ty));
let gep = bx.inbounds_gep(
ptr_ty,
@ -176,7 +181,7 @@ pub fn unsized_info<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
bx.nonnull_metadata(new_vptr);
// VTable loads are invariant.
bx.set_invariant_load(new_vptr);
new_vptr
bx.pointercast(new_vptr, vtable_ptr_ty)
} else {
old_info
}

View File

@ -0,0 +1,21 @@
// build-pass
#![feature(trait_upcasting)]
#![allow(incomplete_features)]
pub trait A {}
pub trait B {}
pub trait C: A + B {}
impl<X: A + B> C for X {}
pub fn test<'a, T>(view: T) -> Option<&'a mut dyn B>
where
T: IntoIterator<Item = &'a mut dyn B>,
{
return Some(view.into_iter().next().unwrap());
}
fn main() {
let mut a: Vec<Box<dyn C>> = Vec::new();
test(a.iter_mut().map(|c| c.as_mut() as &mut dyn B));
}