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