1 import core.stdc.stdio : printf;
2 
3 __gshared int counter;
4 
getID(int expectedID)5 int getID(int expectedID) nothrow {
6     printf("getID: counter = %d, expecting %d\n", counter, expectedID);
7     assert(counter == expectedID);
8     ++counter;
9     return expectedID;
10 }
11 
getCounterRef(int expectedID)12 ref int getCounterRef(int expectedID) nothrow {
13     getID(expectedID);
14     return counter;
15 }
16 
17 struct StructWithDtor {
18     __gshared int numDtor;
19     int id;
20 
thisStructWithDtor21     this(int expectedID) nothrow {
22         printf("constructing %d\n", expectedID);
23         this.id = getID(expectedID);
24     }
25 
~thisStructWithDtor26     ~this() nothrow {
27         printf("destructing %d\n", id);
28         ++numDtor;
29     }
30 }
31 
make(int expectedID,bool doThrow)32 StructWithDtor make(int expectedID, bool doThrow) {
33     if (doThrow)
34         throw new Exception("make()");
35     return StructWithDtor(expectedID);
36 }
37 
evaluationOrder(int a,int b,StructWithDtor c,int d,int e,ref int f,StructWithDtor g,int h,int i)38 void evaluationOrder(int a, int b, StructWithDtor c, int d, int e, ref int f, StructWithDtor g, int h, int i) {
39     assert(f is counter);
40 }
evaluationOrderTest()41 void evaluationOrderTest() {
42     counter = StructWithDtor.numDtor = 0;
43     evaluationOrder(getID(0), getID(1), StructWithDtor(2), getID(3), getID(4), getCounterRef(5), make(6, false), getID(7), getID(8));
44     assert(counter == 9);
45 
46     // TODO: add right-to-left test (array ops)
47 }
48 
dtors(StructWithDtor a,StructWithDtor b,StructWithDtor c,StructWithDtor d)49 void dtors(StructWithDtor a, StructWithDtor b, StructWithDtor c, StructWithDtor d) {
50     throw new Exception("dtors()");
51 }
dtorsTest()52 void dtorsTest() {
53     // no throw in args, but in callee
54     counter = StructWithDtor.numDtor = 0;
55     try {
56         dtors(StructWithDtor(0), make(1, false), StructWithDtor(2), make(3, false));
57         assert(0);
58     } catch (Exception) {}
59     assert(counter == 4);
60     assert(StructWithDtor.numDtor == 4);
61 
62     // throw in last arg
63     counter = StructWithDtor.numDtor = 0;
64     try {
65         dtors(StructWithDtor(0), make(1, false), StructWithDtor(2), make(3, true));
66         assert(0);
67     } catch (Exception) {}
68     assert(counter == 3);
69     assert(StructWithDtor.numDtor == 3);
70 
71     // throw in 2nd arg
72     counter = StructWithDtor.numDtor = 0;
73     try {
74         dtors(StructWithDtor(0), make(1, true), StructWithDtor(2), make(3, true));
75         assert(0);
76     } catch (Exception) {}
77     assert(counter == 1);
78     assert(StructWithDtor.numDtor == 1);
79 
80     // TODO: test exception chaining with throwing dtors
81 }
82 
main()83 void main() {
84     evaluationOrderTest();
85     dtorsTest();
86 }
87