From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by sourceware.org (Postfix) with ESMTPS id C2BC63858284 for ; Mon, 10 Oct 2022 13:09:15 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org C2BC63858284 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1665407355; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: in-reply-to:in-reply-to:references:references; bh=M8YapnY4+V1/AvXlsGy/+UvM/6msRDJqiSn4tuAchGc=; b=g4++UJv6r1TXkIZG6A5pXoxTL5lBPqmszJZ0ojgIHHQLvd+fgr0qNy4x9KnMG1fYFOx5xd JFnjvcOCtnlNS2VJiP/8G8iCJ62wuWtjJBNgchz8HDwuV/y5xbV1EHJMMWSp/8mxrJQiAx bMfwWCWEPIYLppyGmrPHYM/mu0nsyYE= Received: from mail-qk1-f198.google.com (mail-qk1-f198.google.com [209.85.222.198]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_128_GCM_SHA256) id us-mta-497-rOlu44UcNyGihb4xt-AfAA-1; Mon, 10 Oct 2022 09:09:14 -0400 X-MC-Unique: rOlu44UcNyGihb4xt-AfAA-1 Received: by mail-qk1-f198.google.com with SMTP id de16-20020a05620a371000b006ceb92bc740so9253572qkb.15 for ; Mon, 10 Oct 2022 06:09:14 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=mime-version:references:message-id:in-reply-to:subject:cc:to:date :from:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=M8YapnY4+V1/AvXlsGy/+UvM/6msRDJqiSn4tuAchGc=; b=v4FpRkMJyBB16CLSEdOgCztxu/5bHM3RBJFPvlqqgCFjUgwmiZCNSGohx5dN4IPIfw 1hs7pvUzIMVd1PqjNdzO0cHQ1OMBJwFrL1xk06et/WwLS9NNjSTYhNcYIBT+xRtUBV4B TnpQ/6P9z0KkgU81wf/r2MlLpNW7ceSYlLNoqkRuS5mP0k+VQOqLbsHTe20TGZz5JDXx GBg48oqMExuSPDOKlFFDOKwl9NUuBKArbdMEBYEWSyD2nMHS2APgi4MyOfEVZwRNMgtg fShEhh8Dugywp26qU9hc67LnV2+TX8waeVF0lvgTnzbqHKaZnhMZG8Lx5yg763Tq119/ rW0A== X-Gm-Message-State: ACrzQf1g0dJOVx5mf0XLS+x5MFcXRkiKzv6wYcbSR7M8X4z/dVFbl2yh jAJZ0RrVS21qfqXfzrZihfmbkjB+TEp4LOOKuf/5p+IdE+ig73yd49YLLLInMxvJ00+RezRl/zF N9YQ0OMUkXqW4yBE= X-Received: by 2002:a05:620a:1911:b0:6ee:53e7:578 with SMTP id bj17-20020a05620a191100b006ee53e70578mr484082qkb.80.1665407353711; Mon, 10 Oct 2022 06:09:13 -0700 (PDT) X-Google-Smtp-Source: AMsMyM43xZcCDoGgWpuPuwTjLa/X2APWTYzfINGg3yP2xrSapBe7rny4Zne1lFAVpy9cCHp+W6BcxQ== X-Received: by 2002:a05:620a:1911:b0:6ee:53e7:578 with SMTP id bj17-20020a05620a191100b006ee53e70578mr484059qkb.80.1665407353350; Mon, 10 Oct 2022 06:09:13 -0700 (PDT) Received: from [192.168.1.130] (ool-457670bb.dyn.optonline.net. [69.118.112.187]) by smtp.gmail.com with ESMTPSA id s12-20020a05622a178c00b003972790deb9sm6827928qtk.84.2022.10.10.06.09.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 10 Oct 2022 06:09:12 -0700 (PDT) From: Patrick Palka X-Google-Original-From: Patrick Palka Date: Mon, 10 Oct 2022 09:09:12 -0400 (EDT) To: Jonathan Wakely cc: libstdc++@gcc.gnu.org, gcc-patches@gcc.gnu.org Subject: Re: [committed] libstdc++: std::make_signed_t should be ill-formed In-Reply-To: <20221010112005.1523979-1-jwakely@redhat.com> Message-ID: <5ff9237f-9298-0964-d61b-58313ae32348@idea> References: <20221010112005.1523979-1-jwakely@redhat.com> MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset=US-ASCII X-Spam-Status: No, score=-14.5 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,GIT_PATCH_0,KAM_SHORT,RCVD_IN_DNSWL_LOW,SPF_HELO_NONE,SPF_NONE,TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: On Mon, 10 Oct 2022, Jonathan Wakely via Libstdc++ wrote: > Tested powerpc64le-linux. Pushed to trunk. > > -- >8 -- > > Currently we only reject std::make_signed_t but not cv bool. > Similarly for std::make_unsigned_t. > > As well as making those ill-formed, this adds a requires-clause to the > make_signed and make_unsigned primary templates. This makes > non-integral, non-enum cases fail immediately with a clear error, rather > than giving an error about __make_signed_selector being > incomplete. IIUC the requires-clause turns what was once a hard error into a SFINAE error, so e.g. for template typename make_signed::type f(int); template void f(...); int main() { f(0); } the call to f would previously be rejected due to an error outside the immediate context about incomplete __make_signed_selector, and now with the requires-clause resolves to the second overload. I wonder if this new behavior is conforming -- the examples in [structure.specifications] of how to implement 'Mandates' suggest that a failed 'Mandates' should yield a hard error? > > libstdc++-v3/ChangeLog: > > * include/std/type_traits (make_signed, make_unsigned): Add > specializations for cv bool. Add requires-clause for C++20 to > improve diagnostics for non-integral, non-enum cases. > * testsuite/20_util/make_signed/requirements/typedefs_neg.cc: > Check cv bool. > * testsuite/20_util/make_unsigned/requirements/typedefs_neg.cc: > Likewise. > * testsuite/24_iterators/range_access/range_access_cpp20_neg.cc: > Adjust expected errors for C++20 and later. > * testsuite/lib/prune.exp: Prune "in requirements [with ...]" > lines from diagnostics. > --- > libstdc++-v3/include/std/type_traits | 18 ++++++++++--- > .../make_signed/requirements/typedefs_neg.cc | 27 +++++++++---------- > .../requirements/typedefs_neg.cc | 25 ++++++++--------- > .../range_access/range_access_cpp20_neg.cc | 3 ++- > libstdc++-v3/testsuite/lib/prune.exp | 1 + > 5 files changed, 40 insertions(+), 34 deletions(-) > > diff --git a/libstdc++-v3/include/std/type_traits b/libstdc++-v3/include/std/type_traits > index b74565eb521..6108b98aa6a 100644 > --- a/libstdc++-v3/include/std/type_traits > +++ b/libstdc++-v3/include/std/type_traits > @@ -1802,12 +1802,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION > // Primary template. > /// make_unsigned > template > +#if __cpp_concepts > + requires is_integral<_Tp>::value || __is_enum(_Tp) > +#endif > struct make_unsigned > { typedef typename __make_unsigned_selector<_Tp>::__type type; }; > > // Integral, but don't define. > - template<> > - struct make_unsigned; > + template<> struct make_unsigned; > + template<> struct make_unsigned; > + template<> struct make_unsigned; > + template<> struct make_unsigned; > > /// @cond undocumented > > @@ -1932,12 +1937,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION > // Primary template. > /// make_signed > template > +#if __cpp_concepts > + requires is_integral<_Tp>::value || __is_enum(_Tp) > +#endif > struct make_signed > { typedef typename __make_signed_selector<_Tp>::__type type; }; > > // Integral, but don't define. > - template<> > - struct make_signed; > + template<> struct make_signed; > + template<> struct make_signed; > + template<> struct make_signed; > + template<> struct make_signed; > > #if __cplusplus > 201103L > /// Alias template for make_signed > diff --git a/libstdc++-v3/testsuite/20_util/make_signed/requirements/typedefs_neg.cc b/libstdc++-v3/testsuite/20_util/make_signed/requirements/typedefs_neg.cc > index 051bb64c710..88b8ae887ef 100644 > --- a/libstdc++-v3/testsuite/20_util/make_signed/requirements/typedefs_neg.cc > +++ b/libstdc++-v3/testsuite/20_util/make_signed/requirements/typedefs_neg.cc > @@ -20,31 +20,28 @@ > // . > > #include > -#include > > -enum test_enum { first_selection }; > +struct pod_class { }; > > void test01() > { > using std::make_signed; > > // Negative tests. > - typedef make_signed::type test1_type; > + using T1 = make_signed::type; // { dg-error "incomplete" } > + using T2 = make_signed::type; // { dg-error "incomplete" } > + using T3 = make_signed::type; // { dg-error "incomplete" } > + using T4 = make_signed::type; // { dg-error "incomplete" } > > - typedef make_signed<__gnu_test::pod_uint>::type test2_type; > + using T5 = make_signed::type; // { dg-error "here" } > > - typedef make_signed::type test3_type; > + using T6 = make_signed::type; // { dg-error "here" } > > - typedef void (fn_type) (); > - typedef make_signed::type test4_type; > + using fn_type = void (); > + using T7 = make_signed::type; // { dg-error "here" } > > - typedef make_signed::type test5_type; > + using T8 = make_signed::type; // { dg-error "here" } > } > > -// { dg-error "invalid use of incomplete type" "" { target *-*-* } 32 } > -// { dg-error "required from here" "" { target *-*-* } 34 } > -// { dg-error "required from here" "" { target *-*-* } 36 } > -// { dg-error "required from here" "" { target *-*-* } 39 } > -// { dg-error "required from here" "" { target *-*-* } 41 } > - > -// { dg-error "invalid use of incomplete type" "" { target *-*-* } 0 } > +// { dg-error "invalid use of incomplete type" "" { target c++17_down } 0 } > +// { dg-error "constraint failure" "" { target c++20 } 0 } > diff --git a/libstdc++-v3/testsuite/20_util/make_unsigned/requirements/typedefs_neg.cc b/libstdc++-v3/testsuite/20_util/make_unsigned/requirements/typedefs_neg.cc > index ff98cc42ef7..50f15e7037c 100644 > --- a/libstdc++-v3/testsuite/20_util/make_unsigned/requirements/typedefs_neg.cc > +++ b/libstdc++-v3/testsuite/20_util/make_unsigned/requirements/typedefs_neg.cc > @@ -21,7 +21,6 @@ > > #include > > -enum test_enum { first_selection }; > struct pod_class { }; > > void test01() > @@ -29,22 +28,20 @@ void test01() > using std::make_unsigned; > > // Negative tests. > - typedef make_unsigned::type test1_type; > + using T1 = make_unsigned::type; // { dg-error "incomplete" } > + using T2 = make_unsigned::type; // { dg-error "incomplete" } > + using T3 = make_unsigned::type; // { dg-error "incomplete" } > + using T4 = make_unsigned::type; // { dg-error "incomplete" } > > - typedef make_unsigned::type test2_type; > + using T5 = make_unsigned::type; // { dg-error "here" } > > - typedef make_unsigned::type test3_type; > + using T6 = make_unsigned::type; // { dg-error "here" } > > - typedef void (fn_type) (); > - typedef make_unsigned::type test4_type; > + using fn_type = void (); > + using T7 = make_unsigned::type; // { dg-error "here" } > > - typedef make_unsigned::type test5_type; > + using T8 = make_unsigned::type; // { dg-error "here" } > } > > -// { dg-error "invalid use of incomplete type" "" { target *-*-* } 32 } > -// { dg-error "required from here" "" { target *-*-* } 34 } > -// { dg-error "required from here" "" { target *-*-* } 36 } > -// { dg-error "required from here" "" { target *-*-* } 39 } > -// { dg-error "required from here" "" { target *-*-* } 41 } > - > -// { dg-error "invalid use of incomplete type" "" { target *-*-* } 0 } > +// { dg-error "invalid use of incomplete type" "" { target c++17_down } 0 } > +// { dg-error "constraint failure" "" { target c++20 } 0 } > diff --git a/libstdc++-v3/testsuite/24_iterators/range_access/range_access_cpp20_neg.cc b/libstdc++-v3/testsuite/24_iterators/range_access/range_access_cpp20_neg.cc > index c0825a58587..26c8ae0ee1e 100644 > --- a/libstdc++-v3/testsuite/24_iterators/range_access/range_access_cpp20_neg.cc > +++ b/libstdc++-v3/testsuite/24_iterators/range_access/range_access_cpp20_neg.cc > @@ -46,4 +46,5 @@ test03() > C c; > std::ssize(c); // { dg-error "no matching function" } > } > -// { dg-error "incomplete type .*make_signed.*S" "" { target *-*-* } 0 } > +// { dg-error "incomplete type .*make_signed.*S" "" { target c++17_down } 0 } > +// { dg-error "constraint failure" "" { target c++20 } 0 } > diff --git a/libstdc++-v3/testsuite/lib/prune.exp b/libstdc++-v3/testsuite/lib/prune.exp > index d457e975218..6d0b77a8ccd 100644 > --- a/libstdc++-v3/testsuite/lib/prune.exp > +++ b/libstdc++-v3/testsuite/lib/prune.exp > @@ -51,6 +51,7 @@ proc libstdc++-dg-prune { system text } { > regsub -all "(^|\n)\[^\n\]*: (recursively )?required \[^\n\]*" $text "" text > regsub -all "(^|\n)\[^\n\]*: . skipping \[0-9\]* instantiation contexts \[^\n\]*" $text "" text > regsub -all "(^|\n)\[^\n\]*: in .constexpr. expansion \[^\n\]*" $text "" text > + regsub -all "(^|\n)\[^\n\]*: in requirements .with\[^\n\]*" $text "" text > regsub -all "(^|\n) inlined from \[^\n\]*" $text "" text > # Why doesn't GCC need these to strip header context? > regsub -all "(^|\n)In file included from \[^\n\]*" $text "" text > -- > 2.37.3 > >