diff options
author | Jonathan Wakely <jwakely@redhat.com> | 2019-02-14 15:08:33 +0000 |
---|---|---|
committer | Jonathan Wakely <redi@gcc.gnu.org> | 2019-02-14 15:08:33 +0000 |
commit | b7dbc6723a622c22140206005bfb1eb9ac7593f9 (patch) | |
tree | a6f827ea26d8782bc9139e813dfb2fc55e163674 | |
parent | 6461bdc48fa3f98015584953598a83f8c7caa506 (diff) | |
download | gcc-b7dbc6723a622c22140206005bfb1eb9ac7593f9.zip gcc-b7dbc6723a622c22140206005bfb1eb9ac7593f9.tar.gz gcc-b7dbc6723a622c22140206005bfb1eb9ac7593f9.tar.bz2 |
DR 2586 fix value category in uses-allocator checks
Because uses-allocator construction is invariably done with a const
lvalue the __uses_alloc helper should use a const lvalue for the
is_constructible checks. Otherwise, it can detect that the type can be
constructed from an rvalue, and then an error happens when a const
lvalue is passed to the constructor instead.
Prior to LWG DR 2586 scoped_allocator_adaptor incorrectly used an rvalue
type in the is_constructible check and then used a non-const lvalue for
the actual construction. The other components using uses-allocator
construction (tuple and polymorphic_allocator) have always done so with
a const lvalue allocator, although the use of __use_alloc in our
implementation meant they behaved the same as scoped_allocator_adaptor
and incorrectly used rvalues for the is_constructible checks.
In C++20 the P0591R4 changes mean that all uses-allocator construction
is defined in terms of the new uses_allocator_construction_args
functions, which always use a const lvalue allocator.
The changes in this patch ensure that the __use_alloc helper correctly
matches the requirements in the standard, consistently using a const
lvalue allocator for the is_constructible checks and the actual
constructor arguments.
* doc/xml/manual/intro.xml: Document LWG 2586 status.
* include/bits/uses_allocator.h (__uses_alloc): Use const lvalue
allocator type in is_constructible checks.
* testsuite/20_util/scoped_allocator/69293_neg.cc: Adjust dg-error.
* testsuite/20_util/scoped_allocator/dr2586.cc: New test.
* testsuite/20_util/tuple/cons/allocators.cc: Add test using
problematic type from LWG 2586 discussion.
* testsuite/20_util/uses_allocator/69293_neg.cc: Adjust dg-error.
* testsuite/20_util/uses_allocator/cons_neg.cc: Likewise.
From-SVN: r268882
-rw-r--r-- | libstdc++-v3/ChangeLog | 10 | ||||
-rw-r--r-- | libstdc++-v3/doc/xml/manual/intro.xml | 8 | ||||
-rw-r--r-- | libstdc++-v3/include/bits/uses_allocator.h | 11 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/20_util/scoped_allocator/69293_neg.cc | 2 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/20_util/scoped_allocator/dr2586.cc | 34 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/20_util/tuple/cons/allocators.cc | 14 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/20_util/uses_allocator/69293_neg.cc | 2 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/20_util/uses_allocator/cons_neg.cc | 2 |
8 files changed, 76 insertions, 7 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 932b807..4790afb 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,5 +1,15 @@ 2019-02-14 Jonathan Wakely <jwakely@redhat.com> + * doc/xml/manual/intro.xml: Document LWG 2586 status. + * include/bits/uses_allocator.h (__uses_alloc): Use const lvalue + allocator type in is_constructible checks. + * testsuite/20_util/scoped_allocator/69293_neg.cc: Adjust dg-error. + * testsuite/20_util/scoped_allocator/dr2586.cc: New test. + * testsuite/20_util/tuple/cons/allocators.cc: Add test using + problematic type from LWG 2586 discussion. + * testsuite/20_util/uses_allocator/69293_neg.cc: Adjust dg-error. + * testsuite/20_util/uses_allocator/cons_neg.cc: Likewise. + * configure.ac: Check for C11 timespec_get function. * crossconfig.m4 (freebsd, linux, gnu, cygwin, solaris, netbsd) (openbsd): Likewise diff --git a/libstdc++-v3/doc/xml/manual/intro.xml b/libstdc++-v3/doc/xml/manual/intro.xml index 656e32b..9761b82 100644 --- a/libstdc++-v3/doc/xml/manual/intro.xml +++ b/libstdc++-v3/doc/xml/manual/intro.xml @@ -1142,6 +1142,14 @@ requirements of the license of GCC. <listitem><para>Add new constructor. </para></listitem></varlistentry> + <varlistentry xml:id="manual.bugs.dr2586"><term><link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="&DR;#2586">2586</link>: + <emphasis>Wrong value category used in <code>scoped_allocator_adaptor::construct()</code> + </emphasis> + </term> + <listitem><para>Change internal helper for uses-allocator construction + to always check using const lvalue allocators. + </para></listitem></varlistentry> + <varlistentry xml:id="manual.bugs.dr2684"><term><link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="&DR;#2684">2684</link>: <emphasis><code>priority_queue</code> lacking comparator typedef </emphasis> diff --git a/libstdc++-v3/include/bits/uses_allocator.h b/libstdc++-v3/include/bits/uses_allocator.h index a118f69..015828b 100644 --- a/libstdc++-v3/include/bits/uses_allocator.h +++ b/libstdc++-v3/include/bits/uses_allocator.h @@ -87,14 +87,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _Tp, typename _Alloc, typename... _Args> struct __uses_alloc<true, _Tp, _Alloc, _Args...> : conditional< - is_constructible<_Tp, allocator_arg_t, _Alloc, _Args...>::value, + is_constructible<_Tp, allocator_arg_t, const _Alloc&, _Args...>::value, __uses_alloc1<_Alloc>, __uses_alloc2<_Alloc>>::type { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 2586. Wrong value category used in scoped_allocator_adaptor::construct static_assert(__or_< - is_constructible<_Tp, allocator_arg_t, _Alloc, _Args...>, - is_constructible<_Tp, _Args..., _Alloc>>::value, "construction with" - " an allocator must be possible if uses_allocator is true"); + is_constructible<_Tp, allocator_arg_t, const _Alloc&, _Args...>, + is_constructible<_Tp, _Args..., const _Alloc&>>::value, + "construction with an allocator must be possible" + " if uses_allocator is true"); }; template<typename _Tp, typename _Alloc, typename... _Args> diff --git a/libstdc++-v3/testsuite/20_util/scoped_allocator/69293_neg.cc b/libstdc++-v3/testsuite/20_util/scoped_allocator/69293_neg.cc index bdd14de..69f7280 100644 --- a/libstdc++-v3/testsuite/20_util/scoped_allocator/69293_neg.cc +++ b/libstdc++-v3/testsuite/20_util/scoped_allocator/69293_neg.cc @@ -46,5 +46,5 @@ test01() scoped_alloc sa; auto p = sa.allocate(1); sa.construct(p); // this is required to be ill-formed - // { dg-error "static assertion failed" "" { target *-*-* } 96 } + // { dg-error "failed: .* uses_allocator is true" "" { target *-*-* } 0 } } diff --git a/libstdc++-v3/testsuite/20_util/scoped_allocator/dr2586.cc b/libstdc++-v3/testsuite/20_util/scoped_allocator/dr2586.cc new file mode 100644 index 0000000..11aab8a --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/scoped_allocator/dr2586.cc @@ -0,0 +1,34 @@ +// Copyright (C) 2019 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 +// <http://www.gnu.org/licenses/>. + +// { dg-do compile { target c++11 } } + +#include <memory> +#include <scoped_allocator> + +// DR 2586. Wrong value category used in scoped_allocator_adaptor::construct() + +struct X { + using allocator_type = std::allocator<X>; + X(std::allocator_arg_t, allocator_type&&) { } + X(const allocator_type&) { } +}; + +int main() { + std::scoped_allocator_adaptor<std::allocator<X>> sa; + sa.construct(sa.allocate(1)); +} diff --git a/libstdc++-v3/testsuite/20_util/tuple/cons/allocators.cc b/libstdc++-v3/testsuite/20_util/tuple/cons/allocators.cc index 2951de0..92938ec 100644 --- a/libstdc++-v3/testsuite/20_util/tuple/cons/allocators.cc +++ b/libstdc++-v3/testsuite/20_util/tuple/cons/allocators.cc @@ -181,9 +181,23 @@ void test02() test_type empty = make_tuple(); } +void test03() +{ + struct dr2586 + { + using allocator_type = std::allocator<int>; + dr2586(std::allocator_arg_t, allocator_type&&) { } + dr2586(const allocator_type&) { } + }; + + const dr2586::allocator_type a; + std::tuple<dr2586> t{std::allocator_arg, a}; +} + int main() { test01(); test02(); + test03(); return 0; } diff --git a/libstdc++-v3/testsuite/20_util/uses_allocator/69293_neg.cc b/libstdc++-v3/testsuite/20_util/uses_allocator/69293_neg.cc index 575fe54..8f2d4b1 100644 --- a/libstdc++-v3/testsuite/20_util/uses_allocator/69293_neg.cc +++ b/libstdc++-v3/testsuite/20_util/uses_allocator/69293_neg.cc @@ -44,5 +44,5 @@ test01() { alloc_type a; std::tuple<X> t(std::allocator_arg, a); // this is required to be ill-formed - // { dg-error "static assertion failed" "" { target *-*-* } 96 } + // { dg-error "failed: .* uses_allocator is true" "" { target *-*-* } 0 } } diff --git a/libstdc++-v3/testsuite/20_util/uses_allocator/cons_neg.cc b/libstdc++-v3/testsuite/20_util/uses_allocator/cons_neg.cc index 021d56c..abad4ec 100644 --- a/libstdc++-v3/testsuite/20_util/uses_allocator/cons_neg.cc +++ b/libstdc++-v3/testsuite/20_util/uses_allocator/cons_neg.cc @@ -43,4 +43,4 @@ void test01() tuple<Type> t(allocator_arg, a, 1); } -// { dg-error "static assertion failed" "" { target *-*-* } 96 } +// { dg-error "failed: .* uses_allocator is true" "" { target *-*-* } 0 } |