6052 – [CTFE] Structs elements in an array are treated like reference type

D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 6052 - [CTFE] Structs elements in an array are treated like reference type
Summary: [CTFE] Structs elements in an array are treated like reference type
Status: RESOLVED FIXED
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D2
Hardware: Other Mac OS X
: P2 regression
Assignee: No Owner
URL:
Keywords: wrong-code
Depends on:
Blocks:
Reported: 2011年05月24日 09:06 UTC by kennytm
Modified: 2011年06月01日 22:49 UTC (History)
1 user (show)

See Also:


Attachments
Add an attachment (proposed patch, testcase, etc.)

Note You need to log in before you can comment on or make changes to this issue.
Description kennytm 2011年05月24日 09:06:57 UTC
Test case:
--------------------------------------------------
struct Bug6052 {
 int a;
}
bool bug6052() {
 Bug6052[2] arr;
 for (int i = 0; i < 2; ++ i) {
 Bug6052 el = {i};
 Bug6052 ek = el;
 arr[i] = el;
 el.a = i + 2;
 assert(ek.a == i); // ok
 assert(arr[i].a == i); // fail
 }
 assert(arr[1].a == 1); // ok
 assert(arr[0].a == 0); // fail
 return true;
}
static assert(bug6052());
--------------------------------------------------
x.d(16): Error: assert(arr[cast(uint)i].a == i) failed
x.d(23): Error: cannot evaluate bug6052() at compile time
x.d(23): Error: static assert (bug6052()) is not evaluatable at compile time
--------------------------------------------------
Setting a struct value on a array should perform a bit-copy, so modifying 'el' should not affect 'arr[i]', but currently CTFE does it wrongly.
Comment 1 kennytm 2011年05月24日 09:10:47 UTC
Note: the last 2 asserts refer to the case when the line 'el.a = i + 2;' is commented out.
Comment 2 Don 2011年05月30日 17:02:43 UTC
A related test case which also fails, but involves static arrays rather than structs:
bool bug6052b() {
 int[][1] arr;
 int[1] z = [7];
 arr[0] = z;
 assert(arr[0][0] == 7);
 arr[0] = z;
 z[0] = 3;
 assert(arr[0][0] == 3);
 return true;
}
static assert(bug6052b());
https://github.com/D-Programming-Language/dmd/commit/bccb02ad1d8578767f99efeab4a230a229e24392
Case b:
https://github.com/D-Programming-Language/dmd/commit/2ee56a0038ccac3b2225b7feda9d69798cc203e3
D1:
https://github.com/D-Programming-Language/dmd/commit/bccb02ad1d8578767f99efeab4a230a229e24392 
Comment 3 kennytm 2011年05月31日 01:34:45 UTC
The bug still exists if the the struct has a constructor and we're appending to a dynamic array....
---------------------------------------------
struct Bug6052c {
 int x;
 this(int a) { x = a; }
}
static assert({
 Bug6052c[] pieces = [];
 for (int c = 0; c < 2; ++ c)
 pieces ~= Bug6052c(c);
 assert(pieces[1].x == 1); // ok
 assert(pieces[0].x == 0); // asserts
 return true;
}());
---------------------------------------------
x.d(10): Error: assert(pieces[0u].x == 0) failed
<snipped>
---------------------------------------------
or filling the uninitialized portion of a dynamic array....
---------------------------------------------
static assert({
 int[1][] pieces = [];
 pieces.length = 2;
 for (int c = 0; c < 2; ++ c)
 pieces[c][0] = c;
 assert(pieces[1][0] == 1); // ok
 assert(pieces[0][0] == 0); // asserts
 return true;
}());
---------------------------------------------
x.d(7): Error: assert(pieces[0u][0u] == 0) failed
<snipped>
---------------------------------------------


AltStyle によって変換されたページ (->オリジナル) /