Home | History | Annotate | Download | only in SemaCXX
      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;
      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));
     21 int &ovl1(_Atomic int); // ok, redeclaration
     22 long &ovl1(_Atomic(long));
     23 float &ovl1(_Atomic(float));
     24 double &ovl1(_Atomic(A const *const *));
     25 double &ovl1(A const *const *_Atomic);
     26 short &ovl1(_Atomic(A **));
     27 
     28 void test_overloading(int i, float f, _Atomic(int) ai, _Atomic(float) af,
     29                       long l, _Atomic(long) al, A const *const *acc,
     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 
     44 typedef _Atomic(int(A::*)) atomic_mem_ptr_to_int;
     45 typedef int(A::*_Atomic atomic_mem_ptr_to_int);
     46 
     47 typedef _Atomic(int)(A::*mem_ptr_to_atomic_int);
     48 typedef _Atomic int(A::*mem_ptr_to_atomic_int);
     49 
     50 typedef _Atomic(int)&atomic_int_ref;
     51 typedef _Atomic int &atomic_int_ref;
     52 typedef _Atomic atomic_int_ref atomic_int_ref; // expected-warning {{'_Atomic' qualifier on reference type 'atomic_int_ref' (aka '_Atomic(int) &') has no effect}}
     53 
     54 typedef int &_Atomic atomic_reference_to_int; // expected-error {{'_Atomic' qualifier may not be applied to a reference}}
     55 typedef _Atomic(int &) atomic_reference_to_int; // expected-error {{_Atomic cannot be applied to reference type 'int &'}}
     56 
     57 struct S {
     58   _Atomic union { int n; }; // expected-warning {{anonymous union cannot be '_Atomic'}}
     59 };
     60 
     61 namespace copy_init {
     62   struct X {
     63     X(int);
     64     int n;
     65   };
     66   _Atomic(X) y = X(0);
     67   _Atomic(X) z(X(0));
     68   void f() { y = X(0); }
     69 
     70   _Atomic(X) e1(0); // expected-error {{cannot initialize}}
     71 #if __cplusplus >= 201103L
     72   _Atomic(X) e2{0}; // expected-error {{illegal initializer}}
     73   _Atomic(X) a{X(0)};
     74   // FIXME: This does not seem like the right answer.
     75   _Atomic(int) e3{0}; // expected-error {{illegal initializer}}
     76 #endif
     77 
     78   struct Y {
     79     _Atomic(X) a;
     80     _Atomic(int) b;
     81   };
     82   Y y1 = { X(0), 4 };
     83   Y y2 = { 0, 4 }; // expected-error {{cannot initialize}}
     84 
     85   // FIXME: It's not really clear if we should allow these. Generally, C++11
     86   // allows extraneous braces around initializers. We should at least give the
     87   // same answer in all these cases:
     88   Y y3 = { X(0), { 4 } }; // expected-error {{illegal initializer type}}
     89   Y y4 = { { X(0) }, 4 };
     90   _Atomic(int) ai = { 4 }; // expected-error {{illegal initializer type}}
     91   _Atomic(X) ax = { X(0) };
     92 }
     93 
     94 bool PR21836(_Atomic(int) *x) {
     95     return *x;
     96 }
     97