-
Notifications
You must be signed in to change notification settings - Fork 13.3k
Employ non-null metadata for loads from fat pointers #27180
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -408,9 +408,7 @@ pub fn iter_structural_ty<'blk, 'tcx, F>(cx: Block<'blk, 'tcx>, | |
let (data_ptr, info) = if common::type_is_sized(cx.tcx(), t) { | ||
(av, None) | ||
} else { | ||
let data = GEPi(cx, av, &[0, abi::FAT_PTR_ADDR]); | ||
let info = GEPi(cx, av, &[0, abi::FAT_PTR_EXTRA]); | ||
(Load(cx, data), Some(Load(cx, info))) | ||
(load_addr(cx, av), Some(load_extra(cx, av, t))) | ||
}; | ||
|
||
let mut cx = cx; | ||
|
@@ -426,8 +424,8 @@ pub fn iter_structural_ty<'blk, 'tcx, F>(cx: Block<'blk, 'tcx>, | |
llfld_a | ||
} else { | ||
let scratch = datum::rvalue_scratch_datum(cx, field_ty, "__fat_ptr_iter"); | ||
Store(cx, llfld_a, GEPi(cx, scratch.val, &[0, abi::FAT_PTR_ADDR])); | ||
Store(cx, info.unwrap(), GEPi(cx, scratch.val, &[0, abi::FAT_PTR_EXTRA])); | ||
store_addr(cx, llfld_a, scratch.val); | ||
store_extra(cx, info.unwrap(), scratch.val); | ||
scratch.val | ||
}; | ||
cx = f(cx, val, field_ty); | ||
|
@@ -777,6 +775,27 @@ pub fn load_if_immediate<'blk, 'tcx>(cx: Block<'blk, 'tcx>, | |
return v; | ||
} | ||
|
||
pub fn load_addr(bcx: Block, fatptr: ValueRef) -> ValueRef { | ||
LoadNonNull(bcx, expr::get_dataptr(bcx, fatptr)) | ||
} | ||
|
||
pub fn store_addr(bcx: Block, addr: ValueRef, fatptr: ValueRef) -> ValueRef { | ||
Store(bcx, addr, expr::get_dataptr(bcx, fatptr)) | ||
} | ||
|
||
pub fn load_extra<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, fatptr: ValueRef, ty: Ty<'tcx>) -> ValueRef { | ||
assert!(!common::type_is_sized(bcx.tcx(), ty)); | ||
if ty.is_trait() { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should this be There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Indeed! |
||
LoadNonNull(bcx, expr::get_len(bcx, fatptr)) | ||
} else { | ||
Load(bcx, expr::get_len(bcx, fatptr)) | ||
} | ||
} | ||
|
||
pub fn store_extra(bcx: Block, extra: ValueRef, fatptr: ValueRef) -> ValueRef { | ||
Store(bcx, extra, expr::get_len(bcx, fatptr)) | ||
} | ||
|
||
/// Helper for loading values from memory. Does the necessary conversion if the in-memory type | ||
/// differs from the type used for SSA values. Also handles various special cases where the type | ||
/// gives us better information about what we are loading. | ||
|
@@ -835,8 +854,8 @@ pub fn store_ty<'blk, 'tcx>(cx: Block<'blk, 'tcx>, v: ValueRef, dst: ValueRef, t | |
} | ||
|
||
if common::type_is_fat_ptr(cx.tcx(), t) { | ||
Store(cx, ExtractValue(cx, v, abi::FAT_PTR_ADDR), expr::get_dataptr(cx, dst)); | ||
Store(cx, ExtractValue(cx, v, abi::FAT_PTR_EXTRA), expr::get_len(cx, dst)); | ||
store_addr(cx, ExtractValue(cx, v, abi::FAT_PTR_ADDR), dst); | ||
store_extra(cx, ExtractValue(cx, v, abi::FAT_PTR_EXTRA), dst); | ||
} else { | ||
let store = Store(cx, from_arg_ty(cx, v, t), to_arg_ty_ptr(cx, dst, t)); | ||
unsafe { | ||
|
@@ -960,7 +979,9 @@ pub fn memcpy_ty<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, | |
t: Ty<'tcx>) { | ||
let _icx = push_ctxt("memcpy_ty"); | ||
let ccx = bcx.ccx(); | ||
if t.is_structural() { | ||
if common::type_is_fat_ptr(bcx.tcx(), t) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Be sure you don't miscompile the likes of pub fn foo() -> *const [u8] { unsafe { std::mem::transmute([0u64,0]) } } There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @arielb1 out of curiosity, what was the red flag here that made you worry about that test case? At first blush, I would have thought that Update: ah, I see, there is a separate note on the commit where @areilb1 states some concern about the change to |
||
expr::copy_fat_ptr(bcx, src, dst, t); | ||
} else if t.is_structural() { | ||
let llty = type_of::type_of(ccx, t); | ||
let llsz = llsize_of(ccx, llty); | ||
let llalign = type_of::align_of(ccx, t); | ||
|
@@ -1348,8 +1369,8 @@ pub fn create_datums_for_fn_args<'a, 'tcx>(mut bcx: Block<'a, 'tcx>, | |
unpack_datum!(bcx, datum::lvalue_scratch_datum(bcx, arg_ty, "", | ||
arg_scope_id, (data, extra), | ||
|(data, extra), bcx, dst| { | ||
Store(bcx, data, expr::get_dataptr(bcx, dst)); | ||
Store(bcx, extra, expr::get_len(bcx, dst)); | ||
store_addr(bcx, data, dst); | ||
store_extra(bcx, extra, dst); | ||
bcx | ||
})) | ||
} else { | ||
|
@@ -1379,8 +1400,8 @@ pub fn create_datums_for_fn_args<'a, 'tcx>(mut bcx: Block<'a, 'tcx>, | |
if common::type_is_fat_ptr(bcx.tcx(), tupled_arg_ty) { | ||
let data = get_param(bcx.fcx.llfn, idx); | ||
let extra = get_param(bcx.fcx.llfn, idx + 1); | ||
Store(bcx, data, expr::get_dataptr(bcx, lldest)); | ||
Store(bcx, extra, expr::get_len(bcx, lldest)); | ||
store_addr(bcx, data, lldest); | ||
store_extra(bcx, extra, lldest); | ||
idx += 2; | ||
} else { | ||
let datum = datum::Datum::new( | ||
|
@@ -1784,8 +1805,8 @@ fn trans_enum_variant_or_tuple_like_struct<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx | |
disr, | ||
i); | ||
if common::type_is_fat_ptr(bcx.tcx(), arg_ty) { | ||
Store(bcx, get_param(fcx.llfn, llarg_idx), expr::get_dataptr(bcx, lldestptr)); | ||
Store(bcx, get_param(fcx.llfn, llarg_idx + 1), expr::get_len(bcx, lldestptr)); | ||
store_addr(bcx, get_param(fcx.llfn, llarg_idx), lldestptr); | ||
store_extra(bcx, get_param(fcx.llfn, llarg_idx + 1), lldestptr); | ||
llarg_idx += 2; | ||
} else { | ||
let arg = get_param(fcx.llfn, llarg_idx); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's already a function Ty::builtin_deref.