forked from OSchip/llvm-project
[libc++] Implement LWG 2510
Summary: LWG2510 makes tag types like allocator_arg_t explicitly default constructible instead of implicitly default constructible. It also makes the constructors for std::pair and std::tuple conditionally explicit based on the explicit-ness of the default constructibility for the pair/tuple's elements. Reviewers: mclow.lists, EricWF Subscribers: christof, jkorous, dexonsmith, libcxx-commits Tags: #libc Differential Revision: https://reviews.llvm.org/D65161 llvm-svn: 372777
This commit is contained in:
parent
19712415a5
commit
95411dd426
|
@ -558,7 +558,7 @@ struct __is_transparent<_Tp, _Up,
|
||||||
|
|
||||||
// allocator_arg_t
|
// allocator_arg_t
|
||||||
|
|
||||||
struct _LIBCPP_TEMPLATE_VIS allocator_arg_t { };
|
struct _LIBCPP_TEMPLATE_VIS allocator_arg_t { explicit allocator_arg_t() = default; };
|
||||||
|
|
||||||
#if defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_LIBRARY)
|
#if defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_LIBRARY)
|
||||||
extern _LIBCPP_EXPORTED_FROM_ABI const allocator_arg_t allocator_arg;
|
extern _LIBCPP_EXPORTED_FROM_ABI const allocator_arg_t allocator_arg;
|
||||||
|
|
|
@ -66,9 +66,9 @@ public:
|
||||||
static_assert(is_nothrow_default_constructible<mutex>::value,
|
static_assert(is_nothrow_default_constructible<mutex>::value,
|
||||||
"the default constructor for std::mutex must be nothrow");
|
"the default constructor for std::mutex must be nothrow");
|
||||||
|
|
||||||
struct _LIBCPP_TYPE_VIS defer_lock_t {};
|
struct _LIBCPP_TYPE_VIS defer_lock_t { explicit defer_lock_t() = default; };
|
||||||
struct _LIBCPP_TYPE_VIS try_to_lock_t {};
|
struct _LIBCPP_TYPE_VIS try_to_lock_t { explicit try_to_lock_t() = default; };
|
||||||
struct _LIBCPP_TYPE_VIS adopt_lock_t {};
|
struct _LIBCPP_TYPE_VIS adopt_lock_t { explicit adopt_lock_t() = default; };
|
||||||
|
|
||||||
#if defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_LIBRARY)
|
#if defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_LIBRARY)
|
||||||
|
|
||||||
|
|
|
@ -86,9 +86,9 @@ public:
|
||||||
void unlock();
|
void unlock();
|
||||||
};
|
};
|
||||||
|
|
||||||
struct defer_lock_t {};
|
struct defer_lock_t { explicit defer_lock_t() = default; };
|
||||||
struct try_to_lock_t {};
|
struct try_to_lock_t { explicit try_to_lock_t() = default; };
|
||||||
struct adopt_lock_t {};
|
struct adopt_lock_t { explicit adopt_lock_t() = default; };
|
||||||
|
|
||||||
inline constexpr defer_lock_t defer_lock{};
|
inline constexpr defer_lock_t defer_lock{};
|
||||||
inline constexpr try_to_lock_t try_to_lock{};
|
inline constexpr try_to_lock_t try_to_lock{};
|
||||||
|
|
|
@ -39,7 +39,7 @@ struct destroying_delete_t { // C++20
|
||||||
};
|
};
|
||||||
inline constexpr destroying_delete_t destroying_delete{}; // C++20
|
inline constexpr destroying_delete_t destroying_delete{}; // C++20
|
||||||
|
|
||||||
struct nothrow_t {};
|
struct nothrow_t { explicit nothrow_t() = default; };
|
||||||
extern const nothrow_t nothrow;
|
extern const nothrow_t nothrow;
|
||||||
typedef void (*new_handler)();
|
typedef void (*new_handler)();
|
||||||
new_handler set_new_handler(new_handler new_p) noexcept;
|
new_handler set_new_handler(new_handler new_p) noexcept;
|
||||||
|
@ -126,7 +126,7 @@ namespace std // purposefully not using versioning namespace
|
||||||
{
|
{
|
||||||
|
|
||||||
#if !defined(_LIBCPP_ABI_VCRUNTIME)
|
#if !defined(_LIBCPP_ABI_VCRUNTIME)
|
||||||
struct _LIBCPP_TYPE_VIS nothrow_t {};
|
struct _LIBCPP_TYPE_VIS nothrow_t { explicit nothrow_t() = default; };
|
||||||
extern _LIBCPP_FUNC_VIS const nothrow_t nothrow;
|
extern _LIBCPP_FUNC_VIS const nothrow_t nothrow;
|
||||||
|
|
||||||
class _LIBCPP_EXCEPTION_ABI bad_alloc
|
class _LIBCPP_EXCEPTION_ABI bad_alloc
|
||||||
|
|
|
@ -19,7 +19,7 @@ namespace std
|
||||||
template <class... T>
|
template <class... T>
|
||||||
class tuple {
|
class tuple {
|
||||||
public:
|
public:
|
||||||
constexpr tuple();
|
explicit(see-below) constexpr tuple();
|
||||||
explicit(see-below) tuple(const T&...); // constexpr in C++14
|
explicit(see-below) tuple(const T&...); // constexpr in C++14
|
||||||
template <class... U>
|
template <class... U>
|
||||||
explicit(see-below) tuple(U&&...); // constexpr in C++14
|
explicit(see-below) tuple(U&&...); // constexpr in C++14
|
||||||
|
@ -500,8 +500,19 @@ class _LIBCPP_TEMPLATE_VIS tuple
|
||||||
struct _CheckArgsConstructor<true, _Dummy>
|
struct _CheckArgsConstructor<true, _Dummy>
|
||||||
{
|
{
|
||||||
template <class ..._Args>
|
template <class ..._Args>
|
||||||
static constexpr bool __enable_default() {
|
static constexpr bool __enable_implicit_default() {
|
||||||
return __all<is_default_constructible<_Args>::value...>::value;
|
// In C++03, there's no way to implement the resolution of LWG2510.
|
||||||
|
#ifdef _LIBCPP_CXX03_LANG
|
||||||
|
return true;
|
||||||
|
#else
|
||||||
|
return __all<__is_implicitly_default_constructible<_Args>::value...>::value;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class ..._Args>
|
||||||
|
static constexpr bool __enable_explicit_default() {
|
||||||
|
return __all<is_default_constructible<_Args>::value...>::value
|
||||||
|
&& !__enable_implicit_default<_Args...>();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class ..._Args>
|
template <class ..._Args>
|
||||||
|
@ -641,11 +652,18 @@ class _LIBCPP_TEMPLATE_VIS tuple
|
||||||
const typename tuple_element<_Jp, tuple<_Up...> >::type&& get(const tuple<_Up...>&&) _NOEXCEPT;
|
const typename tuple_element<_Jp, tuple<_Up...> >::type&& get(const tuple<_Up...>&&) _NOEXCEPT;
|
||||||
public:
|
public:
|
||||||
|
|
||||||
template <bool _Dummy = true, class = typename enable_if<
|
template <bool _Dummy = true, _EnableIf<
|
||||||
_CheckArgsConstructor<_Dummy>::template __enable_default<_Tp...>()
|
_CheckArgsConstructor<_Dummy>::template __enable_implicit_default<_Tp...>()
|
||||||
>::type>
|
, void*> = nullptr>
|
||||||
_LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
|
||||||
_LIBCPP_CONSTEXPR tuple()
|
tuple()
|
||||||
|
_NOEXCEPT_(__all<is_nothrow_default_constructible<_Tp>::value...>::value) {}
|
||||||
|
|
||||||
|
template <bool _Dummy = true, _EnableIf<
|
||||||
|
_CheckArgsConstructor<_Dummy>::template __enable_explicit_default<_Tp...>()
|
||||||
|
, void*> = nullptr>
|
||||||
|
explicit _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
|
||||||
|
tuple()
|
||||||
_NOEXCEPT_(__all<is_nothrow_default_constructible<_Tp>::value...>::value) {}
|
_NOEXCEPT_(__all<is_nothrow_default_constructible<_Tp>::value...>::value) {}
|
||||||
|
|
||||||
tuple(tuple const&) = default;
|
tuple(tuple const&) = default;
|
||||||
|
|
|
@ -2807,6 +2807,21 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_default_constructible_v
|
||||||
= is_default_constructible<_Tp>::value;
|
= is_default_constructible<_Tp>::value;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef _LIBCPP_CXX03_LANG
|
||||||
|
template <class _Tp>
|
||||||
|
void __test_implicit_default_constructible(_Tp);
|
||||||
|
|
||||||
|
template <class _Tp, class = void>
|
||||||
|
struct __is_implicitly_default_constructible
|
||||||
|
: false_type
|
||||||
|
{ };
|
||||||
|
|
||||||
|
template <class _Tp>
|
||||||
|
struct __is_implicitly_default_constructible<_Tp, decltype(__test_implicit_default_constructible<_Tp const&>({}))>
|
||||||
|
: is_default_constructible<_Tp>
|
||||||
|
{ };
|
||||||
|
#endif // !C++03
|
||||||
|
|
||||||
// is_copy_constructible
|
// is_copy_constructible
|
||||||
|
|
||||||
template <class _Tp>
|
template <class _Tp>
|
||||||
|
|
|
@ -69,7 +69,7 @@ struct pair
|
||||||
|
|
||||||
pair(const pair&) = default;
|
pair(const pair&) = default;
|
||||||
pair(pair&&) = default;
|
pair(pair&&) = default;
|
||||||
constexpr pair();
|
explicit(see-below) constexpr pair();
|
||||||
explicit(see-below) pair(const T1& x, const T2& y); // constexpr in C++14
|
explicit(see-below) pair(const T1& x, const T2& y); // constexpr in C++14
|
||||||
template <class U, class V> explicit(see-below) pair(U&& x, V&& y); // constexpr in C++14
|
template <class U, class V> explicit(see-below) pair(U&& x, V&& y); // constexpr in C++14
|
||||||
template <class U, class V> explicit(see-below) pair(const pair<U, V>& p); // constexpr in C++14
|
template <class U, class V> explicit(see-below) pair(const pair<U, V>& p); // constexpr in C++14
|
||||||
|
@ -99,7 +99,7 @@ template <class T1, class T2>
|
||||||
void
|
void
|
||||||
swap(pair<T1, T2>& x, pair<T1, T2>& y) noexcept(noexcept(x.swap(y)));
|
swap(pair<T1, T2>& x, pair<T1, T2>& y) noexcept(noexcept(x.swap(y)));
|
||||||
|
|
||||||
struct piecewise_construct_t { };
|
struct piecewise_construct_t { explicit piecewise_construct_t() = default; };
|
||||||
inline constexpr piecewise_construct_t piecewise_construct = piecewise_construct_t();
|
inline constexpr piecewise_construct_t piecewise_construct = piecewise_construct_t();
|
||||||
|
|
||||||
template <class T> struct tuple_size;
|
template <class T> struct tuple_size;
|
||||||
|
@ -276,7 +276,7 @@ template <class _Tp> constexpr add_const_t<_Tp>& as_const(_Tp& __t) noexcept { r
|
||||||
template <class _Tp> void as_const(const _Tp&&) = delete;
|
template <class _Tp> void as_const(const _Tp&&) = delete;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct _LIBCPP_TEMPLATE_VIS piecewise_construct_t { };
|
struct _LIBCPP_TEMPLATE_VIS piecewise_construct_t { explicit piecewise_construct_t() = default; };
|
||||||
#if defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_LIBRARY)
|
#if defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_LIBRARY)
|
||||||
extern _LIBCPP_EXPORTED_FROM_ABI const piecewise_construct_t piecewise_construct;// = piecewise_construct_t();
|
extern _LIBCPP_EXPORTED_FROM_ABI const piecewise_construct_t piecewise_construct;// = piecewise_construct_t();
|
||||||
#else
|
#else
|
||||||
|
@ -335,9 +335,21 @@ struct _LIBCPP_TEMPLATE_VIS pair
|
||||||
|
|
||||||
struct _CheckArgs {
|
struct _CheckArgs {
|
||||||
template <class _U1, class _U2>
|
template <class _U1, class _U2>
|
||||||
static constexpr bool __enable_default() {
|
static constexpr bool __enable_explicit_default() {
|
||||||
return is_default_constructible<_U1>::value
|
return is_default_constructible<_U1>::value
|
||||||
&& is_default_constructible<_U2>::value;
|
&& is_default_constructible<_U2>::value
|
||||||
|
&& !__enable_implicit_default<_U1, _U2>();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class _U1, class _U2>
|
||||||
|
static constexpr bool __enable_implicit_default() {
|
||||||
|
// In C++03, there's no way to implement the resolution of LWG2510.
|
||||||
|
#ifdef _LIBCPP_CXX03_LANG
|
||||||
|
return true;
|
||||||
|
#else
|
||||||
|
return __is_implicitly_default_constructible<_U1>::value
|
||||||
|
&& __is_implicitly_default_constructible<_U2>::value;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class _U1, class _U2>
|
template <class _U1, class _U2>
|
||||||
|
@ -388,7 +400,15 @@ struct _LIBCPP_TEMPLATE_VIS pair
|
||||||
>::type;
|
>::type;
|
||||||
|
|
||||||
template<bool _Dummy = true, _EnableB<
|
template<bool _Dummy = true, _EnableB<
|
||||||
_CheckArgsDep<_Dummy>::template __enable_default<_T1, _T2>()
|
_CheckArgsDep<_Dummy>::template __enable_explicit_default<_T1, _T2>()
|
||||||
|
> = false>
|
||||||
|
explicit _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
|
||||||
|
pair() _NOEXCEPT_(is_nothrow_default_constructible<first_type>::value &&
|
||||||
|
is_nothrow_default_constructible<second_type>::value)
|
||||||
|
: first(), second() {}
|
||||||
|
|
||||||
|
template<bool _Dummy = true, _EnableB<
|
||||||
|
_CheckArgsDep<_Dummy>::template __enable_implicit_default<_T1, _T2>()
|
||||||
> = false>
|
> = false>
|
||||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
|
||||||
pair() _NOEXCEPT_(is_nothrow_default_constructible<first_type>::value &&
|
pair() _NOEXCEPT_(is_nothrow_default_constructible<first_type>::value &&
|
||||||
|
|
|
@ -21,9 +21,9 @@
|
||||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||||
#ifndef _LIBCPP_HAS_NO_THREADS
|
#ifndef _LIBCPP_HAS_NO_THREADS
|
||||||
|
|
||||||
const defer_lock_t defer_lock = {};
|
const defer_lock_t defer_lock{};
|
||||||
const try_to_lock_t try_to_lock = {};
|
const try_to_lock_t try_to_lock{};
|
||||||
const adopt_lock_t adopt_lock = {};
|
const adopt_lock_t adopt_lock{};
|
||||||
|
|
||||||
// ~mutex is defined elsewhere
|
// ~mutex is defined elsewhere
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,6 @@
|
||||||
|
|
||||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||||
|
|
||||||
const piecewise_construct_t piecewise_construct = {};
|
const piecewise_construct_t piecewise_construct{};
|
||||||
|
|
||||||
_LIBCPP_END_NAMESPACE_STD
|
_LIBCPP_END_NAMESPACE_STD
|
||||||
|
|
|
@ -0,0 +1,56 @@
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
// UNSUPPORTED: c++98, c++03
|
||||||
|
|
||||||
|
// <type_traits>
|
||||||
|
|
||||||
|
// __is_implicitly_default_constructible<Tp>
|
||||||
|
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
|
|
||||||
|
struct ExplicitlyDefaultConstructible1 {
|
||||||
|
explicit ExplicitlyDefaultConstructible1() = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ExplicitlyDefaultConstructible2 {
|
||||||
|
explicit ExplicitlyDefaultConstructible2() { }
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ImplicitlyDefaultConstructible1 {
|
||||||
|
ImplicitlyDefaultConstructible1() { }
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ImplicitlyDefaultConstructible2 {
|
||||||
|
ImplicitlyDefaultConstructible2() = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct NonDefaultConstructible1 {
|
||||||
|
NonDefaultConstructible1() = delete;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct NonDefaultConstructible2 {
|
||||||
|
explicit NonDefaultConstructible2() = delete;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct NonDefaultConstructible3 {
|
||||||
|
NonDefaultConstructible3(NonDefaultConstructible3&&) { }
|
||||||
|
};
|
||||||
|
|
||||||
|
static_assert(!std::__is_implicitly_default_constructible<ExplicitlyDefaultConstructible1>::value, "");
|
||||||
|
static_assert(!std::__is_implicitly_default_constructible<ExplicitlyDefaultConstructible2>::value, "");
|
||||||
|
static_assert(std::__is_implicitly_default_constructible<ImplicitlyDefaultConstructible1>::value, "");
|
||||||
|
static_assert(std::__is_implicitly_default_constructible<ImplicitlyDefaultConstructible2>::value, "");
|
||||||
|
static_assert(!std::__is_implicitly_default_constructible<NonDefaultConstructible1>::value, "");
|
||||||
|
static_assert(!std::__is_implicitly_default_constructible<NonDefaultConstructible2>::value, "");
|
||||||
|
static_assert(!std::__is_implicitly_default_constructible<NonDefaultConstructible3>::value, "");
|
||||||
|
|
||||||
|
int main(int, char**) {
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// The LLVM Compiler Infrastructure
|
||||||
|
//
|
||||||
|
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||||
|
// Source Licenses. See LICENSE.TXT for details.
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
// UNSUPPORTED: c++98, c++03
|
||||||
|
|
||||||
|
// struct nothrow_t {
|
||||||
|
// explicit nothrow_t() = default;
|
||||||
|
// };
|
||||||
|
// extern const nothrow_t nothrow;
|
||||||
|
|
||||||
|
// This test checks for LWG 2510.
|
||||||
|
|
||||||
|
#include <new>
|
||||||
|
|
||||||
|
|
||||||
|
std::nothrow_t f() { return {}; } // expected-error 1 {{chosen constructor is explicit in copy-initialization}}
|
||||||
|
|
||||||
|
int main(int, char**) {
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// The LLVM Compiler Infrastructure
|
||||||
|
//
|
||||||
|
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||||
|
// Source Licenses. See LICENSE.TXT for details.
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
// struct nothrow_t {
|
||||||
|
// explicit nothrow_t() = default;
|
||||||
|
// };
|
||||||
|
// extern const nothrow_t nothrow;
|
||||||
|
|
||||||
|
#include <new>
|
||||||
|
|
||||||
|
|
||||||
|
int main(int, char**) {
|
||||||
|
std::nothrow_t x = std::nothrow;
|
||||||
|
(void)x;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// The LLVM Compiler Infrastructure
|
||||||
|
//
|
||||||
|
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||||
|
// Source Licenses. See LICENSE.TXT for details.
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
// UNSUPPORTED: c++98, c++03
|
||||||
|
|
||||||
|
// UNSUPPORTED: libcpp-has-no-threads
|
||||||
|
|
||||||
|
// <mutex>
|
||||||
|
|
||||||
|
// struct defer_lock_t { explicit defer_lock_t() = default; };
|
||||||
|
// struct try_to_lock_t { explicit try_to_lock_t() = default; };
|
||||||
|
// struct adopt_lock_t { explicit adopt_lock_t() = default; };
|
||||||
|
|
||||||
|
// This test checks for LWG 2510.
|
||||||
|
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
|
|
||||||
|
std::defer_lock_t f1() { return {}; } // expected-error 1 {{chosen constructor is explicit in copy-initialization}}
|
||||||
|
std::try_to_lock_t f2() { return {}; } // expected-error 1 {{chosen constructor is explicit in copy-initialization}}
|
||||||
|
std::adopt_lock_t f3() { return {}; } // expected-error 1 {{chosen constructor is explicit in copy-initialization}}
|
||||||
|
|
||||||
|
int main(int, char**) {
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -10,16 +10,15 @@
|
||||||
|
|
||||||
// <mutex>
|
// <mutex>
|
||||||
|
|
||||||
// struct defer_lock_t {};
|
// struct defer_lock_t { explicit defer_lock_t() = default; };
|
||||||
// struct try_to_lock_t {};
|
// struct try_to_lock_t { explicit try_to_lock_t() = default; };
|
||||||
// struct adopt_lock_t {};
|
// struct adopt_lock_t { explicit adopt_lock_t() = default; };
|
||||||
//
|
//
|
||||||
// constexpr defer_lock_t defer_lock{};
|
// constexpr defer_lock_t defer_lock{};
|
||||||
// constexpr try_to_lock_t try_to_lock{};
|
// constexpr try_to_lock_t try_to_lock{};
|
||||||
// constexpr adopt_lock_t adopt_lock{};
|
// constexpr adopt_lock_t adopt_lock{};
|
||||||
|
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <type_traits>
|
|
||||||
|
|
||||||
#include "test_macros.h"
|
#include "test_macros.h"
|
||||||
|
|
||||||
|
@ -33,5 +32,5 @@ int main(int, char**)
|
||||||
T2 t2 = std::try_to_lock; ((void)t2);
|
T2 t2 = std::try_to_lock; ((void)t2);
|
||||||
T3 t3 = std::adopt_lock; ((void)t3);
|
T3 t3 = std::adopt_lock; ((void)t3);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
// UNSUPPORTED: c++98, c++03
|
||||||
|
|
||||||
|
// <memory>
|
||||||
|
|
||||||
|
// struct allocator_arg_t { explicit allocator_arg_t() = default; };
|
||||||
|
// const allocator_arg_t allocator_arg = allocator_arg_t();
|
||||||
|
|
||||||
|
// This test checks for LWG 2510.
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
|
||||||
|
std::allocator_arg_t f() { return {}; } // expected-error 1 {{chosen constructor is explicit in copy-initialization}}
|
||||||
|
|
||||||
|
int main(int, char**) {
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
// <memory>
|
// <memory>
|
||||||
|
|
||||||
// struct allocator_arg_t { };
|
// struct allocator_arg_t { explicit allocator_arg_t() = default; };
|
||||||
// const allocator_arg_t allocator_arg = allocator_arg_t();
|
// const allocator_arg_t allocator_arg = allocator_arg_t();
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
@ -21,5 +21,5 @@ int main(int, char**)
|
||||||
{
|
{
|
||||||
test(std::allocator_arg);
|
test(std::allocator_arg);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
// UNSUPPORTED: c++98, c++03
|
||||||
|
|
||||||
|
// <tuple>
|
||||||
|
|
||||||
|
// template <class... Types> class tuple;
|
||||||
|
|
||||||
|
// explicit(see-below) constexpr tuple();
|
||||||
|
|
||||||
|
#include <tuple>
|
||||||
|
|
||||||
|
|
||||||
|
struct Implicit {
|
||||||
|
Implicit() = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Explicit {
|
||||||
|
explicit Explicit() = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::tuple<> test1() { return {}; }
|
||||||
|
|
||||||
|
std::tuple<Implicit> test2() { return {}; }
|
||||||
|
std::tuple<Explicit> test3() { return {}; } // expected-error 1 {{chosen constructor is explicit in copy-initialization}}
|
||||||
|
|
||||||
|
std::tuple<Implicit, Implicit> test4() { return {}; }
|
||||||
|
std::tuple<Explicit, Implicit> test5() { return {}; } // expected-error 1 {{chosen constructor is explicit in copy-initialization}}
|
||||||
|
std::tuple<Implicit, Explicit> test6() { return {}; } // expected-error 1 {{chosen constructor is explicit in copy-initialization}}
|
||||||
|
std::tuple<Explicit, Explicit> test7() { return {}; } // expected-error 1 {{chosen constructor is explicit in copy-initialization}}
|
||||||
|
|
||||||
|
std::tuple<Implicit, Implicit, Implicit> test8() { return {}; }
|
||||||
|
std::tuple<Implicit, Implicit, Explicit> test9() { return {}; } // expected-error 1 {{chosen constructor is explicit in copy-initialization}}
|
||||||
|
std::tuple<Implicit, Explicit, Implicit> test10() { return {}; } // expected-error 1 {{chosen constructor is explicit in copy-initialization}}
|
||||||
|
std::tuple<Implicit, Explicit, Explicit> test11() { return {}; } // expected-error 1 {{chosen constructor is explicit in copy-initialization}}
|
||||||
|
std::tuple<Explicit, Implicit, Implicit> test12() { return {}; } // expected-error 1 {{chosen constructor is explicit in copy-initialization}}
|
||||||
|
std::tuple<Explicit, Implicit, Explicit> test13() { return {}; } // expected-error 1 {{chosen constructor is explicit in copy-initialization}}
|
||||||
|
std::tuple<Explicit, Explicit, Implicit> test14() { return {}; } // expected-error 1 {{chosen constructor is explicit in copy-initialization}}
|
||||||
|
std::tuple<Explicit, Explicit, Explicit> test15() { return {}; } // expected-error 1 {{chosen constructor is explicit in copy-initialization}}
|
||||||
|
|
||||||
|
int main(int, char**) {
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -10,7 +10,7 @@
|
||||||
|
|
||||||
// template <class... Types> class tuple;
|
// template <class... Types> class tuple;
|
||||||
|
|
||||||
// constexpr tuple();
|
// explicit(see-below) constexpr tuple();
|
||||||
|
|
||||||
// UNSUPPORTED: c++98, c++03
|
// UNSUPPORTED: c++98, c++03
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
|
|
||||||
// template <class T1, class T2> struct pair
|
// template <class T1, class T2> struct pair
|
||||||
|
|
||||||
// struct piecewise_construct_t { };
|
// struct piecewise_construct_t { explicit piecewise_construct_t() = default; };
|
||||||
// constexpr piecewise_construct_t piecewise_construct = piecewise_construct_t();
|
// constexpr piecewise_construct_t piecewise_construct = piecewise_construct_t();
|
||||||
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
// UNSUPPORTED: c++98, c++03
|
||||||
|
|
||||||
|
// <utility>
|
||||||
|
|
||||||
|
// struct piecewise_construct_t { explicit piecewise_construct_t() = default; };
|
||||||
|
// constexpr piecewise_construct_t piecewise_construct = piecewise_construct_t();
|
||||||
|
|
||||||
|
// This test checks for LWG 2510.
|
||||||
|
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
|
||||||
|
std::piecewise_construct_t f() { return {}; } // expected-error 1 {{chosen constructor is explicit in copy-initialization}}
|
||||||
|
|
||||||
|
int main(int, char**) {
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
// UNSUPPORTED: c++98, c++03
|
||||||
|
|
||||||
|
// <utility>
|
||||||
|
|
||||||
|
// struct piecewise_construct_t { explicit piecewise_construct_t() = default; };
|
||||||
|
// constexpr piecewise_construct_t piecewise_construct = piecewise_construct_t();
|
||||||
|
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
|
||||||
|
int main(int, char**) {
|
||||||
|
std::piecewise_construct_t x = std::piecewise_construct;
|
||||||
|
(void)x;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
// UNSUPPORTED: c++98, c++03
|
||||||
|
|
||||||
|
// <utility>
|
||||||
|
|
||||||
|
// template <class T1, class T2> struct pair
|
||||||
|
|
||||||
|
// explicit(see-below) constexpr pair();
|
||||||
|
|
||||||
|
// This test checks the conditional explicitness of std::pair's default
|
||||||
|
// constructor as introduced by the resolution of LWG 2510.
|
||||||
|
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
|
||||||
|
struct ImplicitlyDefaultConstructible {
|
||||||
|
ImplicitlyDefaultConstructible() = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ExplicitlyDefaultConstructible {
|
||||||
|
explicit ExplicitlyDefaultConstructible() = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::pair<ImplicitlyDefaultConstructible, ExplicitlyDefaultConstructible> test1() { return {}; } // expected-error 1 {{chosen constructor is explicit in copy-initialization}}
|
||||||
|
std::pair<ExplicitlyDefaultConstructible, ImplicitlyDefaultConstructible> test2() { return {}; } // expected-error 1 {{chosen constructor is explicit in copy-initialization}}
|
||||||
|
std::pair<ExplicitlyDefaultConstructible, ExplicitlyDefaultConstructible> test3() { return {}; } // expected-error 1 {{chosen constructor is explicit in copy-initialization}}
|
||||||
|
std::pair<ImplicitlyDefaultConstructible, ImplicitlyDefaultConstructible> test4() { return {}; }
|
||||||
|
|
||||||
|
int main(int, char**) {
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -10,7 +10,7 @@
|
||||||
|
|
||||||
// template <class T1, class T2> struct pair
|
// template <class T1, class T2> struct pair
|
||||||
|
|
||||||
// constexpr pair();
|
// explicit(see-below) constexpr pair();
|
||||||
|
|
||||||
// This test doesn't pass due to a constexpr bug in GCC 4.9 that fails
|
// This test doesn't pass due to a constexpr bug in GCC 4.9 that fails
|
||||||
// to initialize any type without a user provided constructor in a constant
|
// to initialize any type without a user provided constructor in a constant
|
||||||
|
|
|
@ -372,7 +372,7 @@
|
||||||
<tr><td><a href="https://wg21.link/LWG2468">2468</a></td><td>Self-move-assignment of library types</td><td>Issaquah</td><td></td></tr>
|
<tr><td><a href="https://wg21.link/LWG2468">2468</a></td><td>Self-move-assignment of library types</td><td>Issaquah</td><td></td></tr>
|
||||||
<tr><td><a href="https://wg21.link/LWG2475">2475</a></td><td>Allow overwriting of std::basic_string terminator with charT() to allow cleaner interoperation with legacy APIs</td><td>Issaquah</td><td>Complete</td></tr>
|
<tr><td><a href="https://wg21.link/LWG2475">2475</a></td><td>Allow overwriting of std::basic_string terminator with charT() to allow cleaner interoperation with legacy APIs</td><td>Issaquah</td><td>Complete</td></tr>
|
||||||
<tr><td><a href="https://wg21.link/LWG2503">2503</a></td><td>multiline option should be added to syntax_option_type</td><td>Issaquah</td><td></td></tr>
|
<tr><td><a href="https://wg21.link/LWG2503">2503</a></td><td>multiline option should be added to syntax_option_type</td><td>Issaquah</td><td></td></tr>
|
||||||
<tr><td><a href="https://wg21.link/LWG2510">2510</a></td><td>Tag types should not be DefaultConstructible</td><td>Issaquah</td><td></td></tr>
|
<tr><td><a href="https://wg21.link/LWG2510">2510</a></td><td>Tag types should not be DefaultConstructible</td><td>Issaquah</td><td>Complete</td></tr>
|
||||||
<tr><td><a href="https://wg21.link/LWG2514">2514</a></td><td>Type traits must not be final</td><td>Issaquah</td><td>Complete</td></tr>
|
<tr><td><a href="https://wg21.link/LWG2514">2514</a></td><td>Type traits must not be final</td><td>Issaquah</td><td>Complete</td></tr>
|
||||||
<tr><td><a href="https://wg21.link/LWG2518">2518</a></td><td>[fund.ts.v2] Non-member swap for propagate_const should call member swap</td><td>Issaquah</td><td>Complete</td></tr>
|
<tr><td><a href="https://wg21.link/LWG2518">2518</a></td><td>[fund.ts.v2] Non-member swap for propagate_const should call member swap</td><td>Issaquah</td><td>Complete</td></tr>
|
||||||
<tr><td><a href="https://wg21.link/LWG2519">2519</a></td><td>Iterator operator-= has gratuitous undefined behaviour</td><td>Issaquah</td><td>Complete</td></tr>
|
<tr><td><a href="https://wg21.link/LWG2519">2519</a></td><td>Iterator operator-= has gratuitous undefined behaviour</td><td>Issaquah</td><td>Complete</td></tr>
|
||||||
|
|
Loading…
Reference in New Issue