diff --git a/compiler/src/dmd/cparse.d b/compiler/src/dmd/cparse.d index 4fd923438c..ba5bbf4400 100644 --- a/compiler/src/dmd/cparse.d +++ b/compiler/src/dmd/cparse.d @@ -508,6 +508,14 @@ final class CParser(AST) : Parser!AST nextToken(); auto exp = cparseAssignExp(); + AST.Expression expHigh; + if (token.value == TOK.dotDotDot) + { + /* Case Ranges https://gcc.gnu.org/onlinedocs/gcc/Case-Ranges.html + */ + nextToken(); + expHigh = cparseAssignExp(); + } check(TOK.colon); if (flags & ParseStatementFlags.curlyScope) @@ -533,7 +541,10 @@ final class CParser(AST) : Parser!AST s = cparseStatement(0); } s = new AST.ScopeStatement(loc, s, token.loc); - s = new AST.CaseStatement(loc, exp, s); + if (expHigh) + s = new AST.CaseRangeStatement(loc, exp, expHigh, s); + else + s = new AST.CaseStatement(loc, exp, s); break; } diff --git a/compiler/test/compilable/test22559.i b/compiler/test/compilable/test22559.i new file mode 100644 index 0000000000..d8e5cc8847 --- /dev/null +++ b/compiler/test/compilable/test22559.i @@ -0,0 +1,17 @@ +// https://gcc.gnu.org/onlinedocs/gcc/Case-Ranges.html + +int alpha(char c) +{ + switch (c) + { + case 'A' ... 'Z': return 1; + case 'a' ... 'z': return 1; + default: return 0; + } +} + +_Static_assert(alpha('A') == 1, "1"); +_Static_assert(alpha('B') == 1, "2"); +_Static_assert(alpha('z') == 1, "3"); +_Static_assert(alpha('z' + 1) == 0, "3"); +_Static_assert(alpha('0') == 0, "4");