public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc/devel/rust/master] gccrs: add uninit intrinsic
@ 2023-03-05 11:42 Thomas Schwinge
0 siblings, 0 replies; only message in thread
From: Thomas Schwinge @ 2023-03-05 11:42 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:32a9736ef6ea85993a95cd038cf1712378172fb8
commit 32a9736ef6ea85993a95cd038cf1712378172fb8
Author: Philip Herron <herron.philip@googlemail.com>
Date: Wed Mar 1 12:43:56 2023 +0000
gccrs: add uninit intrinsic
Following an investigation from rustc and discussions on zulip the
recommendation was that for uninit we memset to 0x01 which is less likely
to be a null ptr but still an invalid reference.
Fixes #1899
Signed-off-by: Philip Herron <herron.philip@googlemail.com>
gcc/rust/ChangeLog:
* backend/rust-builtins.cc (BuiltinsContext::setup): add memset builtin to the map
* backend/rust-compile-intrinsic.cc (uninit_handler): implement uninit intrinsic
gcc/testsuite/ChangeLog:
* rust/compile/torture/uninit-intrinsic-1.rs: New test.
Diff:
---
gcc/rust/backend/rust-builtins.cc | 6 +++
gcc/rust/backend/rust-compile-intrinsic.cc | 56 ++++++++++++++++++++++
.../rust/compile/torture/uninit-intrinsic-1.rs | 21 ++++++++
3 files changed, 83 insertions(+)
diff --git a/gcc/rust/backend/rust-builtins.cc b/gcc/rust/backend/rust-builtins.cc
index 0517a9aeaf0..c96553b8c59 100644
--- a/gcc/rust/backend/rust-builtins.cc
+++ b/gcc/rust/backend/rust-builtins.cc
@@ -249,6 +249,12 @@ BuiltinsContext::setup ()
size_type_node, NULL_TREE),
0);
+ define_builtin ("memset", BUILT_IN_MEMSET, "__builtin_memset", "memset",
+ build_function_type_list (void_type_node, ptr_type_node,
+ integer_type_node, size_type_node,
+ NULL_TREE),
+ 0);
+
define_builtin ("prefetch", BUILT_IN_PREFETCH, "__builtin_prefetch",
"prefetch",
build_varargs_function_type_list (
diff --git a/gcc/rust/backend/rust-compile-intrinsic.cc b/gcc/rust/backend/rust-compile-intrinsic.cc
index 04b0d3a2611..85f6e1c63d2 100644
--- a/gcc/rust/backend/rust-compile-intrinsic.cc
+++ b/gcc/rust/backend/rust-compile-intrinsic.cc
@@ -81,6 +81,8 @@ static tree
copy_nonoverlapping_handler (Context *ctx, TyTy::FnType *fntype);
static tree
op_with_overflow_inner (Context *ctx, TyTy::FnType *fntype, tree_code op);
+static tree
+uninit_handler (Context *ctx, TyTy::FnType *fntype);
enum class Prefetch
{
@@ -202,6 +204,7 @@ static const std::map<std::string,
{"unchecked_rem", unchecked_op_handler (TRUNC_MOD_EXPR)},
{"unchecked_shl", unchecked_op_handler (LSHIFT_EXPR)},
{"unchecked_shr", unchecked_op_handler (RSHIFT_EXPR)},
+ {"uninit", uninit_handler},
};
Intrinsics::Intrinsics (Context *ctx) : ctx (ctx) {}
@@ -986,5 +989,58 @@ unchecked_op_inner (Context *ctx, TyTy::FnType *fntype, tree_code op)
return fndecl;
}
+static tree
+uninit_handler (Context *ctx, TyTy::FnType *fntype)
+{
+ // uninit has _zero_ parameters its parameter is the generic one
+ rust_assert (fntype->get_params ().size () == 0);
+
+ tree lookup = NULL_TREE;
+ if (check_for_cached_intrinsic (ctx, fntype, &lookup))
+ return lookup;
+
+ auto fndecl = compile_intrinsic_function (ctx, fntype);
+
+ // get the template parameter type tree fn size_of<T>();
+ rust_assert (fntype->get_num_substitutions () == 1);
+ auto ¶m_mapping = fntype->get_substs ().at (0);
+ const TyTy::ParamType *param_tyty = param_mapping.get_param_ty ();
+ TyTy::BaseType *resolved_tyty = param_tyty->resolve ();
+ tree template_parameter_type
+ = TyTyResolveCompile::compile (ctx, resolved_tyty);
+
+ enter_intrinsic_block (ctx, fndecl);
+
+ // BUILTIN size_of FN BODY BEGIN
+
+ tree memset_builtin = error_mark_node;
+ BuiltinsContext::get ().lookup_simple_builtin ("memset", &memset_builtin);
+ rust_assert (memset_builtin != error_mark_node);
+
+ // call memset with 0x01 and size of the thing see
+ // https://github.com/Rust-GCC/gccrs/issues/1899
+
+ tree dst = DECL_RESULT (fndecl);
+ 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);
+ 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)},
+ Location ());
+ ctx->add_statement (return_statement);
+ // BUILTIN size_of FN BODY END
+
+ finalize_intrinsic_block (ctx, fndecl);
+
+ return fndecl;
+}
+
} // namespace Compile
} // namespace Rust
diff --git a/gcc/testsuite/rust/compile/torture/uninit-intrinsic-1.rs b/gcc/testsuite/rust/compile/torture/uninit-intrinsic-1.rs
new file mode 100644
index 00000000000..0c6772b5f38
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/uninit-intrinsic-1.rs
@@ -0,0 +1,21 @@
+mod intrinsics {
+ extern "rust-intrinsic" {
+ pub fn uninit<T>() -> T;
+ }
+}
+
+mod mem {
+ pub unsafe fn uninitialized<T>() -> T {
+ intrinsics::uninit()
+ }
+}
+
+struct Foo(i32, i32);
+// { dg-warning "struct is never constructed: .Foo." "" { target *-*-* } .-1 }
+// FIXME ^^ above is a bad-warning
+
+impl Foo {
+ pub fn new() -> Self {
+ unsafe { mem::uninitialized::<Foo>() }
+ }
+}
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2023-03-05 11:42 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-03-05 11:42 [gcc/devel/rust/master] gccrs: add uninit intrinsic Thomas Schwinge
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).