Stephen Hines | 176edba | 2014-12-01 14:53:08 -0800 | [diff] [blame] | 1 | // RUN: %clang_cc1 -verify -pedantic %s -std=c++98 |
| 2 | // RUN: %clang_cc1 -verify -pedantic %s -std=c++11 |
Richard Smith | 8327118 | 2012-02-11 18:03:45 +0000 | [diff] [blame] | 3 | |
| 4 | template<typename T> struct atomic { |
| 5 | _Atomic(T) value; |
Richard Smith | 4cf4a5e | 2013-03-28 01:55:44 +0000 | [diff] [blame] | 6 | |
| 7 | void f() _Atomic; // expected-error {{expected ';' at end of declaration list}} |
Richard Smith | 8327118 | 2012-02-11 18:03:45 +0000 | [diff] [blame] | 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; |
Douglas Gregor | f7ecc30 | 2012-04-12 17:51:55 +0000 | [diff] [blame] | 16 | |
| 17 | // Test overloading behavior of atomics. |
| 18 | struct A { }; |
| 19 | |
| 20 | int &ovl1(_Atomic(int)); |
Richard Smith | 4cf4a5e | 2013-03-28 01:55:44 +0000 | [diff] [blame] | 21 | int &ovl1(_Atomic int); // ok, redeclaration |
Douglas Gregor | f7ecc30 | 2012-04-12 17:51:55 +0000 | [diff] [blame] | 22 | long &ovl1(_Atomic(long)); |
| 23 | float &ovl1(_Atomic(float)); |
| 24 | double &ovl1(_Atomic(A const *const *)); |
Richard Smith | 4cf4a5e | 2013-03-28 01:55:44 +0000 | [diff] [blame] | 25 | double &ovl1(A const *const *_Atomic); |
Douglas Gregor | f7ecc30 | 2012-04-12 17:51:55 +0000 | [diff] [blame] | 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 | } |
Richard Smith | 4cf4a5e | 2013-03-28 01:55:44 +0000 | [diff] [blame] | 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; |
Stephen Hines | 176edba | 2014-12-01 14:53:08 -0800 | [diff] [blame] | 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}} |
Richard Smith | 4cf4a5e | 2013-03-28 01:55:44 +0000 | [diff] [blame] | 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 | }; |
Stephen Hines | 176edba | 2014-12-01 14:53:08 -0800 | [diff] [blame] | 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)}; |
Stephen Hines | 0e2c34f | 2015-03-23 12:09:02 -0700 | [diff] [blame] | 74 | // FIXME: This does not seem like the right answer. |
| 75 | _Atomic(int) e3{0}; // expected-error {{illegal initializer}} |
Stephen Hines | 176edba | 2014-12-01 14:53:08 -0800 | [diff] [blame] | 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}} |
Stephen Hines | 0e2c34f | 2015-03-23 12:09:02 -0700 | [diff] [blame] | 84 | |
Stephen Hines | 176edba | 2014-12-01 14:53:08 -0800 | [diff] [blame] | 85 | // FIXME: It's not really clear if we should allow these. Generally, C++11 |
Stephen Hines | 0e2c34f | 2015-03-23 12:09:02 -0700 | [diff] [blame] | 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; |
Stephen Hines | 176edba | 2014-12-01 14:53:08 -0800 | [diff] [blame] | 96 | } |