Bug 11553 – dmd segfault with recursive template

Status
RESOLVED
Resolution
FIXED
Severity
regression
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2013-11-19T04:39:00Z
Last change time
2014-01-07T02:33:10Z
Keywords
ice, pull
Assigned to
nobody
Creator
john.loughran.colvin

Comments

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*) ()
Comment #4 by k.hara.pg — 2013-11-19T07:48:46Z
Comment #5 by john.loughran.colvin — 2013-11-19T08:24:25Z
Thanks Kenji, that fixes the problem in my full code-base too.
Comment #6 by github-bugzilla — 2014-01-05T12:27:15Z
Commits pushed to master at https://github.com/D-Programming-Language/dmd https://github.com/D-Programming-Language/dmd/commit/fcd656147f10ec53f68df473883ddc68aaee546e fix Issue 11553 - dmd segfault with recursive template https://github.com/D-Programming-Language/dmd/commit/a78295a1c99299880c8c8adb475688d1e1ae8484 Merge pull request #2826 from 9rnsr/fix11553 Issue 11553 - dmd segfault with recursive template
Comment #7 by k.hara.pg — 2014-01-07T02:31:10Z
(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
Commit pushed to 2.065 at https://github.com/D-Programming-Language/dmd https://github.com/D-Programming-Language/dmd/commit/e1866902b88e36537197da16b098afd2df304425 Merge pull request #2826 from 9rnsr/fix11553 Issue 11553 - dmd segfault with recursive template