1// RUN: %clang_cc1 -fsyntax-only -verify -pedantic %s
2struct X {
3  union {
4    float f3;
5    double d2;
6  } named;
7
8  union {
9    int i;
10    float f;
11
12    union { // expected-warning{{anonymous types declared in an anonymous union are an extension}}
13      float f2;
14      mutable double d;
15    };
16  };
17
18  void test_unqual_references();
19
20  struct { // expected-warning{{anonymous structs are a GNU extension}}
21    int a;
22    float b;
23  };
24
25  void test_unqual_references_const() const;
26
27  mutable union { // expected-error{{anonymous union at class scope must not have a storage specifier}}
28    float c1;
29    double c2;
30  };
31};
32
33void X::test_unqual_references() {
34  i = 0;
35  f = 0.0;
36  f2 = f;
37  d = f;
38  f3 = 0; // expected-error{{use of undeclared identifier 'f3'}}
39  a = 0;
40}
41
42void X::test_unqual_references_const() const {
43  d = 0.0;
44  f2 = 0; // expected-error{{read-only variable is not assignable}}
45  a = 0; // expected-error{{read-only variable is not assignable}}
46}
47
48void test_unqual_references(X x, const X xc) {
49  x.i = 0;
50  x.f = 0.0;
51  x.f2 = x.f;
52  x.d = x.f;
53  x.f3 = 0; // expected-error{{no member named 'f3'}}
54  x.a = 0;
55
56  xc.d = 0.0;
57  xc.f = 0; // expected-error{{read-only variable is not assignable}}
58  xc.a = 0; // expected-error{{read-only variable is not assignable}}
59}
60
61
62struct Redecl {
63  int x; // expected-note{{previous declaration is here}}
64  class y { };
65
66  union {
67    int x; // expected-error{{member of anonymous union redeclares 'x'}}
68    float y;
69    double z; // expected-note{{previous declaration is here}}
70    double zz; // expected-note{{previous definition is here}}
71  };
72
73  int z; // expected-error{{duplicate member 'z'}}
74  void zz(); // expected-error{{redefinition of 'zz' as different kind of symbol}}
75};
76
77union { // expected-error{{anonymous unions at namespace or global scope must be declared 'static'}}
78  int int_val;
79  float float_val;
80};
81
82static union {
83  int int_val2;
84  float float_val2;
85};
86
87void f() {
88  int_val2 = 0;
89  float_val2 = 0.0;
90}
91
92void g() {
93  union {
94    int i;
95    float f2;
96  };
97  i = 0;
98  f2 = 0.0;
99}
100
101struct BadMembers {
102  union {
103    struct X { }; // expected-error {{types cannot be declared in an anonymous union}}
104    struct { int x; int y; } y; // expected-warning{{anonymous types declared in an anonymous union are an extension}}
105
106    void f(); // expected-error{{functions cannot be declared in an anonymous union}}
107  private: int x1; // expected-error{{anonymous union cannot contain a private data member}}
108  protected: float x2; // expected-error{{anonymous union cannot contain a protected data member}}
109  };
110};
111
112// <rdar://problem/6481130>
113typedef union { }; // expected-warning{{typedef requires a name}}
114
115// <rdar://problem/7562438>
116typedef struct objc_module *Foo ;
117
118typedef struct _s {
119    union {
120        int a;
121        int Foo;
122    };
123} s, *ps;
124
125// <rdar://problem/7987650>
126namespace test4 {
127  class A {
128    struct { // expected-warning{{anonymous structs are a GNU extension}}
129      int s0; // expected-note {{declared private here}}
130      double s1; // expected-note {{declared private here}}
131      union { // expected-warning{{anonymous types declared in an anonymous struct are an extension}}
132        int su0; // expected-note {{declared private here}}
133        double su1; // expected-note {{declared private here}}
134      };
135    };
136    union {
137      int u0; // expected-note {{declared private here}}
138      double u1; // expected-note {{declared private here}}
139      struct { // expected-warning{{anonymous structs are a GNU extension}} expected-warning{{anonymous types declared in an anonymous union are an extension}}
140        int us0; // expected-note {{declared private here}}
141        double us1; // expected-note {{declared private here}}
142      };
143    };
144  };
145
146  void test() {
147    A a;
148    (void) a.s0;  // expected-error {{private member}}
149    (void) a.s1;  // expected-error {{private member}}
150    (void) a.su0; // expected-error {{private member}}
151    (void) a.su1; // expected-error {{private member}}
152    (void) a.u0;  // expected-error {{private member}}
153    (void) a.u1;  // expected-error {{private member}}
154    (void) a.us0; // expected-error {{private member}}
155    (void) a.us1; // expected-error {{private member}}
156  }
157}
158
159typedef void *voidPtr;
160
161void f2() {
162    union { int **ctxPtr; void **voidPtr; };
163}
164
165void foo_PR6741() {
166    union {
167        char *m_a;
168        int *m_b;
169    };
170
171    if(1) {
172        union {
173            char *m_a;
174            int *m_b;
175        };
176    }
177}
178
179namespace PR8326 {
180  template <class T>
181  class Foo {
182  public:
183    Foo()
184      : x(0)
185      , y(1){
186    }
187
188  private:
189    const union { // expected-warning{{anonymous union cannot be 'const'}}
190      struct { // expected-warning{{anonymous structs are a GNU extension}} expected-warning{{declared in an anonymous union}}
191        T x;
192        T y;
193      };
194      T v[2];
195    };
196  };
197
198  Foo<int> baz;
199}
200
201namespace PR16630 {
202  struct A { union { int x; float y; }; }; // expected-note {{member is declared here}}
203  struct B : private A { using A::x; } b; // expected-note 2 {{private}}
204  void foo () {
205    b.x = 10;
206    b.y = 0; // expected-error {{cannot cast 'struct B' to its private base class 'PR16630::A'}} expected-error {{'y' is a private member of 'PR16630::A'}}
207  }
208}
209