aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Wakely <jwakely@redhat.com>2019-02-14 15:08:33 +0000
committerJonathan Wakely <redi@gcc.gnu.org>2019-02-14 15:08:33 +0000
commitb7dbc6723a622c22140206005bfb1eb9ac7593f9 (patch)
treea6f827ea26d8782bc9139e813dfb2fc55e163674
parent6461bdc48fa3f98015584953598a83f8c7caa506 (diff)
downloadgcc-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/ChangeLog10
-rw-r--r--libstdc++-v3/doc/xml/manual/intro.xml8
-rw-r--r--libstdc++-v3/include/bits/uses_allocator.h11
-rw-r--r--libstdc++-v3/testsuite/20_util/scoped_allocator/69293_neg.cc2
-rw-r--r--libstdc++-v3/testsuite/20_util/scoped_allocator/dr2586.cc34
-rw-r--r--libstdc++-v3/testsuite/20_util/tuple/cons/allocators.cc14
-rw-r--r--libstdc++-v3/testsuite/20_util/uses_allocator/69293_neg.cc2
-rw-r--r--libstdc++-v3/testsuite/20_util/uses_allocator/cons_neg.cc2
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 }