| import core.stdc.stdio : printf; |
| |
| __gshared int counter; |
| |
| int getID(int expectedID) nothrow { |
| printf("getID: counter = %d, expecting %d\n", counter, expectedID); |
| assert(counter == expectedID); |
| ++counter; |
| return expectedID; |
| } |
| |
| ref int getCounterRef(int expectedID) nothrow { |
| getID(expectedID); |
| return counter; |
| } |
| |
| struct StructWithDtor { |
| __gshared int numDtor; |
| int id; |
| |
| this(int expectedID) nothrow { |
| printf("constructing %d\n", expectedID); |
| this.id = getID(expectedID); |
| } |
| |
| ~this() nothrow { |
| printf("destructing %d\n", id); |
| ++numDtor; |
| } |
| } |
| |
| StructWithDtor make(int expectedID, bool doThrow) { |
| if (doThrow) |
| throw new Exception("make()"); |
| return StructWithDtor(expectedID); |
| } |
| |
| void evaluationOrder(int a, int b, StructWithDtor c, int d, int e, ref int f, StructWithDtor g, int h, int i) { |
| assert(f is counter); |
| } |
| void evaluationOrderTest() { |
| counter = StructWithDtor.numDtor = 0; |
| evaluationOrder(getID(0), getID(1), StructWithDtor(2), getID(3), getID(4), getCounterRef(5), make(6, false), getID(7), getID(8)); |
| assert(counter == 9); |
| |
| // TODO: add right-to-left test (array ops) |
| } |
| |
| void dtors(StructWithDtor a, StructWithDtor b, StructWithDtor c, StructWithDtor d) { |
| throw new Exception("dtors()"); |
| } |
| void dtorsTest() { |
| // no throw in args, but in callee |
| counter = StructWithDtor.numDtor = 0; |
| try { |
| dtors(StructWithDtor(0), make(1, false), StructWithDtor(2), make(3, false)); |
| assert(0); |
| } catch (Exception) {} |
| assert(counter == 4); |
| assert(StructWithDtor.numDtor == 4); |
| |
| // throw in last arg |
| counter = StructWithDtor.numDtor = 0; |
| try { |
| dtors(StructWithDtor(0), make(1, false), StructWithDtor(2), make(3, true)); |
| assert(0); |
| } catch (Exception) {} |
| assert(counter == 3); |
| assert(StructWithDtor.numDtor == 3); |
| |
| // throw in 2nd arg |
| counter = StructWithDtor.numDtor = 0; |
| try { |
| dtors(StructWithDtor(0), make(1, true), StructWithDtor(2), make(3, true)); |
| assert(0); |
| } catch (Exception) {} |
| assert(counter == 1); |
| assert(StructWithDtor.numDtor == 1); |
| |
| // TODO: test exception chaining with throwing dtors |
| } |
| |
| void main() { |
| evaluationOrderTest(); |
| dtorsTest(); |
| } |