aboutsummaryrefslogtreecommitdiff
path: root/gcc/rust/backend
diff options
context:
space:
mode:
authorliushuyu <liushuyu011@gmail.com>2024-12-02 14:24:04 -0700
committerArthur Cohen <arthur.cohen@embecosm.com>2025-03-21 12:56:56 +0100
commit33462c81bb01469837c0cfe5039963b53495481a (patch)
tree282101d6b57b005b5d38228c34e8179449009994 /gcc/rust/backend
parent165e7575a96af9ba901af199fa525f069efef574 (diff)
downloadgcc-33462c81bb01469837c0cfe5039963b53495481a.zip
gcc-33462c81bb01469837c0cfe5039963b53495481a.tar.gz
gcc-33462c81bb01469837c0cfe5039963b53495481a.tar.bz2
gccrs: rust/intrinsic: add new "catch_unwind" variant of API
gcc/rust/ChangeLog: * backend/rust-compile-intrinsic.cc: add the new `catch_unwind` variant of the `try` intrinsic: this variant can be seen on Rust 1.78+ and returns `()` instead of `i32`.
Diffstat (limited to 'gcc/rust/backend')
-rw-r--r--gcc/rust/backend/rust-compile-intrinsic.cc57
1 files changed, 47 insertions, 10 deletions
diff --git a/gcc/rust/backend/rust-compile-intrinsic.cc b/gcc/rust/backend/rust-compile-intrinsic.cc
index 77b67c3..0f05458 100644
--- a/gcc/rust/backend/rust-compile-intrinsic.cc
+++ b/gcc/rust/backend/rust-compile-intrinsic.cc
@@ -196,7 +196,15 @@ expect_handler (bool likely)
}
static tree
-try_handler (Context *ctx, TyTy::FnType *fntype);
+try_handler_inner (Context *ctx, TyTy::FnType *fntype, bool is_new_api);
+
+const static std::function<tree (Context *, TyTy::FnType *)>
+try_handler (bool is_new_api)
+{
+ return [is_new_api] (Context *ctx, TyTy::FnType *fntype) {
+ return try_handler_inner (ctx, fntype, is_new_api);
+ };
+}
inline tree
sorry_handler (Context *ctx, TyTy::FnType *fntype)
@@ -245,7 +253,8 @@ static const std::map<std::string,
{"likely", expect_handler (true)},
{"unlikely", expect_handler (false)},
{"assume", assume_handler},
- {"try", try_handler},
+ {"try", try_handler (false)},
+ {"catch_unwind", try_handler (true)},
};
Intrinsics::Intrinsics (Context *ctx) : ctx (ctx) {}
@@ -1272,7 +1281,7 @@ assume_handler (Context *ctx, TyTy::FnType *fntype)
}
static tree
-try_handler (Context *ctx, TyTy::FnType *fntype)
+try_handler_inner (Context *ctx, TyTy::FnType *fntype, bool is_new_api)
{
rust_assert (fntype->get_params ().size () == 3);
@@ -1283,6 +1292,13 @@ try_handler (Context *ctx, TyTy::FnType *fntype)
enter_intrinsic_block (ctx, fndecl);
+ // The following tricks are needed to make sure the try-catch blocks are not
+ // optimized away
+ TREE_READONLY (fndecl) = 0;
+ DECL_DISREGARD_INLINE_LIMITS (fndecl) = 1;
+ DECL_ATTRIBUTES (fndecl) = tree_cons (get_identifier ("always_inline"),
+ NULL_TREE, DECL_ATTRIBUTES (fndecl));
+
// BUILTIN try_handler FN BODY BEGIN
// setup the params
std::vector<Bvariable *> param_vars;
@@ -1296,15 +1312,31 @@ try_handler (Context *ctx, TyTy::FnType *fntype)
tree try_fn = Backend::var_expression (param_vars[0], UNDEF_LOCATION);
tree user_data = Backend::var_expression (param_vars[1], UNDEF_LOCATION);
tree catch_fn = Backend::var_expression (param_vars[2], UNDEF_LOCATION);
- tree normal_return_stmt
- = Backend::return_statement (fndecl, integer_zero_node, BUILTINS_LOCATION);
- tree error_return_stmt
- = Backend::return_statement (fndecl, integer_one_node, BUILTINS_LOCATION);
+ tree normal_return_stmt = NULL_TREE;
+ tree error_return_stmt = NULL_TREE;
tree try_call = Backend::call_expression (try_fn, {user_data}, nullptr,
BUILTINS_LOCATION);
tree catch_call = NULL_TREE;
tree try_block = Backend::block (fndecl, enclosing_scope, {}, UNDEF_LOCATION,
UNDEF_LOCATION);
+
+ if (is_new_api)
+ {
+ auto ret_type = TyTyResolveCompile::get_unit_type ();
+ auto ret_expr = Backend::constructor_expression (ret_type, false, {}, -1,
+ UNDEF_LOCATION);
+ normal_return_stmt
+ = Backend::return_statement (fndecl, ret_expr, BUILTINS_LOCATION);
+ error_return_stmt
+ = Backend::return_statement (fndecl, ret_expr, BUILTINS_LOCATION);
+ }
+ else
+ {
+ normal_return_stmt = Backend::return_statement (fndecl, integer_zero_node,
+ BUILTINS_LOCATION);
+ error_return_stmt = Backend::return_statement (fndecl, integer_one_node,
+ BUILTINS_LOCATION);
+ }
Backend::block_add_statements (try_block,
std::vector<tree>{try_call,
normal_return_stmt});
@@ -1320,17 +1352,22 @@ try_handler (Context *ctx, TyTy::FnType *fntype)
= build_call_expr (builtin_decl_explicit (BUILT_IN_EH_POINTER), 1,
integer_zero_node);
catch_call = Backend::call_expression (catch_fn, {user_data, eh_pointer},
- nullptr, BUILTINS_LOCATION);
+ NULL_TREE, BUILTINS_LOCATION);
tree catch_block = Backend::block (fndecl, enclosing_scope, {},
UNDEF_LOCATION, UNDEF_LOCATION);
Backend::block_add_statements (catch_block,
std::vector<tree>{catch_call,
error_return_stmt});
+ // emulate what cc1plus is doing for C++ try-catch
+ tree inner_eh_construct
+ = Backend::exception_handler_statement (catch_call, NULL_TREE,
+ error_return_stmt,
+ BUILTINS_LOCATION);
// TODO(liushuyu): eh_personality needs to be implemented as a runtime thing
auto eh_construct
- = Backend::exception_handler_statement (try_block, catch_block, NULL_TREE,
- BUILTINS_LOCATION);
+ = Backend::exception_handler_statement (try_block, inner_eh_construct,
+ NULL_TREE, BUILTINS_LOCATION);
ctx->add_statement (eh_construct);
// BUILTIN try_handler FN BODY END
finalize_intrinsic_block (ctx, fndecl);