blob: a2b314aacdd420c635f5bb1e9da22dee509d17b0 [file] [log] [blame]
Stephen Hines176edba2014-12-01 14:53:08 -08001// RUN: %clang_cc1 -verify -pedantic %s -std=c++98
2// RUN: %clang_cc1 -verify -pedantic %s -std=c++11
Richard Smith83271182012-02-11 18:03:45 +00003
4template<typename T> struct atomic {
5 _Atomic(T) value;
Richard Smith4cf4a5e2013-03-28 01:55:44 +00006
7 void f() _Atomic; // expected-error {{expected ';' at end of declaration list}}
Richard Smith83271182012-02-11 18:03:45 +00008};
9
10template<typename T> struct user {
11 struct inner { char n[sizeof(T)]; };
12 atomic<inner> i;
13};
14
15user<int> u;
Douglas Gregorf7ecc302012-04-12 17:51:55 +000016
17// Test overloading behavior of atomics.
18struct A { };
19
20int &ovl1(_Atomic(int));
Richard Smith4cf4a5e2013-03-28 01:55:44 +000021int &ovl1(_Atomic int); // ok, redeclaration
Douglas Gregorf7ecc302012-04-12 17:51:55 +000022long &ovl1(_Atomic(long));
23float &ovl1(_Atomic(float));
24double &ovl1(_Atomic(A const *const *));
Richard Smith4cf4a5e2013-03-28 01:55:44 +000025double &ovl1(A const *const *_Atomic);
Douglas Gregorf7ecc302012-04-12 17:51:55 +000026short &ovl1(_Atomic(A **));
27
28void 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}
Richard Smith4cf4a5e2013-03-28 01:55:44 +000041
42typedef int (A::*fp)() _Atomic; // expected-error {{expected ';' after top level declarator}} expected-warning {{does not declare anything}}
43
44typedef _Atomic(int(A::*)) atomic_mem_ptr_to_int;
45typedef int(A::*_Atomic atomic_mem_ptr_to_int);
46
47typedef _Atomic(int)(A::*mem_ptr_to_atomic_int);
48typedef _Atomic int(A::*mem_ptr_to_atomic_int);
49
50typedef _Atomic(int)&atomic_int_ref;
51typedef _Atomic int &atomic_int_ref;
Stephen Hines176edba2014-12-01 14:53:08 -080052typedef _Atomic atomic_int_ref atomic_int_ref; // expected-warning {{'_Atomic' qualifier on reference type 'atomic_int_ref' (aka '_Atomic(int) &') has no effect}}
Richard Smith4cf4a5e2013-03-28 01:55:44 +000053
54typedef int &_Atomic atomic_reference_to_int; // expected-error {{'_Atomic' qualifier may not be applied to a reference}}
55typedef _Atomic(int &) atomic_reference_to_int; // expected-error {{_Atomic cannot be applied to reference type 'int &'}}
56
57struct S {
58 _Atomic union { int n; }; // expected-warning {{anonymous union cannot be '_Atomic'}}
59};
Stephen Hines176edba2014-12-01 14:53:08 -080060
61namespace 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)};
Stephen Hines0e2c34f2015-03-23 12:09:02 -070074 // FIXME: This does not seem like the right answer.
75 _Atomic(int) e3{0}; // expected-error {{illegal initializer}}
Stephen Hines176edba2014-12-01 14:53:08 -080076#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}}
Stephen Hines0e2c34f2015-03-23 12:09:02 -070084
Stephen Hines176edba2014-12-01 14:53:08 -080085 // FIXME: It's not really clear if we should allow these. Generally, C++11
Stephen Hines0e2c34f2015-03-23 12:09:02 -070086 // 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
94bool PR21836(_Atomic(int) *x) {
95 return *x;
Stephen Hines176edba2014-12-01 14:53:08 -080096}