From patchwork Sat Apr 13 19:21:18 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Fran=C3=A7ois_Dumont?= X-Patchwork-Id: 236389 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 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client CN "localhost", Issuer "www.qmailtoaster.com" (not verified)) by ozlabs.org (Postfix) with ESMTPS id D20652C008F for ; Sun, 14 Apr 2013 05:21:37 +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 :message-id:date:from:mime-version:to:subject:references :in-reply-to:content-type; q=dns; s=default; b=RSWTR2wGxuASXfQ3C 8/cSnGuicLWENn9vnu/sv+/XeEgFY131iJ/dB1hJa9y02ZX8E3DPDbbAhnK1yIhY 1XDANNvdAil+pCqX7Bn4k6ZzmoCVKtLP9li80lXsn4CqEU2Mz4CbRNcBq+OR3RoL eaRz0wILt6Qa0OaZDhKZ46Cf/g= 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 :message-id:date:from:mime-version:to:subject:references :in-reply-to:content-type; s=default; bh=oUEmI6AdEZbguf9THCSGODV BGwA=; b=ja3DHDqx9lFkDw4aLchdDItYpumrmIdL0d4V71CkqdtpWERiZZvyp6a aNmXHwu3Lb1XEz8EOyE/4Srq69umVWK3nVzsNYE0ZTE28Sl/NRLhOHbGSKSg/dDG Rre7tHpMDq9KA6jG/SDoD585Q4c6nfTgfiX1P2BB0IRqJjLK7p1U= Received: (qmail 12944 invoked by alias); 13 Apr 2013 19:21:26 -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 12879 invoked by uid 89); 13 Apr 2013 19:21:25 -0000 X-Spam-SWARE-Status: No, score=-5.2 required=5.0 tests=AWL, BAYES_00, FREEMAIL_FROM, KHOP_RCVD_TRUST, KHOP_THREADED, RCVD_IN_DNSWL_LOW, RCVD_IN_HOSTKARMA_YE autolearn=ham version=3.3.1 X-Spam-User: vpopmail, 2 recipients Received: from mail-wi0-f176.google.com (HELO mail-wi0-f176.google.com) (209.85.212.176) by sourceware.org (qpsmtpd/0.84/v0.84-167-ge50287c) with ESMTP; Sat, 13 Apr 2013 19:21:23 +0000 Received: by mail-wi0-f176.google.com with SMTP id hm14so493941wib.15 for ; Sat, 13 Apr 2013 12:21:20 -0700 (PDT) X-Received: by 10.194.23.105 with SMTP id l9mr24121657wjf.41.1365880880552; Sat, 13 Apr 2013 12:21:20 -0700 (PDT) Received: from localhost.localdomain (arf62-1-82-237-250-248.fbx.proxad.net. [82.237.250.248]) by mx.google.com with ESMTPS id q13sm4740749wie.0.2013.04.13.12.21.18 (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Sat, 13 Apr 2013 12:21:19 -0700 (PDT) Message-ID: <5169B02E.1060802@gmail.com> Date: Sat, 13 Apr 2013 21:21:18 +0200 From: =?ISO-8859-1?Q?Fran=E7ois_Dumont?= User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:15.0) Gecko/20120829 Thunderbird/15.0 MIME-Version: 1.0 To: gcc-patches , "libstdc++@gcc.gnu.org" Subject: Fwd: Fix std::pair std::is_copy_assignable behavior References: <51687815.6030507@gmail.com> In-Reply-To: <51687815.6030507@gmail.com> X-Forwarded-Message-Id: <51687815.6030507@gmail.com> X-Virus-Found: No Hider Here is a patch already posted to libstdc++ mailing but I am resending following libstdc++ maintainers advises to add gcc-patches mailing list. This patch proposal is to fix the behavior of std::pair regarding the std::is_*_assignable meta programming functions. As announced it is requiring a compiler patch to extend DR 1402 resolution to all defaulted methods. 2013-04-12 François Dumont * call.c (joust): Extend DR 1402 to all defaulted methods. This modification is mandatory so that pair& operator=(const pair&) can be defaulted whereas leaving gcc consider the other operator= in some situations like std::pair. This way, with usage of std::enable_if on the template operator=, we can control when p1= p2 is a valid expression resulting in a correct behavior of std::is_copy_assignable. For the moment I preferred to add a dg-require-normal-mode option in the single test that fail to compile because of the compiler modification. Does DR 1402 resolution generalization need a Standard committee validation first ? 2013-04-13 François Dumont * include/bits/stl_pair.h (operator=(const pair&)): Defaulted. (operator=(pair&&)): Likewise. (template<> operator=(const pair&)): Add noexcept qualification. Enable if is_assignable true for both parameters. (template<> operator=(pair<>&&)): Add noexcept qualification. Enable if is_assignable true for both parameters. * testsuite/23_containers/unordered_set/55043.cc: Add dg-require-normal-mode. * testsuite/20_util/pair/is_move_assignable.cc: New. * testsuite/20_util/pair/is_copy_assignable.cc: Likewise. * testsuite/20_util/pair/is_assignable.cc: Likewise. * testsuite/20_util/pair/is_nothrow_move_assignable.cc: Likewise. * testsuite/20_util/pair/assign_neg.cc: Likewise. * testsuite/20_util/pair/is_nothrow_copy_assignable.cc: Likewise. * testsuite/20_util/pair/assign.cc: Likewise. François Index: include/bits/stl_pair.h =================================================================== --- include/bits/stl_pair.h (revision 197829) +++ include/bits/stl_pair.h (working copy) @@ -155,26 +155,18 @@ pair(piecewise_construct_t, tuple<_Args1...>, tuple<_Args2...>); pair& - operator=(const pair& __p) - { - first = __p.first; - second = __p.second; - return *this; - } + operator=(const pair&) = default; pair& - operator=(pair&& __p) - noexcept(__and_, - is_nothrow_move_assignable<_T2>>::value) - { - first = std::forward(__p.first); - second = std::forward(__p.second); - return *this; - } + operator=(pair&&) = default; template - pair& + typename enable_if<__and_, + is_assignable<_T2&, const _U2&>>::value, + pair&>::type operator=(const pair<_U1, _U2>& __p) + noexcept(__and_, + is_nothrow_assignable<_T2&, const _U2&>>::value) { first = __p.first; second = __p.second; @@ -182,8 +174,12 @@ } template - pair& + typename enable_if<__and_, + is_assignable<_T2&, _U2&&>>::value, + pair&>::type operator=(pair<_U1, _U2>&& __p) + noexcept(__and_, + is_nothrow_assignable<_T2&, _U2&&>>::value) { first = std::forward<_U1>(__p.first); second = std::forward<_U2>(__p.second); Index: testsuite/23_containers/unordered_set/55043.cc =================================================================== --- testsuite/23_containers/unordered_set/55043.cc (revision 197829) +++ testsuite/23_containers/unordered_set/55043.cc (working copy) @@ -1,5 +1,6 @@ // { dg-options "-std=gnu++0x" } // { dg-do compile } +// { dg-require-normal-mode "" } // Copyright (C) 2013 Free Software Foundation, Inc. // Index: testsuite/20_util/pair/is_nothrow_move_assignable.cc =================================================================== --- testsuite/20_util/pair/is_nothrow_move_assignable.cc (revision 0) +++ testsuite/20_util/pair/is_nothrow_move_assignable.cc (revision 0) @@ -0,0 +1,57 @@ +// { dg-do compile } +// { dg-options "-std=c++11" } + +// Copyright (C) 2013 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 +#include + +using namespace __gnu_test; + +typedef std::pair pt1; +typedef std::pair pt2; +typedef std::pair pt3; +typedef std::pair pt4; +typedef std::pair pt5; +typedef std::pair pt6; +typedef std::pair pt7; +typedef std::pair pt8; +typedef std::pair pt9; +typedef std::pair pt10; +typedef std::pair pt11; +typedef std::pair pt12; +typedef std::pair pt13; +typedef std::pair pt14; +typedef std::pair pt15; + +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"); +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/pair/assign_neg.cc =================================================================== --- testsuite/20_util/pair/assign_neg.cc (revision 0) +++ testsuite/20_util/pair/assign_neg.cc (revision 0) @@ -0,0 +1,29 @@ +// { dg-do compile } +// { dg-options "-std=c++11" } + +// Copyright (C) 2013 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 + +void test01() +{ + std::pair p; + p = p; // { dg-error "use of deleted function" } +} + +// { dg-error "can't use default assignment operator" "" { target *-*-* } 158 } Index: testsuite/20_util/pair/is_nothrow_copy_assignable.cc =================================================================== --- testsuite/20_util/pair/is_nothrow_copy_assignable.cc (revision 0) +++ testsuite/20_util/pair/is_nothrow_copy_assignable.cc (revision 0) @@ -0,0 +1,53 @@ +// { dg-do compile } +// { dg-options "-std=c++11" } + +// Copyright (C) 2013 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 +#include + +using namespace __gnu_test; + +typedef std::pair pt1; +typedef std::pair pt2; +typedef std::pair pt3; +typedef std::pair pt4; +typedef std::pair& pt5; +typedef std::pair pt6; +typedef std::pair pt7; +typedef std::pair pt8; +typedef std::pair pt9; +typedef std::pair pt10; +typedef std::pair pt11; +typedef std::pair pt12; +typedef std::pair pt13; + +static_assert(std::is_nothrow_copy_assignable::value, "Error"); +static_assert(std::is_nothrow_copy_assignable::value, "Error"); +static_assert(!std::is_nothrow_copy_assignable::value, "Error"); +static_assert(!std::is_nothrow_copy_assignable::value, "Error"); +static_assert(!std::is_nothrow_copy_assignable::value, "Error"); +static_assert(std::is_nothrow_copy_assignable::value, "Error"); +static_assert(!std::is_nothrow_copy_assignable::value, "Error"); +static_assert(!std::is_nothrow_copy_assignable::value, "Error"); +static_assert(!std::is_nothrow_copy_assignable::value, "Error"); +static_assert(!std::is_nothrow_copy_assignable::value, "Error"); +static_assert(std::is_nothrow_copy_assignable::value, "Error"); +static_assert(std::is_nothrow_copy_assignable::value, "Error"); +static_assert(!std::is_nothrow_copy_assignable::value, "Error"); Index: testsuite/20_util/pair/assign.cc =================================================================== --- testsuite/20_util/pair/assign.cc (revision 0) +++ testsuite/20_util/pair/assign.cc (revision 0) @@ -0,0 +1,124 @@ +// { dg-options "-std=c++11" } + +// Copyright (C) 2013 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 +#include +#include + +void test01() +{ + bool test __attribute__((unused)) = true; + using __gnu_test::counter_type; + + typedef std::pair ptype; + ptype p1(0, 0); + ptype p2(1, 1); + + counter_type::reset(); + + p1 = p2; + + VERIFY( p1.first == 1 ); + VERIFY( p1.second.val == 1 ); + VERIFY( counter_type::copy_assign_count == 1 ); +} + +void test02() +{ + bool test __attribute__((unused)) = true; + using __gnu_test::counter_type; + + typedef std::pair ptype; + ptype p1(0, 0); + ptype p2(1, 1); + + counter_type::reset(); + + p1 = std::move(p2); + + VERIFY( p1.first == 1 ); + VERIFY( p1.second.val == 1 ); + VERIFY( counter_type::move_assign_count == 1 ); +} + +void test03() +{ + bool test __attribute__((unused)) = true; + + typedef std::pair ptype; + int i = 0, j = 1; + ptype p1(i, j); + VERIFY( p1.first == 0 ); + VERIFY( p1.second == 1 ); + + int k = 2, l = 3; + ptype p2(k, l); + VERIFY( p2.first == 2 ); + VERIFY( p2.second == 3 ); + + p1 = p2; + + VERIFY( p1.first == 2 ); + VERIFY( p1.second == 3 ); + VERIFY( p2.first == 2 ); + VERIFY( p2.second == 3 ); + + VERIFY( i == 2 ); + + i = 0; + VERIFY( p1.first == 0 ); +} + +void test04() +{ + bool test __attribute__((unused)) = true; + + typedef std::pair ptype; + int i = 0; + ptype p1(i, 1); + VERIFY( p1.first == 0 ); + VERIFY( p1.second == 1 ); + + int j = 2; + ptype p2(j, 3); + VERIFY( p2.first == 2 ); + VERIFY( p2.second == 3 ); + + p1 = p2; + + VERIFY( p1.first == 2 ); + VERIFY( p1.second == 3 ); + VERIFY( p2.first == 2 ); + VERIFY( p2.second == 3 ); + + VERIFY( i == 2 ); + + i = 0; + VERIFY( p1.first == 0 ); +} + +int main() +{ + test01(); + test02(); + test03(); + test04(); + return 0; +} Index: testsuite/20_util/pair/is_move_assignable.cc =================================================================== --- testsuite/20_util/pair/is_move_assignable.cc (revision 0) +++ testsuite/20_util/pair/is_move_assignable.cc (revision 0) @@ -0,0 +1,59 @@ +// { dg-do compile } +// { dg-options "-std=c++11" } + +// Copyright (C) 2013 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 +#include + +using namespace __gnu_test; + +typedef std::pair pt1; +typedef std::pair pt2; +typedef std::pair pt3; +typedef std::pair pt4; +typedef std::pair pt5; +typedef std::pair pt6; +typedef std::pair pt7; +typedef std::pair pt8; +typedef std::pair pt9; +typedef std::pair pt10; +typedef std::pair pt11; +typedef std::pair pt12; +typedef std::pair pt13; +typedef std::pair pt14; +typedef std::pair pt15; +typedef std::pair pt16; + +static_assert(std::is_move_assignable::value, "Error"); +static_assert(std::is_move_assignable::value, "Error"); +static_assert(std::is_move_assignable::value, "Error"); +static_assert(std::is_move_assignable::value, "Error"); +static_assert(std::is_move_assignable::value, "Error"); +static_assert(std::is_move_assignable::value, "Error"); +static_assert(!std::is_move_assignable::value, "Error"); +static_assert(!std::is_move_assignable::value, "Error"); +static_assert(std::is_move_assignable::value, "Error"); +static_assert(std::is_move_assignable::value, "Error"); +static_assert(std::is_move_assignable::value, "Error"); +static_assert(!std::is_move_assignable::value, "Error"); +static_assert(!std::is_move_assignable::value, "Error"); +static_assert(!std::is_move_assignable::value, "Error"); +static_assert(std::is_move_assignable::value, "Error"); +static_assert(!std::is_move_assignable::value, "Error"); Index: testsuite/20_util/pair/is_copy_assignable.cc =================================================================== --- testsuite/20_util/pair/is_copy_assignable.cc (revision 0) +++ testsuite/20_util/pair/is_copy_assignable.cc (revision 0) @@ -0,0 +1,53 @@ +// { dg-do compile } +// { dg-options "-std=c++11" } + +// Copyright (C) 2013 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 +#include + +using namespace __gnu_test; + +typedef std::pair pt1; +typedef std::pair pt2; +typedef std::pair pt3; +typedef std::pair pt4; +typedef std::pair& pt5; +typedef std::pair pt6; +typedef std::pair pt7; +typedef std::pair pt8; +typedef std::pair pt9; +typedef std::pair pt10; +typedef std::pair pt11; +typedef std::pair pt12; +typedef std::pair pt13; + +static_assert(std::is_copy_assignable::value, "Error"); +static_assert(std::is_copy_assignable::value, "Error"); +static_assert(!std::is_copy_assignable::value, "Error"); +static_assert(!std::is_copy_assignable::value, "Error"); +static_assert(!std::is_copy_assignable::value, "Error"); +static_assert(std::is_copy_assignable::value, "Error"); +static_assert(std::is_copy_assignable::value, "Error"); +static_assert(std::is_copy_assignable::value, "Error"); +static_assert(std::is_copy_assignable::value, "Error"); +static_assert(!std::is_copy_assignable::value, "Error"); +static_assert(std::is_copy_assignable::value, "Error"); +static_assert(std::is_copy_assignable::value, "Error"); +static_assert(!std::is_copy_assignable::value, "Error"); Index: testsuite/20_util/pair/is_assignable.cc =================================================================== --- testsuite/20_util/pair/is_assignable.cc (revision 0) +++ testsuite/20_util/pair/is_assignable.cc (revision 0) @@ -0,0 +1,48 @@ +// { dg-do compile } +// { dg-options "-std=c++11" } + +// Copyright (C) 2013 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 + +struct T1 +{ +}; + +struct T2 +{ + T2& + operator=(const T1&); +}; + +typedef std::pair pt1; +typedef std::pair pt2; +typedef std::pair pt3; +typedef std::pair pt4; +typedef std::pair pt5; + +static_assert(std::is_assignable::value, "Error"); +static_assert(std::is_assignable::value, "Error"); +static_assert(std::is_assignable::value, "Error"); +static_assert(!std::is_assignable::value, "Error"); +static_assert(!std::is_assignable::value, "Error"); +static_assert(std::is_assignable::value, "Error"); +static_assert(!std::is_assignable::value, "Error"); + +