Skip to content

Commit d189e9f

Browse files
authored
Merge pull request #873 from cijiugechu/fix/transmuted-fn-ptr-call
Fix ICE when calling transmuted function pointers
2 parents 897df45 + 3084520 commit d189e9f

5 files changed

Lines changed: 33 additions & 32 deletions

File tree

src/abi.rs

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -224,15 +224,8 @@ impl<'gcc, 'tcx> FnAbiGccExt<'gcc, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
224224

225225
fn ptr_to_gcc_type(&self, cx: &CodegenCx<'gcc, 'tcx>) -> Type<'gcc> {
226226
// FIXME(antoyo): Should we do something with `FnAbiGcc::fn_attributes`?
227-
let FnAbiGcc { return_type, arguments_type, is_c_variadic, on_stack_param_indices, .. } =
228-
self.gcc_type(cx);
229-
let pointer_type =
230-
cx.context.new_function_pointer_type(None, return_type, &arguments_type, is_c_variadic);
231-
cx.on_stack_params.borrow_mut().insert(
232-
pointer_type.dyncast_function_ptr_type().expect("function ptr type"),
233-
on_stack_param_indices,
234-
);
235-
pointer_type
227+
let FnAbiGcc { return_type, arguments_type, is_c_variadic, .. } = self.gcc_type(cx);
228+
cx.context.new_function_pointer_type(None, return_type, &arguments_type, is_c_variadic)
236229
}
237230

238231
#[cfg(feature = "master")]

src/builder.rs

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ use rustc_span::def_id::DefId;
3333
use rustc_target::callconv::FnAbi;
3434
use rustc_target::spec::{HasTargetSpec, HasX86AbiOpt, Target, X86Abi};
3535

36+
use crate::abi::FnAbiGccExt;
3637
use crate::common::{SignType, TypeReflection, type_is_pointer};
3738
use crate::context::CodegenCx;
3839
use crate::errors;
@@ -213,6 +214,7 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
213214
_typ: &str,
214215
func_ptr: RValue<'gcc>,
215216
args: &'b [RValue<'gcc>],
217+
on_stack_param_indices: &FxHashSet<usize>,
216218
) -> Cow<'b, [RValue<'gcc>]> {
217219
let mut all_args_match = true;
218220
let mut param_types = vec![];
@@ -225,11 +227,6 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
225227
param_types.push(param);
226228
}
227229

228-
let mut on_stack_param_indices = FxHashSet::default();
229-
if let Some(indices) = self.on_stack_params.borrow().get(&gcc_func) {
230-
on_stack_param_indices.clone_from(indices);
231-
}
232-
233230
if all_args_match {
234231
return Cow::Borrowed(args);
235232
}
@@ -351,19 +348,24 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
351348
fn function_ptr_call(
352349
&mut self,
353350
typ: Type<'gcc>,
351+
fn_abi: Option<&FnAbi<'tcx, Ty<'tcx>>>,
354352
mut func_ptr: RValue<'gcc>,
355353
args: &[RValue<'gcc>],
356354
_funclet: Option<&Funclet>,
357355
) -> RValue<'gcc> {
358-
let gcc_func = match func_ptr.get_type().dyncast_function_ptr_type() {
359-
Some(func) => func,
360-
None => {
361-
// NOTE: due to opaque pointers now being used, we need to cast here.
362-
let new_func_type = typ.dyncast_function_ptr_type().expect("function ptr");
356+
let func_ptr_type = {
357+
let func_ptr_type = func_ptr.get_type();
358+
if func_ptr_type != typ {
363359
func_ptr = self.context.new_cast(self.location, func_ptr, typ);
364-
new_func_type
360+
typ
361+
} else {
362+
func_ptr_type
365363
}
366364
};
365+
let gcc_func = func_ptr_type.dyncast_function_ptr_type().expect("function ptr");
366+
let on_stack_param_indices = fn_abi
367+
.map(|fn_abi| fn_abi.gcc_type(self.cx).on_stack_param_indices)
368+
.unwrap_or_default();
367369
let func_name = format!("{:?}", func_ptr);
368370
let previous_arg_count = args.len();
369371
let orig_args = args;
@@ -372,7 +374,7 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
372374
llvm::adjust_intrinsic_arguments(self, gcc_func, args.into(), &func_name)
373375
};
374376
let args_adjusted = args.len() != previous_arg_count;
375-
let args = self.check_ptr_call("call", func_ptr, &args);
377+
let args = self.check_ptr_call("call", func_ptr, &args, &on_stack_param_indices);
376378

377379
// gccjit requires to use the result of functions, even when it's not used.
378380
// That's why we assign the result to a local or call add_eval().
@@ -599,7 +601,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
599601
&mut self,
600602
typ: Type<'gcc>,
601603
fn_attrs: Option<&CodegenFnAttrs>,
602-
_fn_abi: Option<&FnAbi<'tcx, Ty<'tcx>>>,
604+
fn_abi: Option<&FnAbi<'tcx, Ty<'tcx>>>,
603605
func: RValue<'gcc>,
604606
args: &[RValue<'gcc>],
605607
then: Block<'gcc>,
@@ -611,7 +613,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
611613

612614
let current_block = self.block;
613615
self.block = try_block;
614-
let call = self.call(typ, fn_attrs, None, func, args, None, instance); // FIXME(antoyo): use funclet here?
616+
let call = self.call(typ, fn_attrs, fn_abi, func, args, None, instance); // FIXME(antoyo): use funclet here?
615617
self.block = current_block;
616618

617619
let return_value =
@@ -645,7 +647,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
645647
_funclet: Option<&Funclet>,
646648
instance: Option<Instance<'tcx>>,
647649
) -> RValue<'gcc> {
648-
let call_site = self.call(typ, fn_attrs, None, func, args, None, instance);
650+
let call_site = self.call(typ, fn_attrs, fn_abi, func, args, None, instance);
649651
let condition = self.context.new_rvalue_from_int(self.bool_type, 1);
650652
self.llbb().end_with_conditional(self.location, condition, then, catch);
651653
if let Some(_fn_abi) = fn_abi {
@@ -1773,7 +1775,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
17731775
self.function_call(func, args, funclet)
17741776
} else {
17751777
// If it's a not function that was defined, it's a function pointer.
1776-
self.function_ptr_call(typ, func, args, funclet)
1778+
self.function_ptr_call(typ, fn_abi, func, args, funclet)
17771779
};
17781780
if let Some(_fn_abi) = fn_abi {
17791781
// FIXME(bjorn3): Apply function attributes

src/context.rs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
use std::cell::{Cell, RefCell};
22
use std::collections::HashMap;
33

4-
use gccjit::{
5-
Block, CType, Context, Function, FunctionPtrType, FunctionType, LValue, Location, RValue, Type,
6-
};
4+
use gccjit::{Block, CType, Context, Function, FunctionType, LValue, Location, RValue, Type};
75
use rustc_abi::{Align, HasDataLayout, PointeeInfo, Size, TargetDataLayout, VariantIdx};
86
use rustc_codegen_ssa::base::wants_msvc_seh;
97
use rustc_codegen_ssa::errors as ssa_errors;
@@ -100,8 +98,6 @@ pub struct CodegenCx<'gcc, 'tcx> {
10098
RefCell<FxHashMap<(Ty<'tcx>, Option<ty::ExistentialTraitRef<'tcx>>), RValue<'gcc>>>,
10199

102100
// FIXME(antoyo): improve the SSA API to not require those.
103-
/// Mapping from function pointer type to indexes of on stack parameters.
104-
pub on_stack_params: RefCell<FxHashMap<FunctionPtrType<'gcc>, FxHashSet<usize>>>,
105101
/// Mapping from function to indexes of on stack parameters.
106102
pub on_stack_function_params: RefCell<FxHashMap<Function<'gcc>, FxHashSet<usize>>>,
107103

@@ -289,7 +285,6 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
289285
instances: Default::default(),
290286
function_instances: Default::default(),
291287
intrinsic_instances: Default::default(),
292-
on_stack_params: Default::default(),
293288
on_stack_function_params: Default::default(),
294289
vtables: Default::default(),
295290
const_globals: Default::default(),
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// Compiler:
2+
3+
// Regression test for <https://github.com/rust-lang/rustc_codegen_gcc/issues/836>
4+
5+
#![crate_type = "lib"]
6+
7+
#[unsafe(no_mangle)]
8+
extern "C" fn third(_a: usize, b: usize, c: usize) {
9+
let throw_away_f: fn((), usize, usize) =
10+
unsafe { std::mem::transmute(third as extern "C" fn(_, _, _)) };
11+
throw_away_f((), 2, 3)
12+
}

tests/failing-ui-tests.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@ tests/ui/sanitizer/cfi/virtual-auto.rs
4747
tests/ui/sanitizer/cfi/sized-associated-ty.rs
4848
tests/ui/sanitizer/cfi/can-reveal-opaques.rs
4949
tests/ui/sanitizer/kcfi-mangling.rs
50-
tests/ui/backtrace/dylib-dep.rs
5150
tests/ui/delegation/fn-header.rs
5251
tests/ui/consts/const-eval/parse_ints.rs
5352
tests/ui/simd/intrinsic/generic-as.rs

0 commit comments

Comments
 (0)