Ping for the non-libstdc++ parts.

On Mon, Jul 19, 2021 at 02:46:22PM -0400, Marek Polacek wrote:
> On Sat, Jul 17, 2021 at 02:50:28PM -0700, Jason Merrill wrote:
> > On 7/16/21 6:34 PM, Jakub Jelinek wrote:
> > > On Fri, Jul 16, 2021 at 05:36:13PM -0400, Marek Polacek via Gcc-patches 
> > > wrote:
> > > > When implementing DR 1512 in r11-467 I neglected to reject ordered
> > > > comparison of two null pointers, like nullptr < nullptr.  This patch
> > > > fixes that omission.
> > > > 
> > > > Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?
> > > > 
> > > >         DR 1512
> > > >         PR c++/99701
> > > > 
> > > > gcc/cp/ChangeLog:
> > > > 
> > > >         * cp-gimplify.c (cp_fold): Remove {LE,LT,GE,GT_EXPR} from
> > > >         a switch.
> > > >         * typeck.c (cp_build_binary_op): Reject ordered comparison
> > > >         of two null pointers.
> > > > 
> > > > gcc/testsuite/ChangeLog:
> > > > 
> > > >         * g++.dg/cpp0x/nullptr11.C: Remove invalid tests.
> > > >         * g++.dg/cpp0x/nullptr46.C: Add dg-error.
> > > >         * g++.dg/expr/ptr-comp4.C: New test.
> > > > 
> > > > libstdc++-v3/ChangeLog:
> > > > 
> > > >         * testsuite/20_util/tuple/comparison_operators/overloaded.cc:
> > > >         Add dg-error.
> > > 
> > > Maybe it would be useful to have also a g++.dg/cpp2a/ testcase with
> > > nullptr <=> nullptr etc. (nullptr <=> 0, etc. what you test
> > > in ptr-comp4.C after #include <compare>).
> > 
> > Sounds good.
> 
> Done.
>  
> > > +++ 
> > > b/libstdc++-v3/testsuite/20_util/tuple/comparison_operators/overloaded.cc
> > > @@ -49,3 +49,5 @@ TwistedLogic operator<(const Compares&, const 
> > > Compares&) { return {false}; }
> > >  auto a = std::make_tuple(nullptr, Compares{}, 2, 'U');
> > >  auto b = a == a;
> > >  auto c = a < a;
> > > +
> > > +// { dg-error "ordered comparison" "" { target *-*-* } 0 }
> > 
> > If we can't test for the specific problematic line, let's split this
> > testcase into separate well-formed and ill-formed tests.
> 
> Done, I don't know if there's a trick to check an error that comes
> from tuple.  Jon, are you OK with what I'm doing here?  Since
> overloaded.cc and overloaded2.cc are essentially the same I could
> make the substance of the test into a separate file but since it's
> just a test, I didn't bother.
> 
> Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?
> 
> -- >8 --
> When implementing DR 1512 in r11-467 I neglected to reject ordered
> comparison of two null pointers, like nullptr < nullptr.  This patch
> fixes that omission.
> 
>       DR 1512
>       PR c++/99701
> 
> gcc/cp/ChangeLog:
> 
>       * cp-gimplify.c (cp_fold): Remove {LE,LT,GE,GT_EXPR} from
>       a switch.
>       * typeck.c (cp_build_binary_op): Reject ordered comparison
>       of two null pointers.
> 
> gcc/testsuite/ChangeLog:
> 
>       * g++.dg/cpp0x/nullptr11.C: Remove invalid tests.
>       * g++.dg/cpp0x/nullptr46.C: Add dg-error.
>       * g++.dg/cpp2a/spaceship-err7.C: New test.
>       * g++.dg/expr/ptr-comp4.C: New test.
> 
> libstdc++-v3/ChangeLog:
> 
>       * testsuite/20_util/tuple/comparison_operators/overloaded.cc:
>       Move a line...
>       * testsuite/20_util/tuple/comparison_operators/overloaded2.cc:
>       ...here.  New test.
> ---
>  gcc/cp/cp-gimplify.c                          |  4 --
>  gcc/cp/typeck.c                               | 15 ++----
>  gcc/testsuite/g++.dg/cpp0x/nullptr11.C        | 16 ------
>  gcc/testsuite/g++.dg/cpp0x/nullptr46.C        |  3 +-
>  gcc/testsuite/g++.dg/cpp2a/spaceship-err7.C   | 14 +++++
>  gcc/testsuite/g++.dg/expr/ptr-comp4.C         | 21 ++++++++
>  .../tuple/comparison_operators/overloaded.cc  |  1 -
>  .../tuple/comparison_operators/overloaded2.cc | 52 +++++++++++++++++++
>  8 files changed, 92 insertions(+), 34 deletions(-)
>  create mode 100644 gcc/testsuite/g++.dg/cpp2a/spaceship-err7.C
>  create mode 100644 gcc/testsuite/g++.dg/expr/ptr-comp4.C
>  create mode 100644 
> libstdc++-v3/testsuite/20_util/tuple/comparison_operators/overloaded2.cc
> 
> diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c
> index ff0bff771df..0520fa45b91 100644
> --- a/gcc/cp/cp-gimplify.c
> +++ b/gcc/cp/cp-gimplify.c
> @@ -2433,13 +2433,9 @@ cp_fold (tree x)
>         switch (code)
>           {
>           case EQ_EXPR:
> -         case LE_EXPR:
> -         case GE_EXPR:
>             x = constant_boolean_node (true, TREE_TYPE (x));
>             break;
>           case NE_EXPR:
> -         case LT_EXPR:
> -         case GT_EXPR:
>             x = constant_boolean_node (false, TREE_TYPE (x));
>             break;
>           default:
> diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
> index a483e1f988d..738e69a0440 100644
> --- a/gcc/cp/typeck.c
> +++ b/gcc/cp/typeck.c
> @@ -5483,7 +5483,9 @@ cp_build_binary_op (const op_location_t &location,
>       result_type = composite_pointer_type (location,
>                                             type0, type1, op0, op1,
>                                             CPO_COMPARISON, complain);
> -      else if (code0 == POINTER_TYPE && null_ptr_cst_p (orig_op1))
> +      else if ((code0 == POINTER_TYPE && null_ptr_cst_p (orig_op1))
> +            || (code1 == POINTER_TYPE && null_ptr_cst_p (orig_op0))
> +            || (null_ptr_cst_p (orig_op0) && null_ptr_cst_p (orig_op1)))
>       {
>         /* Core Issue 1512 made this ill-formed.  */
>         if (complain & tf_error)
> @@ -5491,17 +5493,6 @@ cp_build_binary_op (const op_location_t &location,
>                     "integer zero (%qT and %qT)", type0, type1);
>         return error_mark_node;
>       }
> -      else if (code1 == POINTER_TYPE && null_ptr_cst_p (orig_op0))
> -     {
> -       /* Core Issue 1512 made this ill-formed.  */
> -       if (complain & tf_error)
> -         error_at (location, "ordered comparison of pointer with "
> -                   "integer zero (%qT and %qT)", type0, type1);
> -       return error_mark_node;
> -     }
> -      else if (null_ptr_cst_p (orig_op0) && null_ptr_cst_p (orig_op1))
> -     /* One of the operands must be of nullptr_t type.  */
> -        result_type = TREE_TYPE (nullptr_node);
>        else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE)
>       {
>         result_type = type0;
> diff --git a/gcc/testsuite/g++.dg/cpp0x/nullptr11.C 
> b/gcc/testsuite/g++.dg/cpp0x/nullptr11.C
> index f81f0c3c1c8..b8bc682f2ea 100644
> --- a/gcc/testsuite/g++.dg/cpp0x/nullptr11.C
> +++ b/gcc/testsuite/g++.dg/cpp0x/nullptr11.C
> @@ -9,31 +9,15 @@ void fun()
>  {
>    assert_true(nullptr == nullptr);
>    assert_false(nullptr != nullptr);
> -  assert_false(nullptr < nullptr);
> -  assert_false(nullptr > nullptr);
> -  assert_true(nullptr <= nullptr);
> -  assert_true(nullptr >= nullptr);
>  
>    decltype(nullptr) mynull = 0;
>  
>    assert_true(mynull == nullptr);
>    assert_false(mynull != nullptr);
> -  assert_false(mynull < nullptr);
> -  assert_false(mynull > nullptr);
> -  assert_true(mynull <= nullptr);
> -  assert_true(mynull >= nullptr);
>  
>    assert_true(nullptr == mynull);
>    assert_false(nullptr != mynull);
> -  assert_false(nullptr < mynull);
> -  assert_false(nullptr > mynull);
> -  assert_true(nullptr <= mynull);
> -  assert_true(nullptr >= mynull);
>  
>    assert_true(mynull == mynull);
>    assert_false(mynull != mynull);
> -  assert_false(mynull < mynull);
> -  assert_false(mynull > mynull);
> -  assert_true(mynull <= mynull);
> -  assert_true(mynull >= mynull);
>  }
> diff --git a/gcc/testsuite/g++.dg/cpp0x/nullptr46.C 
> b/gcc/testsuite/g++.dg/cpp0x/nullptr46.C
> index 1514cee3c3b..6c08eaa4d8f 100644
> --- a/gcc/testsuite/g++.dg/cpp0x/nullptr46.C
> +++ b/gcc/testsuite/g++.dg/cpp0x/nullptr46.C
> @@ -7,5 +7,6 @@ decltype(nullptr) foo ();
>  bool
>  bar ()
>  {
> -  return foo () > nullptr || foo () < nullptr;
> +  return foo () > nullptr // { dg-error "ordered comparison" }
> +    || foo () < nullptr; // { dg-error "ordered comparison" }
>  }
> diff --git a/gcc/testsuite/g++.dg/cpp2a/spaceship-err7.C 
> b/gcc/testsuite/g++.dg/cpp2a/spaceship-err7.C
> new file mode 100644
> index 00000000000..bc309230239
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/cpp2a/spaceship-err7.C
> @@ -0,0 +1,14 @@
> +// PR c++/99701
> +// { dg-do compile { target c++20 } }
> +
> +#include <compare>
> +
> +decltype(nullptr) foo ();
> +
> +auto b0 = nullptr <=> nullptr; // { dg-error "ordered comparison" }
> +auto b1 = 0 <=> nullptr; // { dg-error "ordered comparison" }
> +auto b2 = nullptr <=> 0; // { dg-error "ordered comparison" }
> +auto b3 = foo () <=> 0; // { dg-error "ordered comparison" }
> +auto b4 = 0 <=> foo (); // { dg-error "ordered comparison" }
> +auto b5 = foo () <=> nullptr; // { dg-error "ordered comparison" }
> +auto b6 = nullptr <=> foo (); // { dg-error "ordered comparison" }
> diff --git a/gcc/testsuite/g++.dg/expr/ptr-comp4.C 
> b/gcc/testsuite/g++.dg/expr/ptr-comp4.C
> new file mode 100644
> index 00000000000..da4951806c1
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/expr/ptr-comp4.C
> @@ -0,0 +1,21 @@
> +// PR c++/99701
> +// DR 1512
> +// { dg-do compile { target c++11 } }
> +
> +/* Relational comparisons between null pointer constants and pointers are
> +   ill-formed.  */
> +
> +decltype(nullptr) foo ();
> +
> +auto lt = nullptr < nullptr; // { dg-error "ordered comparison" }
> +auto gt = nullptr > nullptr; // { dg-error "ordered comparison" }
> +auto le = nullptr <= nullptr; // { dg-error "ordered comparison" }
> +auto ge = nullptr >= nullptr; // { dg-error "ordered comparison" }
> +auto eq = nullptr == nullptr;
> +auto ne = nullptr != nullptr;
> +auto a1 = nullptr > 0; // { dg-error "ordered comparison" }
> +auto a2 = 0 < nullptr; // { dg-error "ordered comparison" }
> +auto a3 = foo () > 0; // { dg-error "ordered comparison" }
> +auto a4 = 0 < foo (); // { dg-error "ordered comparison" }
> +auto a5 = 0 <= foo (); // { dg-error "ordered comparison" }
> +auto a6 = foo () >= 0; // { dg-error "ordered comparison" }
> diff --git 
> a/libstdc++-v3/testsuite/20_util/tuple/comparison_operators/overloaded.cc 
> b/libstdc++-v3/testsuite/20_util/tuple/comparison_operators/overloaded.cc
> index a25c374a932..ef90b6b5b73 100644
> --- a/libstdc++-v3/testsuite/20_util/tuple/comparison_operators/overloaded.cc
> +++ b/libstdc++-v3/testsuite/20_util/tuple/comparison_operators/overloaded.cc
> @@ -48,4 +48,3 @@ TwistedLogic operator<(const Compares&, const Compares&) { 
> return {false}; }
>  
>  auto a = std::make_tuple(nullptr, Compares{}, 2, 'U');
>  auto b = a == a;
> -auto c = a < a;
> diff --git 
> a/libstdc++-v3/testsuite/20_util/tuple/comparison_operators/overloaded2.cc 
> b/libstdc++-v3/testsuite/20_util/tuple/comparison_operators/overloaded2.cc
> new file mode 100644
> index 00000000000..fc3118f85a8
> --- /dev/null
> +++ b/libstdc++-v3/testsuite/20_util/tuple/comparison_operators/overloaded2.cc
> @@ -0,0 +1,52 @@
> +// { dg-do compile { target c++11 } }
> +
> +// Copyright (C) 2014-2021 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 <tuple>
> +
> +// A type that is contextually convertible to bool but cannot be used with
> +// the usual logical operators, and/or/not.
> +struct TwistedLogic {
> +  bool value;
> +
> +  explicit operator bool() const noexcept { return value; }
> +};
> +
> +template<typename T>
> +bool operator&&(const T&, TwistedLogic) = delete;
> +
> +template<typename T>
> +bool operator&&(TwistedLogic, const T&) = delete;
> +
> +template<typename T>
> +bool operator||(const T&, TwistedLogic) = delete;
> +
> +template<typename T>
> +bool operator||(TwistedLogic, const T&) = delete;
> +
> +bool operator!(TwistedLogic) noexcept = delete;
> +
> +struct Compares {};
> +
> +TwistedLogic operator==(const Compares&, const Compares&) { return {true}; }
> +TwistedLogic operator<(const Compares&, const Compares&) { return {false}; }
> +
> +auto a = std::make_tuple(nullptr, Compares{}, 2, 'U');
> +auto b = a < a;
> +
> +// { dg-error "ordered comparison" "" { target *-*-* } 0 }
> 
> base-commit: f007a638a86e4b59bef0a0d8efa5bb8c5e5b200a
> -- 
> 2.31.1
> 

Marek

Reply via email to