diff options
Diffstat (limited to 'test/SemaCXX/atomic-type.cpp')
-rw-r--r-- | test/SemaCXX/atomic-type.cpp | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/test/SemaCXX/atomic-type.cpp b/test/SemaCXX/atomic-type.cpp new file mode 100644 index 000000000000..ae18eab5b4a9 --- /dev/null +++ b/test/SemaCXX/atomic-type.cpp @@ -0,0 +1,85 @@ +// RUN: %clang_cc1 -verify -pedantic %s -std=c++98 +// RUN: %clang_cc1 -verify -pedantic %s -std=c++11 + +template<typename T> struct atomic { + _Atomic(T) value; + + void f() _Atomic; // expected-error {{expected ';' at end of declaration list}} +}; + +template<typename T> struct user { + struct inner { char n[sizeof(T)]; }; + atomic<inner> i; +}; + +user<int> u; + +// Test overloading behavior of atomics. +struct A { }; + +int &ovl1(_Atomic(int)); +int &ovl1(_Atomic int); // ok, redeclaration +long &ovl1(_Atomic(long)); +float &ovl1(_Atomic(float)); +double &ovl1(_Atomic(A const *const *)); +double &ovl1(A const *const *_Atomic); +short &ovl1(_Atomic(A **)); + +void test_overloading(int i, float f, _Atomic(int) ai, _Atomic(float) af, + long l, _Atomic(long) al, A const *const *acc, + A const ** ac, A **a) { + int& ir1 = ovl1(i); + int& ir2 = ovl1(ai); + long& lr1 = ovl1(l); + long& lr2 = ovl1(al); + float &fr1 = ovl1(f); + float &fr2 = ovl1(af); + double &dr1 = ovl1(acc); + double &dr2 = ovl1(ac); + short &sr1 = ovl1(a); +} + +typedef int (A::*fp)() _Atomic; // expected-error {{expected ';' after top level declarator}} expected-warning {{does not declare anything}} + +typedef _Atomic(int(A::*)) atomic_mem_ptr_to_int; +typedef int(A::*_Atomic atomic_mem_ptr_to_int); + +typedef _Atomic(int)(A::*mem_ptr_to_atomic_int); +typedef _Atomic int(A::*mem_ptr_to_atomic_int); + +typedef _Atomic(int)&atomic_int_ref; +typedef _Atomic int &atomic_int_ref; +typedef _Atomic atomic_int_ref atomic_int_ref; // expected-warning {{'_Atomic' qualifier on reference type 'atomic_int_ref' (aka '_Atomic(int) &') has no effect}} + +typedef int &_Atomic atomic_reference_to_int; // expected-error {{'_Atomic' qualifier may not be applied to a reference}} +typedef _Atomic(int &) atomic_reference_to_int; // expected-error {{_Atomic cannot be applied to reference type 'int &'}} + +struct S { + _Atomic union { int n; }; // expected-warning {{anonymous union cannot be '_Atomic'}} +}; + +namespace copy_init { + struct X { + X(int); + int n; + }; + _Atomic(X) y = X(0); + _Atomic(X) z(X(0)); + void f() { y = X(0); } + + _Atomic(X) e1(0); // expected-error {{cannot initialize}} +#if __cplusplus >= 201103L + _Atomic(X) e2{0}; // expected-error {{illegal initializer}} + _Atomic(X) a{X(0)}; +#endif + + struct Y { + _Atomic(X) a; + _Atomic(int) b; + }; + Y y1 = { X(0), 4 }; + Y y2 = { 0, 4 }; // expected-error {{cannot initialize}} + // FIXME: It's not really clear if we should allow these. Generally, C++11 + // allows extraneous braces around initializers. + Y y3 = { { X(0) }, { 4 } }; // expected-error 2{{illegal initializer type}} +} |