Thread overview
[Issue 3010] New: ICE(mtype.c) function pointer type deduction puts compiler in corrupt state
May 24, 2009
Don
May 25, 2009
Don
Jul 09, 2009
Don
May 20, 2009
http://d.puremagic.com/issues/show_bug.cgi?id=3010

           Summary: ICE(mtype.c) function pointer type deduction puts
                    compiler in corrupt state
           Product: D
           Version: 2.029
          Platform: PC
        OS/Version: Windows
            Status: NEW
          Keywords: ice-on-valid-code
          Severity: critical
          Priority: P2
         Component: DMD
        AssignedTo: bugzilla@digitalmars.com
        ReportedBy: clugdbug@yahoo.com.au


This is the ICE case originally reported as a comment in bug 2672.

----
auto x = &bar;
int bar() { return 1;}
int function() y = null;
---
Assertion failure: 'tn->mod == MODinvariant' on line 760 in file 'mtype.c'

======
ANALYSIS
======
This one is really tough. What's happening is that when a forward reference is
involved, auto type deduction for function pointers is failing to initialize
something about the Type object (or maybe the TypeNext object) for that
function pointer type. [ At the very least, the 'mod' member of the Type is
wrong, but it could be more serious than that, it might even affect D1].
Then, when the NEXT declaration of a function pointer of exactly the same type
occurs, it grabs the corrupted Type object. This has the wrong const/immutable
state, so an ICE occurs.

This is particularly nasty, because adding a declaration of that exact same
function pointer type earlier in the file (or maybe even in another module?)
will prevent the ICE, since it will have created a valid Type object before the
auto declaration gets a chance to make a corrupt one.
So, for example
int function() z = null;
auto x = &bar;
int bar() { return 1;}
int function() y = null; // Test case 1

does not ICE, but change the declaration of z to be 'uint function()', and it will crash at the declaration of y, even though it's the declaration at x which is the root cause. Marking as critical since it can be incredibly difficult to track down.

Despite spending ages on this, I haven't yet tracked down the root cause enough to provide a patch.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
May 24, 2009
http://d.puremagic.com/issues/show_bug.cgi?id=3010





--- Comment #1 from Don <clugdbug@yahoo.com.au>  2009-05-24 13:24:23 PDT ---
I making really slow progress on this, so am including a progress update.

In mtype.c, TypeNext::makeInvariant(), there's a line:

    if (ty != Tfunction && ty != Tdelegate && next->deco &&
    !next->isInvariant())
    {    t->next = next->invariantOf();

But in the case where 'next' was created by auto type deduction, next->deco is NULL, so next->invariantOf() never gets called, and we get a malformed immutable type. I haven't yet worked out why next->deco is NULL when next is a TypeFunction which was created through type inference. It could be  because it began life as a TypeSymOff?

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
May 25, 2009
http://d.puremagic.com/issues/show_bug.cgi?id=3010


Don <clugdbug@yahoo.com.au> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |patch




--- Comment #2 from Don <clugdbug@yahoo.com.au>  2009-05-25 00:42:42 PDT ---
At last I have a patch. The root cause is that merge() never gets called on the .next member of TypeNext.

In Type::merge(), there's a bit of code which is commented out:
--------
    if (!deco)
    {
    OutBuffer buf;
    StringValue *sv;

    //if (next)
        //next = next->merge();
-------
Possibly, we need a dynamic cast to reinstate it. What I've done as an alternative is to perform the merge inside TypeNext::toDecoBuffer. Certainly, it shouldn't be generating the type decoration for a pointer, when it hasn't yet generated the type decoration for the type being pointed to.

I'm not sure if that's really the correct place (it might be too late), but at least it fixes a raft of bugs. As well as both test cases for this bug and for bug 2672 , it also fixes the very nasty ICE bug 1994.

-------
PATCH 1 (a mostly unrelated cosmetic change): mtype.c, Type::toCBuffer3(),
change
        case MODinvariant:
        p = "invariant(";
to
        case MODinvariant:
        p = "immutable(";
-----
PATCH 2: (mtype.c) in
void TypeNext::toDecoBuffer(OutBuffer *buf, int flag)
  if (!next->deco) next->merge(); // add this line
  next->toDecoBuffer(buf, (flag & 0x100) ? 0 : mod);
-----

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
July 09, 2009
http://d.puremagic.com/issues/show_bug.cgi?id=3010


Don <clugdbug@yahoo.com.au> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
         Resolution|                            |FIXED




--- Comment #3 from Don <clugdbug@yahoo.com.au>  2009-07-09 07:12:22 PDT ---
Fixed DMD 2.031

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------