From patchwork Tue Jan 11 13:30:15 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Wakely X-Patchwork-Id: 49840 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 0BA28385AC32 for ; Tue, 11 Jan 2022 13:40:19 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 0BA28385AC32 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1641908419; bh=ETiwvg4k8Zh356vQBBsvq47Lq9y5QaGDoHUjcychCJc=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=T1uEedOlqU596OJ4cHJC4n5EJEOj2YyUfXaTj5BzIWOEnvYJCKuDiM/Q++ZHw/6xH xAaRj9k/2QdxIpyb4SJhGvfX6dVZaacidZ3COuNev75g+n2WjfuZ2jjLLs3FwtHn59 qV32Pooj2kTQBc62myg37lOmGq1sLHxqILs2OZPE= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org 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 BBEAC38AAC2A for ; Tue, 11 Jan 2022 13:30:20 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org BBEAC38AAC2A Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-103-ZxPKz7XuNyqTRC5aet_QcQ-1; Tue, 11 Jan 2022 08:30:17 -0500 X-MC-Unique: ZxPKz7XuNyqTRC5aet_QcQ-1 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 5D2DC86A061; Tue, 11 Jan 2022 13:30:16 +0000 (UTC) Received: from localhost (unknown [10.33.36.252]) by smtp.corp.redhat.com (Postfix) with ESMTP id 08A4D7E133; Tue, 11 Jan 2022 13:30:15 +0000 (UTC) To: libstdc++@gcc.gnu.org, gcc-patches@gcc.gnu.org Subject: [committed] libstdc++: Install header for freestanding [PR103726] Date: Tue, 11 Jan 2022 13:30:15 +0000 Message-Id: <20220111133015.2560682-1-jwakely@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-13.9 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_LOW, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=unavailable autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Jonathan Wakely via Gcc-patches From: Jonathan Wakely Reply-To: Jonathan Wakely Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" Tested x86_64-linux and by minimally tested on mips-none-elf. Pushed to trunk. The standard says that should be present for freestanding. That was intentionally left out of the initial implementation, but can be done without much trouble. The header should be moved to libsupc++ at some point in stage 1. The standard also says that defines a std::hash specialization, which was missing from our implementation. That's a problem for freestanding (see LWG 3653) so only do that for hosted. We can use concepts to constrain the __coroutine_traits_impl base class when compiled with concepts enabled. In a pure C++20 implementation we would not need that base class at all and could just use a constrained partial specialization of coroutine_traits. But the absence of the __coroutine_traits_impl base would create an ABI difference between the non-standard C++14/C++17 support for coroutines and the same code compiled as C++20. If we drop support for pre-C++20 we should revisit this. libstdc++-v3/ChangeLog: PR libstdc++/103726 * include/Makefile.am: Install for freestanding. * include/Makefile.in: Regenerate. * include/std/coroutine: Adjust headers and preprocessor conditions. (__coroutine_traits_impl): Use concepts when available. [_GLIBCXX_HOSTED] (hash): Define. --- libstdc++-v3/include/Makefile.am | 4 +-- libstdc++-v3/include/Makefile.in | 4 +-- libstdc++-v3/include/std/coroutine | 55 ++++++++++++++++++++++-------- 3 files changed, 45 insertions(+), 18 deletions(-) diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am index 7afebb5c5f0..8f93bf2d7b7 100644 --- a/libstdc++-v3/include/Makefile.am +++ b/libstdc++-v3/include/Makefile.am @@ -1425,7 +1425,7 @@ endif # This is a subset of the full install-headers rule. We only need , # , , , , , , , # , , , , , , -# , , , , , +# , , , , , , # and any files which they include (and which we provide). # , , , and # are installed by libsupc++, so only the others and the sub-includes @@ -1440,7 +1440,7 @@ install-freestanding-headers: ${glibcxx_srcdir}/$(CPU_DEFINES_SRCDIR)/cpu_defines.h; do \ $(INSTALL_DATA) $${file} $(DESTDIR)${host_installdir}; done $(mkinstalldirs) $(DESTDIR)${gxx_include_dir}/${std_builddir} - for file in limits type_traits atomic bit concepts version; do \ + for file in limits type_traits atomic bit concepts coroutine version; do \ $(INSTALL_DATA) ${std_builddir}/$${file} $(DESTDIR)${gxx_include_dir}/${std_builddir}; done $(mkinstalldirs) $(DESTDIR)${gxx_include_dir}/${c_base_builddir} for file in ciso646 cstddef cfloat climits cstdint cstdlib \ diff --git a/libstdc++-v3/include/Makefile.in b/libstdc++-v3/include/Makefile.in index 0031f54f3fa..4ab942ae666 100644 --- a/libstdc++-v3/include/Makefile.in +++ b/libstdc++-v3/include/Makefile.in @@ -1906,7 +1906,7 @@ ${pch3_output}: ${pch3_source} ${pch2_output} # This is a subset of the full install-headers rule. We only need , # , , , , , , , # , , , , , , -# , , , , , +# , , , , , , # and any files which they include (and which we provide). # , , , and # are installed by libsupc++, so only the others and the sub-includes @@ -1921,7 +1921,7 @@ install-freestanding-headers: ${glibcxx_srcdir}/$(CPU_DEFINES_SRCDIR)/cpu_defines.h; do \ $(INSTALL_DATA) $${file} $(DESTDIR)${host_installdir}; done $(mkinstalldirs) $(DESTDIR)${gxx_include_dir}/${std_builddir} - for file in limits type_traits atomic bit concepts version; do \ + for file in limits type_traits atomic bit concepts coroutine version; do \ $(INSTALL_DATA) ${std_builddir}/$${file} $(DESTDIR)${gxx_include_dir}/${std_builddir}; done $(mkinstalldirs) $(DESTDIR)${gxx_include_dir}/${c_base_builddir} for file in ciso646 cstddef cfloat climits cstdint cstdlib \ diff --git a/libstdc++-v3/include/std/coroutine b/libstdc++-v3/include/std/coroutine index ead5dad9bf0..f4189c7e3fc 100644 --- a/libstdc++-v3/include/std/coroutine +++ b/libstdc++-v3/include/std/coroutine @@ -34,22 +34,23 @@ // It is very likely that earlier versions would work, but they are untested. #if __cplusplus >= 201402L -#include +#include +#if __cplusplus > 201703L +# include +#endif + +#if !defined __cpp_lib_three_way_comparison && _GLIBCXX_HOSTED +# include // for std::less +#endif /** * @defgroup coroutines Coroutines * * Components for supporting coroutine implementations. + * + * @since C++20 (and since C++14 as a libstdc++ extension) */ -#if __cplusplus > 201703L && __cpp_impl_three_way_comparison >= 201907L -# include -# define _COROUTINES_USE_SPACESHIP 1 -#else -# include // for std::less -# define _COROUTINES_USE_SPACESHIP 0 -#endif - namespace std _GLIBCXX_VISIBILITY (default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION @@ -60,25 +61,33 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION inline namespace __n4861 { - // 17.12.2 coroutine traits + // C++20 17.12.2 coroutine traits /// [coroutine.traits] /// [coroutine.traits.primary] /// If _Result::promise_type is valid and denotes a type then the traits /// have a single publicly accessible member, otherwise they are empty. + template + struct coroutine_traits; + template struct __coroutine_traits_impl {}; template +#if __cpp_concepts + requires requires { typename _Result::promise_type; } + struct __coroutine_traits_impl<_Result, void> +#else struct __coroutine_traits_impl<_Result, - __void_t> + __void_t> +#endif { using promise_type = typename _Result::promise_type; }; - template + template struct coroutine_traits : __coroutine_traits_impl<_Result> {}; - // 17.12.3 Class template coroutine_handle + // C++20 17.12.3 Class template coroutine_handle /// [coroutine.handle] template struct coroutine_handle; @@ -139,7 +148,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return __a.address() == __b.address(); } -#if _COROUTINES_USE_SPACESHIP +#ifdef __cpp_lib_three_way_comparison constexpr strong_ordering operator<=>(coroutine_handle<> __a, coroutine_handle<> __b) noexcept { @@ -156,7 +165,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION constexpr bool operator<(coroutine_handle<> __a, coroutine_handle<> __b) noexcept { +#if _GLIBCXX_HOSTED return less()(__a.address(), __b.address()); +#else + return (__UINTPTR_TYPE__)__a.address() < (__UINTPTR_TYPE__)__b.address(); +#endif } constexpr bool @@ -330,6 +343,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } // namespace __n4861 +#if _GLIBCXX_HOSTED + template struct hash; + + template + struct hash> + { + size_t + operator()(const coroutine_handle<_Promise>& __h) noexcept + { + return reinterpret_cast(__h.address()); + } + }; +#endif + #else #error "the coroutine header requires -fcoroutines" #endif