digitalmars.D.bugs - [Issue 12603] New: [CTFE] Unknown bug with goto case.
- via Digitalmars-d-bugs (139/139) Apr 20 2014 https://issues.dlang.org/show_bug.cgi?id=12603
https://issues.dlang.org/show_bug.cgi?id=12603 Issue ID: 12603 Summary: [CTFE] Unknown bug with goto case. Product: D Version: D2 Hardware: x86_64 OS: Windows Status: NEW Severity: normal Priority: P1 Component: DMD Assignee: nobody puremagic.com Reporter: dmitry.olsh gmail.com Not yet reduced, but is very curious. Found in CTFE code of std.regex. import std.uni, std.array, std.typetuple, std.range, std.exception; struct Parser(R) { dchar _current; bool empty; R pat, origin; CodepointSet charset; // trusted this(S)(R pattern, S flags) { pat = origin = pattern; next(); next(); auto a = parseCharTerm(); auto b = parseCharTerm(); a.set |= b.set; charset = a.set; } property dchar current(){ return _current; } bool next() { if(pat.empty) { empty = true; return false; } _current = pat[0]; pat = pat[1..$]; return true; } static struct AB{ CodepointSet set; } enum Operator { None, Union, Difference, SymDifference, Intersection }; //parse unit of CodepointSet spec, most notably escape sequences and char ranges //also fetches next set operation AB parseCharTerm() { enum State{ Start, Char, Escape, CharDash, CharDashEscape, PotentialTwinSymbolOperator } Operator op = Operator.None; dchar last; CodepointSet set; State state = State.Start; static void addWithFlags(ref CodepointSet set, uint ch) { set |= ch; } L_CharTermLoop: for(;;) { final switch(state) { case State.Start: switch(current) { case ']': break L_CharTermLoop; default: state = State.Char; last = current; } break; case State.Char: // xxx last current xxx switch(current) { case '|': case '~': case '&': state = State.PotentialTwinSymbolOperator; addWithFlags(set, last); last = current; break; case ']': set |= last; break L_CharTermLoop; default: addWithFlags(set, last); last = current; } break; case State.PotentialTwinSymbolOperator: //Uncomment the following to get matching results at C-T and R-T //BASICALLY A COPY OF State.Char code above /*switch(current) { case ']': set |= last; break L_CharTermLoop; default: addWithFlags(set, last); last = current; } break;*/ goto case State.Char; case State.Escape: case State.CharDash: case State.CharDashEscape: //xxx last - \ current xxx assert(0); } bool r = next(); assert(r); } return AB(set); } } auto getIt() { auto p = Parser!(string)("[A~]", ""); assert(p.cnt == 2); return p.charset; } import std.stdio; system void main() { auto r1 = getIt(); writeln(r1); static r2 = getIt(); writeln(r2); assert(r1 == r2); //fails } --
Apr 20 2014