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; + }); + } +}
