From 71ed3c0c9a3458998bded8e2443c0a680c2eb8cd Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Tue, 25 Aug 2020 15:52:57 +0100 Subject: [PATCH] libstdc++: Adjust static assertions in futures and promises [LWG 3466] Add a static_assertions to check the result type is destructible, as in the proposed resolution for LWG 3466 (which supersedes 3458). libstdc++-v3/ChangeLog: * include/std/future (future, shared_future. promise): Add is_destructible assertion (LWG 3466). Adjust string-literal for !is_array and !is_function assertions. * testsuite/30_threads/future/requirements/lwg3458.cc: Check types with no accessible destructor. Adjust expected errors. * testsuite/30_threads/promise/requirements/lwg3466.cc: Likewise. * testsuite/30_threads/shared_future/requirements/lwg3458.cc: Likewise. --- libstdc++-v3/include/std/future | 18 ++++++++++++------ .../30_threads/future/requirements/lwg3458.cc | 13 +++++++++++-- .../30_threads/promise/requirements/lwg3466.cc | 13 +++++++++++-- .../shared_future/requirements/lwg3458.cc | 13 +++++++++++-- 4 files changed, 45 insertions(+), 12 deletions(-) diff --git a/libstdc++-v3/include/std/future b/libstdc++-v3/include/std/future index e0816c2f5e1..a7466a32e03 100644 --- a/libstdc++-v3/include/std/future +++ b/libstdc++-v3/include/std/future @@ -757,8 +757,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { // _GLIBCXX_RESOLVE_LIB_DEFECTS // 3458. Is shared_future intended to work with arrays or function types? - static_assert(!is_array<_Res>{}, "result type is not an array"); - static_assert(!is_function<_Res>{}, "result type is not a function"); + static_assert(!is_array<_Res>{}, "result type must not be an array"); + static_assert(!is_function<_Res>{}, "result type must not be a function"); + static_assert(is_destructible<_Res>{}, + "result type must be destructible"); friend class promise<_Res>; template friend class packaged_task; @@ -892,8 +894,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { // _GLIBCXX_RESOLVE_LIB_DEFECTS // 3458. Is shared_future intended to work with arrays or function types? - static_assert(!is_array<_Res>{}, "result type is not an array"); - static_assert(!is_function<_Res>{}, "result type is not a function"); + static_assert(!is_array<_Res>{}, "result type must not be an array"); + static_assert(!is_function<_Res>{}, "result type must not be a function"); + static_assert(is_destructible<_Res>{}, + "result type must be destructible"); typedef __basic_future<_Res> _Base_type; @@ -1049,8 +1053,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { // _GLIBCXX_RESOLVE_LIB_DEFECTS // 3466: Specify the requirements for promise/future/[...] consistently - static_assert(!is_array<_Res>{}, "result type is not an array"); - static_assert(!is_function<_Res>{}, "result type is not a function"); + static_assert(!is_array<_Res>{}, "result type must not be an array"); + static_assert(!is_function<_Res>{}, "result type must not be a function"); + static_assert(is_destructible<_Res>{}, + "result type must be destructible"); typedef __future_base::_State_base _State; typedef __future_base::_Result<_Res> _Res_type; diff --git a/libstdc++-v3/testsuite/30_threads/future/requirements/lwg3458.cc b/libstdc++-v3/testsuite/30_threads/future/requirements/lwg3458.cc index 2bc206c9450..f26e17bd799 100644 --- a/libstdc++-v3/testsuite/30_threads/future/requirements/lwg3458.cc +++ b/libstdc++-v3/testsuite/30_threads/future/requirements/lwg3458.cc @@ -26,9 +26,18 @@ std::future good; std::future good2; std::future bad; // { dg-error "here" } -// { dg-error "result type is not an array" "" { target *-*-* } 0 } +// { dg-error "result type must not be an array" "" { target *-*-* } 0 } // { dg-prune-output "function returning an array" } std::future bad2; // { dg-error "here" } -// { dg-error "result type is not a function" "" { target *-*-* } 0 } +// { dg-error "result type must not be a function" "" { target *-*-* } 0 } // { dg-prune-output "function returning a function" } + +struct Indestructible { ~Indestructible() = delete; }; +std::future bad3; // { dg-error "here" } +// { dg-error "result type must be destructible" "" { target *-*-* } 0 } +// { dg-prune-output {deleted function} } + +class PrivateDtor { public: PrivateDtor(); private: ~PrivateDtor(); }; +std::future bad4; // { dg-error "here" } +// { dg-prune-output {is private} } diff --git a/libstdc++-v3/testsuite/30_threads/promise/requirements/lwg3466.cc b/libstdc++-v3/testsuite/30_threads/promise/requirements/lwg3466.cc index 124c86c0392..71eb2603e83 100644 --- a/libstdc++-v3/testsuite/30_threads/promise/requirements/lwg3466.cc +++ b/libstdc++-v3/testsuite/30_threads/promise/requirements/lwg3466.cc @@ -26,9 +26,18 @@ std::promise good; std::promise good2; std::promise bad; // { dg-error "here" } -// { dg-error "result type is not an array" "" { target *-*-* } 0 } +// { dg-error "result type must not be an array" "" { target *-*-* } 0 } // { dg-prune-output {request for member '~int \[1\]'} } std::promise bad2; // { dg-error "here" } -// { dg-error "result type is not a function" "" { target *-*-* } 0 } +// { dg-error "result type must not be a function" "" { target *-*-* } 0 } // { dg-prune-output {'sizeof \(int\(\)\)'} } + +struct Indestructible { ~Indestructible() = delete; }; +std::promise bad3; // { dg-error "here" } +// { dg-error "result type must be destructible" "" { target *-*-* } 0 } +// { dg-prune-output {deleted function} } + +class PrivateDtor { public: PrivateDtor(); private: ~PrivateDtor(); }; +std::promise bad4; // { dg-error "here" } +// { dg-prune-output {is private} } diff --git a/libstdc++-v3/testsuite/30_threads/shared_future/requirements/lwg3458.cc b/libstdc++-v3/testsuite/30_threads/shared_future/requirements/lwg3458.cc index df5bfd2b976..cf767698f40 100644 --- a/libstdc++-v3/testsuite/30_threads/shared_future/requirements/lwg3458.cc +++ b/libstdc++-v3/testsuite/30_threads/shared_future/requirements/lwg3458.cc @@ -26,7 +26,16 @@ std::shared_future good; std::shared_future good2; std::shared_future bad; // { dg-error "here" } -// { dg-error "result type is not an array" "" { target *-*-* } 0 } +// { dg-error "result type must not be an array" "" { target *-*-* } 0 } std::shared_future bad2; // { dg-error "here" } -// { dg-error "result type is not a function" "" { target *-*-* } 0 } +// { dg-error "result type must not be a function" "" { target *-*-* } 0 } + +struct Indestructible { ~Indestructible() = delete; }; +std::shared_future bad3; // { dg-error "here" } +// { dg-error "result type must be destructible" "" { target *-*-* } 0 } +// { dg-prune-output {deleted function} } + +class PrivateDtor { public: PrivateDtor(); private: ~PrivateDtor(); }; +std::shared_future bad4; // { dg-error "here" } +// { dg-prune-output {is private} } -- 2.30.2