diff options
author | liushuyu <liushuyu011@gmail.com> | 2024-12-02 14:24:04 -0700 |
---|---|---|
committer | Arthur Cohen <arthur.cohen@embecosm.com> | 2025-03-21 12:56:56 +0100 |
commit | 33462c81bb01469837c0cfe5039963b53495481a (patch) | |
tree | 282101d6b57b005b5d38228c34e8179449009994 /gcc/rust/backend | |
parent | 165e7575a96af9ba901af199fa525f069efef574 (diff) | |
download | gcc-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.cc | 57 |
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); |