Comment #0 by john.loughran.colvin — 2013-11-19T04:39:23Z
An example that is clearly wrong code, but segfaults the compiler on Scope::push
template A(alias T)
{
template A()
{
alias A = T!();
}
}
alias B() = A!(.B);
static if(A!B){}
I have similar but correct code that triggers the same fault, I'll add it when I've minimised it properly.
Comment #1 by john.loughran.colvin — 2013-11-19T05:45:55Z
Ok this is proving near impossible to reduce. Changing the slightest things moves the segfault to different parts of the compiler and it's very hard to find examples that are correct and fail. I've seen
Scope::Scope(Scope*),
functionResolve(Match*, Dsymbol*, Loc, Scope*, Array<RootObject>*, Type*, Array<Expression>*)::ParamDeduce::fp(TemplateDeclaration*),
TemplateInstance::findBestMatch(Scope*, Array<Expression>*) (),
TemplateTupleParameter::matchArg(Loc, Scope*, Array<RootObject>*, unsigned long, Array<TemplateParameter>*, Array<RootObject>*, Declaration**) (),
Dsymbol::Dsymbol()
so far, if that's of any help at all.
Comment #2 by yebblies — 2013-11-19T06:07:34Z
(In reply to comment #1)
> Ok this is proving near impossible to reduce. Changing the slightest things
> moves the segfault to different parts of the compiler and it's very hard to
> find examples that are correct and fail. I've seen
>
> Scope::Scope(Scope*),
>
> functionResolve(Match*, Dsymbol*, Loc, Scope*, Array<RootObject>*, Type*,
> Array<Expression>*)::ParamDeduce::fp(TemplateDeclaration*),
>
> TemplateInstance::findBestMatch(Scope*, Array<Expression>*) (),
>
> TemplateTupleParameter::matchArg(Loc, Scope*, Array<RootObject>*, unsigned
> long, Array<TemplateParameter>*, Array<RootObject>*, Declaration**) (),
>
> Dsymbol::Dsymbol()
>
> so far, if that's of any help at all.
It's jumping around because the segfault is a stack overflow. Chances are any segfault you see will be the same thing underneath.
Comment #3 by john.loughran.colvin — 2013-11-19T06:42:42Z
Finally, a correct (should compile) example that causes a segfault. It's still a little large, sorry:
struct Pack(T ...)
{
alias Unpack = T;
enum length = T.length;
}
template isPack(TList ...)
{
static if(TList.length == 1 &&
is(Pack!(TList[0].Unpack) == TList[0]))
{
enum isPack = true;
}
else
{
enum isPack = false;
}
}
template PartialApply(alias T, uint argLoc, Arg ...)
if(Arg.length == 1)
{
template PartialApply(L ...)
{
alias PartialApply = T!(L[0 .. argLoc], Arg, L[argLoc .. $]);
}
}
template _hasLength(size_t len, T)
{
static if(T.length == len)
{
enum _hasLength = true;
}
else
{
enum _hasLength = false;
}
}
alias _hasLength(size_t len) = PartialApply!(._hasLength, 0, len);
alias hl1 = _hasLength!1;
//this segfaults
static if(!isPack!hl1){ pragma(msg, "All good 1"); }
//these are fine
static if(hl1!(Pack!(5))) { pragma(msg, "All good 2"); }
static if(!hl1!(Pack!())) { pragma(msg, "All good 3"); }
The result:
Program received signal SIGSEGV, Segmentation fault.
0x0000000000434a45 in Dsymbol::Dsymbol(Identifier*) ()
(In reply to comment #0)
> An example that is clearly wrong code, but segfaults the compiler on
> Scope::push
>
> template A(alias T)
> {
> template A()
> {
> alias A = T!();
> }
> }
> alias B() = A!(.B);
>
> static if(A!B){}
With 2.063, following equivalent code did not cause segfault.
template A(alias T)
{
template A()
{
alias A = T!();
}
}
template B() { alias B = A!(.B); }
static if (A!B) {} // Line 9
Output:
test.d(9): Error: expression template A() of type void does not have a boolean value
Comment #8 by github-bugzilla — 2014-01-07T02:33:10Z