mirror of
https://github.com/dlang/dmd.git
synced 2025-04-25 20:50:41 +03:00
Fix: Prevent ICE on final switch forward referencing its enum (#21001)
* Fix: Prevent ICE on final switch forward referencing its enum * more simpler approach * moved the enum member analysis * Move enum number analysis to sementic2 * WhiteSpace Remove * Remove Redundant Code in enumsem
This commit is contained in:
parent
49a7c10bdf
commit
dafb58bc77
3 changed files with 34 additions and 0 deletions
|
@ -240,6 +240,10 @@ void enumSemantic(Scope* sc, EnumDeclaration ed)
|
|||
|
||||
//if (ed.defaultval) printf("ed.defaultval: %s %s\n", ed.defaultval.toChars(), ed.defaultval.type.toChars());
|
||||
//printf("members = %s\n", members.toChars());
|
||||
|
||||
// Set semantic2done here to indicate all members have been processed
|
||||
// This prevents using the enum in a final switch while being defined
|
||||
ed.semanticRun = PASS.semantic2done;
|
||||
}
|
||||
|
||||
Expression getDefaultValue(EnumDeclaration ed, Loc loc)
|
||||
|
|
|
@ -1959,6 +1959,16 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
|
|||
ed = ds.isEnumDeclaration(); // typedef'ed enum
|
||||
if (!ed && te && ((ds = te.toDsymbol(sc)) !is null))
|
||||
ed = ds.isEnumDeclaration();
|
||||
|
||||
// Circular references
|
||||
// Check if enum semantic analysis is not yet complete
|
||||
if (ed && ed.semanticRun < PASS.semantic2done)
|
||||
{
|
||||
error(ss.loc, "cannot use `final switch` on enum `%s` while it is being defined", ed.toChars());
|
||||
sc.pop();
|
||||
return setError();
|
||||
}
|
||||
|
||||
if (ed && ss.cases.length < ed.members.length)
|
||||
{
|
||||
int missingMembers = 0;
|
||||
|
|
20
compiler/test/fail_compilation/fix20867.d
Normal file
20
compiler/test/fail_compilation/fix20867.d
Normal file
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/fix20867.d(14): Error: cannot use `final switch` on enum `E` while it is being defined
|
||||
---
|
||||
*/
|
||||
|
||||
// Test case from Issue #20867
|
||||
enum E
|
||||
{
|
||||
a = 3,
|
||||
b = () {
|
||||
E e;
|
||||
final switch (e) // This should error out instead of segfaulting
|
||||
{
|
||||
case E.a: break;
|
||||
}
|
||||
return 4;
|
||||
} ()
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue