D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 1140 - ICE(cod1.c) casting last function parameter to 8 byte value
Summary: ICE(cod1.c) casting last function parameter to 8 byte value
Status: RESOLVED FIXED
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D1 (retired)
Hardware: x86 All
: P2 normal
Assignee: No Owner
URL:
Keywords: ice-on-valid-code, patch
: 1139 (view as issue list)
Depends on:
Blocks:
 
Reported: 2007-04-13 08:52 UTC by Don
Modified: 2014-02-16 15:25 UTC (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description Don 2007-04-13 08:52:25 UTC
Useless bit of code, but it shouldn't ICE.

Internal error: ..\ztc\cod1.c 3282
-----------
struct Dog(B...)
{
    B values;
    static Dog!(B) create(B x) {
        return *cast(Dog!(B)*)(&x[1]);
    }
}

void main()
{
    auto c = Dog!(int, int).create(7,4);
}
Comment 1 Frits van Bommel 2007-04-13 09:34:02 UTC
*** Bug 1139 has been marked as a duplicate of this bug. ***
Comment 3 Don 2009-05-19 00:27:41 UTC
Simpler test case shows that it's nothing to do with tuples!
ICE on both D1 and D2.

struct Dog {
  int q;
  int r;
}
Dog hound(int y) {
    return *cast(Dog*)(&y);
}
Comment 4 Don 2009-10-07 06:31:19 UTC
Even simpler test case shows it's nothing to do with structs! It just happens when casting the last parameter, **which is passed in EAX, not on the stack**, to an 8-byte value -- either an 8-byte struct or a long/ulong.
Although this code is legal, it's surely a bug. It would be OK for the compiler to generate an error message.

long foo(int y) {
    return *cast(long*)(&y);
}
Comment 5 Don 2009-10-07 23:58:13 UTC
This seems to be a superficial ICE. It only happens in this wierd situation, 
when a parameter, which was passed in a register, needs to be stored into a 
double-register (EDX:EAX).
In this case, the existing register can't be re-used, even though it satisfies 
all the conditions in cod1 line 3433.
We simply need to add an extra condition to prevent the register being 
re-used.After this simple change, correct code is generated instead of the ICE. 
I think this case never occurs in the calling conventions used in DMC.

 Of course, taking the address of an parameter, then casting it to the wrong 
size is a highly dubious thing
 to be doing, since it's getting whatever happens to be on the stack. Unsafe 
mode only!
 
 PATCH (against DMD2.033) cod1.c, line 3434:
 
    // See if we can use register that parameter was passed in
    if (regcon.params && e->EV.sp.Vsym->Sclass == SCfastpar &&
-	regcon.params & mask[e->EV.sp.Vsym->Spreg])
+	regcon.params & mask[e->EV.sp.Vsym->Spreg] && sz!=REGSIZE*2)
    {	assert(sz <= REGSIZE);
	reg = e->EV.sp.Vsym->Spreg;
	forregs = mask[reg];
	mfuncreg &= ~forregs;
	regcon.used |= forregs;
	return fixresult(e,forregs,pretregs);
    }
Comment 6 Walter Bright 2009-10-13 13:43:47 UTC
Fixed dmd 1.049 and 2.034