Stephen Hines | 651f13c | 2014-04-23 16:59:28 -0700 | [diff] [blame] | 1 | // RUN: %clang_cc1 -fsyntax-only -verify %s |
Douglas Gregor | 0c74e8a | 2009-04-29 22:16:16 +0000 | [diff] [blame] | 2 | typedef union { |
| 3 | int *ip; |
| 4 | float *fp; |
Peter Collingbourne | b97c403 | 2010-12-02 20:02:29 +0000 | [diff] [blame] | 5 | long *__restrict rlp; |
Peter Collingbourne | f91d757 | 2010-12-02 21:00:06 +0000 | [diff] [blame] | 6 | void *vpa[1]; |
Douglas Gregor | 0c74e8a | 2009-04-29 22:16:16 +0000 | [diff] [blame] | 7 | } TU __attribute__((transparent_union)); |
| 8 | |
Douglas Gregor | a41a8c5 | 2010-04-22 00:20:18 +0000 | [diff] [blame] | 9 | void f(TU); // expected-note{{passing argument to parameter here}} |
Douglas Gregor | 0c74e8a | 2009-04-29 22:16:16 +0000 | [diff] [blame] | 10 | |
| 11 | void g(int *ip, float *fp, char *cp) { |
| 12 | f(ip); |
| 13 | f(fp); |
| 14 | f(cp); // expected-error{{incompatible type}} |
| 15 | f(0); |
| 16 | |
| 17 | TU tu_ip = ip; // expected-error{{incompatible type}} |
| 18 | TU tu; |
| 19 | tu.ip = ip; |
| 20 | } |
| 21 | |
Peter Collingbourne | 4846675 | 2010-10-24 18:30:18 +0000 | [diff] [blame] | 22 | /* Test ability to redeclare a function taking a transparent_union arg |
| 23 | with various compatible and incompatible argument types. */ |
| 24 | |
| 25 | void fip(TU); |
| 26 | void fip(int *i) {} |
| 27 | |
| 28 | void ffp(TU); |
| 29 | void ffp(float *f) {} |
| 30 | |
Peter Collingbourne | b97c403 | 2010-12-02 20:02:29 +0000 | [diff] [blame] | 31 | void flp(TU); |
| 32 | void flp(long *l) {} |
| 33 | |
Peter Collingbourne | 4846675 | 2010-10-24 18:30:18 +0000 | [diff] [blame] | 34 | void fvp(TU); // expected-note{{previous declaration is here}} |
| 35 | void fvp(void *p) {} // expected-error{{conflicting types}} |
| 36 | |
| 37 | void fsp(TU); // expected-note{{previous declaration is here}} |
| 38 | void fsp(short *s) {} // expected-error{{conflicting types}} |
| 39 | |
| 40 | void fi(TU); // expected-note{{previous declaration is here}} |
| 41 | void fi(int i) {} // expected-error{{conflicting types}} |
| 42 | |
Peter Collingbourne | f91d757 | 2010-12-02 21:00:06 +0000 | [diff] [blame] | 43 | void fvpp(TU); // expected-note{{previous declaration is here}} |
| 44 | void fvpp(void **v) {} // expected-error{{conflicting types}} |
| 45 | |
Douglas Gregor | 0c74e8a | 2009-04-29 22:16:16 +0000 | [diff] [blame] | 46 | /* FIXME: we'd like to just use an "int" here and align it differently |
| 47 | from the normal "int", but if we do so we lose the alignment |
| 48 | information from the typedef within the compiler. */ |
| 49 | typedef struct { int x, y; } __attribute__((aligned(8))) aligned_struct8; |
| 50 | |
| 51 | typedef struct { int x, y; } __attribute__((aligned(4))) aligned_struct4; |
| 52 | typedef union { |
| 53 | aligned_struct4 s4; // expected-note{{alignment of first field}} |
| 54 | aligned_struct8 s8; // expected-warning{{alignment of field}} |
| 55 | } TU1 __attribute__((transparent_union)); |
| 56 | |
| 57 | typedef union { |
| 58 | char c; // expected-note{{size of first field is 8 bits}} |
| 59 | int i; // expected-warning{{size of field}} |
| 60 | } TU2 __attribute__((transparent_union)); |
| 61 | |
| 62 | typedef union { |
| 63 | float f; // expected-warning{{floating}} |
| 64 | } TU3 __attribute__((transparent_union)); |
| 65 | |
| 66 | typedef union { } TU4 __attribute__((transparent_union)); // expected-warning{{field}} |
Douglas Gregor | 90cd672 | 2010-06-30 17:24:13 +0000 | [diff] [blame] | 67 | |
| 68 | typedef int int4 __attribute__((ext_vector_type(4))); |
| 69 | typedef union { |
Stephen Hines | 6bcf27b | 2014-05-29 04:14:42 -0700 | [diff] [blame] | 70 | int4 vec; // expected-warning{{first field of a transparent union cannot have vector type 'int4' (vector of 4 'int' values); transparent_union attribute ignored}} |
Douglas Gregor | 90cd672 | 2010-06-30 17:24:13 +0000 | [diff] [blame] | 71 | } TU5 __attribute__((transparent_union)); |
| 72 | |
Stephen Hines | 651f13c | 2014-04-23 16:59:28 -0700 | [diff] [blame] | 73 | union pr15134 { |
| 74 | unsigned int u; |
| 75 | struct { |
| 76 | unsigned int expo:2; |
| 77 | unsigned int mant:30; |
| 78 | } __attribute__((packed)); |
| 79 | // The packed attribute is acceptable because it defines a less strict |
| 80 | // alignment than required by the first field of the transparent union. |
| 81 | } __attribute__((transparent_union)); |
| 82 | |
| 83 | union pr15134v2 { |
| 84 | struct { // expected-note {{alignment of first field is 32 bits}} |
| 85 | unsigned int u1; |
| 86 | unsigned int u2; |
| 87 | }; |
| 88 | struct { // expected-warning {{alignment of field '' (64 bits) does not match the alignment of the first field in transparent union; transparent_union attribute ignored}} |
| 89 | unsigned int u3; |
| 90 | } __attribute__((aligned(8))); |
| 91 | } __attribute__((transparent_union)); |