diff options
author | dim <dim@FreeBSD.org> | 2015-01-18 16:23:48 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2015-01-18 16:23:48 +0000 |
commit | c86b984ea8ecb3e944dc3de48539f4c1f65851ea (patch) | |
tree | 3eb853da77d46cc77c4b017525a422f9ddb1385b /test/SemaCXX/libstdcxx_pair_swap_hack.cpp | |
parent | c696171ff15f0ee60dea4abfd99a135473c95656 (diff) | |
download | FreeBSD-src-c86b984ea8ecb3e944dc3de48539f4c1f65851ea.zip FreeBSD-src-c86b984ea8ecb3e944dc3de48539f4c1f65851ea.tar.gz |
Vendor import of clang RELEASE_360/rc1 tag r226102 (effectively, 3.6.0 RC1):
https://llvm.org/svn/llvm-project/cfe/tags/RELEASE_360/rc1@226102
Diffstat (limited to 'test/SemaCXX/libstdcxx_pair_swap_hack.cpp')
-rw-r--r-- | test/SemaCXX/libstdcxx_pair_swap_hack.cpp | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/test/SemaCXX/libstdcxx_pair_swap_hack.cpp b/test/SemaCXX/libstdcxx_pair_swap_hack.cpp new file mode 100644 index 0000000..02431e0 --- /dev/null +++ b/test/SemaCXX/libstdcxx_pair_swap_hack.cpp @@ -0,0 +1,74 @@ +// This is a test for an egregious hack in Clang that works around +// an issue with GCC's <utility> implementation. std::pair::swap +// has an exception specification that makes an unqualified call to +// swap. This is invalid, because it ends up calling itself with +// the wrong number of arguments. +// +// The same problem afflicts a bunch of other class templates. Those +// affected are array, pair, priority_queue, stack, and queue. + +// RUN: %clang_cc1 -fsyntax-only %s -std=c++11 -verify -fexceptions -fcxx-exceptions -DCLASS=array +// RUN: %clang_cc1 -fsyntax-only %s -std=c++11 -verify -fexceptions -fcxx-exceptions -DCLASS=pair +// RUN: %clang_cc1 -fsyntax-only %s -std=c++11 -verify -fexceptions -fcxx-exceptions -DCLASS=priority_queue +// RUN: %clang_cc1 -fsyntax-only %s -std=c++11 -verify -fexceptions -fcxx-exceptions -DCLASS=stack +// RUN: %clang_cc1 -fsyntax-only %s -std=c++11 -verify -fexceptions -fcxx-exceptions -DCLASS=queue + +// MSVC's standard library uses a very similar pattern that relies on delayed +// parsing of exception specifications. +// +// RUN: %clang_cc1 -fsyntax-only %s -std=c++11 -verify -fexceptions -fcxx-exceptions -DCLASS=array -DMSVC + +#ifdef BE_THE_HEADER + +#pragma GCC system_header +namespace std { + template<typename T> void swap(T &, T &); + template<typename T> void do_swap(T &a, T &b) noexcept(noexcept(swap(a, b))) { + swap(a, b); + } + + template<typename A, typename B> struct CLASS { +#ifdef MSVC + void swap(CLASS &other) noexcept(noexcept(do_swap(member, other.member))); +#endif + A member; +#ifndef MSVC + void swap(CLASS &other) noexcept(noexcept(swap(member, other.member))); +#endif + }; + +// template<typename T> void do_swap(T &, T &); +// template<typename A> struct vector { +// void swap(vector &other) noexcept(noexcept(do_swap(member, other.member))); +// A member; +// }; +} + +#else + +#define BE_THE_HEADER +#include __FILE__ + +struct X {}; +using PX = std::CLASS<X, X>; +using PI = std::CLASS<int, int>; +void swap(X &, X &) noexcept; +PX px; +PI pi; + +static_assert(noexcept(px.swap(px)), ""); +static_assert(!noexcept(pi.swap(pi)), ""); + +namespace sad { + template<typename T> void swap(T &, T &); + + template<typename A, typename B> struct CLASS { + void swap(CLASS &other) noexcept(noexcept(swap(*this, other))); // expected-error {{too many arguments}} expected-note {{declared here}} + }; + + CLASS<int, int> pi; + + static_assert(!noexcept(pi.swap(pi)), ""); // expected-note {{in instantiation of}} +} + +#endif |