Using dmd 2.059 trunk
import std.regex;
//enum re = ctRegex!`(^[a-z]+)|([A-Z0-9][a-z0-9]+)|([A-Z]+)|([a-z]+)`;
//enum re = ctRegex!`(a)|(b)`;
enum re = ctRegex!`a|b`;
void main() {}
/home/simendsjo/code/dmd-trunk/build/src/phobos/std/regex.d(1150): Error: assert(this.ir[cast(ulong)orStart].code() == cast(IR)129u) failed
/home/simendsjo/code/dmd-trunk/build/src/phobos/std/regex.d(876): called from here: this.parseRegex()
/home/simendsjo/code/dmd-trunk/build/src/phobos/std/regex.d(6428): called from here: parser.this(pattern,flags)
/home/simendsjo/code/dmd-trunk/build/src/phobos/std/regex.d(6412): called from here: regexImpl(pattern,flags)
/home/simendsjo/code/dmd-trunk/build/src/phobos/std/regex.d(6437): called from here: regex("a|b",[])
/home/simendsjo/code/dmd-trunk/build/src/phobos/std/regex.d(1150): Error: assert(this.ir[cast(ulong)orStart].code() == cast(IR)129u) failed
/home/simendsjo/code/dmd-trunk/build/src/phobos/std/regex.d(876): called from here: this.parseRegex()
/home/simendsjo/code/dmd-trunk/build/src/phobos/std/regex.d(6428): called from here: parser.this(pattern,flags)
/home/simendsjo/code/dmd-trunk/build/src/phobos/std/regex.d(6412): called from here: regexImpl(pattern,flags)
/home/simendsjo/code/dmd-trunk/build/src/phobos/std/regex.d(6439): called from here: regex("a|b",[])
/home/simendsjo/code/dmd-trunk/build/src/phobos/std/regex.d(6439): called from here: ctGenRegExCode(regex("a|b",[]))
/home/simendsjo/code/dmd-trunk/build/src/phobos/std/regex.d(1150): Error: assert(this.ir[cast(ulong)orStart].code() == cast(IR)129u) failed
/home/simendsjo/code/dmd-trunk/build/src/phobos/std/regex.d(876): called from here: this.parseRegex()
/home/simendsjo/code/dmd-trunk/build/src/phobos/std/regex.d(6428): called from here: parser.this(pattern,flags)
/home/simendsjo/code/dmd-trunk/build/src/phobos/std/regex.d(6412): called from here: regexImpl(pattern,flags)
/home/simendsjo/code/dmd-trunk/build/src/phobos/std/regex.d(6446): called from here: regex("a|b",[])
/home/simendsjo/code/dmd-trunk/build/src/phobos/std/regex.d(6446): called from here: StaticRegex(null,Regex(null,null,null,0u,0u,0u,0u,0u,null,null,ShiftOr(null,0u,0u))).this(regex("a|b",[]),& func)
/home/simendsjo/code/dmd-trunk/build/src/phobos/std/regex.d(6463): Error: template instance std.regex.ctRegexImpl!("a|b",[]) error instantiating
re.d(4): instantiated from here: ctRegex!("a|b")
re.d(4): Error: template instance std.regex.ctRegex!("a|b") error instantiating
Comment #1 by dmitry.olsh — 2012-04-17T01:55:53Z
Created attachment 1094
Stripped down regex parser
Comment #2 by dmitry.olsh — 2012-04-17T01:57:52Z
It's a bug in CTFE not in Phobos. R-T version runs the same code and doesn't hit the assert. See reduced test case.
Comment #3 by dmitry.olsh — 2012-04-19T09:36:11Z
*** Issue 7567 has been marked as a duplicate of this issue. ***
Comment #4 by eco — 2012-05-17T19:40:52Z
Doesn't appear to require ctRegex to trigger. This produces the same assertion failure.
import std.regex;
auto r = regex(r"(a|c");
void main() { }
This worked in 2.058 but not 2.059.
Comment #5 by dmitry.olsh — 2012-05-17T23:01:09Z
(In reply to comment #4)
> Doesn't appear to require ctRegex to trigger. This produces the same assertion
> failure.
>
> import std.regex;
>
> auto r = regex(r"(a|c");
>
> void main() { }
>
> This worked in 2.058 but not 2.059.
not the same.
And yes, global variable == CTFE parser.
+ r"(a|c" unbalanced paren, so it should eventually throw exception but it asserts before it have the chance to do that.
Comment #6 by dmitry.olsh — 2012-09-26T11:47:45Z
I've finally pinned down this bugger.
The problem is in typesafe variadic function if the parameter type is a struct.
See simple test below:
//encoded IR instruction
struct Bytecode
{
uint raw;
}
int fn1(T)(T[] items...)
{
assert(items[0] == 20);
return 42;
}
int fn2(T)(T[] items...)
{
assert(items[0] == Bytecode(20));
return 42;
}
//this passes...
static assert(fn1(20, 30) == 42);
//this dies inside of fn2
static assert(fn2(Bytecode(20), Bytecode(30)) == 42);
void main()
{//both of these pass at R-T
assert(fn1(20, 30) == 42);
assert(fn2(Bytecode(20), Bytecode(30)) == 42);
}
Output:
sr_micro.d(15): Error: assert(items[0u] == Bytecode(20u)) failed
sr_micro.d(23): called from here: fn2((Bytecode[2u] __arrayArg6 = void;
, __arrayArg6[0u] = Bytecode(20u) , __arrayArg6[1u] = Bytecode(30u) , cast(Bytecode[])__arrayArg6))
sr_micro.d(23): while evaluating: static assert(fn2((Bytecode[2u] __arrayArg6 = void;
, __arrayArg6[0u] = Bytecode(20u) , __arrayArg6[1u] = Bytecode(30u) , cast(Bytecode[])__arrayArg6)) == 42)
Comment #7 by clugdbug — 2012-09-28T00:01:52Z
Problem happens when an array is initialized to void in global scope (outside of CTFE) and then modified in CTFE. Haven't fixed this yet.
Comment #8 by dmitry.olsh — 2012-09-28T03:08:46Z
(In reply to comment #7)
> Problem happens when an array is initialized to void in global scope (outside
> of CTFE) and then modified in CTFE. Haven't fixed this yet.
Thanks for looking into it.
It took soo long to reduce but at least now I have an idea of a workaround.
Comment #9 by clugdbug — 2012-10-01T06:17:47Z
Further reduced shows it's a problem with void initialized static arrays. I have a fix.
int bug7810() {
int[1][3] x = void;
x[0] = [2];
x[1] = [7];
assert(x[0][0] == 2);
return 1;
}
static assert(bug7810());