diff options
author | Philip Herron <herron.philip@googlemail.com> | 2023-05-09 15:59:46 +0100 |
---|---|---|
committer | Arthur Cohen <arthur.cohen@embecosm.com> | 2024-01-16 18:37:15 +0100 |
commit | b90dc2bdd23127ab998f352eaa592d7d052d8d64 (patch) | |
tree | 56faa326bdfb5ac73a89bf89e1ec18db9b5a3bb1 /gcc | |
parent | f91d7d39067de97adb5c67f052daa2dcd27f3cc6 (diff) | |
download | gcc-b90dc2bdd23127ab998f352eaa592d7d052d8d64.zip gcc-b90dc2bdd23127ab998f352eaa592d7d052d8d64.tar.gz gcc-b90dc2bdd23127ab998f352eaa592d7d052d8d64.tar.bz2 |
gccrs: Add missing coercion site logic to return expressions
gcc/rust/ChangeLog:
* backend/rust-compile-base.cc: track return type in fncontext
* backend/rust-compile-context.h (struct fncontext): likewise
* backend/rust-compile-expr.cc (CompileExpr::visit): apply coercion site
(CompileExpr::generate_closure_function): update push_context
* typecheck/rust-hir-type-check-expr.cc (TypeCheckExpr::visit): likewise
gcc/testsuite/ChangeLog:
* rust/execute/torture/coercion3.rs: New test.
Signed-off-by: Philip Herron <herron.philip@googlemail.com>
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/rust/backend/rust-compile-base.cc | 4 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile-context.h | 5 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile-expr.cc | 21 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check-expr.cc | 7 | ||||
-rw-r--r-- | gcc/testsuite/rust/execute/torture/coercion3.rs | 35 |
5 files changed, 63 insertions, 9 deletions
diff --git a/gcc/rust/backend/rust-compile-base.cc b/gcc/rust/backend/rust-compile-base.cc index 1a9a3d2..6bfc19e 100644 --- a/gcc/rust/backend/rust-compile-base.cc +++ b/gcc/rust/backend/rust-compile-base.cc @@ -639,7 +639,7 @@ HIRCompileBase::compile_function ( ctx->add_statement (ret_var_stmt); - ctx->push_fn (fndecl, return_address); + ctx->push_fn (fndecl, return_address, tyret); compile_function_body (fndecl, *function_body, tyret); tree bind_tree = ctx->pop_block (); @@ -712,7 +712,7 @@ HIRCompileBase::compile_constant_item ( &ret_var_stmt); ctx->add_statement (ret_var_stmt); - ctx->push_fn (fndecl, return_address); + ctx->push_fn (fndecl, return_address, resolved_type); if (is_block_expr) { diff --git a/gcc/rust/backend/rust-compile-context.h b/gcc/rust/backend/rust-compile-context.h index 36febad..095d2a0 100644 --- a/gcc/rust/backend/rust-compile-context.h +++ b/gcc/rust/backend/rust-compile-context.h @@ -35,6 +35,7 @@ struct fncontext { tree fndecl; ::Bvariable *ret_addr; + TyTy::BaseType *retty; }; class Context @@ -267,9 +268,9 @@ public: return true; } - void push_fn (tree fn, ::Bvariable *ret_addr) + void push_fn (tree fn, ::Bvariable *ret_addr, TyTy::BaseType *retty) { - fn_stack.push_back (fncontext{fn, ret_addr}); + fn_stack.push_back (fncontext{fn, ret_addr, retty}); } void pop_fn () { fn_stack.pop_back (); } diff --git a/gcc/rust/backend/rust-compile-expr.cc b/gcc/rust/backend/rust-compile-expr.cc index 59afc01..78448dd 100644 --- a/gcc/rust/backend/rust-compile-expr.cc +++ b/gcc/rust/backend/rust-compile-expr.cc @@ -114,6 +114,25 @@ CompileExpr::visit (HIR::ReturnExpr &expr) tree return_value = expr.has_return_expr () ? CompileExpr::Compile (expr.return_expr.get (), ctx) : unit_expression (ctx, expr.get_locus ()); + + if (expr.has_return_expr ()) + { + HirId id = expr.get_mappings ().get_hirid (); + Location rvalue_locus = expr.return_expr->get_locus (); + + TyTy::BaseType *expected = fncontext.retty; + Location lvalue_locus + = ctx->get_mappings ()->lookup_location (expected->get_ref ()); + + TyTy::BaseType *actual = nullptr; + bool ok = ctx->get_tyctx ()->lookup_type ( + expr.return_expr->get_mappings ().get_hirid (), &actual); + rust_assert (ok); + + return_value = coercion_site (id, return_value, actual, expected, + lvalue_locus, rvalue_locus); + } + tree return_stmt = ctx->get_backend ()->return_statement (fncontext.fndecl, return_value, expr.get_locus ()); @@ -2804,7 +2823,7 @@ CompileExpr::generate_closure_function (HIR::ClosureExpr &expr, ctx->add_statement (ret_var_stmt); - ctx->push_fn (fndecl, return_address); + ctx->push_fn (fndecl, return_address, tyret); if (is_block_expr) { diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.cc b/gcc/rust/typecheck/rust-hir-type-check-expr.cc index 5eddada..60e63bc 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-expr.cc +++ b/gcc/rust/typecheck/rust-hir-type-check-expr.cc @@ -164,10 +164,9 @@ TypeCheckExpr::visit (HIR::ReturnExpr &expr) ? TypeCheckExpr::Resolve (expr.get_expr ()) : TyTy::TupleType::get_unit_type (expr.get_mappings ().get_hirid ()); - infered = unify_site (expr.get_mappings ().get_hirid (), - TyTy::TyWithLocation (fn_return_tyty), - TyTy::TyWithLocation (expr_ty, expr_locus), - expr.get_locus ()); + coercion_site (expr.get_mappings ().get_hirid (), + TyTy::TyWithLocation (fn_return_tyty), + TyTy::TyWithLocation (expr_ty, expr_locus), expr.get_locus ()); infered = new TyTy::NeverType (expr.get_mappings ().get_hirid ()); } diff --git a/gcc/testsuite/rust/execute/torture/coercion3.rs b/gcc/testsuite/rust/execute/torture/coercion3.rs new file mode 100644 index 0000000..ca66dfa --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/coercion3.rs @@ -0,0 +1,35 @@ +// { dg-output "123\n" } +trait A { + fn get_int(&self) -> i32; +} + +impl A for i32 { + fn get_int(&self) -> i32 { + *self + } +} + +fn get_dyn_a(x: &i32) -> &dyn A { + return x; +} + +fn clobber_stack() { + let _z: [usize; 8] = [1, 2, 3, 4, 5, 6, 7, 8]; +} + +extern "C" { + fn printf(s: *const i8, ...) -> i32; +} + +fn main() -> i32 { + let x = 123; + let y = get_dyn_a(&x); + clobber_stack(); + let value = y.get_int(); + let fmt_string = "%d\n\0" as *const str as *const i8; + unsafe { + printf(fmt_string, value); + } + + 0 +} |