]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/testsuite/gdc.test/compilable/test14838.d
Add D front-end, libphobos library, and D2 testsuite.
[thirdparty/gcc.git] / gcc / testsuite / gdc.test / compilable / test14838.d
1 // PERMUTE_ARGS:
2
3 struct A(T) { ~this() {} }
4 class C { A!int[1] array; }
5
6 void test14838() pure nothrow @nogc @safe
7 {
8 C c;
9 c.__xdtor(); // C.~this() will also be inferred to
10 // pure nothrow @nogc @safe
11
12 A!int[1] array;
13 // scope destructor call does not cause attribute violation.
14 }
15
16 // ----
17
18 /*
19 * This is a reduced test case comes from std.container.Array template,
20 * to fix the semantic analysis order issue for correct destructor attribute inference.
21 *
22 * Before the bugfix:
23 * 1. StructDeclaration('Array!int').semantic() instantiates
24 * RangeT!(Array!int) at the `alias Range = ...;`, but
25 * StructDeclaration('RangeT!(Array!int)').semantic() exits
26 * with sizeok == SIZEOKfwd, because the size of _outer_ field is not yet determined.
27 * 2. StructDeclaration('Array!int').semantic() succeeds to determine the size
28 * (sizeok = SIZEOKdone).
29 * 3. StructDeclaration('Array!int').buildOpAssign() will generate opAssign because
30 * Array!int._data field has identity opAssign member function.
31 * 4. The semantic3 will get called for the generated opAssign, then
32 * 6-1. Array!int.~this() semantic3, and
33 * 6-2. RefCounted!(Array!int.Payload).~this() semantic3
34 * will also get called to infer their attributes.
35 * 5. In RefCounted!(Array!int.Payload).~this(), destroy(t) will be instantiated.
36 * At that, TemplateInstance.expandMembers() will invoke runDeferredSemantic()
37 * and it will re-run StructDeclaration('RangeT!(Array!int)').semantic().
38 * 6. StructDeclaration('RangeT!(Array!int)').semantic() determines the size
39 * (sizeok = SIZEOKdone). Then, it will generate identity opAssign and run its semantic3.
40 * It will need to infer RangeT!(Array!int).~this() attribute, then it requires the
41 * correct attribute of Array!int.~this().
42 *
43 * However, the Array!int.~this() attribute is not yet determined! [bug]
44 * -> it's wongly handled as impure/system/throwable/gc-able.
45 *
46 * -> then, the attribute inference results for
47 * RangeT!(Array!int).~this() and Array!int.~this() will be incorrect.
48 *
49 * After the bugfix:
50 * In 6, StructDeclaration('RangeT!(Array!int)').semantic() will check that:
51 * all base struct types of the instance fields have completed addition of
52 * special functions (dtor, opAssign, etc).
53 * If not, it will defer the completion of its semantic pass.
54 */
55
56 void destroy14838(S)(ref S s) if (is(S == struct))
57 {
58 s.__xdtor();
59 }
60
61 struct RefCounted14838(T)
62 {
63 ~this()
64 {
65 T t;
66 .destroy14838(t);
67 }
68
69 void opAssign(typeof(this) rhs) {}
70 }
71
72 struct RangeT14838(A)
73 {
74 A[1] _outer_;
75 }
76
77 struct Array14838(T)
78 {
79 struct Payload
80 {
81 ~this() {}
82 }
83 RefCounted14838!Payload _data;
84
85 alias Range = RangeT14838!Array14838;
86 }
87
88 class Test14838
89 {
90 Array14838!int[1] field;
91 }