Fix dictionary collision in multi-level break elimination for while loops with nested continue #8972
+129
−10
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
The compiler crashed with a dictionary key collision when a
continuestatement inside aswitchinside awhileloop targeted the while loop's continue block.Root Cause
For
whileloops, the continue block typically equals the target block (loop header). The code only added continue blocks to the exit set when they differed from the target block. This allowed child regions (switches) to include the parent's continue block in their block list, causing the same block to be mapped to multiple regions.Changes
populateExitBlocks(): Always add continue block to exit blocks, even when it equals target blockcollectBreakableRegionBlocks(): Explicitly add target block for loops where continue == target, since it's now in the exit set but must still be part of the loop regionTest Coverage
Added regression test
tests/bugs/gh-while-continue-in-switch.slangcovering continue statements in switches nested within while loops.Original prompt
This section details on the original issue you should resolve
<issue_title>Compiler exception with nested continue inside a switch</issue_title>
<issue_description>I believe nested breaks are not allowed, but this code causes an exception inside
Slang::EliminateMultiLevelBreakContext::gatherInfo, leading toMinimal-ish reproduction:
Exception backtrace (it would be nice if slang would print the backtrace to stderr when it hits an exception, rather than only printing the exception type and message, so I didn't have to comment out the exception handling or faff around in the debugger to get this output)