blob: dff599b6d5b661543f263a9eabdcdcdc336b4589 [file] [log] [blame]
Richard Smith6403e932014-11-14 00:37:55 +00001// 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.
Richard Smith3ef3e892014-11-20 22:32:11 +00006//
7// The same problem afflicts a bunch of other class templates. Those
8// affected are array, pair, priority_queue, stack, and queue.
9
10// RUN: %clang_cc1 -fsyntax-only %s -std=c++11 -verify -fexceptions -fcxx-exceptions -DCLASS=array
Vassil Vassilev86436392016-08-20 14:50:22 +000011// RUN: %clang_cc1 -fsyntax-only %s -std=c++11 -verify -fexceptions -fcxx-exceptions -DCLASS=array -DPR28423
Richard Smith3ef3e892014-11-20 22:32:11 +000012// 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
Richard Smith62895462016-10-19 23:47:37 +000016//
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
Richard Smith3ef3e892014-11-20 22:32:11 +000019
20// MSVC's standard library uses a very similar pattern that relies on delayed
21// parsing of exception specifications.
22//
23// RUN: %clang_cc1 -fsyntax-only %s -std=c++11 -verify -fexceptions -fcxx-exceptions -DCLASS=array -DMSVC
Richard Smith6403e932014-11-14 00:37:55 +000024
25#ifdef BE_THE_HEADER
26
27#pragma GCC system_header
Vassil Vassilev86436392016-08-20 14:50:22 +000028#ifdef PR28423
29using namespace std;
30#endif
31
Richard Smith6403e932014-11-14 00:37:55 +000032namespace std {
33 template<typename T> void swap(T &, T &);
Richard Smith3ef3e892014-11-20 22:32:11 +000034 template<typename T> void do_swap(T &a, T &b) noexcept(noexcept(swap(a, b))) {
35 swap(a, b);
36 }
Richard Smith6403e932014-11-14 00:37:55 +000037
Richard Smith62895462016-10-19 23:47:37 +000038#ifdef NAMESPACE
39 namespace NAMESPACE {
40#define STD_CLASS std::NAMESPACE::CLASS
41#else
42#define STD_CLASS std::CLASS
43#endif
44
Richard Smith3ef3e892014-11-20 22:32:11 +000045 template<typename A, typename B> struct CLASS {
46#ifdef MSVC
47 void swap(CLASS &other) noexcept(noexcept(do_swap(member, other.member)));
48#endif
49 A member;
50#ifndef MSVC
51 void swap(CLASS &other) noexcept(noexcept(swap(member, other.member)));
52#endif
Richard Smith6403e932014-11-14 00:37:55 +000053 };
Richard Smith3ef3e892014-11-20 22:32:11 +000054
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)));
58// A member;
59// };
Richard Smith62895462016-10-19 23:47:37 +000060
61#ifdef NAMESPACE
62 }
63#endif
Richard Smith6403e932014-11-14 00:37:55 +000064}
65
66#else
67
68#define BE_THE_HEADER
69#include __FILE__
70
71struct X {};
Richard Smith62895462016-10-19 23:47:37 +000072using PX = STD_CLASS<X, X>;
73using PI = STD_CLASS<int, int>;
Richard Smith3ef3e892014-11-20 22:32:11 +000074void swap(X &, X &) noexcept;
Richard Smith6403e932014-11-14 00:37:55 +000075PX px;
76PI pi;
77
78static_assert(noexcept(px.swap(px)), "");
79static_assert(!noexcept(pi.swap(pi)), "");
80
81namespace sad {
82 template<typename T> void swap(T &, T &);
83
Richard Smith3ef3e892014-11-20 22:32:11 +000084 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}}
Richard Smith84a0b6d2016-10-18 23:39:12 +000086 // expected-error@-1{{uses itself}} expected-note@-1{{in instantiation of}}
Richard Smith6403e932014-11-14 00:37:55 +000087 };
88
Richard Smith3ef3e892014-11-20 22:32:11 +000089 CLASS<int, int> pi;
Richard Smith6403e932014-11-14 00:37:55 +000090
Richard Smith73c3c212017-02-23 02:09:03 +000091 static_assert(!noexcept(pi.swap(pi)), ""); // expected-note 2{{in instantiation of exception specification for 'swap'}}
Richard Smith6403e932014-11-14 00:37:55 +000092}
93
94#endif