diff mbox

[v3] PR libstdc++/79141

Message ID CAFk2RUbfaK=+i_6Gm9fcbZaXFJAC3HC5UDp4z9qd2cuxdzEiiA@mail.gmail.com
State New
Headers show

Commit Message

Ville Voutilainen April 1, 2017, 11:45 p.m. UTC
Tested on Linux-x64.

2017-04-02  Ville Voutilainen  <ville.voutilainen@gmail.com>

    PR libstdc++/79141
    * include/bits/stl_pair.h (__wrap_nonesuch): New.
    (operator=(typename conditional<
    __and_<is_copy_assignable<_T1>,
    is_copy_assignable<_T2>>::value,
    const pair&, const __wrap_nonesuch&>::type)): Change __nonesuch
    to __wrap_nonesuch.
    (operator=(typename conditional<
    __not_<__and_<is_copy_assignable<_T1>,
    is_copy_assignable<_T2>>>::value,
    const pair&, const __nonesuch&>::type)): Likewise.
    (operator=(typename conditional<
    __and_<is_move_assignable<_T1>,
    is_move_assignable<_T2>>::value,
    pair&&, __wrap_nonesuch&&>::type)): Likewise.
    * testsuite/20_util/pair/79141.cc: New.

Comments

Ville Voutilainen April 2, 2017, 8:36 p.m. UTC | #1
On 2 April 2017 at 02:45, Ville Voutilainen <ville.voutilainen@gmail.com> wrote:
> Tested on Linux-x64.


For what it's worth, here's a saner changelog that uses the signatures
that were originally in place. The patch
passes the full testsuite on Linux-PPC64 without regressions.

2017-04-02  Ville Voutilainen  <ville.voutilainen@gmail.com>

    PR libstdc++/79141
    * include/bits/stl_pair.h (__wrap_nonesuch): New.
    (operator=(typename conditional<
    __and_<is_copy_assignable<_T1>,
    is_copy_assignable<_T2>>::value,
    const pair&, const __nonesuch&>::type)): Change __nonesuch
    to __wrap_nonesuch.
    (operator=(typename conditional<
    __not_<__and_<is_copy_assignable<_T1>,
    is_copy_assignable<_T2>>>::value,
    const pair&, const __nonesuch&>::type)): Likewise.
    (operator=(typename conditional<
    __and_<is_move_assignable<_T1>,
    is_move_assignable<_T2>>::value,
    pair&&, __nonesuch&&>::type)): Likewise.
    * testsuite/20_util/pair/79141.cc: New.
Jonathan Wakely April 3, 2017, 3:43 p.m. UTC | #2
On 02/04/17 02:45 +0300, Ville Voutilainen wrote:
>    PR libstdc++/79141
>    * include/bits/stl_pair.h (__wrap_nonesuch): New.
>    (operator=(typename conditional<
>    __and_<is_copy_assignable<_T1>,
>    is_copy_assignable<_T2>>::value,
>    const pair&, const __wrap_nonesuch&>::type)): Change __nonesuch
>    to __wrap_nonesuch.
>    (operator=(typename conditional<
>    __not_<__and_<is_copy_assignable<_T1>,
>    is_copy_assignable<_T2>>>::value,
>    const pair&, const __nonesuch&>::type)): Likewise.
>    (operator=(typename conditional<
>    __and_<is_move_assignable<_T1>,
>    is_move_assignable<_T2>>::value,
>    pair&&, __wrap_nonesuch&&>::type)): Likewise.
>    * testsuite/20_util/pair/79141.cc: New.

>diff --git a/libstdc++-v3/include/bits/stl_pair.h b/libstdc++-v3/include/bits/stl_pair.h
>index 7c7cee2..b746fb4 100644
>--- a/libstdc++-v3/include/bits/stl_pair.h
>+++ b/libstdc++-v3/include/bits/stl_pair.h
>@@ -179,6 +179,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>       }
>   };
>
>+  struct __wrap_nonesuch : std::__nonesuch {
>+    explicit __wrap_nonesuch(const __nonesuch&) = delete;
>+  };

Could you please add a comment explaining that this is needed to
ensure that functions with parameters of this type are not viable when
an argument of {} is used. Because even with such a comment I'll
probably not understand this by next week.

And I think __explicit_nonesuch or __no_list_init would be a clearer
name. We're not really "wrapping" this, unless I misunderstand.

OK for trunk, I suppose.


This kind of thing is why I want to burn std::pair and std::tuple to
the ground.
Jonathan Wakely April 3, 2017, 4:48 p.m. UTC | #3
On 03/04/17 16:43 +0100, Jonathan Wakely wrote:
>On 02/04/17 02:45 +0300, Ville Voutilainen wrote:
>>   PR libstdc++/79141
>>   * include/bits/stl_pair.h (__wrap_nonesuch): New.
>>   (operator=(typename conditional<
>>   __and_<is_copy_assignable<_T1>,
>>   is_copy_assignable<_T2>>::value,
>>   const pair&, const __wrap_nonesuch&>::type)): Change __nonesuch
>>   to __wrap_nonesuch.
>>   (operator=(typename conditional<
>>   __not_<__and_<is_copy_assignable<_T1>,
>>   is_copy_assignable<_T2>>>::value,
>>   const pair&, const __nonesuch&>::type)): Likewise.
>>   (operator=(typename conditional<
>>   __and_<is_move_assignable<_T1>,
>>   is_move_assignable<_T2>>::value,
>>   pair&&, __wrap_nonesuch&&>::type)): Likewise.
>>   * testsuite/20_util/pair/79141.cc: New.
>
>>diff --git a/libstdc++-v3/include/bits/stl_pair.h b/libstdc++-v3/include/bits/stl_pair.h
>>index 7c7cee2..b746fb4 100644
>>--- a/libstdc++-v3/include/bits/stl_pair.h
>>+++ b/libstdc++-v3/include/bits/stl_pair.h
>>@@ -179,6 +179,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>>      }
>>  };
>>
>>+  struct __wrap_nonesuch : std::__nonesuch {
>>+    explicit __wrap_nonesuch(const __nonesuch&) = delete;
>>+  };
>
>Could you please add a comment explaining that this is needed to
>ensure that functions with parameters of this type are not viable when
>an argument of {} is used. Because even with such a comment I'll
>probably not understand this by next week.
>
>And I think __explicit_nonesuch or __no_list_init would be a clearer
>name. We're not really "wrapping" this, unless I misunderstand.
>
>OK for trunk, I suppose.

Oh, and gcc-6-branch.
diff mbox

Patch

diff --git a/libstdc++-v3/include/bits/stl_pair.h b/libstdc++-v3/include/bits/stl_pair.h
index 7c7cee2..b746fb4 100644
--- a/libstdc++-v3/include/bits/stl_pair.h
+++ b/libstdc++-v3/include/bits/stl_pair.h
@@ -179,6 +179,10 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
       }
   };
 
+  struct __wrap_nonesuch : std::__nonesuch {
+    explicit __wrap_nonesuch(const __nonesuch&) = delete;
+  };
+  
 #endif
 
  /**
@@ -360,7 +364,7 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
       operator=(typename conditional<
 		__and_<is_copy_assignable<_T1>,
 		       is_copy_assignable<_T2>>::value,
-		const pair&, const __nonesuch&>::type __p)
+		const pair&, const __wrap_nonesuch&>::type __p)
       {
 	first = __p.first;
 	second = __p.second;
@@ -371,13 +375,13 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
       operator=(typename conditional<
 		__not_<__and_<is_copy_assignable<_T1>,
 		              is_copy_assignable<_T2>>>::value,
-		const pair&, const __nonesuch&>::type __p) = delete;
+		const pair&, const __wrap_nonesuch&>::type __p) = delete;
 
       pair&
       operator=(typename conditional<
 		__and_<is_move_assignable<_T1>,
 		       is_move_assignable<_T2>>::value,
-		pair&&, __nonesuch&&>::type __p)
+		pair&&, __wrap_nonesuch&&>::type __p)
       noexcept(__and_<is_nothrow_move_assignable<_T1>,
 	              is_nothrow_move_assignable<_T2>>::value)
       {
diff --git a/libstdc++-v3/testsuite/20_util/pair/79141.cc b/libstdc++-v3/testsuite/20_util/pair/79141.cc
new file mode 100644
index 0000000..d4b5c94
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/pair/79141.cc
@@ -0,0 +1,25 @@ 
+// { dg-do compile { target c++11 } }
+
+// Copyright (C) 2017 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/>.
+
+#include <utility>
+
+int main() {
+    std::pair<int,int> p;
+    p = {};
+}