From patchwork Thu May 19 17:21:31 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Carlini X-Patchwork-Id: 96432 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]) by ozlabs.org (Postfix) with SMTP id E02EBB6F84 for ; Fri, 20 May 2011 03:23:15 +1000 (EST) Received: (qmail 31014 invoked by alias); 19 May 2011 17:23:04 -0000 Received: (qmail 30991 invoked by uid 22791); 19 May 2011 17:22:59 -0000 X-SWARE-Spam-Status: No, hits=-1.8 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_NONE X-Spam-Check-By: sourceware.org Received: from smtp208.alice.it (HELO smtp208.alice.it) (82.57.200.104) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Thu, 19 May 2011 17:22:33 +0000 Received: from [192.168.1.4] (79.52.192.9) by smtp208.alice.it (8.5.124.08) id 4C1A27161A32724A; Thu, 19 May 2011 19:22:28 +0200 Message-ID: <4DD5519B.1030008@oracle.com> Date: Thu, 19 May 2011 19:21:31 +0200 From: Paolo Carlini User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.17) Gecko/20110414 SUSE/3.1.10 Thunderbird/3.1.10 MIME-Version: 1.0 To: "gcc-patches@gcc.gnu.org" CC: libstdc++ Subject: [v3] More noexcept work on , etc X-IsSubscribed: yes 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 Hi, also exploiting the new std::is_nothrow_move_assignable, plus various fixes (added 2 testcases). Tested x86_64-linux, committed to mainline. Paolo. /////////////////// 2011-05-19 Paolo Carlini * include/std/tuple (tuple<>::operator=(tuple&&)): Specify as noexcept. (__get_helper): Likewise. (_Head_base<>::_M_head, _Tuple_impl<>::_M_head, _M_tail): Likewise. * include/bits/move.h (swap): Likewise. * include/bits/algorithmfwd.h (swap): Adjust. * include/bits/stl_pair.h (pair<>::operator=(pair&&)): Spec noexcept. * testsuite/util/testsuite_allocator.h (uneq_allocator): In C++0x mode, prefer delete to access control to make the type not copy assignable. * testsuite/util/testsuite_tr1.h: Add test classes. * testsuite/20_util/tuple/noexcept_swap.cc: New. * testsuite/20_util/tuple/noexcept_move_assign.cc: Likewise. * testsuite/25_algorithms/reverse/moveable.cc: Likewise, prefer delete to access control. * testsuite/25_algorithms/swap_ranges/moveable.cc: Likewise. * testsuite/20_util/weak_ptr/comparison/cmp_neg.cc: Adjust dg-warning line numbers. Index: include/std/tuple =================================================================== --- include/std/tuple (revision 173912) +++ include/std/tuple (working copy) @@ -85,8 +85,8 @@ _Head_base(_UHead&& __h) : _Head(std::forward<_UHead>(__h)) { } - _Head& _M_head() { return *this; } - const _Head& _M_head() const { return *this; } + _Head& _M_head() noexcept { return *this; } + const _Head& _M_head() const noexcept { return *this; } }; template @@ -102,8 +102,8 @@ _Head_base(_UHead&& __h) : _M_head_impl(std::forward<_UHead>(__h)) { } - _Head& _M_head() { return _M_head_impl; } - const _Head& _M_head() const { return _M_head_impl; } + _Head& _M_head() noexcept { return _M_head_impl; } + const _Head& _M_head() const noexcept { return _M_head_impl; } _Head _M_head_impl; }; @@ -147,11 +147,11 @@ typedef _Tuple_impl<_Idx + 1, _Tail...> _Inherited; typedef _Head_base<_Idx, _Head, std::is_empty<_Head>::value> _Base; - _Head& _M_head() { return _Base::_M_head(); } - const _Head& _M_head() const { return _Base::_M_head(); } + _Head& _M_head() noexcept { return _Base::_M_head(); } + const _Head& _M_head() const noexcept { return _Base::_M_head(); } - _Inherited& _M_tail() { return *this; } - const _Inherited& _M_tail() const { return *this; } + _Inherited& _M_tail() noexcept { return *this; } + const _Inherited& _M_tail() const noexcept { return *this; } constexpr _Tuple_impl() : _Inherited(), _Base() { } @@ -191,6 +191,8 @@ _Tuple_impl& operator=(_Tuple_impl&& __in) + noexcept(is_nothrow_move_assignable<_Head>::value + && is_nothrow_move_assignable<_Inherited>::value) { _M_head() = std::forward<_Head>(__in._M_head()); _M_tail() = std::move(__in._M_tail()); @@ -276,6 +278,7 @@ tuple& operator=(tuple&& __in) + noexcept(is_nothrow_move_assignable<_Inherited>::value) { static_cast<_Inherited&>(*this) = std::move(__in); return *this; @@ -364,7 +367,7 @@ tuple& operator=(tuple&& __in) - // noexcept has to wait is_nothrow_move_assignable + noexcept(is_nothrow_move_assignable<_Inherited>::value) { static_cast<_Inherited&>(*this) = std::move(__in); return *this; @@ -397,7 +400,7 @@ template tuple& - operator=(pair<_U1, _U2>&& __in) noexcept + operator=(pair<_U1, _U2>&& __in) { this->_M_head() = std::forward<_U1>(__in.first); this->_M_tail()._M_head() = std::forward<_U2>(__in.second); @@ -452,6 +455,7 @@ tuple& operator=(tuple&& __in) + noexcept(is_nothrow_move_assignable<_Inherited>::value) { static_cast<_Inherited&>(*this) = std::move(__in); return *this; @@ -517,12 +521,12 @@ template inline typename __add_ref<_Head>::type - __get_helper(_Tuple_impl<__i, _Head, _Tail...>& __t) + __get_helper(_Tuple_impl<__i, _Head, _Tail...>& __t) noexcept { return __t._M_head(); } template inline typename __add_c_ref<_Head>::type - __get_helper(const _Tuple_impl<__i, _Head, _Tail...>& __t) + __get_helper(const _Tuple_impl<__i, _Head, _Tail...>& __t) noexcept { return __t._M_head(); } // Return a reference (const reference, rvalue reference) to the ith element Index: include/bits/move.h =================================================================== --- include/bits/move.h (revision 173912) +++ include/bits/move.h (working copy) @@ -135,7 +135,10 @@ template inline void swap(_Tp& __a, _Tp& __b) - // noexcept has to wait is_nothrow_move_assignable +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + noexcept(is_nothrow_move_constructible<_Tp>::value + && is_nothrow_move_assignable<_Tp>::value) +#endif { // concept requirements __glibcxx_function_requires(_SGIAssignableConcept<_Tp>) Index: include/bits/stl_pair.h =================================================================== --- include/bits/stl_pair.h (revision 173912) +++ include/bits/stl_pair.h (working copy) @@ -153,7 +153,8 @@ pair& operator=(pair&& __p) - // noexcept has to wait is_nothrow_move_assignable + noexcept(is_nothrow_move_assignable<_T1>::value + && is_nothrow_move_assignable<_T2>::value) { first = std::move(__p.first); second = std::move(__p.second); Index: include/bits/algorithmfwd.h =================================================================== --- include/bits/algorithmfwd.h (revision 173912) +++ include/bits/algorithmfwd.h (working copy) @@ -549,7 +549,12 @@ template void - swap(_Tp&, _Tp&); + swap(_Tp&, _Tp&) +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + noexcept(is_nothrow_move_constructible<_Tp>::value + && is_nothrow_move_assignable<_Tp>::value) +#endif + ; template void Index: testsuite/25_algorithms/swap_ranges/moveable.cc =================================================================== --- testsuite/25_algorithms/swap_ranges/moveable.cc (revision 173912) +++ testsuite/25_algorithms/swap_ranges/moveable.cc (working copy) @@ -1,7 +1,7 @@ // { dg-do compile } // { dg-options "-std=gnu++0x" } -// Copyright (C) 2005, 2007, 2009 Free Software Foundation, Inc. +// Copyright (C) 2005, 2007, 2009, 2011 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 @@ -27,11 +27,11 @@ using __gnu_test::forward_iterator_wrapper; -class X +struct X { - X(); - X(const X&); - void operator=(const X&); + X() = delete; + X(const X&) = delete; + void operator=(const X&) = delete; }; void Index: testsuite/25_algorithms/reverse/moveable.cc =================================================================== --- testsuite/25_algorithms/reverse/moveable.cc (revision 173912) +++ testsuite/25_algorithms/reverse/moveable.cc (working copy) @@ -1,7 +1,7 @@ // { dg-do compile } // { dg-options "-std=gnu++0x" } -// Copyright (C) 2005, 2007, 2009 Free Software Foundation, Inc. +// Copyright (C) 2005, 2007, 2009, 2011 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 @@ -27,11 +27,11 @@ using __gnu_test::bidirectional_iterator_wrapper; -class X -{ - X(); - X(const X&); - void operator=(const X&); +struct X +{ + X() = delete; + X(const X&) = delete; + void operator=(const X&) = delete; }; void Index: testsuite/util/testsuite_tr1.h =================================================================== --- testsuite/util/testsuite_tr1.h (revision 173912) +++ testsuite/util/testsuite_tr1.h (working copy) @@ -240,6 +240,42 @@ DeletedMoveAssignClass& operator=(DeletedMoveAssignClass&&) = delete; }; + + struct NoexceptMoveConsNoexceptMoveAssignClass + { + NoexceptMoveConsNoexceptMoveAssignClass + (NoexceptMoveConsNoexceptMoveAssignClass&&) noexcept(true); + + NoexceptMoveConsNoexceptMoveAssignClass& + operator=(NoexceptMoveConsNoexceptMoveAssignClass&&) noexcept(true); + }; + + struct ExceptMoveConsNoexceptMoveAssignClass + { + ExceptMoveConsNoexceptMoveAssignClass + (ExceptMoveConsNoexceptMoveAssignClass&&) noexcept(false); + + ExceptMoveConsNoexceptMoveAssignClass& + operator=(ExceptMoveConsNoexceptMoveAssignClass&&) noexcept(true); + }; + + struct NoexceptMoveConsExceptMoveAssignClass + { + NoexceptMoveConsExceptMoveAssignClass + (NoexceptMoveConsExceptMoveAssignClass&&) noexcept(true); + + NoexceptMoveConsExceptMoveAssignClass& + operator=(NoexceptMoveConsExceptMoveAssignClass&&) noexcept(false); + }; + + struct ExceptMoveConsExceptMoveAssignClass + { + ExceptMoveConsExceptMoveAssignClass + (ExceptMoveConsExceptMoveAssignClass&&) noexcept(false); + + ExceptMoveConsExceptMoveAssignClass& + operator=(ExceptMoveConsExceptMoveAssignClass&&) noexcept(false); + }; #endif struct NType // neither trivial nor standard-layout Index: testsuite/util/testsuite_allocator.h =================================================================== --- testsuite/util/testsuite_allocator.h (revision 173912) +++ testsuite/util/testsuite_allocator.h (working copy) @@ -327,10 +327,19 @@ void destroy(pointer p) { p->~Tp(); } +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + // Not copy assignable... + uneq_allocator& + operator=(const uneq_allocator&) = delete; +#endif + private: + +#ifndef __GXX_EXPERIMENTAL_CXX0X__ // Not assignable... uneq_allocator& operator=(const uneq_allocator&); +#endif // ... yet swappable! friend inline void Index: testsuite/20_util/tuple/noexcept_swap.cc =================================================================== --- testsuite/20_util/tuple/noexcept_swap.cc (revision 0) +++ testsuite/20_util/tuple/noexcept_swap.cc (revision 0) @@ -0,0 +1,116 @@ +// { dg-do compile } +// { dg-options "-std=gnu++0x" } + +// 2011-05-19 Paolo Carlini +// +// Copyright (C) 2011 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 +// . + +#include +#include + +using namespace __gnu_test; + +typedef std::tuple tt1; +typedef std::tuple tt2; +typedef std::tuple tt3; +typedef std::tuple tt4; +typedef std::tuple tt5; +typedef std::tuple tt6; +typedef std::tuple tt7; +typedef std::tuple tt8; +typedef std::tuple tt9; +typedef std::tuple tt10; +typedef std::tuple tt11; +typedef std::tuple tt12; +typedef std::tuple tt13; +typedef std::tuple tt14; +typedef std::tuple tt15; +typedef std::tuple tt16; +typedef std::tuple tt17; +typedef std::tuple tt18; +typedef std::tuple tt19; +typedef std::tuple tt20; +typedef std::tuple tt21; +typedef std::tuple tt22; +typedef std::tuple tt23; +typedef std::tuple tt24; +typedef std::tuple tt25; + +static_assert(noexcept(std::declval().swap(std::declval())), + "Error"); +static_assert(noexcept(std::declval().swap(std::declval())), + "Error"); +static_assert(noexcept(std::declval().swap(std::declval())), + "Error"); +static_assert(noexcept(std::declval().swap(std::declval())), + "Error"); +static_assert(!noexcept(std::declval().swap(std::declval())), + "Error"); +static_assert(!noexcept(std::declval().swap(std::declval())), + "Error"); +static_assert(!noexcept(std::declval().swap(std::declval())), + "Error"); +static_assert(!noexcept(std::declval().swap(std::declval())), + "Error"); +static_assert(!noexcept(std::declval().swap(std::declval())), + "Error"); +static_assert(!noexcept(std::declval().swap(std::declval())), + "Error"); +static_assert(noexcept(std::declval().swap(std::declval())), + "Error"); +static_assert(noexcept(std::declval().swap(std::declval())), + "Error"); +static_assert(noexcept(std::declval().swap(std::declval())), + "Error"); +static_assert(!noexcept(std::declval().swap(std::declval())), + "Error"); +static_assert(!noexcept(std::declval().swap(std::declval())), + "Error"); +static_assert(!noexcept(std::declval().swap(std::declval())), + "Error"); +static_assert(noexcept(std::declval().swap(std::declval())), + "Error"); +static_assert(noexcept(std::declval().swap(std::declval())), + "Error"); +static_assert(noexcept(std::declval().swap(std::declval())), + "Error"); +static_assert(noexcept(std::declval().swap(std::declval())), + "Error"); +static_assert(!noexcept(std::declval().swap(std::declval())), + "Error"); +static_assert(!noexcept(std::declval().swap(std::declval())), + "Error"); +static_assert(!noexcept(std::declval().swap(std::declval())), + "Error"); +static_assert(!noexcept(std::declval().swap(std::declval())), + "Error"); Index: testsuite/20_util/tuple/noexcept_move_assign.cc =================================================================== --- testsuite/20_util/tuple/noexcept_move_assign.cc (revision 0) +++ testsuite/20_util/tuple/noexcept_move_assign.cc (revision 0) @@ -0,0 +1,59 @@ +// { dg-do compile } +// { dg-options "-std=gnu++0x" } + +// 2011-05-19 Paolo Carlini +// +// Copyright (C) 2011 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 +// . + +#include +#include + +using namespace __gnu_test; + +typedef std::tuple tt1; +typedef std::tuple tt2; +typedef std::tuple tt3; +typedef std::tuple tt4; +typedef std::tuple tt5; +typedef std::tuple tt6; +typedef std::tuple tt7; +typedef std::tuple tt8; +typedef std::tuple tt9; +typedef std::tuple tt10; +typedef std::tuple tt11; +typedef std::tuple tt12; + +static_assert(std::is_nothrow_move_assignable::value, "Error"); +static_assert(std::is_nothrow_move_assignable::value, "Error"); +static_assert(std::is_nothrow_move_assignable::value, "Error"); +static_assert(std::is_nothrow_move_assignable::value, "Error"); +static_assert(std::is_nothrow_move_assignable::value, "Error"); +static_assert(std::is_nothrow_move_assignable::value, "Error"); +static_assert(!std::is_nothrow_move_assignable::value, "Error"); +static_assert(!std::is_nothrow_move_assignable::value, "Error"); +static_assert(!std::is_nothrow_move_assignable::value, "Error"); +static_assert(!std::is_nothrow_move_assignable::value, "Error"); +static_assert(!std::is_nothrow_move_assignable::value, "Error"); +static_assert(!std::is_nothrow_move_assignable::value, "Error"); Index: testsuite/20_util/weak_ptr/comparison/cmp_neg.cc =================================================================== --- testsuite/20_util/weak_ptr/comparison/cmp_neg.cc (revision 173912) +++ testsuite/20_util/weak_ptr/comparison/cmp_neg.cc (working copy) @@ -51,9 +51,9 @@ // { dg-warning "note" "" { target *-*-* } 485 } // { dg-warning "note" "" { target *-*-* } 479 } // { dg-warning "note" "" { target *-*-* } 469 } -// { dg-warning "note" "" { target *-*-* } 599 } +// { dg-warning "note" "" { target *-*-* } 603 } // { dg-warning "note" "" { target *-*-* } 1056 } // { dg-warning "note" "" { target *-*-* } 1050 } // { dg-warning "note" "" { target *-*-* } 342 } // { dg-warning "note" "" { target *-*-* } 292 } -// { dg-warning "note" "" { target *-*-* } 211 } +// { dg-warning "note" "" { target *-*-* } 212 }