mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-22 21:51:36 +08:00
re PR libstdc++/60497 (unique_ptr<T> tries to complete its type T even though it's not required to be a complete type)
PR libstdc++/60497 * include/debug/array (get): Qualify call to other get overload. * include/profile/array (get): Likewise. * include/std/array (get): Likewise. * include/std/functional (_Mu, _Bind, _Bind_result): Qualify std::get. * include/std/mutex (unique_lock, call_once): Use __addressof. (__unlock_impl): Remove unused template. (__try_to_lock): Declare inline. (__try_lock_impl::__do_try_lock): Qualify function calls. (lock): Avoid narrowing conversion. * testsuite/20_util/bind/60497.cc: New. * testsuite/23_containers/array/element_access/60497.cc: New. * testsuite/30_threads/call_once/60497.cc: New. * testsuite/30_threads/unique_lock/cons/60497.cc: New. From-SVN: r210388
This commit is contained in:
parent
54fde020cc
commit
b82f988e8d
@ -6,6 +6,21 @@
|
||||
* testsuite/20_util/tuple/60497.cc: Test accessing rvalues.
|
||||
* testsuite/20_util/tuple/comparison_operators/overloaded.cc: New.
|
||||
|
||||
PR libstdc++/60497
|
||||
* include/debug/array (get): Qualify call to other get overload.
|
||||
* include/profile/array (get): Likewise.
|
||||
* include/std/array (get): Likewise.
|
||||
* include/std/functional (_Mu, _Bind, _Bind_result): Qualify std::get.
|
||||
* include/std/mutex (unique_lock, call_once): Use __addressof.
|
||||
(__unlock_impl): Remove unused template.
|
||||
(__try_to_lock): Declare inline.
|
||||
(__try_lock_impl::__do_try_lock): Qualify function calls.
|
||||
(lock): Avoid narrowing conversion.
|
||||
* testsuite/20_util/bind/60497.cc: New.
|
||||
* testsuite/23_containers/array/element_access/60497.cc: New.
|
||||
* testsuite/30_threads/call_once/60497.cc: New.
|
||||
* testsuite/30_threads/unique_lock/cons/60497.cc: New.
|
||||
|
||||
2014-05-09 Jonathan Wakely <jwakely@redhat.com>
|
||||
|
||||
* config/abi/pre/gnu.ver (GLIBCXX_3.4.20): Correct regex_error export.
|
||||
|
@ -278,7 +278,7 @@ namespace __debug
|
||||
get(array<_Tp, _Nm>&& __arr) noexcept
|
||||
{
|
||||
static_assert(_Int < _Nm, "index is out of bounds");
|
||||
return std::move(get<_Int>(__arr));
|
||||
return std::move(__debug::get<_Int>(__arr));
|
||||
}
|
||||
|
||||
template<std::size_t _Int, typename _Tp, std::size_t _Nm>
|
||||
|
@ -240,7 +240,7 @@ namespace __profile
|
||||
get(array<_Tp, _Nm>&& __arr) noexcept
|
||||
{
|
||||
static_assert(_Int < _Nm, "index is out of bounds");
|
||||
return std::move(get<_Int>(__arr));
|
||||
return std::move(__profile::get<_Int>(__arr));
|
||||
}
|
||||
|
||||
template<std::size_t _Int, typename _Tp, std::size_t _Nm>
|
||||
|
@ -281,7 +281,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
|
||||
get(array<_Tp, _Nm>&& __arr) noexcept
|
||||
{
|
||||
static_assert(_Int < _Nm, "index is out of bounds");
|
||||
return std::move(get<_Int>(__arr));
|
||||
return std::move(_GLIBCXX_STD_C::get<_Int>(__arr));
|
||||
}
|
||||
|
||||
template<std::size_t _Int, typename _Tp, std::size_t _Nm>
|
||||
|
@ -1120,7 +1120,7 @@ _GLIBCXX_HAS_NESTED_TYPE(result_type)
|
||||
const _Index_tuple<_Indexes...>&) const volatile
|
||||
-> decltype(__arg(declval<_Args>()...))
|
||||
{
|
||||
return __arg(std::forward<_Args>(get<_Indexes>(__tuple))...);
|
||||
return __arg(std::forward<_Args>(std::get<_Indexes>(__tuple))...);
|
||||
}
|
||||
};
|
||||
|
||||
@ -1261,7 +1261,7 @@ _GLIBCXX_HAS_NESTED_TYPE(result_type)
|
||||
__call(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>)
|
||||
{
|
||||
return _M_f(_Mu<_Bound_args>()
|
||||
(get<_Indexes>(_M_bound_args), __args)...);
|
||||
(std::get<_Indexes>(_M_bound_args), __args)...);
|
||||
}
|
||||
|
||||
// Call as const
|
||||
@ -1270,7 +1270,7 @@ _GLIBCXX_HAS_NESTED_TYPE(result_type)
|
||||
__call_c(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>) const
|
||||
{
|
||||
return _M_f(_Mu<_Bound_args>()
|
||||
(get<_Indexes>(_M_bound_args), __args)...);
|
||||
(std::get<_Indexes>(_M_bound_args), __args)...);
|
||||
}
|
||||
|
||||
// Call as volatile
|
||||
@ -1393,7 +1393,7 @@ _GLIBCXX_HAS_NESTED_TYPE(result_type)
|
||||
typename __disable_if_void<_Res>::type = 0)
|
||||
{
|
||||
return _M_f(_Mu<_Bound_args>()
|
||||
(get<_Indexes>(_M_bound_args), __args)...);
|
||||
(std::get<_Indexes>(_M_bound_args), __args)...);
|
||||
}
|
||||
|
||||
// Call unqualified, return void
|
||||
@ -1403,7 +1403,7 @@ _GLIBCXX_HAS_NESTED_TYPE(result_type)
|
||||
typename __enable_if_void<_Res>::type = 0)
|
||||
{
|
||||
_M_f(_Mu<_Bound_args>()
|
||||
(get<_Indexes>(_M_bound_args), __args)...);
|
||||
(std::get<_Indexes>(_M_bound_args), __args)...);
|
||||
}
|
||||
|
||||
// Call as const
|
||||
@ -1413,7 +1413,7 @@ _GLIBCXX_HAS_NESTED_TYPE(result_type)
|
||||
typename __disable_if_void<_Res>::type = 0) const
|
||||
{
|
||||
return _M_f(_Mu<_Bound_args>()
|
||||
(get<_Indexes>(_M_bound_args), __args)...);
|
||||
(std::get<_Indexes>(_M_bound_args), __args)...);
|
||||
}
|
||||
|
||||
// Call as const, return void
|
||||
@ -1423,7 +1423,7 @@ _GLIBCXX_HAS_NESTED_TYPE(result_type)
|
||||
typename __enable_if_void<_Res>::type = 0) const
|
||||
{
|
||||
_M_f(_Mu<_Bound_args>()
|
||||
(get<_Indexes>(_M_bound_args), __args)...);
|
||||
(std::get<_Indexes>(_M_bound_args), __args)...);
|
||||
}
|
||||
|
||||
// Call as volatile
|
||||
|
@ -400,22 +400,22 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
{ }
|
||||
|
||||
explicit unique_lock(mutex_type& __m)
|
||||
: _M_device(&__m), _M_owns(false)
|
||||
: _M_device(std::__addressof(__m)), _M_owns(false)
|
||||
{
|
||||
lock();
|
||||
_M_owns = true;
|
||||
}
|
||||
|
||||
unique_lock(mutex_type& __m, defer_lock_t) noexcept
|
||||
: _M_device(&__m), _M_owns(false)
|
||||
: _M_device(std::__addressof(__m)), _M_owns(false)
|
||||
{ }
|
||||
|
||||
unique_lock(mutex_type& __m, try_to_lock_t)
|
||||
: _M_device(&__m), _M_owns(_M_device->try_lock())
|
||||
: _M_device(std::__addressof(__m)), _M_owns(_M_device->try_lock())
|
||||
{ }
|
||||
|
||||
unique_lock(mutex_type& __m, adopt_lock_t)
|
||||
: _M_device(&__m), _M_owns(true)
|
||||
: _M_device(std::__addressof(__m)), _M_owns(true)
|
||||
{
|
||||
// XXX calling thread owns mutex
|
||||
}
|
||||
@ -423,13 +423,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
template<typename _Clock, typename _Duration>
|
||||
unique_lock(mutex_type& __m,
|
||||
const chrono::time_point<_Clock, _Duration>& __atime)
|
||||
: _M_device(&__m), _M_owns(_M_device->try_lock_until(__atime))
|
||||
: _M_device(std::__addressof(__m)),
|
||||
_M_owns(_M_device->try_lock_until(__atime))
|
||||
{ }
|
||||
|
||||
template<typename _Rep, typename _Period>
|
||||
unique_lock(mutex_type& __m,
|
||||
const chrono::duration<_Rep, _Period>& __rtime)
|
||||
: _M_device(&__m), _M_owns(_M_device->try_lock_for(__rtime))
|
||||
: _M_device(std::__addressof(__m)),
|
||||
_M_owns(_M_device->try_lock_for(__rtime))
|
||||
{ }
|
||||
|
||||
~unique_lock()
|
||||
@ -563,37 +565,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
bool _M_owns; // XXX use atomic_bool
|
||||
};
|
||||
|
||||
/// Partial specialization for unique_lock objects.
|
||||
/// Swap overload for unique_lock objects.
|
||||
template<typename _Mutex>
|
||||
inline void
|
||||
swap(unique_lock<_Mutex>& __x, unique_lock<_Mutex>& __y) noexcept
|
||||
{ __x.swap(__y); }
|
||||
|
||||
template<int _Idx>
|
||||
struct __unlock_impl
|
||||
{
|
||||
template<typename... _Lock>
|
||||
static void
|
||||
__do_unlock(tuple<_Lock&...>& __locks)
|
||||
{
|
||||
std::get<_Idx>(__locks).unlock();
|
||||
__unlock_impl<_Idx - 1>::__do_unlock(__locks);
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct __unlock_impl<-1>
|
||||
{
|
||||
template<typename... _Lock>
|
||||
static void
|
||||
__do_unlock(tuple<_Lock&...>&)
|
||||
{ }
|
||||
};
|
||||
|
||||
template<typename _Lock>
|
||||
unique_lock<_Lock>
|
||||
inline unique_lock<_Lock>
|
||||
__try_to_lock(_Lock& __l)
|
||||
{ return unique_lock<_Lock>(__l, try_to_lock); }
|
||||
{ return unique_lock<_Lock>{__l, try_to_lock}; }
|
||||
|
||||
template<int _Idx, bool _Continue = true>
|
||||
struct __try_lock_impl
|
||||
@ -603,11 +584,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
__do_try_lock(tuple<_Lock&...>& __locks, int& __idx)
|
||||
{
|
||||
__idx = _Idx;
|
||||
auto __lock = __try_to_lock(std::get<_Idx>(__locks));
|
||||
auto __lock = std::__try_to_lock(std::get<_Idx>(__locks));
|
||||
if (__lock.owns_lock())
|
||||
{
|
||||
__try_lock_impl<_Idx + 1, _Idx + 2 < sizeof...(_Lock)>::
|
||||
__do_try_lock(__locks, __idx);
|
||||
constexpr bool __cont = _Idx + 2 < sizeof...(_Lock);
|
||||
using __try_locker = __try_lock_impl<_Idx + 1, __cont>;
|
||||
__try_locker::__do_try_lock(__locks, __idx);
|
||||
if (__idx == -1)
|
||||
__lock.release();
|
||||
}
|
||||
@ -622,7 +604,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
__do_try_lock(tuple<_Lock&...>& __locks, int& __idx)
|
||||
{
|
||||
__idx = _Idx;
|
||||
auto __lock = __try_to_lock(std::get<_Idx>(__locks));
|
||||
auto __lock = std::__try_to_lock(std::get<_Idx>(__locks));
|
||||
if (__lock.owns_lock())
|
||||
{
|
||||
__idx = -1;
|
||||
@ -665,16 +647,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
* and unlock(). If the call exits via an exception any locks that were
|
||||
* obtained will be released.
|
||||
*/
|
||||
template<typename _L1, typename _L2, typename ..._L3>
|
||||
template<typename _L1, typename _L2, typename... _L3>
|
||||
void
|
||||
lock(_L1& __l1, _L2& __l2, _L3&... __l3)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
using __try_locker = __try_lock_impl<0, sizeof...(_L3) != 0>;
|
||||
unique_lock<_L1> __first(__l1);
|
||||
int __idx;
|
||||
auto __locks = std::tie(__l2, __l3...);
|
||||
__try_lock_impl<0, sizeof...(_L3)>::__do_try_lock(__locks, __idx);
|
||||
__try_locker::__do_try_lock(__locks, __idx);
|
||||
if (__idx == -1)
|
||||
{
|
||||
__first.release();
|
||||
@ -735,7 +718,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
#ifdef _GLIBCXX_HAVE_TLS
|
||||
auto __bound_functor = std::__bind_simple(std::forward<_Callable>(__f),
|
||||
std::forward<_Args>(__args)...);
|
||||
__once_callable = &__bound_functor;
|
||||
__once_callable = std::__addressof(__bound_functor);
|
||||
__once_call = &__once_call_impl<decltype(__bound_functor)>;
|
||||
#else
|
||||
unique_lock<mutex> __functor_lock(__get_once_mutex());
|
||||
|
40
libstdc++-v3/testsuite/20_util/bind/60497.cc
Normal file
40
libstdc++-v3/testsuite/20_util/bind/60497.cc
Normal file
@ -0,0 +1,40 @@
|
||||
// { dg-options "-std=gnu++11" }
|
||||
// { dg-do compile }
|
||||
|
||||
// Copyright (C) 2014 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/>.
|
||||
|
||||
// libstdc++/60497
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
struct A;
|
||||
template<typename T> struct B { T t; };
|
||||
|
||||
using UP = std::unique_ptr<B<A>>;
|
||||
|
||||
bool f(UP&, UP&) { return true; }
|
||||
|
||||
bool g(UP& p)
|
||||
{
|
||||
auto binder = std::bind(f, std::ref(p), std::placeholders::_1);
|
||||
bool b1 = binder(std::ref(p));
|
||||
auto binderbinder = std::bind(binder, std::placeholders::_1);
|
||||
bool b2 = binderbinder(std::ref(p));
|
||||
return b1 && b2;
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
// { dg-options "-std=gnu++11" }
|
||||
// { dg-do compile }
|
||||
//
|
||||
// Copyright (C) 2014 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/>.
|
||||
|
||||
// libstdc++/60497
|
||||
|
||||
#include <array>
|
||||
#include <debug/array>
|
||||
#include <profile/array>
|
||||
#include <memory>
|
||||
|
||||
struct A;
|
||||
template<typename T> struct B { T t; };
|
||||
|
||||
std::array<B<A>*, 1> a;
|
||||
auto b = std::get<0>(std::move(a));
|
||||
|
||||
std::__debug::array<B<A>*, 1> c;
|
||||
auto d = std::__debug::get<0>(std::move(c));
|
||||
|
||||
std::__profile::array<B<A>*, 1> e;
|
||||
auto f = std::__profile::get<0>(std::move(e));
|
41
libstdc++-v3/testsuite/30_threads/call_once/60497.cc
Normal file
41
libstdc++-v3/testsuite/30_threads/call_once/60497.cc
Normal file
@ -0,0 +1,41 @@
|
||||
// { dg-do compile }
|
||||
// { dg-options " -std=gnu++11 -pthread" { target *-*-freebsd* *-*-netbsd* *-*-linux* *-*-gnu* powerpc-ibm-aix* } }
|
||||
// { dg-options " -std=gnu++11 -pthreads" { target *-*-solaris* } }
|
||||
// { dg-options " -std=gnu++11 " { target *-*-cygwin *-*-darwin* } }
|
||||
// { dg-require-cstdint "" }
|
||||
// { dg-require-gthreads "" }
|
||||
|
||||
// Copyright (C) 2014 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/>.
|
||||
|
||||
// libstdc++/60497
|
||||
|
||||
#include <mutex>
|
||||
#include <memory>
|
||||
|
||||
struct A;
|
||||
template<typename T> struct B { T t; };
|
||||
|
||||
using UP = std::unique_ptr<B<A>>;
|
||||
|
||||
void f(UP&) { }
|
||||
|
||||
void g(UP& p)
|
||||
{
|
||||
std::once_flag o;
|
||||
std::call_once(o, f, std::ref(p));
|
||||
}
|
49
libstdc++-v3/testsuite/30_threads/unique_lock/cons/60497.cc
Normal file
49
libstdc++-v3/testsuite/30_threads/unique_lock/cons/60497.cc
Normal file
@ -0,0 +1,49 @@
|
||||
// { dg-do compile }
|
||||
// { dg-options " -std=gnu++11 " }
|
||||
|
||||
// Copyright (C) 2014 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/>.
|
||||
|
||||
// libstdc++/60497
|
||||
|
||||
#include <mutex>
|
||||
#include <memory>
|
||||
|
||||
struct A;
|
||||
template<typename T> struct B { T t; };
|
||||
|
||||
template<typename Dummy>
|
||||
struct Lockable
|
||||
{
|
||||
void lock();
|
||||
void unlock();
|
||||
bool try_lock();
|
||||
};
|
||||
|
||||
using test_type = Lockable<std::unique_ptr<B<A>>>;
|
||||
|
||||
void test01()
|
||||
{
|
||||
test_type l;
|
||||
std::unique_lock<test_type> ul(l);
|
||||
}
|
||||
|
||||
void test02()
|
||||
{
|
||||
test_type l1, l2, l3;
|
||||
std::lock(l1, l2, l3);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user