Skip to content

Commit 654d800

Browse files
committed
gccrs: Fix segv when handling invalid array capacities
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 #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]>
1 parent e7bafde commit 654d800

File tree

5 files changed

+32
-7
lines changed

5 files changed

+32
-7
lines changed

gcc/rust/backend/rust-compile-context.h

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,13 @@ class Context
322322

323323
void push_loop_context (Bvariable *var) { loop_value_stack.push_back (var); }
324324

325-
Bvariable *peek_loop_context () { return loop_value_stack.back (); }
325+
bool have_loop_context () const { return !loop_value_stack.empty (); }
326+
327+
Bvariable *peek_loop_context ()
328+
{
329+
rust_assert (!loop_value_stack.empty ());
330+
return loop_value_stack.back ();
331+
}
326332

327333
Bvariable *pop_loop_context ()
328334
{
@@ -336,7 +342,11 @@ class Context
336342
loop_begin_labels.push_back (label);
337343
}
338344

339-
tree peek_loop_begin_label () { return loop_begin_labels.back (); }
345+
tree peek_loop_begin_label ()
346+
{
347+
rust_assert (!loop_begin_labels.empty ());
348+
return loop_begin_labels.back ();
349+
}
340350

341351
tree pop_loop_begin_label ()
342352
{

gcc/rust/backend/rust-compile-expr.cc

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -891,6 +891,10 @@ CompileExpr::visit (HIR::BreakExpr &expr)
891891
void
892892
CompileExpr::visit (HIR::ContinueExpr &expr)
893893
{
894+
translated = error_mark_node;
895+
if (!ctx->have_loop_context ())
896+
return;
897+
894898
tree label = ctx->peek_loop_begin_label ();
895899
if (expr.has_label ())
896900
{
@@ -2000,13 +2004,11 @@ CompileExpr::array_copied_expr (location_t expr_locus,
20002004
return error_mark_node;
20012005
}
20022006

2003-
ctx->push_const_context ();
2004-
tree capacity_expr = CompileExpr::Compile (elems.get_num_copies_expr (), ctx);
2005-
ctx->pop_const_context ();
2006-
2007+
auto capacity_tyty = array_tyty.get_capacity ();
2008+
tree capacity_expr = capacity_tyty->get_value ();
20072009
if (!TREE_CONSTANT (capacity_expr))
20082010
{
2009-
rust_error_at (expr_locus, "non const num copies %qT", array_type);
2011+
rust_error_at (expr_locus, "non const num copies %qT", capacity_expr);
20102012
return error_mark_node;
20112013
}
20122014

gcc/rust/typecheck/rust-hir-type-check-expr.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1090,6 +1090,8 @@ TypeCheckExpr::visit (HIR::ArrayExpr &expr)
10901090

10911091
auto capacity_expr_ty
10921092
= TypeCheckExpr::Resolve (elems.get_num_copies_expr ());
1093+
if (capacity_expr_ty->is<TyTy::ErrorType> ())
1094+
return;
10931095

10941096
context->insert_type (elems.get_num_copies_expr ().get_mappings (),
10951097
expected_ty);
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
fn main() {
2+
[(); { continue }];
3+
// { dg-error ".continue. outside of a loop .E0268." "" { target *-*-* } .-1 }
4+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
fn main() {
2+
loop { continue }
3+
4+
[(); {while true {break}; 0}];
5+
6+
[(); {while true {break}; 0}];
7+
}

0 commit comments

Comments
 (0)