Skip to content

Conversation

tommyscholly
Copy link
Contributor

@tommyscholly tommyscholly commented May 8, 2025

This PR addresses #3618. With this change, the expected error of reaching the iteration limit is reported:

test.rs:1:17: error: ‘constexpr’ loop iteration count exceeds limit of 262144 (use ‘-fconstexpr-loop-limit=’ to increase the limit)
    1 | static _X: () = loop {};
      |                 ^~~~

My handling of t being a NULL_TREE may not be appropriate in eval_constant_expression, seeking guidance there.

Fixes #3618

@tommyscholly tommyscholly force-pushed the master branch 4 times, most recently from 8ae9e0b to 31f2dba Compare May 8, 2025 03:41
@tommyscholly tommyscholly changed the title fix ICE segfault on empty static loops Fix ICE segfault on empty static loops May 8, 2025
Copy link
Member

@philberty philberty left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM but i would slightly tweak this to be:

if (t == NULL_TREE)
  return NULL_TREE;
  
if (CONST_CLASS_P (t))
   ... <continue on with rest of code>

just means we have an explicit guard against null at the start. Just for reference this ia port from the gcc/cp/constexpr.cc implementation which fits well as it operates on GCC tree's

Also for your commit message please prefix with gccrs: so something like:

"gccrs: fix ICE on empty constexpr loops

Empty loops have no body which means this is a NULL_TREE during const
evaluation which needs a check.

Fixes Rust-GCC # issue number

"

@tommyscholly
Copy link
Contributor Author

Implemented those changes!

@philberty
Copy link
Member

looks like you have a stray t in your fixes line:

"Fixes Rust-GCC #3618t"

Copy link
Member

@philberty philberty left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Copy link
Member

@philberty philberty left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually sorry you need to add a test case too

@philberty
Copy link
Member

it should be enough to add a test case of :

static _X: () = loop {};

into a file in gcc/testsuite/rust/compile/issue-3618.rs

Empty loops have no body which means this is a NULL_TREE during const
evaluation which needs a check. Fixes Rust-GCC Rust-GCC#3618.

gcc/rust/ChangeLog:

	* backend/rust-constexpr.cc (eval_constant_expression):  Check if t is a NULL_TREE

gcc/testsuite/ChangeLog:

	* rust/compile/issue-3618.rs: Test empty loops error properly.

Signed-off-by: Tom Schollenberger <[email protected]>
@tommyscholly tommyscholly reopened this May 8, 2025
@github-project-automation github-project-automation bot moved this from Done to Todo in libcore 1.49 May 8, 2025
@tommyscholly
Copy link
Contributor Author

Fat fingered closing the PR by accident.

Added in the test.

@philberty
Copy link
Member

Nice work but i just realised yes this need another change sorry. This null_tree check should still stay but you need another check the error should be:

error[E0658]: `loop` is not allowed in a `static`
 --> <source>:1:17
  |
1 | static _X: () = loop {};
  |                 ^^^^^^^
  |
  = note: see issue #52000 <https://github.com/rust-lang/rust/issues/52000> for more information

error: aborting due to previous error

So what you need to do is add a catch here:

TyTy::BaseType *block_tyty = nullptr;

if (ctx->const_context_p ())
 {
     rich_location r;
     rust_error_at (r, ErrorCode::0658, "%<loop%> is not allowed in const context");
     return;
  }

@tommyscholly
Copy link
Contributor Author

Oh that's my bad. I was comparing with a 1.86 rustc. On version 1.49 it still gives a "exceeded interpreter step limit (see #[const_eval_limit])" error. Should I not be basing functionality on 1.49?

@philberty
Copy link
Member

Oh good point whats really funny is if you test 1.45 you get loop is not allowed but in 1.49 you get the exceeded limit error.

uughh.. I think we should go both of these fixes in one commit. So we emit that error and if we need to we can remove it.

@philberty
Copy link
Member

@flip1995 @CohenArthur @P-E-P this was interesting patch because the rustc behaviour has changed so much here. later versions seem to fall back to a const eval limit like we have hit here but earlier versions of rust disable loop being allowed in const/static context.

@philberty
Copy link
Member

Hmm maybe we should just open up an issue relating the what behaviour we want since your current PR is more like the latest rustc I bet they let loops return values using break etc now so yeah.. lets go with your patch then.

Copy link
Member

@philberty philberty left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@philberty philberty added this pull request to the merge queue May 8, 2025
@tommyscholly
Copy link
Contributor Author

Yeah, even on 1.49, this compiles fine actually:

static _X: () = loop {
    break;
};

Merged via the queue into Rust-GCC:master with commit 339415a May 8, 2025
24 checks passed
@github-project-automation github-project-automation bot moved this from Todo to Done in libcore 1.49 May 8, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

ICE: segfault assigning loop to static
2 participants