]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
gccrs: Fix bad uninit intrinsic
authorPhilip Herron <herron.philip@googlemail.com>
Mon, 28 Aug 2023 13:20:04 +0000 (14:20 +0100)
committerArthur Cohen <arthur.cohen@embecosm.com>
Tue, 16 Jan 2024 18:00:34 +0000 (19:00 +0100)
We were using the DECL_RESULT but this just contains the TREE_TYPE of the
retval. It was also missing taking the address of the destination for the
memset call. This changes the code to create a temp variable for the return
value and asserts the destination size is the same as the size of the
template param.

Fixes #2583

gcc/rust/ChangeLog:

* backend/rust-compile-intrinsic.cc (enter_intrinsic_block): take the locals vector
(uninit_handler): make a temp variable and use the address of it

gcc/testsuite/ChangeLog:

* rust/execute/torture/issue-2583.rs: New test.

Signed-off-by: Philip Herron <herron.philip@googlemail.com>
gcc/rust/backend/rust-compile-intrinsic.cc
gcc/testsuite/rust/execute/torture/issue-2583.rs [new file with mode: 0644]

index b5cb84b22a9a286670529ba0f002a964ecab387e..5c1cde3b202b8d35bef3047c0765c0729d0907a7 100644 (file)
@@ -315,13 +315,14 @@ compile_intrinsic_function (Context *ctx, TyTy::FnType *fntype)
 }
 
 static void
-enter_intrinsic_block (Context *ctx, tree fndecl)
+enter_intrinsic_block (Context *ctx, tree fndecl,
+                      const std::vector<Bvariable *> &vars = {})
 {
   tree enclosing_scope = NULL_TREE;
   location_t start_location = UNDEF_LOCATION;
   location_t end_location = UNDEF_LOCATION;
 
-  auto block = ctx->get_backend ()->block (fndecl, enclosing_scope, {},
+  auto block = ctx->get_backend ()->block (fndecl, enclosing_scope, vars,
                                           start_location, end_location);
 
   ctx->push_block (block);
@@ -1010,7 +1011,19 @@ uninit_handler (Context *ctx, TyTy::FnType *fntype)
   tree template_parameter_type
     = TyTyResolveCompile::compile (ctx, resolved_tyty);
 
-  enter_intrinsic_block (ctx, fndecl);
+  // result temporary
+  tree dst_type = TREE_TYPE (DECL_RESULT (fndecl));
+  rust_assert (TYPE_SIZE_UNIT (template_parameter_type)
+              == TYPE_SIZE_UNIT (dst_type));
+
+  tree tmp_stmt = error_mark_node;
+  Bvariable *bvar
+    = ctx->get_backend ()->temporary_variable (fndecl, NULL_TREE, dst_type,
+                                              NULL_TREE,
+                                              true /*address_is_taken*/,
+                                              UNDEF_LOCATION, &tmp_stmt);
+
+  enter_intrinsic_block (ctx, fndecl, {bvar});
 
   // BUILTIN size_of FN BODY BEGIN
 
@@ -1021,20 +1034,20 @@ uninit_handler (Context *ctx, TyTy::FnType *fntype)
   // call memset with 0x01 and size of the thing see
   // https://github.com/Rust-GCC/gccrs/issues/1899
 
-  tree dst = DECL_RESULT (fndecl);
+  tree dst = bvar->get_tree (BUILTINS_LOCATION);
+  tree dst_addr = build_fold_addr_expr_loc (BUILTINS_LOCATION, dst);
   tree constant_byte = build_int_cst (integer_type_node, 0x01);
   tree size_expr = TYPE_SIZE_UNIT (template_parameter_type);
 
   tree memset_call = build_call_expr_loc (BUILTINS_LOCATION, memset_builtin, 3,
-                                         dst, constant_byte, size_expr);
+                                         dst_addr, constant_byte, size_expr);
   TREE_READONLY (memset_call) = 0;
   TREE_SIDE_EFFECTS (memset_call) = 1;
 
   ctx->add_statement (memset_call);
 
   auto return_statement
-    = ctx->get_backend ()->return_statement (fndecl, DECL_RESULT (fndecl),
-                                            UNDEF_LOCATION);
+    = ctx->get_backend ()->return_statement (fndecl, dst, UNDEF_LOCATION);
   ctx->add_statement (return_statement);
   // BUILTIN size_of FN BODY END
 
diff --git a/gcc/testsuite/rust/execute/torture/issue-2583.rs b/gcc/testsuite/rust/execute/torture/issue-2583.rs
new file mode 100644 (file)
index 0000000..46f501e
--- /dev/null
@@ -0,0 +1,13 @@
+#[lang = "sized"]
+pub trait Sized {}
+
+mod intrinsics {
+    extern "rust-intrinsic" {
+        pub fn uninit<T>() -> T;
+    }
+}
+
+pub fn main() -> i32 {
+    let _val: usize = unsafe { intrinsics::uninit() };
+    0
+}