1 // This is a test for an egregious hack in Clang that works around
2 // an issue with GCC's <utility> implementation. std::pair::swap
3 // has an exception specification that makes an unqualified call to
4 // swap. This is invalid, because it ends up calling itself with
5 // the wrong number of arguments.
7 // The same problem afflicts a bunch of other class templates. Those
8 // affected are array, pair, priority_queue, stack, and queue.
10 // RUN: %clang_cc1 -fsyntax-only %s -std=c++11 -verify -fexceptions -fcxx-exceptions -DCLASS=array
11 // RUN: %clang_cc1 -fsyntax-only %s -std=c++11 -verify -fexceptions -fcxx-exceptions -DCLASS=array -DPR28423
12 // RUN: %clang_cc1 -fsyntax-only %s -std=c++11 -verify -fexceptions -fcxx-exceptions -DCLASS=pair
13 // RUN: %clang_cc1 -fsyntax-only %s -std=c++11 -verify -fexceptions -fcxx-exceptions -DCLASS=priority_queue
14 // RUN: %clang_cc1 -fsyntax-only %s -std=c++11 -verify -fexceptions -fcxx-exceptions -DCLASS=stack
15 // RUN: %clang_cc1 -fsyntax-only %s -std=c++11 -verify -fexceptions -fcxx-exceptions -DCLASS=queue
17 // RUN: %clang_cc1 -fsyntax-only %s -std=c++11 -verify -fexceptions -fcxx-exceptions -DCLASS=array -DNAMESPACE=__debug
18 // RUN: %clang_cc1 -fsyntax-only %s -std=c++11 -verify -fexceptions -fcxx-exceptions -DCLASS=array -DNAMESPACE=__profile
20 // MSVC's standard library uses a very similar pattern that relies on delayed
21 // parsing of exception specifications.
23 // RUN: %clang_cc1 -fsyntax-only %s -std=c++11 -verify -fexceptions -fcxx-exceptions -DCLASS=array -DMSVC
27 #pragma GCC system_header
33 template<typename T
> void swap(T
&, T
&);
34 template<typename T
> void do_swap(T
&a
, T
&b
) noexcept(noexcept(swap(a
, b
))) {
40 #define STD_CLASS std::NAMESPACE::CLASS
42 #define STD_CLASS std::CLASS
45 template<typename A
, typename B
> struct CLASS
{
47 void swap(CLASS
&other
) noexcept(noexcept(do_swap(member
, other
.member
)));
51 void swap(CLASS
&other
) noexcept(noexcept(swap(member
, other
.member
)));
55 // template<typename T> void do_swap(T &, T &);
56 // template<typename A> struct vector {
57 // void swap(vector &other) noexcept(noexcept(do_swap(member, other.member)));
72 using PX
= STD_CLASS
<X
, X
>;
73 using PI
= STD_CLASS
<int, int>;
74 void swap(X
&, X
&) noexcept
;
78 static_assert(noexcept(px
.swap(px
)), "");
79 static_assert(!noexcept(pi
.swap(pi
)), "");
82 template<typename T
> void swap(T
&, T
&);
84 template<typename A
, typename B
> struct CLASS
{
85 void swap(CLASS
&other
) noexcept(noexcept(swap(*this, other
))); // expected-error {{too many arguments}} expected-note {{declared here}}
86 // expected-error@-1{{uses itself}} expected-note@-1{{in instantiation of}}
91 static_assert(!noexcept(pi
.swap(pi
)), ""); // expected-note 2{{in instantiation of exception specification for 'swap'}}