From patchwork Tue Nov 22 21:50:26 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Wakely X-Patchwork-Id: 60989 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 AD88E38518B5 for ; Tue, 22 Nov 2022 21:51:05 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org AD88E38518B5 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1669153865; bh=oNXhermGwhMQdgBZ6XnZdC4KQu984zWABkY7ChAFixI=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=LMH/RBtdTKJDwlhfeZk48UaZ250SHB2x4ZeL1SEjEID7EgcazbSftGQ7X7ce6AVvb g5vCdmjolvB/eFJDbDleIAIB1/4HmJ/zybKA0RLs/ss2aS9/4Tpwy99y16GFT6nniY cEF14AM0Q7jlxGw1d9wYZzJ1op6LRdoVcY5RRedI= 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 3E9853858C27 for ; Tue, 22 Nov 2022 21:50:33 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 3E9853858C27 Received: from mimecast-mx02.redhat.com (mx3-rdu2.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-271-addk7LF3MAu37pU_tiOl1A-1; Tue, 22 Nov 2022 16:50:29 -0500 X-MC-Unique: addk7LF3MAu37pU_tiOl1A-1 Received: from smtp.corp.redhat.com (int-mx09.intmail.prod.int.rdu2.redhat.com [10.11.54.9]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 47E1429AB445; Tue, 22 Nov 2022 21:50:29 +0000 (UTC) Received: from localhost (unknown [10.33.36.60]) by smtp.corp.redhat.com (Postfix) with ESMTP id 0DE2C4B3FC6; Tue, 22 Nov 2022 21:50:28 +0000 (UTC) To: libstdc++@gcc.gnu.org, gcc-patches@gcc.gnu.org Subject: [committed] libstdc++: Add workaround for fs::path constraint recursion [PR106201] Date: Tue, 22 Nov 2022 21:50:26 +0000 Message-Id: <20221122215026.2156686-1-jwakely@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.9 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-12.2 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_NONE, RCVD_IN_MSPIKE_H2, SPF_HELO_NONE, SPF_NONE, TXREP, URI_HEX autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) 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. Pushed to gcc-12 branch. -- >8 -- This works around a compiler bug where overload resolution attempts implicit conversion to path in order to call a function with a path& parameter. Such conversion would produce a prvalue, which would not be able to bind to the lvalue reference anyway. Attempting to check the conversion causes a constraint recursion because the arguments to the path constructor are checked to see if they're iterators, which checks if they're swappable, which tries to use the swap function that triggered the conversion in the first place. This replaces the swap function with an abbreviated function template that is constrained with same_as auto& so that the invalid conversion is never considered. libstdc++-v3/ChangeLog: PR libstdc++/106201 * include/bits/fs_path.h (filesystem::swap(path&, path&)): Replace with abbreviated function template. * include/experimental/bits/fs_path.h (filesystem::swap): Likewise. * testsuite/27_io/filesystem/iterators/106201.cc: New test. * testsuite/experimental/filesystem/iterators/106201.cc: New test. --- libstdc++-v3/include/bits/fs_path.h | 7 +++++++ libstdc++-v3/include/experimental/bits/fs_path.h | 9 ++++++++- .../testsuite/27_io/filesystem/iterators/106201.cc | 14 ++++++++++++++ .../experimental/filesystem/iterators/106201.cc | 14 ++++++++++++++ 4 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 libstdc++-v3/testsuite/27_io/filesystem/iterators/106201.cc create mode 100644 libstdc++-v3/testsuite/experimental/filesystem/iterators/106201.cc diff --git a/libstdc++-v3/include/bits/fs_path.h b/libstdc++-v3/include/bits/fs_path.h index 65682c2a185..1b4a1b69f37 100644 --- a/libstdc++-v3/include/bits/fs_path.h +++ b/libstdc++-v3/include/bits/fs_path.h @@ -737,7 +737,14 @@ namespace __detail /// @{ /// @relates std::filesystem::path +#if __cpp_concepts >= 201907L + // Workaround for PR libstdc++/106201 + inline void + swap(same_as auto& __lhs, same_as auto& __rhs) noexcept + { __lhs.swap(__rhs); } +#else inline void swap(path& __lhs, path& __rhs) noexcept { __lhs.swap(__rhs); } +#endif size_t hash_value(const path& __p) noexcept; diff --git a/libstdc++-v3/include/experimental/bits/fs_path.h b/libstdc++-v3/include/experimental/bits/fs_path.h index a493e17a37e..ba6acb2158d 100644 --- a/libstdc++-v3/include/experimental/bits/fs_path.h +++ b/libstdc++-v3/include/experimental/bits/fs_path.h @@ -537,7 +537,14 @@ namespace __detail /// @relates std::experimental::filesystem::path @{ /// Swap overload for paths - inline void swap(path& __lhs, path& __rhs) noexcept { __lhs.swap(__rhs); } +#if __cpp_concepts >= 201907L + // Workaround for PR libstdc++/106201 + inline void + swap(same_as auto& __lhs, same_as auto& __rhs) noexcept + { __lhs.swap(__rhs); } +#else + inline void swap(path& __lhs, path& __rhs) noexcept { __lhs.swap(__rhs); } +#endif /// Compute a hash value for a path size_t hash_value(const path& __p) noexcept; diff --git a/libstdc++-v3/testsuite/27_io/filesystem/iterators/106201.cc b/libstdc++-v3/testsuite/27_io/filesystem/iterators/106201.cc new file mode 100644 index 00000000000..c5fefd9ac3f --- /dev/null +++ b/libstdc++-v3/testsuite/27_io/filesystem/iterators/106201.cc @@ -0,0 +1,14 @@ +// { dg-options "-std=gnu++20" } +// { dg-do compile { target c++20 } } +// { dg-require-filesystem-ts "" } + +// PR libstdc++/106201 constraint recursion in path(Source const&) constructor. + +#include +#include +#include +namespace fs = std::filesystem; +using I = std::counted_iterator; +static_assert( std::swappable ); +using R = std::counted_iterator; +static_assert( std::swappable ); diff --git a/libstdc++-v3/testsuite/experimental/filesystem/iterators/106201.cc b/libstdc++-v3/testsuite/experimental/filesystem/iterators/106201.cc new file mode 100644 index 00000000000..017b72ef5f6 --- /dev/null +++ b/libstdc++-v3/testsuite/experimental/filesystem/iterators/106201.cc @@ -0,0 +1,14 @@ +// { dg-options "-std=gnu++20" } +// { dg-do compile { target c++20 } } +// { dg-require-filesystem-ts "" } + +// PR libstdc++/106201 constraint recursion in path(Source const&) constructor. + +#include +#include +#include +namespace fs = std::experimental::filesystem; +using I = std::counted_iterator; +static_assert( std::swappable ); +using R = std::counted_iterator; +static_assert( std::swappable );