[gccrs COMMIT] gccrs: constructors that get borrowed need to be addressable
gerris.rs@gmail.com
gerris.rs@gmail.com
Thu Sep 10 19:20:00 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>
---
This change was merged into the gccrs repository and is posted here for
upstream visibility and potential drive-by review, as requested by GCC
release managers.
Each commit email contains a link to its details on github from where you can
find the Pull-Request and associated discussions.
Commit on github: https://github.com/Rust-GCC/gccrs/commit/1a69267c329f434e3296f48f7b4694a91cb8d7e7
The commit has been mentioned in the following issue(s):
- Rust-GCC/gccrs#4867: https://github.com/Rust-GCC/gccrs/issues/4867
- Rust-GCC/gccrs#4868: https://github.com/Rust-GCC/gccrs/issues/4868
The commit has been mentioned in the following pull-request(s):
- https://github.com/Rust-GCC/gccrs/pull/4877
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 3229dea36..6480e946b 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 22d0ed3bd..44fd235b9 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 000000000..7e6852347
--- /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) {}
base-commit: 930d05a0ec0e0b566bfabf7e931d7e4cff402158
--
2.55.0
More information about the Gcc-rust
mailing list