// Check if the '- .cxx_construct' and '-.cxx_destruct' methods get called // and if they perform their desired function. // { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } // { dg-do run { target *-*-darwin* } } // { dg-skip-if "" { *-*-* } { "-fgnu-runtime" } { "" } } // { dg-options "-fobjc-call-cxx-cdtors" } #include "../objc-obj-c++-shared/TestsuiteObject.m" #include #define CHECK_IF(expr) if(!(expr)) abort() static int ctor1_called, ctor2_called, dtor1_called; struct bar { int a, b; bar(void) { a = 5; b = 6; ctor1_called++; } ~bar(void) { a = b = 99; dtor1_called++; } }; struct boo: bar { int c; boo(int _c = 9): c(_c) { ctor2_called++; } }; @interface Baz: TestsuiteObject { @public bar aa; } @end @implementation Baz @end @interface Foo: Baz { @public int a; boo bb; bar b; float c; bar d; } @end @implementation Foo @end int main (void) { CHECK_IF(!ctor1_called && !ctor2_called && !dtor1_called); /* are we sane? */ Baz *baz = [Baz new]; CHECK_IF(ctor1_called && !ctor2_called && !dtor1_called); CHECK_IF(baz->aa.a == 5 && baz->aa.b == 6); ctor1_called = 0; /* reset */ [baz free]; CHECK_IF(!ctor1_called && !ctor2_called && dtor1_called); dtor1_called = 0; /* reset */ Foo *foo = [Foo new]; CHECK_IF(ctor1_called && ctor2_called && !dtor1_called); CHECK_IF(foo->bb.a == 5 && foo->bb.b == 6 && foo->bb.c == 9); CHECK_IF(foo->b.a == 5 && foo->b.b == 6); CHECK_IF(foo->d.a == 5 && foo->d.b == 6); ctor1_called = ctor2_called = 0; /* reset */ [foo free]; CHECK_IF(!ctor1_called && !ctor2_called && dtor1_called); }