www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 3010] New: ICE(mtype.c) function pointer type deduction puts compiler in corrupt state

reply d-bugmail puremagic.com writes:
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 20 2009
next sibling parent d-bugmail puremagic.com writes:
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 24 2009
prev sibling next sibling parent d-bugmail puremagic.com writes:
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: -------
May 25 2009
prev sibling parent d-bugmail puremagic.com writes:
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: -------
Jul 09 2009