https://gcc.gnu.org/g:ef0d55f4a8f37941a51fad68970492f11b442d56

commit r16-4847-gef0d55f4a8f37941a51fad68970492f11b442d56
Author: Philip Herron <[email protected]>
Date:   Sun Aug 31 23:20:03 2025 +0100

    gccrs: Fix crash on break outside of loop context
    
    We need to add a guard to catch the case when there is no loop context
    for break outside of loop.
    
    Fixes Rust-GCC#3969
    
    gcc/rust/ChangeLog:
    
            * backend/rust-compile-expr.cc (CompileExpr::visit): add guard
    
    gcc/testsuite/ChangeLog:
    
            * rust/compile/issue-3969.rs: New test.
    
    Signed-off-by: Philip Herron <[email protected]>

Diff:
---
 gcc/rust/backend/rust-compile-expr.cc    |  4 ++++
 gcc/testsuite/rust/compile/issue-3969.rs | 30 ++++++++++++++++++++++++++++++
 2 files changed, 34 insertions(+)

diff --git a/gcc/rust/backend/rust-compile-expr.cc 
b/gcc/rust/backend/rust-compile-expr.cc
index 946bbb1234f7..2d910e3e0a45 100644
--- a/gcc/rust/backend/rust-compile-expr.cc
+++ b/gcc/rust/backend/rust-compile-expr.cc
@@ -828,6 +828,10 @@ CompileExpr::visit (HIR::BreakExpr &expr)
     {
       tree compiled_expr = CompileExpr::Compile (expr.get_expr (), ctx);
 
+      translated = error_mark_node;
+      if (!ctx->have_loop_context ())
+       return;
+
       Bvariable *loop_result_holder = ctx->peek_loop_context ();
       tree result_reference
        = Backend::var_expression (loop_result_holder,
diff --git a/gcc/testsuite/rust/compile/issue-3969.rs 
b/gcc/testsuite/rust/compile/issue-3969.rs
new file mode 100644
index 000000000000..9608589c3e27
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3969.rs
@@ -0,0 +1,30 @@
+#[lang = "sized"]
+pub trait Sized {
+    // Empty.
+}
+
+#[lang = "fn_once"]
+pub trait FnOnce<Args> {
+    #[lang = "fn_once_output"]
+    type Output;
+
+    extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
+}
+
+fn main() {
+    [(); {
+        while true {
+            // { dg-error ".constexpr. loop iteration count exceeds limit" "" 
{ target *-*-* } .-1 }
+            break 9;
+            // { dg-error "can only .break. with a value inside a .loop. block 
.E0571." "" { target *-*-* } .-1 }
+        }
+        51
+    }];
+
+    while true {
+        break (|| {
+            // { dg-error "can only .break. with a value inside a .loop. block 
.E0571." "" { target *-*-* } .-1 }
+            let while_true = 9;
+        });
+    }
+}

Reply via email to