summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_codegen_gcc/src/declare.rs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-07 05:48:48 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-07 05:48:48 +0000
commitef24de24a82fe681581cc130f342363c47c0969a (patch)
tree0d494f7e1a38b95c92426f58fe6eaa877303a86c /compiler/rustc_codegen_gcc/src/declare.rs
parentReleasing progress-linux version 1.74.1+dfsg1-1~progress7.99u1. (diff)
downloadrustc-ef24de24a82fe681581cc130f342363c47c0969a.tar.xz
rustc-ef24de24a82fe681581cc130f342363c47c0969a.zip
Merging upstream version 1.75.0+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'compiler/rustc_codegen_gcc/src/declare.rs')
-rw-r--r--compiler/rustc_codegen_gcc/src/declare.rs57
1 files changed, 54 insertions, 3 deletions
diff --git a/compiler/rustc_codegen_gcc/src/declare.rs b/compiler/rustc_codegen_gcc/src/declare.rs
index 493626c3c..247454fa5 100644
--- a/compiler/rustc_codegen_gcc/src/declare.rs
+++ b/compiler/rustc_codegen_gcc/src/declare.rs
@@ -1,10 +1,12 @@
use gccjit::{Function, FunctionType, GlobalKind, LValue, RValue, Type};
+#[cfg(feature="master")]
+use gccjit::{FnAttribute, ToRValue};
use rustc_codegen_ssa::traits::BaseTypeMethods;
use rustc_middle::ty::Ty;
use rustc_span::Symbol;
use rustc_target::abi::call::FnAbi;
-use crate::abi::FnAbiGccExt;
+use crate::abi::{FnAbiGcc, FnAbiGccExt};
use crate::context::CodegenCx;
use crate::intrinsic::llvm;
@@ -78,9 +80,20 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
}
pub fn declare_fn(&self, name: &str, fn_abi: &FnAbi<'tcx, Ty<'tcx>>) -> Function<'gcc> {
- let (return_type, params, variadic, on_stack_param_indices) = fn_abi.gcc_type(self);
- let func = declare_raw_fn(self, name, () /*fn_abi.llvm_cconv()*/, return_type, &params, variadic);
+ let FnAbiGcc {
+ return_type,
+ arguments_type,
+ is_c_variadic,
+ on_stack_param_indices,
+ #[cfg(feature="master")]
+ fn_attributes,
+ } = fn_abi.gcc_type(self);
+ let func = declare_raw_fn(self, name, () /*fn_abi.llvm_cconv()*/, return_type, &arguments_type, is_c_variadic);
self.on_stack_function_params.borrow_mut().insert(func, on_stack_param_indices);
+ #[cfg(feature="master")]
+ for fn_attr in fn_attributes {
+ func.add_attribute(fn_attr);
+ }
func
}
@@ -114,6 +127,44 @@ fn declare_raw_fn<'gcc>(cx: &CodegenCx<'gcc, '_>, name: &str, _callconv: () /*ll
.collect();
let func = cx.context.new_function(None, cx.linkage.get(), return_type, &params, mangle_name(name), variadic);
cx.functions.borrow_mut().insert(name.to_string(), func);
+
+ #[cfg(feature="master")]
+ if name == "rust_eh_personality" {
+ // NOTE: GCC will sometimes change the personality function set on a function from
+ // rust_eh_personality to __gcc_personality_v0 as an optimization.
+ // As such, we need to create a weak alias from __gcc_personality_v0 to
+ // rust_eh_personality in order to avoid a linker error.
+ // This needs to be weak in order to still allow using the standard
+ // __gcc_personality_v0 when the linking to it.
+ // Since aliases don't work (maybe because of a bug in LTO partitioning?), we
+ // create a wrapper function that calls rust_eh_personality.
+
+ let params: Vec<_> = param_types.into_iter().enumerate()
+ .map(|(index, param)| cx.context.new_parameter(None, *param, &format!("param{}", index))) // TODO(antoyo): set name.
+ .collect();
+ let gcc_func = cx.context.new_function(None, FunctionType::Exported, return_type, &params, "__gcc_personality_v0", variadic);
+
+ // We need a normal extern function for the crates that access rust_eh_personality
+ // without defining it, otherwise we'll get a compiler error.
+ //
+ // For the crate defining it, that needs to be a weak alias instead.
+ gcc_func.add_attribute(FnAttribute::Weak);
+
+ let block = gcc_func.new_block("start");
+ let mut args = vec![];
+ for param in &params {
+ args.push(param.to_rvalue());
+ }
+ let call = cx.context.new_call(None, func, &args);
+ if return_type == cx.type_void() {
+ block.add_eval(None, call);
+ block.end_with_void_return(None);
+ }
+ else {
+ block.end_with_return(None, call);
+ }
+ }
+
func
};