blob: cf6a1909162f57642d0f92cae8f548c40668af19 [file] [log] [blame]
/* APPLE LOCAL file Macintosh alignment */
/* { dg-do run } */
/* { dg-options "-Wno-long-long -Wno-invalid-offsetof" } */
/*
* Macintosh compiler alignment test for C++.
* Fred Forsman
* Apple Computer, Inc.
*/
#include <stdio.h>
#include <stddef.h>
#include <string.h>
extern "C" void abort (void);
#define Q(x) #x, x
typedef unsigned char UINT8;
typedef unsigned short UINT16;
typedef unsigned long UINT32;
static int bad_option = 0;
static int flag_verbose = 0;
static int nbr_failures = 0;
/* === classes === */
class C1 {
static const int f1 = 1;
UINT8 f2;
};
class C2 {
static int f1;
UINT8 f2;
};
class C3 {
public:
enum E1 {
f1 = 1
};
protected:
UINT8 f2;
};
class C4 {
UINT8 f1;
static const int f2 = 1;
};
class C5 {
UINT8 f2;
static int f1;
};
class C6 {
UINT8 f1;
enum E1 {
f2 = 1
};
};
class C7 {
/* empty base class */
};
#ifndef __LP64__
#pragma options align=mac68k
class C8 {
/* empty base class */
};
class C9: public C8 {
public:
UINT8 f1;
};
#pragma options align=reset
#endif /* n __LP64 __ */
/* What is offset of first field after an empty base class? */
class C10: public C7 {
public:
UINT8 f1;
};
/* Check that we no longer try to put derived class bits in padding at end of base class. */
class C11 {
public:
UINT32 f1;
UINT8 f2;
};
class C12: public C11 {
public:
UINT8 f3;
};
/* Check whether compiler will reorder members to take advantage of
padding. If the compiler did this (which it does not appear to
do), f3 and f4 in C14 would be reordered to take advantage of the
padding at the end of the base class. */
class C13 {
public:
UINT32 f1;
UINT16 f2;
};
class C14: public C13 {
public:
UINT32 f3;
UINT16 f4;
};
/* Tests for double aligned base class */
class C15 {
public:
double f1;
long f2;
};
class C16: public C15 {
};
class C17: public C15 {
public:
long f3;
};
class C18: public C16 {
public:
char f3;
};
class C19: public C17 {
public:
char f4;
};
/* Tests for alignment in class with v-table pointer */
class C20 {
public:
double f1;
virtual void func1(void);
};
/* === vectors === */
#ifdef __APPLE_ALTIVEC__
class VC1 {
public:
vector signed short f1;
UINT8 f2;
};
typedef struct VS1 {
VC1 f1;
UINT8 f2;
} VS1;
class VC2: public VC1 {
public:
UINT8 f1;
};
typedef struct VS2 {
UINT8 f1;
VC2 f2;
UINT8 f3;
} VS2;
class VC3 {
public:
vector signed short f1;
virtual void func1(void);
};
#endif
/* === bools === */
typedef struct B1 {
bool f1;
UINT8 f2;
} B1;
typedef struct B2 {
UINT8 f1;
bool f2;
} B2;
static void check(char * rec_name, int actual, int expected32, int expected64,
int expected_ia32, char * comment)
{
int expected;
#ifdef __i386__
expected = expected_ia32;
#else
expected = ((sizeof(char *) == 8) ? expected64 : expected32);
#endif
if (flag_verbose || (actual != expected)) {
printf("%-20s = %2d (%2d) ", rec_name, actual, expected);
if (actual != expected) {
printf("*** FAIL");
nbr_failures++;
} else
printf(" PASS");
printf(": %s\n", comment);
}
}
static void check_option(char *option)
{
if (*option == '-') {
if (strcmp(option, "-v") == 0)
flag_verbose = 1;
else {
fprintf(stderr, "*** unrecognized option '%s'.\n", option);
bad_option = 1;
}
} else {
fprintf(stderr, "*** unrecognized option '%s'.\n", option);
bad_option = 1;
}
}
int main(int argc, char *argv[])
{
int i;
for (i = 1; i < argc; i++)
check_option(argv[i]);
if (bad_option)
return 1;
check(Q(sizeof(C1)), 1, 1, 1, "const as 1st field");
check(Q(sizeof(C2)), 1, 1, 1, "static as 1st field");
check(Q(sizeof(C3)), 1, 1, 1, "enum as 1st field");
check(Q(sizeof(C4)), 1, 1, 1, "const as 2nd field");
check(Q(sizeof(C5)), 1, 1, 1, "static as 2nd field");
check(Q(sizeof(C6)), 1, 1, 1, "enum as 2nd field");
check(Q(sizeof(C7)), 1, 1, 1, "empty class, power mode");
#ifndef __LP64__
check(Q(sizeof(C8)), 2, 2, 2, "empty class, mac68k mode");
check(Q(sizeof(C9)), 2, 2, 2, "class with empty base class and one char, mac68k");
check(Q(offsetof(C9, f1)), 0, 0, 0, "offset of 1st field after empty base class");
#endif
check(Q(sizeof(C10)), 1, 1, 1, "class based on an empty class, power mode");
check(Q(sizeof(C11)), 8, 16, 8, "class with long, char");
check(Q(sizeof(C12)), 12, 24, 12, "class with base class with long, char and its own char");
check(Q(offsetof(C12, f3)), 8, 16, 8, "offset of 1st field in class with a base class with a long, char");
check(Q(sizeof(C13)), 8, 16, 8, "class with long, short");
check(Q(sizeof(C14)), 16, 32, 16, "derived class with short, long");
check(Q(offsetof(C14, f3)), 8, 16, 8, "offset of 1st field after base class with padding");
check(Q(offsetof(C14, f4)), 12, 24, 12, "offset of 2nd field after base class with padding");
check(Q(sizeof(C15)), 16, 16, 12, "base class with double, long");
check(Q(sizeof(C16)), 16, 16, 12, "empty derived class with base with double, long");
check(Q(sizeof(C17)), 24, 24, 16, "derived class with base with double, long and its own long");
check(Q(sizeof(C18)), 20, 24, 16, "derived class based on empty derived class with base with double, long");
check(Q(sizeof(C19)), 24, 32, 20, "derived class based on derived class with base with double, long and its own long");
check(Q(sizeof(C20)), 12, 16, 12, "class with double and v-table ptr");
check(Q(offsetof(C20, f1)), 4, 8, 4, "offset of double 1st field in class with v-table ptr");
/* Vector tests */
#ifdef __APPLE_ALTIVEC__
check(Q(sizeof(VC1)), 32, 32, 32, "class with vector as 1st field");
check(Q(sizeof(VS1)), 48, 48, 48, "struct with a class with a vector as 1st field");
check(Q(sizeof(VC2)), 48, 48, 48, "class with base class containing a vector");
check(Q(offsetof(VC2, f1)), 32, 32, 32, "offset of 1st field after base class with vector, char, and padding");
check(Q(sizeof(VS2)), 80, 80, 80, "struct with a char, class with a vector, char");
check(Q(offsetof(VS2, f2)), 16, 16, 16, "offset of class with a vector in a struct with char, class...");
check(Q(offsetof(VS2, f3)), 64, 64, 64, "offset of 2nd char in a struct with char, class, char");
check(Q(sizeof(VC3)), 32, 32, 32, "class with a vector and v-table ptr");
check(Q(offsetof(VC3, f1)), 16, 16, 16, "offset vector in class with a vector and v-table ptr");
#endif
/* bool tests */
check(Q(sizeof(bool)), 4, 1, 1, "bool data type");
check(Q(sizeof(B1)), 8, 2, 2, "struct with bool, char");
check(Q(sizeof(B2)), 8, 2, 2, "struct with char, bool");
if (nbr_failures > 0)
return 1;
else
return 0;
}