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

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 2019