Clang Project

clang_source_code/test/Sema/transparent-union.c
1// RUN: %clang_cc1 -fsyntax-only -verify %s
2typedef union {
3  int *ip;
4  float *fp;
5  long *__restrict rlp;
6  void *vpa[1];
7} TU __attribute__((transparent_union));
8
9void f(TU); // expected-note{{passing argument to parameter here}}
10
11void 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
22/* Test ability to redeclare a function taking a transparent_union arg
23   with various compatible and incompatible argument types. */
24
25void fip(TU);
26void fip(int *i) {}
27
28void ffp(TU);
29void ffp(float *f) {}
30
31void flp(TU);
32void flp(long *l) {}
33
34void fvp(TU); // expected-note{{previous declaration is here}}
35void fvp(void *p) {} // expected-error{{conflicting types}}
36
37void fsp(TU); // expected-note{{previous declaration is here}}
38void fsp(short *s) {} // expected-error{{conflicting types}}
39
40void fi(TU); // expected-note{{previous declaration is here}}
41void fi(int i) {} // expected-error{{conflicting types}}
42
43void fvpp(TU); // expected-note{{previous declaration is here}}
44void fvpp(void **v) {} // expected-error{{conflicting types}}
45
46/* Test redeclaring a function taking a transparent_union arg more than twice.
47   Merging different declarations depends on their order, vary order too. */
48
49void f_triple0(TU tu) {}
50void f_triple0(int *); // expected-note{{previous declaration is here}}
51void f_triple0(float *f); // expected-error{{conflicting types}}
52
53void f_triple1(int *);
54void f_triple1(TU tu) {} // expected-note{{previous definition is here}}
55void f_triple1(float *f); // expected-error{{conflicting types}}
56
57void f_triple2(int *); // expected-note{{previous declaration is here}}
58void f_triple2(float *f); // expected-error{{conflicting types}}
59void f_triple2(TU tu) {}
60
61/* Test calling redeclared function taking a transparent_union arg. */
62
63void f_callee(TU);
64void f_callee(int *i) {} // expected-note{{passing argument to parameter 'i' here}}
65
66void caller(void) {
67  TU tu;
68  f_callee(tu); // expected-error{{passing 'TU' to parameter of incompatible type 'int *'}}
69
70  int *i;
71  f_callee(i);
72}
73
74
75/* FIXME: we'd like to just use an "int" here and align it differently
76   from the normal "int", but if we do so we lose the alignment
77   information from the typedef within the compiler. */
78typedef struct { int x, y; } __attribute__((aligned(8))) aligned_struct8;
79
80typedef struct { int x, y; } __attribute__((aligned(4))) aligned_struct4;
81typedef union {
82  aligned_struct4 s4; // expected-note{{alignment of first field}}
83  aligned_struct8 s8; // expected-warning{{alignment of field}}
84} TU1 __attribute__((transparent_union));
85
86typedef union __attribute__((transparent_union)) {
87  aligned_struct4 s4; // expected-note{{alignment of first field}}
88  aligned_struct8 s8; // expected-warning{{alignment of field}}
89} TU1b ;
90
91typedef union {
92  char c; // expected-note{{size of first field is 8 bits}}
93  int i; // expected-warning{{size of field}}
94} TU2 __attribute__((transparent_union));
95
96typedef union __attribute__((transparent_union)){
97  char c; // expected-note{{size of first field is 8 bits}}
98  int i; // expected-warning{{size of field}}
99} TU2b;
100
101typedef union {
102  float f; // expected-warning{{floating}}
103} TU3 __attribute__((transparent_union));
104
105typedef union { } TU4 __attribute__((transparent_union)); // expected-warning{{field}} 
106
107typedef int int4 __attribute__((ext_vector_type(4)));
108typedef union {
109  int4 vec; // expected-warning{{first field of a transparent union cannot have vector type 'int4' (vector of 4 'int' values); transparent_union attribute ignored}}
110} TU5 __attribute__((transparent_union));
111
112union pr15134 {
113  unsigned int u;
114  struct {
115    unsigned int expo:2;
116    unsigned int mant:30;
117  } __attribute__((packed));
118  // The packed attribute is acceptable because it defines a less strict
119  // alignment than required by the first field of the transparent union.
120} __attribute__((transparent_union));
121
122union pr15134v2 {
123  struct { // expected-note {{alignment of first field is 32 bits}}
124    unsigned int u1;
125    unsigned int u2;
126  };
127  struct {  // expected-warning {{alignment of field '' (64 bits) does not match the alignment of the first field in transparent union; transparent_union attribute ignored}}
128    unsigned int u3;
129  } __attribute__((aligned(8)));
130} __attribute__((transparent_union));
131
132union pr30520v { void b; } __attribute__((transparent_union)); // expected-error {{field has incomplete type 'void'}}
133
134union pr30520a { int b[]; } __attribute__((transparent_union)); // expected-error {{flexible array member 'b' in a union is not allowed}}
135
136// expected-note@+1 2 {{forward declaration of 'struct stb'}}
137union pr30520s { struct stb b; } __attribute__((transparent_union)); // expected-error {{field has incomplete type 'struct stb'}}
138
139union pr30520s2 { int *v; struct stb b; } __attribute__((transparent_union)); // expected-error {{field has incomplete type 'struct stb'}}
140
141typedef union __attribute__((__transparent_union__)) {
142  int *i;
143  struct st *s;
144} TU6;
145
146void bar(TU6);
147
148void foo11(int *i) {
149  bar(i);
150}
151void foo2(struct st *s) {
152  bar(s);
153}
154