Bug 16471 – [CTFE] Incorrect CTFE when assigning to union struct fields

Status
NEW
Severity
major
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2016-09-06T11:54:05Z
Last change time
2024-12-13T18:49:57Z
Assigned to
No Owner
Creator
Johan Engelen
Moved to GitHub: dmd#19185 →

Comments

Comment #0 by jbc.engelen — 2016-09-06T11:54:05Z
The following code asserts with DMD 2.071: ``` struct StructA { this(int a) { i = a; } import std.typecons; mixin Proxy!i; int i; } struct TestValue { union UnionType { int first; StructA second; StructA third; } UnionType value; this(StructA val) { assign(val); } void assign(StructA val) { value.third = val; assignSecond(7); } void assignSecond(int val) { value.second = StructA(val); } } void main() { enum ctObj = TestValue(StructA(1)); // The last assigment in TestValue's construction is to value.second. assert(ctObj.value.second.i == 7); // // Note: assert(ctObj.value.third.i == 1) passes, but shouldn't. } ``` When `enum` is changed to `auto` it all works fine. The problem lies in a corrupt `StructLiteralExp` array of initializers (`StructLiteralExp.elements`). In e2ir `toElemStructLit` there is a comment saying: "If a field has explicit initializer (*sle->elements)[i] != NULL), any other overlapped fields won't have initializer." This however, is not true. When assigning to union fields in `assign` and `assignSecond`, multiple union fields will get an initializer (`(*sle->elements)[i] != NULL`). Even without `assignSecond`, the `first` and `second` fields will both have an initializer (this bugs LDC, https://github.com/ldc-developers/ldc/issues/1324, where DMD's codegen (accidentally) gets it right).
Comment #1 by jbc.engelen — 2016-09-06T12:54:28Z
A simpler testcase: ``` void main() { struct A { int i; } struct S { union U { A first; A second; } U u; this(A val) { u.second = val; assign(val); } void assign(A val) { u.first.i = val.i+1; } } enum a = S(A(1)); assert(a.u.first.i == 2); } ```
Comment #2 by robert.schadek — 2024-12-13T18:49:57Z
THIS ISSUE HAS BEEN MOVED TO GITHUB https://github.com/dlang/dmd/issues/19185 DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB