From: Lucas Ly Ba <[email protected]>
A `break 'label value` expression looks up a temporary variable
associated with the labeled loop to hold the value, but labeled loops
never registered that temporary, leading to an ICE in the code
generator. Register the loop result temporary against the label.
gcc/rust/ChangeLog:
* backend/rust-compile-expr.cc (CompileExpr::visit): Associate the loop
result temporary with the loop label.
gcc/testsuite/ChangeLog:
* rust/compile/break-label-loop.rs: New test.
Signed-off-by: Lucas Ly Ba <[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/f1677688901c1e3ddadc941a89bfd1f7b8e2469e
The commit has NOT been mentioned in any issue.
The commit has been mentioned in the following pull-request(s):
- https://github.com/Rust-GCC/gccrs/pull/4638
gcc/rust/backend/rust-compile-expr.cc | 4 ++++
gcc/testsuite/rust/compile/break-label-loop.rs | 10 ++++++++++
2 files changed, 14 insertions(+)
create mode 100644 gcc/testsuite/rust/compile/break-label-loop.rs
diff --git a/gcc/rust/backend/rust-compile-expr.cc
b/gcc/rust/backend/rust-compile-expr.cc
index 7fabc25a5..79fe6c49e 100644
--- a/gcc/rust/backend/rust-compile-expr.cc
+++ b/gcc/rust/backend/rust-compile-expr.cc
@@ -794,6 +794,10 @@ CompileExpr::visit (HIR::LoopExpr &expr)
ctx->add_statement (label_decl);
ctx->insert_label_decl (
loop_label.get_lifetime ().get_mappings ().get_hirid (), label);
+ // Associate the loop's result temporary with the label so that a
+ // `break 'label value` can locate it (see visit (HIR::BreakExpr)).
+ ctx->insert_var_decl (
+ loop_label.get_lifetime ().get_mappings ().get_hirid (), tmp);
}
tree loop_begin_label
diff --git a/gcc/testsuite/rust/compile/break-label-loop.rs
b/gcc/testsuite/rust/compile/break-label-loop.rs
new file mode 100644
index 000000000..60169e32d
--- /dev/null
+++ b/gcc/testsuite/rust/compile/break-label-loop.rs
@@ -0,0 +1,10 @@
+// `break 'label loop {}` used to ICE in the code generator because the
+// labeled loop never registered its result temporary against the label.
+#![feature(no_core)]
+#![no_core]
+
+pub fn foo() {
+ 'a: loop {
+ break 'a loop {};
+ }
+}
base-commit: daaf19e1a57923725e4acb94f82fad41b0747440
--
2.54.0