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/* 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. */
49typedef struct { int x, y; } __attribute__((aligned(8))) aligned_struct8;
50
51typedef struct { int x, y; } __attribute__((aligned(4))) aligned_struct4;
52typedef 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
57typedef 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
62typedef union {
63  float f; // expected-warning{{floating}}
64} TU3 __attribute__((transparent_union));
65
66typedef union { } TU4 __attribute__((transparent_union)); // expected-warning{{field}}
67
68typedef int int4 __attribute__((ext_vector_type(4)));
69typedef union {
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}}
71} TU5 __attribute__((transparent_union));
72
73union 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
83union 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));
92