From: liushuyu <liushuyu...@gmail.com> 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`. --- gcc/rust/backend/rust-compile-intrinsic.cc | 57 ++++++++++++++++++---- 1 file changed, 47 insertions(+), 10 deletions(-)
diff --git a/gcc/rust/backend/rust-compile-intrinsic.cc b/gcc/rust/backend/rust-compile-intrinsic.cc index 77b67c36c3e..0f054588220 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); -- 2.45.2