aboutsummaryrefslogtreecommitdiff
path: root/gcc/rust
diff options
context:
space:
mode:
authorPhilip Herron <herron.philip@googlemail.com>2023-03-01 12:43:56 +0000
committerPhilip Herron <philip.herron@embecosm.com>2023-03-02 16:35:59 +0000
commit32a9736ef6ea85993a95cd038cf1712378172fb8 (patch)
tree181990151427bae94f128d8e3be51bfd12121ec5 /gcc/rust
parentbaf5c546b59058fcc5aac430e8fbe6e99d355634 (diff)
downloadgcc-32a9736ef6ea85993a95cd038cf1712378172fb8.zip
gcc-32a9736ef6ea85993a95cd038cf1712378172fb8.tar.gz
gcc-32a9736ef6ea85993a95cd038cf1712378172fb8.tar.bz2
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.
Diffstat (limited to 'gcc/rust')
-rw-r--r--gcc/rust/backend/rust-builtins.cc6
-rw-r--r--gcc/rust/backend/rust-compile-intrinsic.cc56
2 files changed, 62 insertions, 0 deletions
diff --git a/gcc/rust/backend/rust-builtins.cc b/gcc/rust/backend/rust-builtins.cc
index 0517a9a..c96553b 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 04b0d3a..85f6e1c 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 &param_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