]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/testsuite/gdc.test/compilable/test14838.d
d: Import dmd b8384668f, druntime e6caaab9, phobos 5ab9ad256 (v2.098.0-beta.1)
[thirdparty/gcc.git] / gcc / testsuite / gdc.test / compilable / test14838.d
CommitLineData
b4c522fa
IB
1// PERMUTE_ARGS:
2
3struct A(T) { ~this() {} }
4class C { A!int[1] array; }
5
6void 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
56void destroy14838(S)(ref S s) if (is(S == struct))
57{
58 s.__xdtor();
59}
60
61struct RefCounted14838(T)
62{
63 ~this()
64 {
65 T t;
66 .destroy14838(t);
67 }
68
69 void opAssign(typeof(this) rhs) {}
70}
71
72struct RangeT14838(A)
73{
74 A[1] _outer_;
75}
76
77struct Array14838(T)
78{
79 struct Payload
80 {
81 ~this() {}
82 }
83 RefCounted14838!Payload _data;
84
85 alias Range = RangeT14838!Array14838;
86}
87
88class Test14838
89{
90 Array14838!int[1] field;
91}