+2019-08-30 Jonathan Wakely <jwakely@redhat.com>
+
+ PR libstdc++/89164
+ * include/bits/stl_algobase.h (__copy_move): Give descriptive names
+ to template parameters.
+ * include/bits/stl_uninitialized.h (uninitialized_copy)
+ (uninitialized_fill, uninitialized_fill_n): Add static assertions to
+ diagnose invalid uses.
+ * testsuite/20_util/specialized_algorithms/uninitialized_copy/1.cc:
+ Adjust expected error.
+ * testsuite/20_util/specialized_algorithms/uninitialized_copy/89164.cc:
+ New test.
+ * testsuite/20_util/specialized_algorithms/uninitialized_copy_n/
+ 89164.cc: New test.
+ * testsuite/20_util/specialized_algorithms/uninitialized_fill/89164.cc:
+ New test.
+ * testsuite/20_util/specialized_algorithms/uninitialized_fill_n/
+ 89164.cc: New test.
+ * testsuite/23_containers/vector/cons/89164.cc: New test.
+ * testsuite/23_containers/vector/cons/89164_c++17.cc: New test.
+
2019-08-29 Jonathan Wakely <jwakely@redhat.com>
PR libstdc++/91067
// (2) If we're using random access iterators, then write the loop as
// a for loop with an explicit count.
- template<bool, bool, typename>
+ template<bool _IsMove, bool _IsSimple, typename _Category>
struct __copy_move
{
template<typename _II, typename _OI>
#if __cplusplus < 201103L
const bool __assignable = true;
#else
- // trivial types can have deleted assignment
+ // Trivial types can have deleted copy constructor, but the std::copy
+ // optimization that uses memmove would happily "copy" them anyway.
+ static_assert(is_constructible<_ValueType2, decltype(*__first)>::value,
+ "result type must be constructible from value type of input range");
+
typedef typename iterator_traits<_InputIterator>::reference _RefType1;
typedef typename iterator_traits<_ForwardIterator>::reference _RefType2;
+ // Trivial types can have deleted assignment, so using std::copy
+ // would be ill-formed. Require assignability before using std::copy:
const bool __assignable = is_assignable<_RefType2, _RefType1>::value;
#endif
#if __cplusplus < 201103L
const bool __assignable = true;
#else
- // trivial types can have deleted assignment
+ // Trivial types can have deleted copy constructor, but the std::fill
+ // optimization that uses memmove would happily "copy" them anyway.
+ static_assert(is_constructible<_ValueType, const _Tp&>::value,
+ "result type must be constructible from input type");
+
+ // Trivial types can have deleted assignment, so using std::fill
+ // would be ill-formed. Require assignability before using std::fill:
const bool __assignable = is_copy_assignable<_ValueType>::value;
#endif
#if __cplusplus < 201103L
const bool __assignable = true;
#else
- // trivial types can have deleted assignment
+ // Trivial types can have deleted copy constructor, but the std::fill
+ // optimization that uses memmove would happily "copy" them anyway.
+ static_assert(is_constructible<_ValueType, const _Tp&>::value,
+ "result type must be constructible from input type");
+
+ // Trivial types can have deleted assignment, so using std::fill
+ // would be ill-formed. Require assignability before using std::fill:
const bool __assignable = is_copy_assignable<_ValueType>::value;
#endif
return __uninitialized_fill_n<__is_trivial(_ValueType) && __assignable>::
T t[1];
std::uninitialized_copy(t, t+1, result); // { dg-error "here" }
}
-// { dg-prune-output "use of deleted function" }
+// { dg-error "constructible from value" "" { target *-*-* } 0 }
--- /dev/null
+// 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 <vector>
+
+// PR libstdc++/89164
+
+struct X
+{
+ X() = default;
+ X(const X&) = delete;
+};
+
+void test01()
+{
+ X x[1];
+ alignas(X) unsigned char buf[sizeof(X)];
+ X* p = (X*)buf;
+
+ std::uninitialized_copy(x, x+1, p); // { dg-error "here" }
+}
+// { dg-error "must be constructible" "" { target *-*-* } 0 }
--- /dev/null
+// 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 <vector>
+
+struct X {
+ X() = default;
+ X(const X&) = delete;
+};
+
+void test01()
+{
+ X x[1];
+ alignas(X) unsigned char buf[sizeof(X)];
+ X* p = (X*)buf;
+
+ std::uninitialized_copy_n(x, 1, p); // { dg-error "here" }
+}
+// { dg-error "must be constructible" "" { target *-*-* } 0 }
--- /dev/null
+// 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 <vector>
+
+struct X {
+ X() = default;
+ X(const X&) = delete;
+};
+
+void f()
+{
+ X x;
+ alignas(X) unsigned char buf[sizeof(X)];
+ X* p = (X*)buf;
+
+ std::uninitialized_fill(p, p+1, x); // { dg-error "here" }
+}
+// { dg-error "must be constructible" "" { target *-*-* } 0 }
--- /dev/null
+// 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 <vector>
+
+struct X {
+ X() = default;
+ X(const X&) = delete;
+};
+
+void test01()
+{
+ X x;
+ alignas(X) unsigned char buf[sizeof(X)];
+ X* p = (X*)buf;
+
+ std::uninitialized_fill_n(p, 1, x); // { dg-error "here" }
+}
+// { dg-error "must be constructible" "" { target *-*-* } 0 }
--- /dev/null
+// 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 <vector>
+
+// PR libstdc++/89164
+
+struct X
+{
+ X() = default;
+ X(const X&) = delete;
+};
+
+void test01()
+{
+ X x[1];
+ // Should not be able to create vector using uninitialized_copy:
+ std::vector<X> v1{x, x+1}; // { dg-error "here" }
+
+ // Should not be able to create vector using uninitialized_fill_n:
+ std::vector<X> v2{2u, X{}}; // { dg-error "here" }
+}
+// { dg-error "constructible from value" "" { target *-*-* } 0 }
+// { dg-error "constructible from input" "" { target *-*-* } 0 }
--- /dev/null
+// 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-options "-std=gnu++17" }
+// { dg-do compile { target c++17 } }
+
+#include <vector>
+
+// PR libstdc++/89164
+
+void test01()
+{
+ X x[1];
+ // Should not be able to create vector using uninitialized_copy:
+ std::vector<X> v1{x, x+1}; // { dg-error "here" }
+
+ // Should not be able to create vector using uninitialized_fill_n:
+ std::vector<X> v2{2u, X{}}; // { dg-error "here" }
+}
+
+void test02()
+{
+#if __cplusplus >= 201703L
+ // Can create initializer_list<X> with C++17 guaranteed copy elision,
+ // but shouldn't be able to copy from it with uninitialized_copy:
+ std::vector<X> v3{X{}, X{}, X{}}; // { dg-error "here" }
+#endif
+}
+// { dg-error "constructible from value" "" { target *-*-* } 0 }
+// { dg-error "constructible from input" "" { target *-*-* } 0 }