Skip to content

Commit 064dddd

Browse files
nsvkeP-E-P
authored andcommitted
intrinsic: Add assert_zero_valid
This patch adds the 'assert_zero_valid' intrinsic to the compiler. Properly implementing this intrinsic requires layout engine support to detect types that cannot be safely zero-initialized (e.g., references and NonNull types). Since gccrs currently lacks this capability, it is implemented as a temporary stub that always returns unit `()`. Normally, this intrinsic should inject a runtime panic during codegen if the provided type does not permit zero-initialization. gcc/rust/ChangeLog: * backend/rust-compile-intrinsic.cc (generic_intrinsics): Add assert_zero_valid to map. * backend/rust-intrinsic-handlers.cc (assert_zero_valid_handler): New function. * backend/rust-intrinsic-handlers.h (assert_zero_valid_handler): New declaration. * typecheck/rust-hir-type-check-intrinsic.cc (IntrinsicChecker::intrinsic_rules): Add new signature rule for assert_zero_valid. * util/rust-intrinsic-values.h (class Intrinsics): Add ASSERT_ZERO_VALID constexpr. gcc/testsuite/ChangeLog: * rust/compile/assert_zero_valid.rs: New test. Signed-off-by: Enes Cevik <enes@nsvke.com>
1 parent 7cc595f commit 064dddd

6 files changed

Lines changed: 73 additions & 1 deletion

File tree

gcc/rust/backend/rust-compile-intrinsic.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ static const std::map<std::string, handlers::HandlerBuilder> generic_intrinsics
3131
= {{IValue::OFFSET, handlers::offset},
3232
{IValue::ARITH_OFFSET, handlers::arith_offset_handler},
3333
{IValue::WRITE_BYTES, handlers::write_bytes_handler},
34+
{IValue::ASSERT_ZERO_VALID, handlers::assert_zero_valid_handler},
3435
{IValue::SIZE_OF, handlers::sizeof_handler},
3536
{IValue::SIZE_OF_VAL, handlers::size_of_val_handler},
3637
{IValue::MIN_ALIGN_OF, handlers::min_align_of_handler},

gcc/rust/backend/rust-intrinsic-handlers.cc

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2176,6 +2176,57 @@ arith_offset_handler (Context *ctx, TyTy::FnType *fntype, location_t expr_locus)
21762176
return fndecl;
21772177
}
21782178

2179+
/**
2180+
* pub fn assert_zero_valid<T>();
2181+
*
2182+
* TODO: Since gccrs currently lacks comprehensive layout engine support for
2183+
* validity ranges (such as `rustc_layout_scalar_valid_range_start`), we cannot
2184+
* accurately determine if a type is safely zeroable. Therefore, this is
2185+
* implemented as a temporary no-op stub that always returns void (unit) and
2186+
* succeeds for all types.
2187+
*/
2188+
tree
2189+
assert_zero_valid_handler (Context *ctx, TyTy::FnType *fntype, location_t)
2190+
{
2191+
rust_assert (fntype->get_params ().size () == 0);
2192+
2193+
tree lookup = NULL_TREE;
2194+
if (check_for_cached_intrinsic (ctx, fntype, &lookup))
2195+
return lookup;
2196+
2197+
auto fndecl = compile_intrinsic_function (ctx, fntype);
2198+
2199+
rust_assert (fntype->get_num_substitutions () == 1);
2200+
auto &param_mapping = fntype->get_substs ().at (0);
2201+
const auto param_tyty = param_mapping.get_param_ty ();
2202+
auto resolved_tyty = param_tyty->resolve ();
2203+
2204+
// Safely resolve the template parameter type to ensure monomorphization
2205+
// works.
2206+
// Suppress unused-variable warning since layout verification is a FIXME.
2207+
[[gnu::unused]] tree template_parameter_type
2208+
= TyTyResolveCompile::compile (ctx, resolved_tyty);
2209+
2210+
enter_intrinsic_block (ctx, fndecl);
2211+
2212+
// BUILTIN assert_zero_valid FN BODY BEGIN
2213+
2214+
// TODO: Implement layout verification via template_parameter_type once
2215+
// niche-filling and valid scalar ranges are supported in the layout engine.
2216+
// If invalid, this should emit a panic.
2217+
2218+
// we always return unit for now.
2219+
auto return_statement
2220+
= Backend::return_statement (fndecl, void_node, UNDEF_LOCATION);
2221+
ctx->add_statement (return_statement);
2222+
2223+
// BUILTIN assert_zero_valid FN BODY END
2224+
2225+
finalize_intrinsic_block (ctx, fndecl);
2226+
2227+
return fndecl;
2228+
}
2229+
21792230
} // namespace handlers
21802231
} // namespace Compile
21812232
} // namespace Rust

gcc/rust/backend/rust-intrinsic-handlers.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,8 @@ tree write_bytes_handler (Context *ctx, TyTy::FnType *fntype,
104104
location_t expr_locus);
105105
tree arith_offset_handler (Context *ctx, TyTy::FnType *fntype,
106106
location_t expr_locus);
107+
tree assert_zero_valid_handler (Context *ctx, TyTy::FnType *fntype,
108+
location_t expr_locus);
107109

108110
} // namespace handlers
109111

gcc/rust/typecheck/rust-hir-type-check-intrinsic.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,8 @@ const std::unordered_map<std::string, IntrinsicRules>
311311
// fn write_bytes<T>(dst: *mut T, val: u8, count: usize)
312312
{IValue::WRITE_BYTES,
313313
{1, {IRT::MutPtrFirstGeneric, IRT::U8, IRT::Usize}, IRT::Unit}},
314-
314+
// pub fn assert_zero_valid<T>();
315+
{IValue::ASSERT_ZERO_VALID, {1, {}, IRT::Unit}},
315316
};
316317

317318
IntrinsicCheckResult

gcc/rust/util/rust-intrinsic-values.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@ class Intrinsics
161161
static constexpr auto &BLACK_BOX = "black_box";
162162
static constexpr auto &ARITH_OFFSET = "arith_offset";
163163
static constexpr auto &WRITE_BYTES = "write_bytes";
164+
static constexpr auto &ASSERT_ZERO_VALID = "assert_zero_valid";
164165
};
165166
} // namespace Values
166167
} // namespace Rust
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#![feature(intrinsics, no_core, lang_items)]
2+
#![no_core]
3+
4+
#[lang = "sized"]
5+
trait Sized {}
6+
7+
extern "rust-intrinsic" {
8+
fn assert_zero_valid<T>();
9+
}
10+
11+
fn main() {
12+
unsafe {
13+
assert_zero_valid::<i32>();
14+
assert_zero_valid::<&i32>();
15+
}
16+
}

0 commit comments

Comments
 (0)