1 // RUN: %clang_cc1 -verify -pedantic %s -std=c++98
2 // RUN: %clang_cc1 -verify -pedantic %s -std=c++11
3 
4 template<typename T> struct atomic {
5   _Atomic(T) value; // expected-warning {{'_Atomic' is a C11 extension}}
6 
7   void f() _Atomic; // expected-error {{expected ';' at end of declaration list}}
8 };
9 
10 template<typename T> struct user {
11   struct inner { char n[sizeof(T)]; };
12   atomic<inner> i;
13 };
14 
15 user<int> u;
16 
17 // Test overloading behavior of atomics.
18 struct A { };
19 
20 int &ovl1(_Atomic(int)); // expected-warning {{'_Atomic' is a C11 extension}}
21 int &ovl1(_Atomic int);  // expected-warning {{'_Atomic' is a C11 extension}} // ok, redeclaration
22 long &ovl1(_Atomic(long)); // expected-warning {{'_Atomic' is a C11 extension}}
23 float &ovl1(_Atomic(float)); // expected-warning {{'_Atomic' is a C11 extension}}
24 double &ovl1(_Atomic(A const *const *)); // expected-warning {{'_Atomic' is a C11 extension}}
25 double &ovl1(A const *const *_Atomic); // expected-warning {{'_Atomic' is a C11 extension}}
26 short &ovl1(_Atomic(A **)); // expected-warning {{'_Atomic' is a C11 extension}}
27 
test_overloading(int i,float f,_Atomic (int)ai,_Atomic (float)af,long l,_Atomic (long)al,A const * const * acc,A const ** ac,A ** a)28 void test_overloading(int i, float f, _Atomic(int) ai, _Atomic(float) af, // expected-warning 2 {{'_Atomic' is a C11 extension}}
29                       long l, _Atomic(long) al, A const *const *acc, // expected-warning {{'_Atomic' is a C11 extension}}
30                       A const ** ac, A **a) {
31   int& ir1 = ovl1(i);
32   int& ir2 = ovl1(ai);
33   long& lr1 = ovl1(l);
34   long& lr2 = ovl1(al);
35   float &fr1 = ovl1(f);
36   float &fr2 = ovl1(af);
37   double &dr1 = ovl1(acc);
38   double &dr2 = ovl1(ac);
39   short &sr1 = ovl1(a);
40 }
41 
42 typedef int (A::*fp)() _Atomic; // expected-error {{expected ';' after top level declarator}} expected-warning {{does not declare anything}} \
43                                 // expected-warning {{'_Atomic' is a C11 extension}}
44 
45 typedef _Atomic(int(A::*)) atomic_mem_ptr_to_int; // expected-warning {{'_Atomic' is a C11 extension}}
46 typedef int(A::*_Atomic atomic_mem_ptr_to_int); // expected-warning {{'_Atomic' is a C11 extension}}
47 
48 typedef _Atomic(int)(A::*mem_ptr_to_atomic_int); // expected-warning {{'_Atomic' is a C11 extension}}
49 typedef _Atomic int(A::*mem_ptr_to_atomic_int); // expected-warning {{'_Atomic' is a C11 extension}}
50 
51 typedef _Atomic(int)&atomic_int_ref; // expected-warning {{'_Atomic' is a C11 extension}}
52 typedef _Atomic int &atomic_int_ref; // expected-warning {{'_Atomic' is a C11 extension}}
53 typedef _Atomic atomic_int_ref atomic_int_ref; // expected-warning {{'_Atomic' qualifier on reference type 'atomic_int_ref' (aka '_Atomic(int) &') has no effect}} \
54                                                // expected-warning {{'_Atomic' is a C11 extension}}
55 
56 typedef int &_Atomic atomic_reference_to_int; // expected-error {{'_Atomic' qualifier may not be applied to a reference}} \
57                                               // expected-warning {{'_Atomic' is a C11 extension}}
58 typedef _Atomic(int &) atomic_reference_to_int; // expected-error {{_Atomic cannot be applied to reference type 'int &'}} \
59                                                 // expected-warning {{'_Atomic' is a C11 extension}}
60 
61 struct S {
62   _Atomic union { int n; }; // expected-warning {{anonymous union cannot be '_Atomic'}} \
63                             // expected-warning {{'_Atomic' is a C11 extension}}
64 };
65 
66 namespace copy_init {
67   struct X {
68     X(int);
69     int n;
70   };
71   _Atomic(X) y = X(0); // expected-warning {{'_Atomic' is a C11 extension}}
72   _Atomic(X) z(X(0)); // expected-warning {{'_Atomic' is a C11 extension}}
f()73   void f() { y = X(0); }
74 
75   _Atomic(X) e1(0); // expected-error {{cannot initialize}} \
76                     // expected-warning {{'_Atomic' is a C11 extension}}
77 #if __cplusplus >= 201103L
_Atomic(X)78   _Atomic(X) e2{0}; // expected-error {{illegal initializer}} \
79                     // expected-warning {{'_Atomic' is a C11 extension}}
_Atomic(X)80   _Atomic(X) a{X(0)}; // expected-warning {{'_Atomic' is a C11 extension}}
81   // FIXME: This does not seem like the right answer.
_Atomic(int)82   _Atomic(int) e3{0}; // expected-error {{illegal initializer}} \
83                       // expected-warning {{'_Atomic' is a C11 extension}}
84 #endif
85 
86   struct Y {
87     _Atomic(X) a; // expected-warning {{'_Atomic' is a C11 extension}}
88     _Atomic(int) b; // expected-warning {{'_Atomic' is a C11 extension}}
89   };
90   Y y1 = { X(0), 4 };
91   Y y2 = { 0, 4 }; // expected-error {{cannot initialize}}
92 
93   // FIXME: It's not really clear if we should allow these. Generally, C++11
94   // allows extraneous braces around initializers. We should at least give the
95   // same answer in all these cases:
96   Y y3 = { X(0), { 4 } }; // expected-error {{illegal initializer type}}
97   Y y4 = { { X(0) }, 4 };
98   _Atomic(int) ai = { 4 }; // expected-error {{illegal initializer type}} \
99                            // expected-warning {{'_Atomic' is a C11 extension}}
100   _Atomic(X) ax = { X(0) }; // expected-warning {{'_Atomic' is a C11 extension}}
101 }
102 
PR21836(_Atomic (int)* x)103 bool PR21836(_Atomic(int) *x) { // expected-warning {{'_Atomic' is a C11 extension}}
104     return *x;
105 }
106 
107 namespace non_trivially_copyable {
108   struct S {
~Snon_trivially_copyable::S109     ~S() {}
110   };
111   _Atomic S s;  // expected-error {{_Atomic cannot be applied to type 'non_trivially_copyable::S' which is not trivially copyable}} \
112                 // expected-warning {{'_Atomic' is a C11 extension}}
113 }
114