www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 19576] New: Dangling TemplateInstance.tinst if set to a dummy

https://issues.dlang.org/show_bug.cgi?id=19576

          Issue ID: 19576
           Summary: Dangling TemplateInstance.tinst if set to a dummy
                    instance created by leastAsSpecialized()
           Product: D
           Version: D2
          Hardware: All
                OS: All
            Status: NEW
          Severity: normal
          Priority: P1
         Component: dmd
          Assignee: nobody puremagic.com
          Reporter: syniurge gmail.com

Created attachment 1724
  --> https://issues.dlang.org/attachment.cgi?id=1724&action=edit
Backtrace of Calypso (based on LDC 1.10) building Phobos

In dtemplate.d's leastAsSpecialized():

        scope TemplateInstance ti = new TemplateInstance(Loc.initial, ident,
tiargs); // create dummy template instance

// ...

        MATCH m = td2.matchWithInstance(sc, ti, &dedtypes, fargs, 1);

If td2 has a default template argument, matchWithInstance may lead to more
template instantiations and those will end up with a dangling .tinst pointer.

The problematic dummy template instance in my case was:

  void encode(UseReplacementDchar useReplacementDchar = No.useReplacementDchar)

in phobos/std/utf.d, which instantiated No.opDispatch:

  struct No  // in phobos/std/typecons.d
  {
      template opDispatch(string name)

And this opDispatch template instance got its .tinst member set to the dummy
instance, so became dangling as soon as leastAsSpecialized returned.

I couldn't reproduce a simple segfaulting case. It was triggered with Calypso
(that I recently updated from LDC 1.7 to LDC 1.10) and the error occurred
during codegen while compiling Phobos's std/utf.d. LDC's codegen was calling
calling TemplateInstance.isCodegen(), which went through the siblings to make a
decision and ended up examining the instance with the dangling .tinst. But it
didn't segfault straightaway (see attached backtrace, the instance with
dangling .tinst is actually 'this' of #8), isCodegen managed to survive with
garbage TemplateInstance pointers, which is why it's hard to reproduce.

I wrote a tentative fix for Calypso:
https://github.com/Syniurge/Calypso/commit/16336e5a6235e113c6d3bebe043d34234f1e80aa
Should I make a PR for DMD or is there a better way to fix it?

--
Jan 11