]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
gccrs: Add missing coercion site logic to return expressions
authorPhilip Herron <herron.philip@googlemail.com>
Tue, 9 May 2023 14:59:46 +0000 (15:59 +0100)
committerArthur Cohen <arthur.cohen@embecosm.com>
Tue, 16 Jan 2024 17:37:15 +0000 (18:37 +0100)
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>
gcc/rust/backend/rust-compile-base.cc
gcc/rust/backend/rust-compile-context.h
gcc/rust/backend/rust-compile-expr.cc
gcc/rust/typecheck/rust-hir-type-check-expr.cc
gcc/testsuite/rust/execute/torture/coercion3.rs [new file with mode: 0644]

index 1a9a3d296913eb9ea1937c4a8c302600ce74d8a2..6bfc19ee3e35a5454cad0c4a1aeffa32e25bd1a6 100644 (file)
@@ -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)
     {
index 36febad8f91dcb8e09e32e88633a95d3bc6c18c7..095d2a0cf6d8d97051fbe9fc0e6836bdd2bc08ce 100644 (file)
@@ -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 (); }
 
index 59afc01f3da45248bad9b26229c494a53b751f41..78448dd84d08a977f2fc8f9667e42ed247102b15 100644 (file)
@@ -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)
     {
index 5eddada3f6293f30b0929da0494fde09078254fe..60e63bcd5426ee8d011f433e737cc19485a9653c 100644 (file)
@@ -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 (file)
index 0000000..ca66dfa
--- /dev/null
@@ -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
+}