aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorPhilip Herron <herron.philip@googlemail.com>2023-05-09 15:59:46 +0100
committerArthur Cohen <arthur.cohen@embecosm.com>2024-01-16 18:37:15 +0100
commitb90dc2bdd23127ab998f352eaa592d7d052d8d64 (patch)
tree56faa326bdfb5ac73a89bf89e1ec18db9b5a3bb1 /gcc
parentf91d7d39067de97adb5c67f052daa2dcd27f3cc6 (diff)
downloadgcc-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.cc4
-rw-r--r--gcc/rust/backend/rust-compile-context.h5
-rw-r--r--gcc/rust/backend/rust-compile-expr.cc21
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-expr.cc7
-rw-r--r--gcc/testsuite/rust/execute/torture/coercion3.rs35
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
+}