Fix volatile_load

This commit is contained in:
Antoni Boucher 2023-10-24 17:43:23 -04:00
parent 16b3da81f3
commit a93d1b73c6
3 changed files with 40 additions and 9 deletions

View File

@ -751,9 +751,8 @@ fn load(&mut self, pointee_ty: Type<'gcc>, ptr: RValue<'gcc>, align: Align) -> R
loaded_value.to_rvalue()
}
fn volatile_load(&mut self, _ty: Type<'gcc>, ptr: RValue<'gcc>) -> RValue<'gcc> {
// TODO(antoyo): use ty.
let ptr = self.context.new_cast(None, ptr, ptr.get_type().make_volatile());
fn volatile_load(&mut self, ty: Type<'gcc>, ptr: RValue<'gcc>) -> RValue<'gcc> {
let ptr = self.context.new_cast(None, ptr, ty.make_volatile().make_pointer());
ptr.dereference(None).to_rvalue()
}

View File

@ -4,7 +4,9 @@
#[cfg(feature="master")]
use std::iter;
use gccjit::{ComparisonOp, Function, RValue, ToRValue, Type, UnaryOp, FunctionType};
#[cfg(feature="master")]
use gccjit::FunctionType;
use gccjit::{ComparisonOp, Function, RValue, ToRValue, Type, UnaryOp};
use rustc_codegen_ssa::MemFlags;
use rustc_codegen_ssa::base::wants_msvc_seh;
use rustc_codegen_ssa::common::IntPredicate;
@ -143,11 +145,15 @@ fn codegen_intrinsic_call(&mut self, instance: Instance<'tcx>, fn_abi: &FnAbi<'t
sym::volatile_load | sym::unaligned_volatile_load => {
let tp_ty = fn_args.type_at(0);
let mut ptr = args[0].immediate();
if let PassMode::Cast { cast: ty, .. } = &fn_abi.ret.mode {
ptr = self.pointercast(ptr, self.type_ptr_to(ty.gcc_type(self)));
}
let load = self.volatile_load(ptr.get_type(), ptr);
let ptr = args[0].immediate();
let load =
if let PassMode::Cast { cast: ty, pad_i32: _ } = &fn_abi.ret.mode {
let gcc_ty = ty.gcc_type(self);
self.volatile_load(gcc_ty, ptr)
}
else {
self.volatile_load(self.layout_of(tp_ty).gcc_type(self), ptr)
};
// TODO(antoyo): set alignment.
self.to_immediate(load, self.layout_of(tp_ty))
}

26
tests/run/volatile.rs Normal file
View File

@ -0,0 +1,26 @@
// Compiler:
//
// Run-time:
// status: 0
use std::mem::MaybeUninit;
#[derive(Debug)]
struct Struct {
pointer: *const (),
func: unsafe fn(*const ()),
}
fn func(ptr: *const ()) {
}
fn main() {
let mut x = MaybeUninit::<&Struct>::uninit();
x.write(&Struct {
pointer: std::ptr::null(),
func,
});
let x = unsafe { x.assume_init() };
let value = unsafe { (x as *const Struct).read_volatile() };
println!("{:?}", value);
}