1 // Copyright (c) Microsoft. All rights reserved. 2 // Licensed under the MIT license. See LICENSE file in the project root for 3 // full license information. 4 5 #include <stdlib.h> 6 #include <stdio.h> 7 8 #define FALSE 0 9 #define TRUE 1 10 #define NO_CTOR_THROW 1 11 #define NO_DTOR_THROW 2 12 13 #define TEST_DTOR 14 15 #define MAX_OBJECTS 500 16 17 #define NOEXCEPT(_x) 18 19 int Object[MAX_OBJECTS]; 20 int CurrentObjectNumber, ThrowCount, MaxObjectCount = 1; 21 int Fail; 22 23 void FAIL(int i) { 24 printf("FAILED on %d\n", i); 25 Fail++; 26 } 27 28 void dealloc(int i, int no_throw) { 29 /* Make sure i is valid, and object exists */ 30 if (i < 0 || i >= MaxObjectCount || !Object[i]) 31 FAIL(i); 32 33 Object[i] = 0; 34 35 /* Try throw in this dtor.. */ 36 #ifdef TEST_DTOR 37 if (i + MaxObjectCount == ThrowCount && !no_throw) { 38 printf("Throwing\n"); 39 throw(1); 40 } 41 #endif 42 } 43 44 void alloc(int i, int no_throw) { 45 if (CurrentObjectNumber > MaxObjectCount) 46 MaxObjectCount = CurrentObjectNumber; 47 48 /* Object already exists? */ 49 if (Object[i]) 50 FAIL(i); 51 52 /* Try throw in this ctor.. */ 53 if (i == ThrowCount && !no_throw) { 54 printf("Throwing\n"); 55 throw(1); 56 } 57 58 if (i >= MAX_OBJECTS) { 59 printf("\n*** Number of objects exceeded. Increase MAX_OBJECTS ***\n\n"); 60 FAIL(i); 61 i = 0; 62 } 63 64 Object[i] = 1; 65 } 66 67 class B { 68 public: 69 int i; 70 int flag; 71 B(); 72 B(int); 73 ~B() NOEXCEPT(false); 74 }; 75 76 B::B() { 77 i = CurrentObjectNumber++; 78 printf("B ctor. i = %d\n", i); 79 alloc(i, FALSE); 80 } 81 82 B::B(int f) { 83 i = CurrentObjectNumber++; 84 flag = f; 85 printf("B ctor. i = %d\n", i); 86 alloc(i, flag == NO_CTOR_THROW); 87 } 88 89 B::~B() NOEXCEPT(false) { 90 printf("B dtor. i = %d\n", i); 91 dealloc(i, flag == NO_DTOR_THROW); 92 } 93 94 class A { 95 public: 96 int i; 97 A(); 98 A(int) { 99 i = CurrentObjectNumber++; 100 printf("A(int) ctor. i = %d\n", i); 101 alloc(i, FALSE); 102 } 103 A operator+(A a); 104 A(const A &a) { 105 /* Try objects in ctor */ 106 B b1 = NO_DTOR_THROW, b2 = NO_DTOR_THROW; 107 108 i = CurrentObjectNumber++; 109 printf("A copy ctor. i = %d\n", i); 110 alloc(i, FALSE); 111 } 112 113 ~A() NOEXCEPT(false) { 114 /* Try objects in dtor */ 115 B b1 = NO_CTOR_THROW, b2 = NO_CTOR_THROW; 116 117 printf("A dtor. i = %d\n", i); 118 dealloc(i, FALSE); 119 }; 120 }; 121 122 A::A() { 123 i = CurrentObjectNumber++; 124 printf("A ctor. i = %d\n", i); 125 alloc(i, FALSE); 126 } 127 128 A A::operator+(A a) { 129 printf("A%d + A%d\n", i, a.i); 130 return A(); 131 } 132 133 A foo(A a1, A a2) { return a1 + a2; }; 134 135 int bar() { 136 A a; 137 138 return 666; 139 } 140 141 void foo2(int i, A a1, A a2, A a3) { 142 if (i != 666) 143 FAIL(666); 144 foo(a1, a3); 145 } 146 147 A test() { 148 puts("Try simple ctor"); 149 A a1; 150 151 puts("Try question op ctor"); 152 A a2 = (ThrowCount & 1) ? A() : ThrowCount; 153 154 puts("Try a more complex question op ctor"); 155 A a3 = (ThrowCount & 1) ? A() + a1 + A() + a2 : a2 + A() + A() + ThrowCount; 156 157 puts("Try mbarg copy ctors, and return UDT"); 158 A a4 = foo(a1, a2); 159 160 puts("Try a more complex mbarg copy ctors, and a function call"); 161 foo2(bar(), a1 + a2, a2 + A() + a3 + a4, a3); 162 163 puts("Try temporary expressions, and return UDT"); 164 return a1 + A() + a2 + A() + a3 + a4; 165 } 166 167 int main() { 168 int i; 169 170 /* Call test(), with a different ctor/dtor throwing each time */ 171 for (ThrowCount = 0; ThrowCount < MaxObjectCount * 2; ThrowCount++) { 172 printf("ThrowCount = %d MaxObjectCount = %d\n", ThrowCount, 173 MaxObjectCount); 174 175 CurrentObjectNumber = 0; 176 177 try { 178 test(); 179 } catch (int) { 180 printf("In catch\n"); 181 } 182 183 /* Any objects which didn't get dtor'd? */ 184 for (i = 0; i < MaxObjectCount; i++) { 185 if (Object[i]) { 186 FAIL(i); 187 Object[i] = 0; 188 } 189 } 190 191 printf("\n"); 192 } 193 194 printf("\n"); 195 if (Fail) 196 printf("FAILED %d tests\n", Fail); 197 else 198 printf("Passed\n"); 199 } 200