[Issue 12603] New: [CTFE] Unknown bug with goto case.
via Digitalmars-d-bugs
digitalmars-d-bugs at puremagic.com
Sun Apr 20 06:52:44 PDT 2014
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 at puremagic.com
Reporter: dmitry.olsh at 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
}
--
More information about the Digitalmars-d-bugs
mailing list