Bug 1140 – ICE(cod1.c) casting last function parameter to 8 byte value

Status
RESOLVED
Resolution
FIXED
Severity
normal
Priority
P2
Component
dmd
Product
D
Version
D1 (retired)
Platform
x86
OS
All
Creation time
2007-04-13T08:52:00Z
Last change time
2014-02-16T15:25:23Z
Keywords
ice-on-valid-code, patch
Assigned to
nobody
Creator
clugdbug

Comments

Comment #0 by clugdbug — 2007-04-13T08:52:25Z
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 by fvbommel — 2007-04-13T09:34:02Z
*** Bug 1139 has been marked as a duplicate of this bug. ***
Comment #2 by thomas-dloop — 2007-04-23T12:55:54Z
Comment #3 by clugdbug — 2009-05-19T00:27:41Z
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 by clugdbug — 2009-10-07T06:31:19Z
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 by clugdbug — 2009-10-07T23:58:13Z
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 by bugzilla — 2009-10-13T13:43:47Z
Fixed dmd 1.049 and 2.034