Skip to content

Commit 52be765

Browse files
committed
Approach 1
1 parent 62a48a5 commit 52be765

File tree

4 files changed

+62
-1
lines changed

4 files changed

+62
-1
lines changed

compiler/src/dmd/enumsem.d

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -542,7 +542,7 @@ void enumMemberSemantic(Scope* sc, EnumMember em)
542542
emax = emax.ctfeInterpret();
543543

544544
// check that (eprev != emax)
545-
Expression e = new EqualExp(EXP.equal, em.loc, eprev, emax);
545+
Expression e = new EqualExp(EXP.equal, em.ed.loc, eprev, emax);
546546
e = e.expressionSemantic(sc);
547547
e = e.ctfeInterpret();
548548
if (global.endGagging(errors))

compiler/src/dmd/semantic2.d

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -696,6 +696,41 @@ private extern(C++) final class Semantic2Visitor : Visitor
696696
{
697697
td.foreachVar((s) { s.accept(this); });
698698
}
699+
700+
override void visit(EnumDeclaration ed)
701+
{
702+
//printf("EnumDeclaration::semantic2(%s) semanticRun = %d\n", ed.toChars(), ed.semanticRun);
703+
if (ed.semanticRun >= PASS.semantic2done)
704+
return;
705+
assert(ed.semanticRun <= PASS.semantic2);
706+
ed.semanticRun = PASS.semantic2;
707+
708+
if (!ed.members)
709+
return;
710+
711+
// Process all enum members for proper value computation
712+
auto scx = ed._scope ? ed._scope : sc;
713+
if (!scx)
714+
return;
715+
716+
scx = scx.startCTFE();
717+
scx.setNoFree(); // needed for getMaxMinValue()
718+
719+
ed.members.foreachDsymbol( (s)
720+
{
721+
if (EnumMember em = s.isEnumMember())
722+
{
723+
if (em._scope)
724+
scx = em._scope;
725+
726+
// Make sure the enum member values are fully evaluated
727+
if (em.semanticRun < PASS.semanticdone)
728+
em.dsymbolSemantic(scx);
729+
}
730+
});
731+
732+
ed.semanticRun = PASS.semantic2done;
733+
}
699734
}
700735

701736
/**

compiler/src/dmd/statementsem.d

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1959,6 +1959,12 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
19591959
ed = ds.isEnumDeclaration(); // typedef'ed enum
19601960
if (!ed && te && ((ds = te.toDsymbol(sc)) !is null))
19611961
ed = ds.isEnumDeclaration();
1962+
if (ed && ed.semanticRun < PASS.semantic2done)
1963+
{
1964+
error(ss.loc, "cannot use `final switch` on enum `%s` while it is being defined", ed.toChars());
1965+
sc.pop();
1966+
return setError();
1967+
}
19621968
if (ed && ss.cases.length < ed.members.length)
19631969
{
19641970
int missingMembers = 0;
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/*
2+
TEST_OUTPUT:
3+
---
4+
fail_compilation/fix20867.d(14): Error: cannot use `final switch` on enum `E` while it is being defined
5+
---
6+
*/
7+
8+
// Test case from Issue #20867
9+
enum E
10+
{
11+
a = 3,
12+
b = () {
13+
E e;
14+
final switch (e) // This should error out instead of segfaulting
15+
{
16+
case E.a: break;
17+
}
18+
return 4;
19+
} ()
20+
}

0 commit comments

Comments
 (0)