D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 2469 - ICE(cod1.c) arbitrary struct accepted as struct initializer
Summary: ICE(cod1.c) arbitrary struct accepted as struct initializer
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-invalid-code, patch
: 3036 3076 3216 3287 (view as issue list)
Depends on:
Blocks:
 
Reported: 2008-11-23 03:56 UTC by Christian Kamm
Modified: 2014-03-01 00:36 UTC (History)
5 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description Christian Kamm 2008-11-23 03:56:09 UTC
The following code compiles

struct Foo { double d; }
struct Bar { byte b; }
void main() { Foo foo; Bar bar = foo; }

even though Foo is not implicitly convertible to Bar. In contrast, assigning

Foo foo;
Bar bar;
bar = foo;

fails as expected.
Comment 1 Christian Kamm 2009-06-17 23:19:21 UTC
*** Issue 3076 has been marked as a duplicate of this issue. ***
Comment 2 Christian Kamm 2009-06-17 23:20:41 UTC
Jarett found this pretty ICE in ztc\cod1.c:1673:

This can lead to the ICE mentioned in the description, if the source type is
smaller than the destination, at least for some values of "smaller," *and* the
source is a function call.  The following, for instance, causes it:

struct Small { uint x; }
struct Large { uint x, y, z; }
Small foo() { return Small(); }
void main() { Large l = foo(); } // bang!
Comment 3 Jarrett Billingsley 2009-06-18 06:45:55 UTC
Ah poop.  I was searching for ICEs and never even came across this one :)
Comment 4 anonymous4 2009-06-23 05:16:12 UTC
possibly related to bug 3036.
Comment 5 Jarrett Billingsley 2009-07-30 08:42:40 UTC
*** Issue 3216 has been marked as a duplicate of this issue. ***
Comment 6 Don 2009-08-07 01:28:58 UTC
There are two completely different bugs in this report. One is the implicit conversion one, which is a bad code generation bug.

The ICE is actually a quite different bug. Here's a test case which doesn't involve the initialisation bug.

struct Small { uint x; }
struct Large { uint x, y, z; }
Small foo() { return Small(); }
void main() { 
  Large l; Small s; 
  l = cast(Large)foo();
}
Comment 7 Don 2009-08-07 01:29:07 UTC
*** Issue 3036 has been marked as a duplicate of this issue. ***
Comment 8 Don 2009-08-08 22:21:44 UTC
There's a patch for the original bug in bug 2702. It's unrelated to the ICE.
(It's really annoying when new bugs are reported in the comments for existing bugs, it's not clear what to do with them).
Comment 9 Jarrett Billingsley 2009-09-03 09:48:19 UTC
*** Issue 3287 has been marked as a duplicate of this issue. ***
Comment 10 Don 2009-09-22 01:07:54 UTC
The root cause is that all kinds of nonsense is allowed in struct casts. Explicit struct casts only make sense when the source and destination are of the same size.

Patch against DMD 2.032.

Index: cast.c
===================================================================
--- cast.c	(revision 196)
+++ cast.c	(working copy)
@@ -822,6 +822,15 @@
 		    return e;
 		}
 	    }
+	    // Struct casts are possible only when the sizes match
+	    if (typeb->ty==Tstruct || tb->ty==Tstruct) {
+		size_t fromsize = tb->size(loc);
+		size_t tosize = typeb->size(loc);
+		if (fromsize !=tosize) {
+		    error("Cannot cast from %s to %s", type->toChars(), t->toChars());
+		    return this;
+		}
+	    }
 	    e = new CastExp(loc, e, tb);
 	}
     }
Comment 11 Walter Bright 2009-10-06 02:14:23 UTC
Fixed dmd 1.048 and 2.033