From: Islam-Imad Date: Sat, 11 Apr 2026 17:31:45 +0000 (+0200) Subject: gccrs: Fix corrupted GIMPLE for CompoundAssignmentExpr in const context X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7948e60bc9a0a54fa2315d005ef597a6f91e070d;p=thirdparty%2Fgcc.git gccrs: Fix corrupted GIMPLE for CompoundAssignmentExpr in const context 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 --- diff --git a/gcc/rust/backend/rust-compile-expr.cc b/gcc/rust/backend/rust-compile-expr.cc index 55b3534a1be..6b21a774577 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 00000000000..3ec68ba4416 --- /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 00000000000..ce5ddde8e42 --- /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 +}