Richard Smith | 4cf4a5e | 2013-03-28 01:55:44 +0000 | [diff] [blame] | 1 | // RUN: %clang_cc1 -verify -pedantic %s |
Richard Smith | 8327118 | 2012-02-11 18:03:45 +0000 | [diff] [blame] | 2 | |
| 3 | template<typename T> struct atomic { |
| 4 | _Atomic(T) value; |
Richard Smith | 4cf4a5e | 2013-03-28 01:55:44 +0000 | [diff] [blame] | 5 | |
| 6 | void f() _Atomic; // expected-error {{expected ';' at end of declaration list}} |
Richard Smith | 8327118 | 2012-02-11 18:03:45 +0000 | [diff] [blame] | 7 | }; |
| 8 | |
| 9 | template<typename T> struct user { |
| 10 | struct inner { char n[sizeof(T)]; }; |
| 11 | atomic<inner> i; |
| 12 | }; |
| 13 | |
| 14 | user<int> u; |
Douglas Gregor | f7ecc30 | 2012-04-12 17:51:55 +0000 | [diff] [blame] | 15 | |
| 16 | // Test overloading behavior of atomics. |
| 17 | struct A { }; |
| 18 | |
| 19 | int &ovl1(_Atomic(int)); |
Richard Smith | 4cf4a5e | 2013-03-28 01:55:44 +0000 | [diff] [blame] | 20 | int &ovl1(_Atomic int); // ok, redeclaration |
Douglas Gregor | f7ecc30 | 2012-04-12 17:51:55 +0000 | [diff] [blame] | 21 | long &ovl1(_Atomic(long)); |
| 22 | float &ovl1(_Atomic(float)); |
| 23 | double &ovl1(_Atomic(A const *const *)); |
Richard Smith | 4cf4a5e | 2013-03-28 01:55:44 +0000 | [diff] [blame] | 24 | double &ovl1(A const *const *_Atomic); |
Douglas Gregor | f7ecc30 | 2012-04-12 17:51:55 +0000 | [diff] [blame] | 25 | short &ovl1(_Atomic(A **)); |
| 26 | |
| 27 | void test_overloading(int i, float f, _Atomic(int) ai, _Atomic(float) af, |
| 28 | long l, _Atomic(long) al, A const *const *acc, |
| 29 | A const ** ac, A **a) { |
| 30 | int& ir1 = ovl1(i); |
| 31 | int& ir2 = ovl1(ai); |
| 32 | long& lr1 = ovl1(l); |
| 33 | long& lr2 = ovl1(al); |
| 34 | float &fr1 = ovl1(f); |
| 35 | float &fr2 = ovl1(af); |
| 36 | double &dr1 = ovl1(acc); |
| 37 | double &dr2 = ovl1(ac); |
| 38 | short &sr1 = ovl1(a); |
| 39 | } |
Richard Smith | 4cf4a5e | 2013-03-28 01:55:44 +0000 | [diff] [blame] | 40 | |
| 41 | typedef int (A::*fp)() _Atomic; // expected-error {{expected ';' after top level declarator}} expected-warning {{does not declare anything}} |
| 42 | |
| 43 | typedef _Atomic(int(A::*)) atomic_mem_ptr_to_int; |
| 44 | typedef int(A::*_Atomic atomic_mem_ptr_to_int); |
| 45 | |
| 46 | typedef _Atomic(int)(A::*mem_ptr_to_atomic_int); |
| 47 | typedef _Atomic int(A::*mem_ptr_to_atomic_int); |
| 48 | |
| 49 | typedef _Atomic(int)&atomic_int_ref; |
| 50 | typedef _Atomic int &atomic_int_ref; |
| 51 | typedef _Atomic atomic_int_ref atomic_int_ref; // ok, qualifiers on references ignored in this case. |
| 52 | |
| 53 | typedef int &_Atomic atomic_reference_to_int; // expected-error {{'_Atomic' qualifier may not be applied to a reference}} |
| 54 | typedef _Atomic(int &) atomic_reference_to_int; // expected-error {{_Atomic cannot be applied to reference type 'int &'}} |
| 55 | |
| 56 | struct S { |
| 57 | _Atomic union { int n; }; // expected-warning {{anonymous union cannot be '_Atomic'}} |
| 58 | }; |