We need to catch the error node for the array capacity and return early.
Otherwise we try to const evaluate something thats just silly. Also
when compiling array expressions we can simply reuse the array capacity
expression we already have cons folded.
Fixes Rust-GCC#3965
gcc/rust/ChangeLog:
* backend/rust-compile-context.h: add assertions for context peeks
* backend/rust-compile-expr.cc (CompileExpr::visit): check for valid loop context
(CompileExpr::array_copied_expr): just reuse array tyty capacity value
* typecheck/rust-hir-type-check-expr.cc (TypeCheckExpr::visit): catch error
gcc/testsuite/ChangeLog:
* rust/compile/issue-3965-1.rs: New test.
* rust/compile/issue-3965-2.rs: New test.
Signed-off-by: Philip Herron <herron.philip@googlemail.com>
void push_loop_context (Bvariable *var) { loop_value_stack.push_back (var); }
- Bvariable *peek_loop_context () { return loop_value_stack.back (); }
+ bool have_loop_context () const { return !loop_value_stack.empty (); }
+
+ Bvariable *peek_loop_context ()
+ {
+ rust_assert (!loop_value_stack.empty ());
+ return loop_value_stack.back ();
+ }
Bvariable *pop_loop_context ()
{
loop_begin_labels.push_back (label);
}
- tree peek_loop_begin_label () { return loop_begin_labels.back (); }
+ tree peek_loop_begin_label ()
+ {
+ rust_assert (!loop_begin_labels.empty ());
+ return loop_begin_labels.back ();
+ }
tree pop_loop_begin_label ()
{
void
CompileExpr::visit (HIR::ContinueExpr &expr)
{
+ translated = error_mark_node;
+ if (!ctx->have_loop_context ())
+ return;
+
tree label = ctx->peek_loop_begin_label ();
if (expr.has_label ())
{
return error_mark_node;
}
- ctx->push_const_context ();
- tree capacity_expr = CompileExpr::Compile (elems.get_num_copies_expr (), ctx);
- ctx->pop_const_context ();
-
+ auto capacity_tyty = array_tyty.get_capacity ();
+ tree capacity_expr = capacity_tyty->get_value ();
if (!TREE_CONSTANT (capacity_expr))
{
- rust_error_at (expr_locus, "non const num copies %qT", array_type);
+ rust_error_at (expr_locus, "non const num copies %qT", capacity_expr);
return error_mark_node;
}
auto capacity_expr_ty
= TypeCheckExpr::Resolve (elems.get_num_copies_expr ());
+ if (capacity_expr_ty->is<TyTy::ErrorType> ())
+ return;
context->insert_type (elems.get_num_copies_expr ().get_mappings (),
expected_ty);
--- /dev/null
+fn main() {
+ [(); { continue }];
+ // { dg-error ".continue. outside of a loop .E0268." "" { target *-*-* } .-1 }
+}
--- /dev/null
+fn main() {
+ loop { continue }
+
+ [(); {while true {break}; 0}];
+
+ [(); {while true {break}; 0}];
+}