about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAntoni Boucher <bouanto@zoho.com>2023-06-04 13:14:55 -0400
committerAntoni Boucher <bouanto@zoho.com>2023-06-11 11:52:15 -0400
commit4115e09c13a975b42d506e2db6119d7c3ff1876e (patch)
tree9b80437658b374110a766f2341249ba15896a069
parent3d4c59ed75cdc0e6162e36279dba85acc6fe73d2 (diff)
downloadrust-4115e09c13a975b42d506e2db6119d7c3ff1876e.tar.gz
rust-4115e09c13a975b42d506e2db6119d7c3ff1876e.zip
Fix for opaque pointers
-rw-r--r--Cargo.toml2
-rw-r--r--src/builder.rs40
-rw-r--r--src/type_of.rs6
3 files changed, 30 insertions, 18 deletions
diff --git a/Cargo.toml b/Cargo.toml
index 7285e3eaf51..81066d9ce1f 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -25,7 +25,7 @@ master = ["gccjit/master"]
 gccjit = { git = "https://github.com/antoyo/gccjit.rs" }
 
 # Local copy.
-# gccjit = { path = "../gccjit.rs" }
+#gccjit = { path = "../gccjit.rs" }
 
 smallvec = { version = "1.6.1", features = ["union", "may_dangle"] }
 
diff --git a/src/builder.rs b/src/builder.rs
index f9ea0f00456..d578a0df51d 100644
--- a/src/builder.rs
+++ b/src/builder.rs
@@ -280,8 +280,17 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
         }
     }
 
-    fn function_ptr_call(&mut self, func_ptr: RValue<'gcc>, args: &[RValue<'gcc>], _funclet: Option<&Funclet>) -> RValue<'gcc> {
-        let gcc_func = func_ptr.get_type().dyncast_function_ptr_type().expect("function ptr");
+    fn function_ptr_call(&mut self, typ: Type<'gcc>, mut func_ptr: RValue<'gcc>, args: &[RValue<'gcc>], _funclet: Option<&Funclet>) -> RValue<'gcc> {
+        let gcc_func =
+            match func_ptr.get_type().dyncast_function_ptr_type() {
+                Some(func) => func,
+                None => {
+                    // NOTE: due to opaque pointers now being used, we need to cast here.
+                    let new_func_type = typ.dyncast_function_ptr_type().expect("function ptr");
+                    func_ptr = self.context.new_cast(None, func_ptr, typ);
+                    new_func_type
+                },
+            };
         let func_name = format!("{:?}", func_ptr);
         let previous_arg_count = args.len();
         let orig_args = args;
@@ -424,16 +433,17 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
         self.llbb().end_with_void_return(None)
     }
 
-    fn ret(&mut self, value: RValue<'gcc>) {
-        let value =
-            if self.structs_as_pointer.borrow().contains(&value) {
-                // NOTE: hack to workaround a limitation of the rustc API: see comment on
-                // CodegenCx.structs_as_pointer
-                value.dereference(None).to_rvalue()
-            }
-            else {
-                value
-            };
+    fn ret(&mut self, mut value: RValue<'gcc>) {
+        if self.structs_as_pointer.borrow().contains(&value) {
+            // NOTE: hack to workaround a limitation of the rustc API: see comment on
+            // CodegenCx.structs_as_pointer
+            value = value.dereference(None).to_rvalue();
+        }
+        let expected_return_type = self.current_func().get_return_type();
+        if !expected_return_type.is_compatible_with(value.get_type()) {
+            // NOTE: due to opaque pointers now being used, we need to cast here.
+            value = self.context.new_cast(None, value, expected_return_type);
+        }
         self.llbb().end_with_return(None, value);
     }
 
@@ -938,6 +948,8 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
             element.get_address(None)
         }
         else if let Some(struct_type) = value_type.is_struct() {
+            // NOTE: due to opaque pointers now being used, we need to bitcast here.
+            let ptr = self.bitcast_if_needed(ptr, value_type.make_pointer());
             ptr.dereference_field(None, struct_type.get_field(idx as i32)).get_address(None)
         }
         else {
@@ -1356,7 +1368,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
 
     fn call(
         &mut self,
-        _typ: Type<'gcc>,
+        typ: Type<'gcc>,
         _fn_attrs: Option<&CodegenFnAttrs>,
         fn_abi: Option<&FnAbi<'tcx, Ty<'tcx>>>,
         func: RValue<'gcc>,
@@ -1370,7 +1382,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
         }
         else {
             // If it's a not function that was defined, it's a function pointer.
-            self.function_ptr_call(func, args, funclet)
+            self.function_ptr_call(typ, func, args, funclet)
         };
         if let Some(_fn_abi) = fn_abi {
             // TODO(bjorn3): Apply function attributes
diff --git a/src/type_of.rs b/src/type_of.rs
index 30a3fe67b85..74f016cf90a 100644
--- a/src/type_of.rs
+++ b/src/type_of.rs
@@ -383,8 +383,8 @@ impl<'gcc, 'tcx> LayoutTypeMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
         unimplemented!();
     }
 
-    fn fn_decl_backend_type(&self, _fn_abi: &FnAbi<'tcx, Ty<'tcx>>) -> Type<'gcc> {
-        // FIXME(antoyo): return correct type.
-        self.type_void()
+    fn fn_decl_backend_type(&self, fn_abi: &FnAbi<'tcx, Ty<'tcx>>) -> Type<'gcc> {
+        let (return_type, param_types, variadic, _) = fn_abi.gcc_type(self);
+        self.context.new_function_pointer_type(None, return_type, &param_types, variadic)
     }
 }