"Fossies" - the Fresh Open Source Software Archive

Member "dmd-2.089.1/test/compilable/test14838.d" (14 Dec 2019, 2897 Bytes) of package /linux/misc/dmd-2.089.1.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) D source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    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 }