From: Jonathan Wakely Date: Fri, 15 Jun 2018 14:19:47 +0000 (+0100) Subject: LWG 2993 reference_wrapper conversion from T&& X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=7f93abd805763ef3827fce9194b0adcd2419a45c;p=gcc.git LWG 2993 reference_wrapper conversion from T&& * doc/xml/manual/intro.xml: Document LWG 2993 change. * include/bits/refwrap.h (reference_wrapper(_Tp&)): Remove. (reference_wrapper(_Tp&&)): Remove. (reference_wrapper<_Up>(_Up&&)): Define new constructor as constrained template. (reference_wrapper): Add deduction guide. * testsuite/20_util/reference_wrapper/deduction.cc: New. * testsuite/20_util/reference_wrapper/lwg2993.cc: New. From-SVN: r261632 --- diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index aafffa58c5c..31c8f369520 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,5 +1,15 @@ 2018-06-15 Jonathan Wakely + LWG 2993 reference_wrapper conversion from T&& + * doc/xml/manual/intro.xml: Document LWG 2993 change. + * include/bits/refwrap.h (reference_wrapper(_Tp&)): Remove. + (reference_wrapper(_Tp&&)): Remove. + (reference_wrapper<_Up>(_Up&&)): Define new constructor as constrained + template. + (reference_wrapper): Add deduction guide. + * testsuite/20_util/reference_wrapper/deduction.cc: New. + * testsuite/20_util/reference_wrapper/lwg2993.cc: New. + LWG 3039 Unnecessary decay in thread and packaged_task * include/std/future (__constrain_pkgdtask): Replace with ... (packaged_task::__not_same): New alias template, using diff --git a/libstdc++-v3/doc/xml/manual/intro.xml b/libstdc++-v3/doc/xml/manual/intro.xml index b0fc131d1eb..90d43903def 100644 --- a/libstdc++-v3/doc/xml/manual/intro.xml +++ b/libstdc++-v3/doc/xml/manual/intro.xml @@ -1160,6 +1160,14 @@ requirements of the license of GCC. Add noexcept. + 2993: + reference_wrapper<T> conversion from T&& + + + Replaced the constructors with a constrained template, + to prevent participation in overload resolution when not valid. + + 3074: Non-member functions for valarray should only deduce from the valarray diff --git a/libstdc++-v3/include/bits/refwrap.h b/libstdc++-v3/include/bits/refwrap.h index c1d46705b6b..2fdf231898f 100644 --- a/libstdc++-v3/include/bits/refwrap.h +++ b/libstdc++-v3/include/bits/refwrap.h @@ -291,14 +291,25 @@ _GLIBCXX_MEM_FN_TRAITS(&& noexcept, false_type, true_type) { _Tp* _M_data; + static _Tp* _S_fun(_Tp& __r) noexcept { return std::__addressof(__r); } + static void _S_fun(_Tp&&) = delete; + + template> + using __not_same + = typename enable_if::value>::type; + public: typedef _Tp type; - reference_wrapper(_Tp& __indata) noexcept - : _M_data(std::__addressof(__indata)) - { } - - reference_wrapper(_Tp&&) = delete; + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 2993. reference_wrapper conversion from T&& + // 3041. Unnecessary decay in reference_wrapper + template, typename + = decltype(reference_wrapper::_S_fun(std::declval<_Up>()))> + reference_wrapper(_Up&& __uref) + noexcept(noexcept(reference_wrapper::_S_fun(std::declval<_Up>()))) + : _M_data(reference_wrapper::_S_fun(std::forward<_Up>(__uref))) + { } reference_wrapper(const reference_wrapper&) = default; @@ -320,6 +331,10 @@ _GLIBCXX_MEM_FN_TRAITS(&& noexcept, false_type, true_type) } }; +#if __cpp_deduction_guides + template + reference_wrapper(_Tp&) -> reference_wrapper<_Tp>; +#endif /// Denotes a reference should be taken to a variable. template diff --git a/libstdc++-v3/testsuite/20_util/reference_wrapper/deduction.cc b/libstdc++-v3/testsuite/20_util/reference_wrapper/deduction.cc new file mode 100644 index 00000000000..cc5b260cb16 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/reference_wrapper/deduction.cc @@ -0,0 +1,45 @@ +// Copyright (C) 2018 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +// { dg-options "-std=gnu++17" } +// { dg-do compile { target c++17 } } + +#include + +void +test01() +{ + int i = 0; + std::reference_wrapper rw0(i); + [[maybe_unused]] std::reference_wrapper* p0 = &rw0; + [[maybe_unused]] int& r0 = rw0; + + std::reference_wrapper rw1(rw0); + [[maybe_unused]] std::reference_wrapper* p1 = &rw1; + [[maybe_unused]] int& r1 = rw1; +} + +void +test02() +{ + const int i = 0; + std::reference_wrapper rw0(i); + [[maybe_unused]] std::reference_wrapper* p0 = &rw0; + + std::reference_wrapper rw1(rw0); + [[maybe_unused]] std::reference_wrapper* p1 = &rw1; +} diff --git a/libstdc++-v3/testsuite/20_util/reference_wrapper/lwg2993.cc b/libstdc++-v3/testsuite/20_util/reference_wrapper/lwg2993.cc new file mode 100644 index 00000000000..0a339486ef8 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/reference_wrapper/lwg2993.cc @@ -0,0 +1,55 @@ +// Copyright (C) 2018 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +// { dg-do compile { target c++11 } } + +#include + +// LWG 2993. reference_wrapper conversion from T&& + +static_assert(std::is_convertible, + std::reference_wrapper>::value, + "LWG 2993 enables qualification conversions"); + +// The comments below are taken from the issue discussion and describe the +// behaviour before the resolution of LWG 2993. There should be no errors now. + +struct convertible_from_int { convertible_from_int(int) { } }; + +void +test01() +{ + + void meow(std::reference_wrapper); //#1 + void meow(convertible_from_int); //#2 + // error, ambiguous; would unambiguously call #2 if #1 instead took int& + meow(0); +} + +void +test02() +{ + std::reference_wrapper purr(); + + // error, ambiguous: ICS exists from int prvalue to + // reference_wrapper and from reference_wrapper to int + auto x = true ? purr() : 0; + + // error: no member 'type' because the conditional + // expression is ill-formed + using t = std::common_type_t, int>; +}