--- /dev/null
+// check cleanup of template temporaries
+
+int ctor = 0;
+int dtor = 0;
+
+template <class T> struct A {
+ A() {ctor++;}
+ A(int) {ctor++;}
+ A(const A&) {ctor++;}
+ ~A() {dtor++;}
+ operator int() {return 0;}
+};
+
+template <class T> void ff(T);
+
+template <class T> void ff(T)
+{
+}
+
+void g(void)
+{
+}
+
+void f()
+{
+ int x;
+
+ A<int> a1;
+ A<double> a2(37);
+ A<long> a3 = A<long>(47);
+ A<short> a4 = 97;
+
+ g(A<char*>());
+
+ A<char**>();
+
+ x ? A<char*>() : A<char*>();
+
+ x = 47, A<double*>(), A<int>(39), A<void>(23), -17;
+
+ while (A<short>())
+ ;
+ for (;A<unsigned>(3);)
+ ;
+ if (A<A<double> >())
+ ;
+
+ ff(A<double>());
+
+ throw 59;
+}
+
+int
+main()
+{
+ int flag = 0;
+
+ try {
+ A<unsigned long>();
+ f();
+ }
+ catch (int) {
+ A<float>(34);
+ flag = 1;
+ }
+
+ if (!flag)
+ abort();
+
+ if (!ctor || ctor != dtor)
+ abort();
+
+ exit(0);
+}
--- /dev/null
+// check MI and VBC offsets on throw
+
+struct A {
+ int x[23];
+};
+
+struct B : virtual public A {
+ int y[33];
+};
+
+struct C : virtual public A, public B {
+ int z[43];
+};
+
+struct D {
+ int xx[53];
+};
+
+struct E : public D, public A {
+ int yy[63];
+};
+
+C c;
+
+E e;
+
+void f1()
+{
+ throw (C*)0;
+}
+
+void f2()
+{
+ throw &c;
+}
+
+void f3()
+{
+ throw (E*)0;
+}
+
+void f4()
+{
+ throw &e;
+}
+
+int main()
+{
+ int flag;
+
+ flag = 0;
+ try {
+ f1();
+ }
+ catch (A* p) {
+ if (p)
+ abort();
+ flag = 1;
+ }
+ if (!flag)
+ abort();
+
+ flag = 0;
+ try {
+ f2();
+ }
+ catch (A* p) {
+ if (!p || (void*)p == (void*)&c)
+ abort();
+ flag = 1;
+ }
+ if (!flag)
+ abort();
+
+ flag = 0;
+ try {
+ f3();
+ }
+ catch (A* p) {
+ if (p)
+ abort();
+ flag = 1;
+ }
+ if (!flag)
+ abort();
+
+ flag = 0;
+ try {
+ f4();
+ }
+ catch (A* p) {
+ if (!p || (void*)p == (void*)&e)
+ abort();
+ flag = 1;
+ }
+ if (!flag)
+ abort();
+
+ exit(0);
+}
--- /dev/null
+// check MI and VBC offsets on throw
+
+struct A {
+ int x[23];
+};
+
+struct B : virtual public A {
+ int y[33];
+};
+
+struct C : virtual public A, public B {
+ int z[43];
+};
+
+struct D {
+ int xx[53];
+};
+
+struct E : public D, public A {
+ int yy[63];
+};
+
+C c;
+
+E e;
+
+void f1()
+{
+ throw (C*)0;
+}
+
+void f2()
+{
+ throw &c;
+}
+
+void f3()
+{
+ throw (E*)0;
+}
+
+void f4()
+{
+ throw &e;
+}
+
+int
+main()
+{
+ int flag;
+
+ flag = 0;
+ try {
+ f1();
+ }
+ catch (void* p) {
+ if (p)
+ abort();
+ flag = 1;
+ }
+ if (!flag)
+ abort();
+
+ flag = 0;
+ try {
+ f2();
+ }
+ catch (void* p) {
+ if (!p || (void*)p != (void*)&c)
+ abort();
+ flag = 1;
+ }
+ if (!flag)
+ abort();
+
+ flag = 0;
+ try {
+ f3();
+ }
+ catch (void* p) {
+ if (p)
+ abort();
+ flag = 1;
+ }
+ if (!flag)
+ abort();
+
+ flag = 0;
+ try {
+ f4();
+ }
+ catch (void* p) {
+ if (!p || (void*)p != (void*)&e)
+ abort();
+ flag = 1;
+ }
+ if (!flag)
+ abort();
+
+ exit(0);
+}
--- /dev/null
+// check cleanup of partial array objects
+
+int ctor = 0;
+int dtor = 0;
+
+int cnt = 1;
+
+struct A {
+ int x;
+ A();
+ A(const A&);
+ ~A();
+};
+
+A::A()
+{
+ if (cnt == 10)
+ throw 57;
+ x = cnt++;
+ ctor++;
+}
+
+A::A(const A&)
+{
+ if (cnt == 10)
+ throw 57;
+ x = cnt++;
+ ctor++;
+}
+
+A::~A()
+{
+ if (x + 1 != cnt--)
+ abort();
+ dtor++;
+}
+
+void f()
+{
+ A a[] = {A(), A(), A(), A(), A(), A(), A(), A(), A(), A(), A(), A()};
+
+ throw -1066;
+}
+
+int
+main()
+{
+ int flag;
+
+ flag = 0;
+ try {
+ f();
+ }
+ catch (int) {
+ flag = 1;
+ }
+ if (!flag)
+ abort();
+ if (ctor != 9)
+ abort();
+ if (dtor != 9)
+ abort();
+
+ exit(0);
+}
--- /dev/null
+// check EH with templates
+
+template <class T, int n, class U> struct A {
+ A() {}
+ A(char*) {}
+};
+
+void f1()
+{
+ throw *(new A<double, 47, A<int, 37, short> >);
+}
+
+void f2()
+{
+ throw *(new A<double, 47, A<int, 36, short> >);
+}
+
+void f3()
+{
+ throw A<double, 47, A<int, 37, short> > ("howdy");
+}
+
+void f4()
+{
+ throw A<double, 47, A<int, 36, short> > ("hi michey");
+}
+
+main()
+{
+ int flag;
+
+ flag = 0;
+ try {
+ f1();
+ }
+ catch (A<double, 47, A<int, 36, short> >) {
+ abort();
+ }
+ catch (A<double, 47, A<int, 37, short> >) {
+ flag = 1;
+ }
+ if (!flag)
+ abort();
+
+ flag = 0;
+ try {
+ f2();
+ }
+ catch (A<double, 47, A<int, 36, short&> >) {
+ abort();
+ }
+ catch (A<double, 47, A<int, 36, short> >) {
+ flag = 1;
+ }
+ if (!flag)
+ abort();
+
+ flag = 0;
+ try {
+ f3();
+ }
+ catch (A<double, 47, A<int, 36, short> >) {
+ abort();
+ }
+ catch (A<double, 47, A<int, 37, short> >) {
+ flag = 1;
+ }
+ if (!flag)
+ abort();
+
+ flag = 0;
+ try {
+ f4();
+ }
+ catch (A<double, 47, A<int, 36, short&> >) {
+ abort();
+ }
+ catch (A<double, 47, A<int, 36, short> >) {
+ flag = 1;
+ }
+ if (!flag)
+ abort();
+
+ exit(0);
+}