From: Philip Herron <[email protected]>

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 <[email protected]>
---
 gcc/rust/backend/rust-compile-context.h        | 14 ++++++++++++--
 gcc/rust/backend/rust-compile-expr.cc          | 12 +++++++-----
 gcc/rust/typecheck/rust-hir-type-check-expr.cc |  2 ++
 gcc/testsuite/rust/compile/issue-3965-1.rs     |  4 ++++
 gcc/testsuite/rust/compile/issue-3965-2.rs     |  7 +++++++
 5 files changed, 32 insertions(+), 7 deletions(-)
 create mode 100644 gcc/testsuite/rust/compile/issue-3965-1.rs
 create mode 100644 gcc/testsuite/rust/compile/issue-3965-2.rs

diff --git a/gcc/rust/backend/rust-compile-context.h 
b/gcc/rust/backend/rust-compile-context.h
index 69bba515882..e98bbc2d49f 100644
--- a/gcc/rust/backend/rust-compile-context.h
+++ b/gcc/rust/backend/rust-compile-context.h
@@ -322,7 +322,13 @@ public:
 
   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 ()
   {
@@ -336,7 +342,11 @@ public:
     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 ()
   {
diff --git a/gcc/rust/backend/rust-compile-expr.cc 
b/gcc/rust/backend/rust-compile-expr.cc
index 2bec52bfc4a..946bbb1234f 100644
--- a/gcc/rust/backend/rust-compile-expr.cc
+++ b/gcc/rust/backend/rust-compile-expr.cc
@@ -891,6 +891,10 @@ CompileExpr::visit (HIR::BreakExpr &expr)
 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 ())
     {
@@ -2000,13 +2004,11 @@ CompileExpr::array_copied_expr (location_t expr_locus,
       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;
     }
 
diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.cc 
b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
index 9a772cba4c6..dc063587e0d 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-expr.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
@@ -1090,6 +1090,8 @@ TypeCheckExpr::visit (HIR::ArrayExpr &expr)
 
        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);
diff --git a/gcc/testsuite/rust/compile/issue-3965-1.rs 
b/gcc/testsuite/rust/compile/issue-3965-1.rs
new file mode 100644
index 00000000000..291a2208c50
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3965-1.rs
@@ -0,0 +1,4 @@
+fn main() {
+    [(); { continue }];
+    // { dg-error ".continue. outside of a loop .E0268." "" { target *-*-* } 
.-1 }
+}
diff --git a/gcc/testsuite/rust/compile/issue-3965-2.rs 
b/gcc/testsuite/rust/compile/issue-3965-2.rs
new file mode 100644
index 00000000000..d48503fa6c0
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3965-2.rs
@@ -0,0 +1,7 @@
+fn main() {
+    loop { continue }
+
+    [(); {while true {break}; 0}];
+
+    [(); {while true {break}; 0}];
+}
-- 
2.50.1

Reply via email to