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