From: Islam-Imad <[email protected]>
CompoundAssignmentExpr codegen was missing the final assignment statement
when it was evaluated in a const context.
gcc/rust/ChangeLog:
* backend/rust-compile-expr.cc (CompileExpr::visit): Emit the
missing assignment for CompoundAssignmentExpr.
gcc/testsuite/ChangeLog:
* rust/compile/const-compound-assignment.rs: New test.
* rust/execute/const-compound-assignment.rs: New test.
Signed-off-by: Islam-Imad <[email protected]>
---
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/679aad3804e8443ec5181fd184785d82aec42bdf
The commit has been mentioned in the following pull-request(s):
- https://github.com/Rust-GCC/gccrs/pull/4520
gcc/rust/backend/rust-compile-expr.cc | 27 +++++++-------
.../rust/compile/const-compound-assignment.rs | 15 ++++++++
.../rust/execute/const-compound-assignment.rs | 35 +++++++++++++++++++
3 files changed, 63 insertions(+), 14 deletions(-)
create mode 100644 gcc/testsuite/rust/compile/const-compound-assignment.rs
create mode 100644 gcc/testsuite/rust/execute/const-compound-assignment.rs
diff --git a/gcc/rust/backend/rust-compile-expr.cc
b/gcc/rust/backend/rust-compile-expr.cc
index 55b3534a1..6b21a7745 100644
--- a/gcc/rust/backend/rust-compile-expr.cc
+++ b/gcc/rust/backend/rust-compile-expr.cc
@@ -192,9 +192,9 @@ void
CompileExpr::visit (HIR::CompoundAssignmentExpr &expr)
{
auto op = expr.get_expr_type ();
- auto lhs = CompileExpr::Compile (expr.get_lhs (), ctx);
- auto rhs = CompileExpr::Compile (expr.get_rhs (), ctx);
-
+ tree lhs = CompileExpr::Compile (expr.get_lhs (), ctx);
+ tree rhs = CompileExpr::Compile (expr.get_rhs (), ctx);
+ tree compound_assignment = NULL_TREE;
// this might be an operator overload situation lets check
TyTy::FnType *fntype;
bool is_op_overload = ctx->get_tyctx ()->lookup_operator_overload (
@@ -203,38 +203,37 @@ CompileExpr::visit (HIR::CompoundAssignmentExpr &expr)
{
auto lang_item_type = LangItem::CompoundAssignmentOperatorToLangItem (
expr.get_expr_type ());
- auto compound_assignment
+ compound_assignment
= resolve_operator_overload (lang_item_type, expr, lhs, rhs,
expr.get_lhs (), expr.get_rhs ());
- ctx->add_statement (compound_assignment);
-
- return;
}
-
- if (ctx->in_fn () && !ctx->const_context_p ())
+ else if (ctx->in_fn () && !ctx->const_context_p ())
{
- auto tmp = NULL_TREE;
+ tree tmp = NULL_TREE;
Bvariable *receiver
= Backend::temporary_variable (ctx->peek_fn ().fndecl, NULL_TREE,
TREE_TYPE (lhs), lhs, true,
expr.get_locus (), &tmp);
- auto check
+ tree check
= Backend::arithmetic_or_logical_expression_checked (op, lhs, rhs,
expr.get_locus (),
receiver);
ctx->add_statement (check);
-
- translated
+ compound_assignment
= Backend::assignment_statement (lhs,
receiver->get_tree (expr.get_locus ()),
expr.get_locus ());
}
else
{
- translated
+ tree expr_tree
= Backend::arithmetic_or_logical_expression (op, lhs, rhs,
expr.get_locus ());
+ compound_assignment
+ = Backend::assignment_statement (lhs, expr_tree, expr.get_locus ());
}
+ ctx->add_statement (compound_assignment);
+ translated = unit_expression (expr.get_locus ());
}
void
diff --git a/gcc/testsuite/rust/compile/const-compound-assignment.rs
b/gcc/testsuite/rust/compile/const-compound-assignment.rs
new file mode 100644
index 000000000..3ec68ba44
--- /dev/null
+++ b/gcc/testsuite/rust/compile/const-compound-assignment.rs
@@ -0,0 +1,15 @@
+// { dg-options "-w -O0 -fdump-tree-gimple" }
+#![feature(no_core)]
+#![no_core]
+
+const fn test(mut x: i32) -> i32 {
+ x += 5;
+ x
+}
+
+const X: i32 = test(10);
+
+fn main() {
+ // { dg-final { scan-tree-dump-times {x = 15} 1 gimple } }
+ let x = X;
+}
\ No newline at end of file
diff --git a/gcc/testsuite/rust/execute/const-compound-assignment.rs
b/gcc/testsuite/rust/execute/const-compound-assignment.rs
new file mode 100644
index 000000000..ce5ddde8e
--- /dev/null
+++ b/gcc/testsuite/rust/execute/const-compound-assignment.rs
@@ -0,0 +1,35 @@
+// { dg-output "45\r*\n55\r*\n" }
+#![feature(no_core)]
+#![no_core]
+
+extern "C" {
+ fn printf(s: *const i8, ...);
+}
+
+fn dump_number(num: i32) {
+ unsafe {
+ let a = "%i\n\0";
+ let c = a as *const str as *const i8;
+ printf(c, num);
+ }
+}
+
+const fn play(b: i32) -> i32 {
+ let mut res = 0;
+ let mut i = 0;
+ while i < b {
+ res += i;
+ i += 1;
+ }
+ res
+}
+
+fn main() -> i32 {
+ const A: i32 = play(10);
+ dump_number(A);
+
+ let b: i32 = play(11);
+ dump_number(b);
+
+ 0
+}
base-commit: 3432069729f6868c92de792e09d0c803dcc1618e
--
2.53.0