| /* 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; |
| |
| |
| /* APPLE LOCAL begin ARM alignments */ |
| /* APPLE LOCAL begin radar 4869885 */ |
| static void check(const char * rec_name, int actual, int expected32, int expected64, |
| int expected_ia32, int expected_arm, const char * comment) |
| /* APPLE LOCAL end radar 4869885 */ |
| { |
| int expected; |
| #ifdef __i386__ |
| expected = expected_ia32; |
| #elif defined (__arm__) |
| expected = expected_arm; |
| #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); |
| } |
| } |
| /* APPLE LOCAL end ARM alignments */ |
| |
| 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; |
| } |
| } |
| |
| /* APPLE LOCAL begin ARM alignments */ |
| 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, 1, "const as 1st field"); |
| check(Q(sizeof(C2)), 1, 1, 1, 1, "static as 1st field"); |
| check(Q(sizeof(C3)), 1, 1, 1, 1, "enum as 1st field"); |
| check(Q(sizeof(C4)), 1, 1, 1, 1, "const as 2nd field"); |
| check(Q(sizeof(C5)), 1, 1, 1, 1, "static as 2nd field"); |
| check(Q(sizeof(C6)), 1, 1, 1, 1, "enum as 2nd field"); |
| check(Q(sizeof(C7)), 1, 1, 1, 1, "empty class, power mode"); |
| #ifndef __LP64__ |
| check(Q(sizeof(C8)), 2, 2, 2, 1, "empty class, mac68k mode"); |
| check(Q(sizeof(C9)), 2, 2, 2, 1, "class with empty base class and one char, mac68k"); |
| check(Q(offsetof(C9, f1)), 0, 0, 0, 0, "offset of 1st field after empty base class"); |
| #endif |
| check(Q(sizeof(C10)), 1, 1, 1, 1, "class based on an empty class, power mode"); |
| check(Q(sizeof(C11)), 8, 16, 8, 8, "class with long, char"); |
| check(Q(sizeof(C12)), 12, 24, 12, 12, "class with base class with long, char and its own char"); |
| check(Q(offsetof(C12, f3)), 8, 16, 8, 8, "offset of 1st field in class with a base class with a long, char"); |
| check(Q(sizeof(C13)), 8, 16, 8, 8, "class with long, short"); |
| check(Q(sizeof(C14)), 16, 32, 16, 16, "derived class with short, long"); |
| check(Q(offsetof(C14, f3)), 8, 16, 8, 8, "offset of 1st field after base class with padding"); |
| check(Q(offsetof(C14, f4)), 12, 24, 12, 12, "offset of 2nd field after base class with padding"); |
| |
| check(Q(sizeof(C15)), 16, 16, 12, 12, "base class with double, long"); |
| check(Q(sizeof(C16)), 16, 16, 12, 12, "empty derived class with base with double, long"); |
| check(Q(sizeof(C17)), 24, 24, 16, 16, "derived class with base with double, long and its own long"); |
| check(Q(sizeof(C18)), 20, 24, 16, 16, "derived class based on empty derived class with base with double, long"); |
| check(Q(sizeof(C19)), 24, 32, 20, 20, "derived class based on derived class with base with double, long and its own long"); |
| check(Q(sizeof(C20)), 12, 16, 12, 12, "class with double and v-table ptr"); |
| check(Q(offsetof(C20, f1)), 4, 8, 4, 4, "offset of double 1st field in class with v-table ptr"); |
| |
| /* Vector tests */ |
| #ifdef __APPLE_ALTIVEC__ |
| check(Q(sizeof(VC1)), 32, 32, 32, 32, "class with vector as 1st field"); |
| check(Q(sizeof(VS1)), 48, 48, 48, 48, "struct with a class with a vector as 1st field"); |
| check(Q(sizeof(VC2)), 48, 48, 48, 48, "class with base class containing a vector"); |
| check(Q(offsetof(VC2, f1)), 32, 32, 32, 32, "offset of 1st field after base class with vector, char, and padding"); |
| check(Q(sizeof(VS2)), 80, 80, 80, 80, "struct with a char, class with a vector, char"); |
| check(Q(offsetof(VS2, f2)), 16, 16, 16, 16, "offset of class with a vector in a struct with char, class..."); |
| check(Q(offsetof(VS2, f3)), 64, 64, 64, 64, "offset of 2nd char in a struct with char, class, char"); |
| check(Q(sizeof(VC3)), 32, 32, 32, 32, "class with a vector and v-table ptr"); |
| check(Q(offsetof(VC3, f1)), 16, 16, 16, 16, "offset vector in class with a vector and v-table ptr"); |
| #endif |
| |
| /* bool tests */ |
| check(Q(sizeof(bool)), 4, 1, 1, 1, "bool data type"); |
| check(Q(sizeof(B1)), 8, 2, 2, 2, "struct with bool, char"); |
| check(Q(sizeof(B2)), 8, 2, 2, 2, "struct with char, bool"); |
| |
| if (nbr_failures > 0) |
| return 1; |
| else |
| return 0; |
| } |
| /* APPLE LOCAL end ARM alignments */ |