1// Check if the '- .cxx_construct' and '-.cxx_destruct' methods get called 2// and if they perform their desired function. 3 4// { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } 5// { dg-do run { target *-*-darwin* } } 6// { dg-skip-if "" { *-*-* } { "-fgnu-runtime" } { "" } } 7// { dg-options "-fobjc-call-cxx-cdtors" } 8 9#include "../objc-obj-c++-shared/TestsuiteObject.m" 10#include <stdlib.h> 11#define CHECK_IF(expr) if(!(expr)) abort() 12 13static int ctor1_called, ctor2_called, dtor1_called; 14 15struct bar { 16 int a, b; 17 bar(void) { 18 a = 5; b = 6; 19 ctor1_called++; 20 } 21 ~bar(void) { 22 a = b = 99; 23 dtor1_called++; 24 } 25}; 26 27struct boo: bar { 28 int c; 29 boo(int _c = 9): c(_c) { 30 ctor2_called++; 31 } 32}; 33 34@interface Baz: TestsuiteObject { 35@public 36 bar aa; 37} 38@end 39 40@implementation Baz 41@end 42 43@interface Foo: Baz { 44@public 45 int a; 46 boo bb; 47 bar b; 48 float c; 49 bar d; 50} 51@end 52 53@implementation Foo 54@end 55 56int main (void) 57{ 58 CHECK_IF(!ctor1_called && !ctor2_called && !dtor1_called); /* are we sane? */ 59 60 Baz *baz = [Baz new]; 61 CHECK_IF(ctor1_called && !ctor2_called && !dtor1_called); 62 CHECK_IF(baz->aa.a == 5 && baz->aa.b == 6); 63 ctor1_called = 0; /* reset */ 64 65 [baz free]; 66 CHECK_IF(!ctor1_called && !ctor2_called && dtor1_called); 67 dtor1_called = 0; /* reset */ 68 69 Foo *foo = [Foo new]; 70 CHECK_IF(ctor1_called && ctor2_called && !dtor1_called); 71 CHECK_IF(foo->bb.a == 5 && foo->bb.b == 6 && foo->bb.c == 9); 72 CHECK_IF(foo->b.a == 5 && foo->b.b == 6); 73 CHECK_IF(foo->d.a == 5 && foo->d.b == 6); 74 ctor1_called = ctor2_called = 0; /* reset */ 75 76 [foo free]; 77 CHECK_IF(!ctor1_called && !ctor2_called && dtor1_called); 78} 79 80