forked from OSchip/llvm-project
				
			
		
			
				
	
	
		
			200 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			200 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			C++
		
	
	
	
| // RUN: %clang_cc1 -fsyntax-only -verify -pedantic %s
 | |
| struct X {
 | |
|   union {
 | |
|     float f3;
 | |
|     double d2;
 | |
|   } named;
 | |
| 
 | |
|   union {
 | |
|     int i;
 | |
|     float f;
 | |
|     
 | |
|     union {
 | |
|       float f2;
 | |
|       mutable double d;
 | |
|     };
 | |
|   };
 | |
| 
 | |
|   void test_unqual_references();
 | |
| 
 | |
|   struct { // expected-warning{{anonymous structs are a GNU extension}}
 | |
|     int a;
 | |
|     float b;
 | |
|   };
 | |
| 
 | |
|   void test_unqual_references_const() const;
 | |
| 
 | |
|   mutable union { // expected-error{{anonymous union at class scope must not have a storage specifier}}
 | |
|     float c1;
 | |
|     double c2;
 | |
|   };
 | |
| };
 | |
| 
 | |
| void X::test_unqual_references() {
 | |
|   i = 0;
 | |
|   f = 0.0;
 | |
|   f2 = f;
 | |
|   d = f;
 | |
|   f3 = 0; // expected-error{{use of undeclared identifier 'f3'}}
 | |
|   a = 0;
 | |
| }
 | |
| 
 | |
| void X::test_unqual_references_const() const {
 | |
|   d = 0.0;
 | |
|   f2 = 0; // expected-error{{read-only variable is not assignable}}
 | |
|   a = 0; // expected-error{{read-only variable is not assignable}}
 | |
| }
 | |
| 
 | |
| void test_unqual_references(X x, const X xc) {
 | |
|   x.i = 0;
 | |
|   x.f = 0.0;
 | |
|   x.f2 = x.f;
 | |
|   x.d = x.f;
 | |
|   x.f3 = 0; // expected-error{{no member named 'f3'}}
 | |
|   x.a = 0;
 | |
| 
 | |
|   xc.d = 0.0;
 | |
|   xc.f = 0; // expected-error{{read-only variable is not assignable}}
 | |
|   xc.a = 0; // expected-error{{read-only variable is not assignable}}
 | |
| }
 | |
| 
 | |
| 
 | |
| struct Redecl {
 | |
|   int x; // expected-note{{previous declaration is here}}
 | |
|   class y { };
 | |
| 
 | |
|   union {
 | |
|     int x; // expected-error{{member of anonymous union redeclares 'x'}}
 | |
|     float y;
 | |
|     double z; // expected-note{{previous declaration is here}}
 | |
|     double zz; // expected-note{{previous definition is here}}
 | |
|   };
 | |
| 
 | |
|   int z; // expected-error{{duplicate member 'z'}}
 | |
|   void zz(); // expected-error{{redefinition of 'zz' as different kind of symbol}}
 | |
| };
 | |
| 
 | |
| union { // expected-error{{anonymous unions at namespace or global scope must be declared 'static'}}
 | |
|   int int_val;
 | |
|   float float_val;
 | |
| };
 | |
| 
 | |
| static union {
 | |
|   int int_val2;
 | |
|   float float_val2;
 | |
| };
 | |
| 
 | |
| void f() {
 | |
|   int_val2 = 0;
 | |
|   float_val2 = 0.0;
 | |
| }
 | |
| 
 | |
| void g() {
 | |
|   union {
 | |
|     int i;
 | |
|     float f2;
 | |
|   };
 | |
|   i = 0;
 | |
|   f2 = 0.0;
 | |
| }
 | |
| 
 | |
| struct BadMembers {
 | |
|   union {
 | |
|     struct X { }; // expected-error {{types cannot be declared in an anonymous union}}
 | |
|     struct { int x; int y; } y;
 | |
|     
 | |
|     void f(); // expected-error{{functions cannot be declared in an anonymous union}}
 | |
|   private: int x1; // expected-error{{anonymous union cannot contain a private data member}}
 | |
|   protected: float x2; // expected-error{{anonymous union cannot contain a protected data member}}
 | |
|   };
 | |
| };
 | |
| 
 | |
| // <rdar://problem/6481130>
 | |
| typedef union { }; // expected-warning{{declaration does not declare anything}}
 | |
| 
 | |
| // <rdar://problem/7562438>
 | |
| typedef struct objc_module *Foo ;
 | |
| 
 | |
| typedef struct _s {
 | |
|     union {
 | |
|         int a;
 | |
|         int Foo;
 | |
|     };
 | |
| } s, *ps;
 | |
| 
 | |
| // <rdar://problem/7987650>
 | |
| namespace test4 {
 | |
|   class A {
 | |
|     struct { // expected-warning{{anonymous structs are a GNU extension}}
 | |
|       int s0; // expected-note {{declared private here}}
 | |
|       double s1; // expected-note {{declared private here}}
 | |
|       union {
 | |
|         int su0; // expected-note {{declared private here}}
 | |
|         double su1; // expected-note {{declared private here}}
 | |
|       };
 | |
|     };
 | |
|     union {
 | |
|       int u0; // expected-note {{declared private here}}
 | |
|       double u1; // expected-note {{declared private here}}
 | |
|       struct { // expected-warning{{anonymous structs are a GNU extension}}
 | |
|         int us0; // expected-note {{declared private here}}
 | |
|         double us1; // expected-note {{declared private here}}
 | |
|       };
 | |
|     };
 | |
|   };
 | |
| 
 | |
|   void test() {
 | |
|     A a;
 | |
|     (void) a.s0;  // expected-error {{private member}}
 | |
|     (void) a.s1;  // expected-error {{private member}}
 | |
|     (void) a.su0; // expected-error {{private member}}
 | |
|     (void) a.su1; // expected-error {{private member}}
 | |
|     (void) a.u0;  // expected-error {{private member}}
 | |
|     (void) a.u1;  // expected-error {{private member}}
 | |
|     (void) a.us0; // expected-error {{private member}}
 | |
|     (void) a.us1; // expected-error {{private member}}
 | |
|   }
 | |
| }
 | |
| 
 | |
| typedef void *voidPtr;
 | |
| 
 | |
| void f2() {
 | |
|     union { int **ctxPtr; void **voidPtr; };
 | |
| }
 | |
| 
 | |
| void foo_PR6741() {
 | |
|     union {
 | |
|         char *m_a;
 | |
|         int *m_b;
 | |
|     };
 | |
|  
 | |
|     if(1) {
 | |
|         union {
 | |
|             char *m_a;
 | |
|             int *m_b;
 | |
|         };
 | |
|     }
 | |
| }
 | |
| 
 | |
| namespace PR8326 {
 | |
|   template <class T>
 | |
|   class Foo {
 | |
|   public:
 | |
|     Foo()
 | |
|       : x(0)
 | |
|       , y(1){
 | |
|     }
 | |
|   
 | |
|   private:
 | |
|     const union { // expected-warning{{anonymous union cannot be 'const'}}
 | |
|       struct { // expected-warning{{anonymous structs are a GNU extension}}
 | |
|         T x;
 | |
|         T y;
 | |
|       };
 | |
|       T v[2];
 | |
|     };
 | |
|   };
 | |
| 
 | |
|   Foo<int> baz;
 | |
| }
 |