mirror of
https://github.com/EmbarkStudios/rust-gpu.git
synced 2024-11-25 00:04:11 +00:00
Actually generate an OpBitcast
for illegal pointercasts.
This commit is contained in:
parent
51dec9f339
commit
b5b651103d
@ -1267,7 +1267,7 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> {
|
||||
if let SpirvValueKind::LogicalPtrCast {
|
||||
original_ptr,
|
||||
original_pointee_ty,
|
||||
zombie_target_undef: _,
|
||||
bitcast_result_id: _,
|
||||
} = ptr.kind
|
||||
{
|
||||
let offset = match pointee_kind {
|
||||
@ -1533,7 +1533,7 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> {
|
||||
SpirvValueKind::LogicalPtrCast {
|
||||
original_ptr,
|
||||
original_pointee_ty,
|
||||
zombie_target_undef: _,
|
||||
bitcast_result_id: _,
|
||||
} => (
|
||||
original_ptr.with_type(
|
||||
SpirvType::Pointer {
|
||||
@ -1572,11 +1572,12 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> {
|
||||
.with_type(dest_ty)
|
||||
} else {
|
||||
// Defer the cast so that it has a chance to be avoided.
|
||||
let original_ptr = val.def(self);
|
||||
SpirvValue {
|
||||
kind: SpirvValueKind::LogicalPtrCast {
|
||||
original_ptr: val.def(self),
|
||||
original_ptr,
|
||||
original_pointee_ty: val_pointee,
|
||||
zombie_target_undef: self.undef(dest_ty).def(self),
|
||||
bitcast_result_id: self.emit().bitcast(dest_ty, None, original_ptr).unwrap(),
|
||||
},
|
||||
ty: dest_ty,
|
||||
}
|
||||
|
@ -59,10 +59,12 @@ pub enum SpirvValueKind {
|
||||
/// Pointee type of `original_ptr`.
|
||||
original_pointee_ty: Word,
|
||||
|
||||
/// `OpUndef` of the right target pointer type, to attach zombies to.
|
||||
// FIXME(eddyb) we should be using a real `OpBitcast` here, but we can't
|
||||
// emit that on the fly during `SpirvValue::def`, due to builder locking.
|
||||
zombie_target_undef: Word,
|
||||
/// Result ID for the `OpBitcast` instruction representing the cast,
|
||||
/// to attach zombies to.
|
||||
//
|
||||
// HACK(eddyb) having an `OpBitcast` only works by being DCE'd away,
|
||||
// or by being replaced with a noop in `qptr::lower`.
|
||||
bitcast_result_id: Word,
|
||||
},
|
||||
}
|
||||
|
||||
@ -170,10 +172,10 @@ impl SpirvValue {
|
||||
SpirvValueKind::LogicalPtrCast {
|
||||
original_ptr: _,
|
||||
original_pointee_ty,
|
||||
zombie_target_undef,
|
||||
bitcast_result_id,
|
||||
} => {
|
||||
cx.zombie_with_span(
|
||||
zombie_target_undef,
|
||||
bitcast_result_id,
|
||||
span,
|
||||
&format!(
|
||||
"cannot cast between pointer types\
|
||||
@ -184,7 +186,7 @@ impl SpirvValue {
|
||||
),
|
||||
);
|
||||
|
||||
zombie_target_undef
|
||||
bitcast_result_id
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -102,8 +102,9 @@ impl Zombies {
|
||||
// No need to zombie defs within a function: If any def within a function is zombied, then the
|
||||
// whole function is zombied. But, we don't have to mark the defs within a function as zombie,
|
||||
// because the defs can't escape the function.
|
||||
// HACK(eddyb) one exception to this is function-local variables, which may
|
||||
// be unused and as such cannot be allowed to always zombie the function.
|
||||
// HACK(eddyb) one exception to this is function-local variables, or the
|
||||
// `OpBitcast`s of pointer casts, either of which which may actually be
|
||||
// unused and as such cannot be allowed to always zombie the function.
|
||||
for func in &module.functions {
|
||||
let func_id = func.def_id().unwrap();
|
||||
if self.id_to_zombie_kind.contains_key(&func_id) {
|
||||
@ -126,7 +127,7 @@ impl Zombies {
|
||||
_ => {}
|
||||
}
|
||||
|
||||
if inst.class.opcode == Op::Variable {
|
||||
if [Op::Variable, Op::Bitcast].contains(&inst.class.opcode) {
|
||||
let result_id = inst.result_id.unwrap();
|
||||
if self.id_to_zombie_kind.contains_key(&result_id) {
|
||||
continue;
|
||||
|
@ -18,11 +18,11 @@ note: called by `main_scalar_scalar_pair_nested`
|
||||
| ^
|
||||
|
||||
error: cannot cast between pointer types
|
||||
from `*struct (usize, usize) { u32, u32 }`
|
||||
from `*u32`
|
||||
to `*struct B { }`
|
||||
--> $DIR/zst_member_ref_arg-broken.rs:33:5
|
||||
--> $DIR/zst_member_ref_arg-broken.rs:23:5
|
||||
|
|
||||
33 | f(&s.y);
|
||||
23 | f(&s.y);
|
||||
| ^
|
||||
|
|
||||
note: used from within `zst_member_ref_arg_broken::main_scalar`
|
||||
@ -37,11 +37,11 @@ note: called by `main_scalar`
|
||||
| ^
|
||||
|
||||
error: cannot cast between pointer types
|
||||
from `*struct (usize, usize) { u32, u32 }`
|
||||
from `*struct S<usize, usize> { u32, u32 }`
|
||||
to `*struct B { }`
|
||||
--> $DIR/zst_member_ref_arg-broken.rs:33:5
|
||||
--> $DIR/zst_member_ref_arg-broken.rs:28:5
|
||||
|
|
||||
33 | f(&s.y);
|
||||
28 | f(&s.y);
|
||||
| ^
|
||||
|
|
||||
note: used from within `zst_member_ref_arg_broken::main_scalar_pair`
|
||||
|
Loading…
Reference in New Issue
Block a user