From patchwork Tue May 13 17:27:17 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Wakely X-Patchwork-Id: 348492 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 377171400D4 for ; Wed, 14 May 2014 03:27:31 +1000 (EST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:subject:message-id:mime-version:content-type; q=dns; s= default; b=lmi1aR/qwO0ygVk5UY8aztFmlo/Im2UPzGwtSRrHp9yKi8IB2GJwN vZU/yo0TMrgrgxchjZSgkcdidBj5jewWl5Ufb26hR2S0bwhBFvP0B/uXO7xKxLZn NF/d/baQH5Cr+AyiQgbMkaGXrkkvKuiSi04mn1aPvg7UkFNmZF0K1I= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:subject:message-id:mime-version:content-type; s= default; bh=vn/JpSFf0ogzyc5dzpqGGZu83N8=; b=ED4mroiqW+AlKNO6SZiz 6F3688NHLgveojUXVPPPdqRQh2X4yv+LzlYClyVBIcAa6hrLTFPt421yxXg1l9+z gagB+OrxGmZZaiqQmYvqRzAvkuMuW5KQlkPjWabY1x9bvWwVXM9j4+Ap/M7bjZ9R C3G0OZA9ik+UYVn4jZKG77I= Received: (qmail 7150 invoked by alias); 13 May 2014 17:27:24 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 7127 invoked by uid 89); 13 May 2014 17:27:23 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.4 required=5.0 tests=AWL, BAYES_00, RP_MATCHES_RCVD, SPF_HELO_PASS, SPF_PASS autolearn=ham version=3.3.2 X-Spam-User: qpsmtpd, 2 recipients X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 13 May 2014 17:27:21 +0000 Received: from int-mx02.intmail.prod.int.phx2.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s4DHRIiS026494 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Tue, 13 May 2014 13:27:19 -0400 Received: from localhost (vpn1-7-203.ams2.redhat.com [10.36.7.203]) by int-mx02.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id s4DHRHxg021996; Tue, 13 May 2014 13:27:18 -0400 Date: Tue, 13 May 2014 18:27:17 +0100 From: Jonathan Wakely To: libstdc++@gcc.gnu.org, gcc-patches@gcc.gnu.org Subject: [patch] libstdc++/60497 again - more std::get qualification Message-ID: <20140513172716.GW10556@redhat.com> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.23 (2014-03-12) This patch ensures everywhere we use std::get we qualify it. It also changes some uses of the built-in operator& with std::__addressof() which doesn't do ADL and so doesn't try to complete its argument. As noted in the bug report, the operator& part of this affects most of the library, so I don't think it's feasible to do anything about it right now. Tested x86_64-linux, committed to trunk. commit d3d2b701493ab363cc9820283bf78250f5a52d31 Author: Jonathan Wakely Date: Tue May 13 15:35:29 2014 +0100 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. diff --git a/libstdc++-v3/include/debug/array b/libstdc++-v3/include/debug/array index ef01c98..2266a53 100644 --- a/libstdc++-v3/include/debug/array +++ b/libstdc++-v3/include/debug/array @@ -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 diff --git a/libstdc++-v3/include/profile/array b/libstdc++-v3/include/profile/array index 1c38b05..1a43a48 100644 --- a/libstdc++-v3/include/profile/array +++ b/libstdc++-v3/include/profile/array @@ -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 diff --git a/libstdc++-v3/include/std/array b/libstdc++-v3/include/std/array index 67680d6..22947ce 100644 --- a/libstdc++-v3/include/std/array +++ b/libstdc++-v3/include/std/array @@ -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 diff --git a/libstdc++-v3/include/std/functional b/libstdc++-v3/include/std/functional index 295022d..2bc3d8d 100644 --- a/libstdc++-v3/include/std/functional +++ b/libstdc++-v3/include/std/functional @@ -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 diff --git a/libstdc++-v3/include/std/mutex b/libstdc++-v3/include/std/mutex index 0b481d6..3d70754 100644 --- a/libstdc++-v3/include/std/mutex +++ b/libstdc++-v3/include/std/mutex @@ -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 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 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 inline void swap(unique_lock<_Mutex>& __x, unique_lock<_Mutex>& __y) noexcept { __x.swap(__y); } - template - struct __unlock_impl - { - template - 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 - static void - __do_unlock(tuple<_Lock&...>&) - { } - }; - template - 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 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 + template 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; #else unique_lock __functor_lock(__get_once_mutex()); diff --git a/libstdc++-v3/testsuite/20_util/bind/60497.cc b/libstdc++-v3/testsuite/20_util/bind/60497.cc new file mode 100644 index 0000000..759c9d8 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/bind/60497.cc @@ -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 +// . + +// libstdc++/60497 + +#include +#include + +struct A; +template struct B { T t; }; + +using UP = std::unique_ptr>; + +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; +} diff --git a/libstdc++-v3/testsuite/23_containers/array/element_access/60497.cc b/libstdc++-v3/testsuite/23_containers/array/element_access/60497.cc new file mode 100644 index 0000000..14932a1 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/array/element_access/60497.cc @@ -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 +// . + +// libstdc++/60497 + +#include +#include +#include +#include + +struct A; +template struct B { T t; }; + +std::array*, 1> a; +auto b = std::get<0>(std::move(a)); + +std::__debug::array*, 1> c; +auto d = std::__debug::get<0>(std::move(c)); + +std::__profile::array*, 1> e; +auto f = std::__profile::get<0>(std::move(e)); diff --git a/libstdc++-v3/testsuite/30_threads/call_once/60497.cc b/libstdc++-v3/testsuite/30_threads/call_once/60497.cc new file mode 100644 index 0000000..76cc710 --- /dev/null +++ b/libstdc++-v3/testsuite/30_threads/call_once/60497.cc @@ -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 +// . + +// libstdc++/60497 + +#include +#include + +struct A; +template struct B { T t; }; + +using UP = std::unique_ptr>; + +void f(UP&) { } + +void g(UP& p) +{ + std::once_flag o; + std::call_once(o, f, std::ref(p)); +} diff --git a/libstdc++-v3/testsuite/30_threads/unique_lock/cons/60497.cc b/libstdc++-v3/testsuite/30_threads/unique_lock/cons/60497.cc new file mode 100644 index 0000000..19be845 --- /dev/null +++ b/libstdc++-v3/testsuite/30_threads/unique_lock/cons/60497.cc @@ -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 +// . + +// libstdc++/60497 + +#include +#include + +struct A; +template struct B { T t; }; + +template +struct Lockable +{ + void lock(); + void unlock(); + bool try_lock(); +}; + +using test_type = Lockable>>; + +void test01() +{ + test_type l; + std::unique_lock ul(l); +} + +void test02() +{ + test_type l1, l2, l3; + std::lock(l1, l2, l3); +}