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 | |