aboutsummaryrefslogtreecommitdiff
path: root/gcc/testsuite/g++.dg/align-test-1.C
blob: e0cdb68c851e69e84b1c60f633c4dbb7bda798a1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
/* 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 __VEC__
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 __VEC__
    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;
}