[COMMITTED 71/83] gccrs: constructors that get borrowed need to be addressable
arthur.cohen@opensrcsec.com
arthur.cohen@opensrcsec.com
Wed Sep 16 12:30:30 GMT 2026
From: Philip Herron <herron.philip@googlemail.com>
When we have const expr dealing with slices we end up taking a pointer of
an array as the data pointer. This is a cosntructor expr ususally but const
eval expects these to be addressable objects like tmps holding onto the data
but we get away with this in regular compilation because gcc optimizes it.
Fixes Rust-GCC/gccrs#4867
Fixes Rust-GCC/gccrs#4868
gcc/rust/ChangeLog:
* backend/rust-compile-expr.cc (CompileExpr::visit): make addressable
* backend/rust-constexpr.cc (eval_store_expression): port over missing cp/constexpr.cc
gcc/testsuite/ChangeLog:
* rust/compile/issue-4867.rs: New test.
Signed-off-by: Philip Herron <herron.philip@googlemail.com>
---
gcc/rust/backend/rust-compile-expr.cc | 15 +++++++++++++
gcc/rust/backend/rust-constexpr.cc | 9 +++++++-
gcc/testsuite/rust/compile/issue-4867.rs | 28 ++++++++++++++++++++++++
3 files changed, 51 insertions(+), 1 deletion(-)
create mode 100644 gcc/testsuite/rust/compile/issue-4867.rs
diff --git a/gcc/rust/backend/rust-compile-expr.cc b/gcc/rust/backend/rust-compile-expr.cc
index 3229dea3646..6480e946b15 100644
--- a/gcc/rust/backend/rust-compile-expr.cc
+++ b/gcc/rust/backend/rust-compile-expr.cc
@@ -1204,6 +1204,21 @@ CompileExpr::visit (HIR::BorrowExpr &expr)
return;
}
+ // const expr needs these to be addressable temps otherwise it cant cope. We
+ // get away with this during regular compilation because gcc middle end
+ // optimizes it
+ if (TREE_CODE (main_expr) == CONSTRUCTOR && !TREE_CONSTANT (main_expr))
+ {
+ tree init_stmt = NULL_TREE;
+ Bvariable *tmp
+ = Backend::temporary_variable (ctx->peek_fn ().fndecl,
+ ctx->peek_enclosing_scope (),
+ TREE_TYPE (main_expr), main_expr, true,
+ expr.get_locus (), &init_stmt);
+ ctx->add_statement (init_stmt);
+ main_expr = Backend::var_expression (tmp, expr.get_locus ());
+ }
+
TyTy::BaseType *tyty = nullptr;
if (!ctx->get_tyctx ()->lookup_type (expr.get_mappings ().get_hirid (),
&tyty))
diff --git a/gcc/rust/backend/rust-constexpr.cc b/gcc/rust/backend/rust-constexpr.cc
index 22d0ed3bd29..44fd235b925 100644
--- a/gcc/rust/backend/rust-constexpr.cc
+++ b/gcc/rust/backend/rust-constexpr.cc
@@ -2763,7 +2763,14 @@ eval_store_expression (const constexpr_ctx *ctx, tree t, bool lval,
/* Evaluate the value to be stored without knowing what object it will be
stored in, so that any side-effects happen first. */
if (!SCALAR_TYPE_P (type))
- new_ctx.ctor = new_ctx.object = NULL_TREE;
+ {
+ new_ctx.ctor = new_ctx.object = NULL_TREE;
+ if (TREE_CODE (init) == CONSTRUCTOR)
+ {
+ new_ctx.ctor = build_constructor (TREE_TYPE (init), NULL);
+ CONSTRUCTOR_NO_CLEARING (new_ctx.ctor) = true;
+ }
+ }
init = eval_constant_expression (&new_ctx, init, false, non_constant_p,
overflow_p, jump_target);
if (*non_constant_p)
diff --git a/gcc/testsuite/rust/compile/issue-4867.rs b/gcc/testsuite/rust/compile/issue-4867.rs
new file mode 100644
index 00000000000..7e6852347c7
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-4867.rs
@@ -0,0 +1,28 @@
+// { dg-options "-w" }
+#![feature(intrinsics, staged_api)]
+#![feature(no_core, lang_items)]
+#![no_core]
+#[lang = "sized"]
+pub trait Sized {}
+const X: () = trigger();
+extern "rust-intrinsic" {
+ #[rustc_const_stable(feature = "const_transmute", since = "1.0.0")]
+ fn transmute<T, U>(x: T) -> U;
+}
+struct Arg {
+ formatter: fn(&i8),
+ value: &'static i8,
+}
+const fn new<T>(x: &'static T, f: fn(&T)) -> Arg {
+ unsafe {
+ Arg {
+ formatter: transmute(f),
+ value: transmute(x),
+ }
+ }
+}
+const fn consume(x: &[Arg]) {}
+const fn trigger() {
+ consume({ &[new(&1i8, display)] });
+}
+fn display(x: &i8) {}
--
2.50.1
More information about the Gcc-rust
mailing list