96 lines · cpp
1// This is a test for an egregious hack in Clang that works around2// an issue with GCC's <utility> implementation. std::pair::swap3// has an exception specification that makes an unqualified call to4// swap. This is invalid, because it ends up calling itself with5// the wrong number of arguments.6//7// The same problem afflicts a bunch of other class templates. Those8// affected are array, pair, priority_queue, stack, and queue.9 10// RUN: %clang_cc1 -fsyntax-only %s -std=c++11 -verify -fexceptions -fcxx-exceptions -D__GLIBCXX__=20100000L -DCLASS=array11// RUN: %clang_cc1 -fsyntax-only %s -std=c++11 -verify -fexceptions -fcxx-exceptions -D__GLIBCXX__=20100000L -DCLASS=array -DPR2842312// RUN: %clang_cc1 -fsyntax-only %s -std=c++11 -verify -fexceptions -fcxx-exceptions -D__GLIBCXX__=20100000L -DCLASS=pair13// RUN: %clang_cc1 -fsyntax-only %s -std=c++11 -verify -fexceptions -fcxx-exceptions -D__GLIBCXX__=20100000L -DCLASS=priority_queue14// RUN: %clang_cc1 -fsyntax-only %s -std=c++11 -verify -fexceptions -fcxx-exceptions -D__GLIBCXX__=20100000L -DCLASS=stack15// RUN: %clang_cc1 -fsyntax-only %s -std=c++11 -verify -fexceptions -fcxx-exceptions -D__GLIBCXX__=20100000L -DCLASS=queue16//17// RUN: %clang_cc1 -fsyntax-only %s -std=c++11 -verify -fexceptions -fcxx-exceptions -D__GLIBCXX__=20100000L -DCLASS=array -DNAMESPACE=__debug18// RUN: %clang_cc1 -fsyntax-only %s -std=c++11 -verify -fexceptions -fcxx-exceptions -D__GLIBCXX__=20100000L -DCLASS=array -DNAMESPACE=__profile19 20// MSVC's standard library uses a very similar pattern that relies on delayed21// parsing of exception specifications.22//23// RUN: %clang_cc1 -fsyntax-only %s -std=c++11 -verify -fexceptions -fcxx-exceptions -D__GLIBCXX__=20100000L -DCLASS=array -DMSVC24 25#ifdef BE_THE_HEADER26 27#pragma GCC system_header28#ifdef PR2842329using namespace std;30#endif31 32namespace std {33 template<typename T> void swap(T &, T &);34 template<typename T> void do_swap(T &a, T &b) noexcept(noexcept(swap(a, b))) {35 swap(a, b);36 }37 38#ifdef NAMESPACE39 namespace NAMESPACE {40#define STD_CLASS std::NAMESPACE::CLASS41#else42#define STD_CLASS std::CLASS43#endif44 45 template<typename A, typename B> struct CLASS {46#ifdef MSVC47 void swap(CLASS &other) noexcept(noexcept(do_swap(member, other.member)));48#endif49 A member;50#ifndef MSVC51 void swap(CLASS &other) noexcept(noexcept(swap(member, other.member)));52#endif53 };54 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// };60 61#ifdef NAMESPACE62 }63#endif64}65 66#else67 68#define BE_THE_HEADER69#include __FILE__70 71struct X {};72using PX = STD_CLASS<X, X>;73using PI = STD_CLASS<int, int>;74void swap(X &, X &) noexcept;75PX 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 84 template<typename A, typename B> struct CLASS {85 void swap(CLASS &other) // expected-note {{declared here}}86 noexcept(noexcept(swap(*this, other))); // expected-error {{too many arguments}}87 // expected-error@-1{{uses itself}}88 };89 90 CLASS<int, int> pi;91 92 static_assert(!noexcept(pi.swap(pi)), ""); // expected-note {{in instantiation of exception specification for 'swap'}}93}94 95#endif96