1176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// RUN: %clang_cc1 -verify -pedantic %s -std=c++98
2176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// RUN: %clang_cc1 -verify -pedantic %s -std=c++11
38327118ff60cd9c4812fba1e5ba4eb3cb5ed3401Richard Smith
48327118ff60cd9c4812fba1e5ba4eb3cb5ed3401Richard Smithtemplate<typename T> struct atomic {
58327118ff60cd9c4812fba1e5ba4eb3cb5ed3401Richard Smith  _Atomic(T) value;
64cf4a5e96ab0babd13774b17112e7c1d83042ea7Richard Smith
74cf4a5e96ab0babd13774b17112e7c1d83042ea7Richard Smith  void f() _Atomic; // expected-error {{expected ';' at end of declaration list}}
88327118ff60cd9c4812fba1e5ba4eb3cb5ed3401Richard Smith};
98327118ff60cd9c4812fba1e5ba4eb3cb5ed3401Richard Smith
108327118ff60cd9c4812fba1e5ba4eb3cb5ed3401Richard Smithtemplate<typename T> struct user {
118327118ff60cd9c4812fba1e5ba4eb3cb5ed3401Richard Smith  struct inner { char n[sizeof(T)]; };
128327118ff60cd9c4812fba1e5ba4eb3cb5ed3401Richard Smith  atomic<inner> i;
138327118ff60cd9c4812fba1e5ba4eb3cb5ed3401Richard Smith};
148327118ff60cd9c4812fba1e5ba4eb3cb5ed3401Richard Smith
158327118ff60cd9c4812fba1e5ba4eb3cb5ed3401Richard Smithuser<int> u;
16f7ecc3016e6309a092493070d071489516b273c0Douglas Gregor
17f7ecc3016e6309a092493070d071489516b273c0Douglas Gregor// Test overloading behavior of atomics.
18f7ecc3016e6309a092493070d071489516b273c0Douglas Gregorstruct A { };
19f7ecc3016e6309a092493070d071489516b273c0Douglas Gregor
20f7ecc3016e6309a092493070d071489516b273c0Douglas Gregorint &ovl1(_Atomic(int));
214cf4a5e96ab0babd13774b17112e7c1d83042ea7Richard Smithint &ovl1(_Atomic int); // ok, redeclaration
22f7ecc3016e6309a092493070d071489516b273c0Douglas Gregorlong &ovl1(_Atomic(long));
23f7ecc3016e6309a092493070d071489516b273c0Douglas Gregorfloat &ovl1(_Atomic(float));
24f7ecc3016e6309a092493070d071489516b273c0Douglas Gregordouble &ovl1(_Atomic(A const *const *));
254cf4a5e96ab0babd13774b17112e7c1d83042ea7Richard Smithdouble &ovl1(A const *const *_Atomic);
26f7ecc3016e6309a092493070d071489516b273c0Douglas Gregorshort &ovl1(_Atomic(A **));
27f7ecc3016e6309a092493070d071489516b273c0Douglas Gregor
28f7ecc3016e6309a092493070d071489516b273c0Douglas Gregorvoid test_overloading(int i, float f, _Atomic(int) ai, _Atomic(float) af,
29f7ecc3016e6309a092493070d071489516b273c0Douglas Gregor                      long l, _Atomic(long) al, A const *const *acc,
30f7ecc3016e6309a092493070d071489516b273c0Douglas Gregor                      A const ** ac, A **a) {
31f7ecc3016e6309a092493070d071489516b273c0Douglas Gregor  int& ir1 = ovl1(i);
32f7ecc3016e6309a092493070d071489516b273c0Douglas Gregor  int& ir2 = ovl1(ai);
33f7ecc3016e6309a092493070d071489516b273c0Douglas Gregor  long& lr1 = ovl1(l);
34f7ecc3016e6309a092493070d071489516b273c0Douglas Gregor  long& lr2 = ovl1(al);
35f7ecc3016e6309a092493070d071489516b273c0Douglas Gregor  float &fr1 = ovl1(f);
36f7ecc3016e6309a092493070d071489516b273c0Douglas Gregor  float &fr2 = ovl1(af);
37f7ecc3016e6309a092493070d071489516b273c0Douglas Gregor  double &dr1 = ovl1(acc);
38f7ecc3016e6309a092493070d071489516b273c0Douglas Gregor  double &dr2 = ovl1(ac);
39f7ecc3016e6309a092493070d071489516b273c0Douglas Gregor  short &sr1 = ovl1(a);
40f7ecc3016e6309a092493070d071489516b273c0Douglas Gregor}
414cf4a5e96ab0babd13774b17112e7c1d83042ea7Richard Smith
424cf4a5e96ab0babd13774b17112e7c1d83042ea7Richard Smithtypedef int (A::*fp)() _Atomic; // expected-error {{expected ';' after top level declarator}} expected-warning {{does not declare anything}}
434cf4a5e96ab0babd13774b17112e7c1d83042ea7Richard Smith
444cf4a5e96ab0babd13774b17112e7c1d83042ea7Richard Smithtypedef _Atomic(int(A::*)) atomic_mem_ptr_to_int;
454cf4a5e96ab0babd13774b17112e7c1d83042ea7Richard Smithtypedef int(A::*_Atomic atomic_mem_ptr_to_int);
464cf4a5e96ab0babd13774b17112e7c1d83042ea7Richard Smith
474cf4a5e96ab0babd13774b17112e7c1d83042ea7Richard Smithtypedef _Atomic(int)(A::*mem_ptr_to_atomic_int);
484cf4a5e96ab0babd13774b17112e7c1d83042ea7Richard Smithtypedef _Atomic int(A::*mem_ptr_to_atomic_int);
494cf4a5e96ab0babd13774b17112e7c1d83042ea7Richard Smith
504cf4a5e96ab0babd13774b17112e7c1d83042ea7Richard Smithtypedef _Atomic(int)&atomic_int_ref;
514cf4a5e96ab0babd13774b17112e7c1d83042ea7Richard Smithtypedef _Atomic int &atomic_int_ref;
52176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinestypedef _Atomic atomic_int_ref atomic_int_ref; // expected-warning {{'_Atomic' qualifier on reference type 'atomic_int_ref' (aka '_Atomic(int) &') has no effect}}
534cf4a5e96ab0babd13774b17112e7c1d83042ea7Richard Smith
544cf4a5e96ab0babd13774b17112e7c1d83042ea7Richard Smithtypedef int &_Atomic atomic_reference_to_int; // expected-error {{'_Atomic' qualifier may not be applied to a reference}}
554cf4a5e96ab0babd13774b17112e7c1d83042ea7Richard Smithtypedef _Atomic(int &) atomic_reference_to_int; // expected-error {{_Atomic cannot be applied to reference type 'int &'}}
564cf4a5e96ab0babd13774b17112e7c1d83042ea7Richard Smith
574cf4a5e96ab0babd13774b17112e7c1d83042ea7Richard Smithstruct S {
584cf4a5e96ab0babd13774b17112e7c1d83042ea7Richard Smith  _Atomic union { int n; }; // expected-warning {{anonymous union cannot be '_Atomic'}}
594cf4a5e96ab0babd13774b17112e7c1d83042ea7Richard Smith};
60176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
61176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesnamespace copy_init {
62176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  struct X {
63176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    X(int);
64176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    int n;
65176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  };
66176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  _Atomic(X) y = X(0);
67176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  _Atomic(X) z(X(0));
68176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  void f() { y = X(0); }
69176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
70176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  _Atomic(X) e1(0); // expected-error {{cannot initialize}}
71176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines#if __cplusplus >= 201103L
72176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  _Atomic(X) e2{0}; // expected-error {{illegal initializer}}
73176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  _Atomic(X) a{X(0)};
740e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  // FIXME: This does not seem like the right answer.
750e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  _Atomic(int) e3{0}; // expected-error {{illegal initializer}}
76176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines#endif
77176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
78176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  struct Y {
79176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    _Atomic(X) a;
80176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    _Atomic(int) b;
81176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  };
82176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  Y y1 = { X(0), 4 };
83176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  Y y2 = { 0, 4 }; // expected-error {{cannot initialize}}
840e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
85176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  // FIXME: It's not really clear if we should allow these. Generally, C++11
860e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  // allows extraneous braces around initializers. We should at least give the
870e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  // same answer in all these cases:
880e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  Y y3 = { X(0), { 4 } }; // expected-error {{illegal initializer type}}
890e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  Y y4 = { { X(0) }, 4 };
900e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  _Atomic(int) ai = { 4 }; // expected-error {{illegal initializer type}}
910e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  _Atomic(X) ax = { X(0) };
920e2c34f92f00628d48968dfea096d36381f494cbStephen Hines}
930e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
940e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesbool PR21836(_Atomic(int) *x) {
950e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    return *x;
96176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}
97