From patchwork Wed Jul 20 23:00:09 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Li, Pan2 via Gcc-patches" X-Patchwork-Id: 84 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:adf:e252:0:0:0:0:0 with SMTP id bl18csp1177642wrb; Wed, 20 Jul 2022 16:01:47 -0700 (PDT) X-Google-Smtp-Source: AGRyM1tCNA9834m7JR0NbAlc7FHIGZ5THFsv1UD50KdagWZzT83AedKMbkdZnmxO8T2DUlGpmNWC X-Received: by 2002:a05:6402:520c:b0:43a:aba8:84ae with SMTP id s12-20020a056402520c00b0043aaba884aemr55691360edd.198.1658358107790; Wed, 20 Jul 2022 16:01:47 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1658358107; cv=none; d=google.com; s=arc-20160816; b=0UxzE3icvWt+Ci/pcTqwZDrcfRmbQjNebSszluy2q1PMK7MRLSpBUEIJ8dUwf6gVEI YNQCeEdTej/oxKrwONCx/Gi30Adxg5n6kMxil+t78qcNmgH1FrZRMS94uN6aoZFBSSnY VDrvHkMz0lRAbkMarS6qQL4+cg/ABozRHV+3oM5104RtlYyMGFF7lrV8mfIW7JAsYZqm 4CU+TkWAtD0pAuwIp5O2dT1KWFPKke9oFzzQb4cDBktHTDLCMwAzhfpWV/dfey03G5Qd 9ctgu1os0A3OjHzUNhttan2Erh8c6iepxisWCB07Q/8Opi3Lvf0aZQwQ4u/e4G2sHLUv wBPQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:reply-to:from:list-subscribe:list-help:list-post :list-archive:list-unsubscribe:list-id:precedence :content-transfer-encoding:mime-version:message-id:date:subject:to :dmarc-filter:delivered-to:dkim-signature:dkim-filter; bh=LVUw7Y9Aa/8cczqjiyFz6ZerL1/6/k+hkxlUbLHgp88=; b=UqfLrQo2AQcBGf4do6nDbYKiE1+i7yzD/8/tNC1LiM77ahX4B0KGc+gRQt3k/Oqy6/ 85KS7EdUXtjQkiPlA1D+ryFceGSWQ+2MsMhEdILve51UvIcrSwjVi9skoK32wCrAlXCq J1EQbQiTHjKZCdt9jZOXyIwPRkJsomy034/CuaE20W8uyp5P7t2pqp5HPeQPvVWKsenE KBVXPIn0nBsMOsK+3JS/NE7uQrbPogCK/1lj0b9FHIIpuBZ6MKYegICx1OvGoDPUBtw0 QXWLnOrd7Qp0pqyM++JuAWj0P/AIhfcx84ecaGR5Iuv4g5QqsJVVNJ203iOToEPoLp1+ TZQw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=gRJNAT6B; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 8.43.85.97 as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gnu.org Received: from sourceware.org (ip-8-43-85-97.sourceware.org. [8.43.85.97]) by mx.google.com with ESMTPS id hq19-20020a1709073f1300b0072f0f088ed7si697091ejc.712.2022.07.20.16.01.47 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 20 Jul 2022 16:01:47 -0700 (PDT) Received-SPF: pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 8.43.85.97 as permitted sender) client-ip=8.43.85.97; Authentication-Results: mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=gRJNAT6B; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 8.43.85.97 as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gnu.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id D90673851A99 for ; Wed, 20 Jul 2022 23:01:04 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org D90673851A99 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1658358064; bh=LVUw7Y9Aa/8cczqjiyFz6ZerL1/6/k+hkxlUbLHgp88=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=gRJNAT6BIGeNDZB1UpSZEo9XM8GgMp/o3d5RtrrNpUz71x38JD20Qi8Hdka8elIUV lxYFJnFeb7ghOTkD20lB6mu0dhEfjKysJngAS1zBBWkjtALkHX4svzGWngNnfvCclN 5XMFGJC0uapJWwnwvApWtB2nFITzF5q5rjkdCP5c= 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.133.124]) by sourceware.org (Postfix) with ESMTPS id C58653858C62 for ; Wed, 20 Jul 2022 23:00:19 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org C58653858C62 Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-378-rTPGJltiMNuwABMy2nQm_A-1; Wed, 20 Jul 2022 19:00:12 -0400 X-MC-Unique: rTPGJltiMNuwABMy2nQm_A-1 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.rdu2.redhat.com [10.11.54.1]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 1A393185A7B2; Wed, 20 Jul 2022 23:00:12 +0000 (UTC) Received: from localhost (unknown [10.33.36.32]) by smtp.corp.redhat.com (Postfix) with ESMTP id DA52C404754B; Wed, 20 Jul 2022 23:00:11 +0000 (UTC) To: libstdc++@gcc.gnu.org, gcc-patches@gcc.gnu.org Subject: [committed 1/3] libstdc++: Fix minor bugs in std::common_iterator Date: Thu, 21 Jul 2022 00:00:09 +0100 Message-Id: <20220720230011.2732391-1-jwakely@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.11.54.1 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-12.3 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, 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 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: "Li, Pan2 via Gcc-patches" Reply-To: Jonathan Wakely Errors-To: gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org Sender: "Gcc-patches" X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1738914511381036083?= X-GMAIL-MSGID: =?utf-8?q?1738914511381036083?= Tested powerpc64le-linux, pushed to trunk. -- >8 -- The noexcept-specifier for some std::common_iterator constructors was incorrectly using an rvalue as the first argument of std::is_nothrow_assignable_v. This gave the wrong answer for some types, e.g. std::common_iterator, because an rvalue of scalar type cannot be assigned to. Also fix the friend declaration to use the same constraints as on the definition of the class template. G++ fails to diagnose this error, due to PR c++/96830. Finally, the copy constructor was using std::move for its argument in some cases, which should be removed. libstdc++-v3/ChangeLog: * include/bits/stl_iterator.h (common_iterator): Fix incorrect uses of is_nothrow_assignable_v. Fix inconsistent constraints on friend declaration. Do not move argument in copy constructor. * testsuite/24_iterators/common_iterator/1.cc: Check for noexcept constructibnle/assignable. --- libstdc++-v3/include/bits/stl_iterator.h | 11 +++++---- .../24_iterators/common_iterator/1.cc | 23 ++++++++++++++++++- 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/libstdc++-v3/include/bits/stl_iterator.h b/libstdc++-v3/include/bits/stl_iterator.h index 049cb02a4c4..fd0ae3aa771 100644 --- a/libstdc++-v3/include/bits/stl_iterator.h +++ b/libstdc++-v3/include/bits/stl_iterator.h @@ -1838,7 +1838,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _S_noexcept1() { if constexpr (is_trivially_default_constructible_v<_Tp>) - return is_nothrow_assignable_v<_Tp, _Up>; + return is_nothrow_assignable_v<_Tp&, _Up>; else return is_nothrow_constructible_v<_Tp, _Up>; } @@ -1932,14 +1932,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION if (_M_index == 0) { if constexpr (is_trivially_default_constructible_v<_It>) - _M_it = std::move(__x._M_it); + _M_it = __x._M_it; else std::construct_at(std::__addressof(_M_it), __x._M_it); } else if (_M_index == 1) { if constexpr (is_trivially_default_constructible_v<_Sent>) - _M_sent = std::move(__x._M_sent); + _M_sent = __x._M_sent; else std::construct_at(std::__addressof(_M_sent), __x._M_sent); } @@ -1964,8 +1964,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION operator=(const common_iterator<_It2, _Sent2>& __x) noexcept(is_nothrow_constructible_v<_It, const _It2&> && is_nothrow_constructible_v<_Sent, const _Sent2&> - && is_nothrow_assignable_v<_It, const _It2&> - && is_nothrow_assignable_v<_Sent, const _Sent2&>) + && is_nothrow_assignable_v<_It&, const _It2&> + && is_nothrow_assignable_v<_Sent&, const _Sent2&>) { switch(_M_index << 2 | __x._M_index) { @@ -2164,6 +2164,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION private: template _Sent2> + requires (!same_as<_It2, _Sent2>) && copyable<_It2> friend class common_iterator; constexpr bool _M_has_value() const noexcept { return _M_index < 2; } diff --git a/libstdc++-v3/testsuite/24_iterators/common_iterator/1.cc b/libstdc++-v3/testsuite/24_iterators/common_iterator/1.cc index 365ee89c02e..ec4a86c862a 100644 --- a/libstdc++-v3/testsuite/24_iterators/common_iterator/1.cc +++ b/libstdc++-v3/testsuite/24_iterators/common_iterator/1.cc @@ -27,15 +27,30 @@ test01() using I = std::common_iterator; static_assert( std::is_default_constructible_v ); static_assert( std::is_copy_constructible_v ); + static_assert( std::is_move_constructible_v ); static_assert( std::is_copy_assignable_v ); + static_assert( std::is_move_assignable_v ); static_assert( std::is_constructible_v ); static_assert( std::is_constructible_v ); - struct sentinel { operator int*() const { return nullptr; } }; + static_assert( std::is_nothrow_copy_constructible_v ); // GCC extension + static_assert( std::is_nothrow_move_constructible_v ); // GCC extension + static_assert( std::is_nothrow_copy_assignable_v ); // GCC extension + static_assert( std::is_nothrow_move_assignable_v ); // GCC extension + + struct sentinel { operator int*() const noexcept { return nullptr; } }; using K = std::common_iterator; static_assert( std::is_constructible_v ); static_assert( std::is_assignable_v ); + static_assert( std::is_nothrow_assignable_v ); // GCC extension + + struct sentinel_throwing { operator int*() const { return nullptr; } }; + using K_throwing = std::common_iterator; + // Conversion is noexcept(false) + static_assert( ! std::is_nothrow_assignable_v ); + + struct sentinel2 { const int* p; @@ -46,6 +61,12 @@ test01() using J = std::common_iterator; static_assert( std::is_constructible_v ); static_assert( std::is_convertible_v ); + + static_assert( std::is_constructible_v ); + static_assert( std::is_convertible_v ); + + // Constructor is noexcept(false) + static_assert( ! std::is_nothrow_constructible_v ); } void From patchwork Wed Jul 20 23:00:10 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Li, Pan2 via Gcc-patches" X-Patchwork-Id: 86 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:adf:e252:0:0:0:0:0 with SMTP id bl18csp1178236wrb; Wed, 20 Jul 2022 16:03:11 -0700 (PDT) X-Google-Smtp-Source: AGRyM1tZIqDfgHVD6cB58DNXTNJIvIUsaSUh0nFiLFeRKCZY3iQel3L43cOz2lZg1Q2CcUbWwHKy X-Received: by 2002:a17:907:6e02:b0:72b:9f16:1bc5 with SMTP id sd2-20020a1709076e0200b0072b9f161bc5mr38129247ejc.676.1658358191253; Wed, 20 Jul 2022 16:03:11 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1658358191; cv=none; d=google.com; s=arc-20160816; b=VR+LS6v8xzCKcH5WVkuG+/2FKweoCv1xAN8/s8rcqtM2oG3DdK2ra1HA5mQB0CfpCY tExSEm5OoGnEwb9fu85QrnqFfwnoLp98kupUqHsWnwMQ/leKlCqwNvkfiEDhTf7GRgZH ATuotzN0f6jzlasX3rYvdblbTLbuxJPCoNzw63rZxYFmNRdf7XKHnamQ0WZFg7Sn6NtZ axe6wH7WsNaRAYD+LUg1tXKgaevrUTJCEUQz8ZRuD3j+S91tNDjjOWUZwSaTr6ak70T4 zHwd9p/zrqsPKgpKwW+UbgrAv7FvnhwaZYVkOrubHF/NGG7WaebVmd7Hk+6oNa/Xodlo sJ0w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:reply-to:from:list-subscribe:list-help:list-post :list-archive:list-unsubscribe:list-id:precedence :content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:dmarc-filter:delivered-to:dkim-signature :dkim-filter; bh=kmyW7L4sCHjK0twVqJFQa+fsM1iZjCx6WduzvIfVqfA=; b=nLAOoPEO+PhXqvDNH2NjXH2WguHeRnh6+UurntI1fMNcalubpowN4p8IIgEmOMbXSc eSFrlDRu/WFoV+0gK+fP6oGk+/tVVN4z+CDJIHetJ8pgpiWAR7NNqNfvJHOe8sU6pne9 sPrr3zHvJJufAFcvYkx8SIDM66V8QHCadMIjHFQ3RqNQu4j+z8dMUwLrY4qtNxrrqi// 1yQA2oOLro/BG3hxiD0cMy+IXX/lkKpkqRcyNcNVtQnensjBCley4R+XN67mYj6wkDBd 5dFW9bApZmesat8GJiWRH/0EmMh31rWFhRWk/8Td35vGjNTGvUWwQI6g4d5+zwVi8mTo Hsag== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=o5KYLolX; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gnu.org Received: from sourceware.org (server2.sourceware.org. [2620:52:3:1:0:246e:9693:128c]) by mx.google.com with ESMTPS id q17-20020a056402519100b0043586d19cf9si340809edd.465.2022.07.20.16.03.11 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 20 Jul 2022 16:03:11 -0700 (PDT) Received-SPF: pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) client-ip=2620:52:3:1:0:246e:9693:128c; Authentication-Results: mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=o5KYLolX; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gnu.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 1C3433851C21 for ; Wed, 20 Jul 2022 23:02:13 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 1C3433851C21 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1658358133; bh=kmyW7L4sCHjK0twVqJFQa+fsM1iZjCx6WduzvIfVqfA=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=o5KYLolX8Z5zs4/jsu4JVg801f16UcICOHs9gl5rZHWSGgfJQAYXpagwW7IqdDGhy l27vk/Kto1W3ke1Hu05rLvNNc6buPo7bxkztR1hW8V+rsBokz2tsxEriHw5m91PhJJ 1xC07HLBOAtZoXg3CPifVdcUWXwvE40Z00mvyhzU= 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.133.124]) by sourceware.org (Postfix) with ESMTPS id 983EB3858C83 for ; Wed, 20 Jul 2022 23:00:17 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 983EB3858C83 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-172-Z300pIbcMC-P8sThLWeIxQ-1; Wed, 20 Jul 2022 19:00:13 -0400 X-MC-Unique: Z300pIbcMC-P8sThLWeIxQ-1 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.rdu2.redhat.com [10.11.54.4]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id DC0583802B81; Wed, 20 Jul 2022 23:00:12 +0000 (UTC) Received: from localhost (unknown [10.33.36.32]) by smtp.corp.redhat.com (Postfix) with ESMTP id A83362026D64; Wed, 20 Jul 2022 23:00:12 +0000 (UTC) To: libstdc++@gcc.gnu.org, gcc-patches@gcc.gnu.org Subject: [committed 2/3] libstdc++: Fix std::common_iterator assignment [PR100823] Date: Thu, 21 Jul 2022 00:00:10 +0100 Message-Id: <20220720230011.2732391-2-jwakely@redhat.com> In-Reply-To: <20220720230011.2732391-1-jwakely@redhat.com> References: <20220720230011.2732391-1-jwakely@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.78 on 10.11.54.4 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-14.1 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, 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: "Li, Pan2 via Gcc-patches" Reply-To: Jonathan Wakely Errors-To: gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org Sender: "Gcc-patches" X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1738914599102419148?= X-GMAIL-MSGID: =?utf-8?q?1738914599102419148?= Tested powerpc64le-linux, pushed to trunk. -- >8 -- This fixes the following conformance problems reported in the PR: - Move constructor and move assignment should be defined. - Copy assignment from a valueless object should be allowed. Assignment is completely rewritten by this patch, as the previous version had a number of problems. The converting assignment failed to handle the case of assigning a new value to a valueless object, which should work. It only accepted lvalue arguments, so wasn't usable to implement the move assignment operator. Finally, it enforced the precondition that the argument is not valueless, which is correct for the converting assignment but not for the copy assignment. A new _M_assign member is added to handle all cases of assignment (copying from an lvalue, moving from an rvalue, and converting from a different type). The not valueless precondition is checked in the converting assignment before calling _M_assign, so isn't enforced for copy and move assignment. The new function no longer uses a switch, so handles valueless objects as the LHS or RHS of the assignment. libstdc++-v3/ChangeLog: PR libstdc++/100823 * include/bits/stl_iterator.h (common_iterator): Define move constructor and move assignment operator. (common_iterator::_M_assign): New function implementing assignment. (common_iterator::operator=): Use _M_assign. (common_iterator::_S_valueless): New constant. * testsuite/24_iterators/common_iterator/100823.cc: New test. --- libstdc++-v3/include/bits/stl_iterator.h | 126 ++++++++++++------ .../24_iterators/common_iterator/100823.cc | 43 ++++++ 2 files changed, 129 insertions(+), 40 deletions(-) create mode 100644 libstdc++-v3/testsuite/24_iterators/common_iterator/100823.cc diff --git a/libstdc++-v3/include/bits/stl_iterator.h b/libstdc++-v3/include/bits/stl_iterator.h index fd0ae3aa771..a913c04deaa 100644 --- a/libstdc++-v3/include/bits/stl_iterator.h +++ b/libstdc++-v3/include/bits/stl_iterator.h @@ -1908,6 +1908,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION noexcept(_S_noexcept()) : _M_valueless(), _M_index(__x._M_index) { + __glibcxx_assert(__x._M_has_value()); if (_M_index == 0) { if constexpr (is_trivially_default_constructible_v<_It>) @@ -1945,14 +1946,58 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } } + constexpr + common_iterator(common_iterator&& __x) + noexcept(_S_noexcept<_It, _Sent>()) + : _M_valueless(), _M_index(__x._M_index) + { + if (_M_index == 0) + { + if constexpr (is_trivially_default_constructible_v<_It>) + _M_it = std::move(__x._M_it); + else + std::construct_at(std::__addressof(_M_it), std::move(__x._M_it)); + } + else if (_M_index == 1) + { + if constexpr (is_trivially_default_constructible_v<_Sent>) + _M_sent = std::move(__x._M_sent); + else + std::construct_at(std::__addressof(_M_sent), + std::move(__x._M_sent)); + } + } + + constexpr common_iterator& + operator=(const common_iterator&) = default; + constexpr common_iterator& operator=(const common_iterator& __x) noexcept(is_nothrow_copy_assignable_v<_It> && is_nothrow_copy_assignable_v<_Sent> && is_nothrow_copy_constructible_v<_It> && is_nothrow_copy_constructible_v<_Sent>) + requires (!is_trivially_copy_assignable_v<_It> + || !is_trivially_copy_assignable_v<_Sent>) { - return this->operator=<_It, _Sent>(__x); + _M_assign(__x); + return *this; + } + + constexpr common_iterator& + operator=(common_iterator&&) = default; + + constexpr common_iterator& + operator=(common_iterator&& __x) + noexcept(is_nothrow_move_assignable_v<_It> + && is_nothrow_move_assignable_v<_Sent> + && is_nothrow_move_constructible_v<_It> + && is_nothrow_move_constructible_v<_Sent>) + requires (!is_trivially_move_assignable_v<_It> + || !is_trivially_move_assignable_v<_Sent>) + { + _M_assign(std::move(__x)); + return *this; } template @@ -1967,49 +2012,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION && is_nothrow_assignable_v<_It&, const _It2&> && is_nothrow_assignable_v<_Sent&, const _Sent2&>) { - switch(_M_index << 2 | __x._M_index) - { - case 0b0000: - _M_it = __x._M_it; - break; - case 0b0101: - _M_sent = __x._M_sent; - break; - case 0b0001: - _M_it.~_It(); - _M_index = -1; - [[fallthrough]]; - case 0b1001: - std::construct_at(std::__addressof(_M_sent), _Sent(__x._M_sent)); - _M_index = 1; - break; - case 0b0100: - _M_sent.~_Sent(); - _M_index = -1; - [[fallthrough]]; - case 0b1000: - std::construct_at(std::__addressof(_M_it), _It(__x._M_it)); - _M_index = 0; - break; - default: - __glibcxx_assert(__x._M_has_value()); - __builtin_unreachable(); - } + __glibcxx_assert(__x._M_has_value()); + _M_assign(__x); return *this; } constexpr ~common_iterator() { - switch (_M_index) - { - case 0: - _M_it.~_It(); - break; - case 1: - _M_sent.~_Sent(); - break; - } + if (_M_index == 0) + _M_it.~_It(); + else if (_M_index == 1) + _M_sent.~_Sent(); } [[nodiscard]] @@ -2167,7 +2181,37 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION requires (!same_as<_It2, _Sent2>) && copyable<_It2> friend class common_iterator; - constexpr bool _M_has_value() const noexcept { return _M_index < 2; } + constexpr bool + _M_has_value() const noexcept { return _M_index != _S_valueless; } + + template + constexpr void + _M_assign(_CIt&& __x) + { + if (_M_index == __x._M_index) + { + if (_M_index == 0) + _M_it = std::forward<_CIt>(__x)._M_it; + else if (_M_index == 1) + _M_sent = std::forward<_CIt>(__x)._M_sent; + } + else + { + if (_M_index == 0) + _M_it.~_It(); + else if (_M_index == 1) + _M_sent.~_Sent(); + _M_index = _S_valueless; + + if (__x._M_index == 0) + std::construct_at(std::__addressof(_M_it), + std::forward<_CIt>(__x)._M_it); + else if (__x._M_index == 1) + std::construct_at(std::__addressof(_M_sent), + std::forward<_CIt>(__x)._M_sent); + _M_index = __x._M_index; + } + } union { @@ -2175,7 +2219,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _Sent _M_sent; unsigned char _M_valueless; }; - unsigned char _M_index; // 0==_M_it, 1==_M_sent, 2==valueless + unsigned char _M_index; // 0 == _M_it, 1 == _M_sent, 2 == valueless + + static constexpr unsigned char _S_valueless{2}; }; template diff --git a/libstdc++-v3/testsuite/24_iterators/common_iterator/100823.cc b/libstdc++-v3/testsuite/24_iterators/common_iterator/100823.cc new file mode 100644 index 00000000000..4f2b23de8cc --- /dev/null +++ b/libstdc++-v3/testsuite/24_iterators/common_iterator/100823.cc @@ -0,0 +1,43 @@ +// { dg-options "-std=gnu++20 -D_GLIBCXX_ASSERTIONS" } +// { dg-do run { target c++20 } } +#include +#include +#include + +void +test_valueless_assignment() +{ + int x[1] { }; + __gnu_test::test_forward_range r(x); + using Iter = decltype(r.begin()); + using Sent = decltype(r.end()); + + std::common_iterator i; + const std::common_iterator j(r.begin()); + try + { + struct Bomb + { + bool operator==(Iter) const { return true; } + operator Sent() const { throw 1; } + }; + std::common_iterator b{Bomb{}}; + i = b; // Throws, leaving i valueless-by-exception. + VERIFY(false); + } + catch (int) + { + std::common_iterator k(i); + + // PR libstdc++/100823 + k = i; // Valid even though both operands are valueless. + + i = j; // No longer valueless. + } + VERIFY( i == j ); +} + +int main() +{ + test_valueless_assignment(); +} From patchwork Wed Jul 20 23:00:11 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Li, Pan2 via Gcc-patches" X-Patchwork-Id: 85 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:adf:e252:0:0:0:0:0 with SMTP id bl18csp1178178wrb; Wed, 20 Jul 2022 16:02:59 -0700 (PDT) X-Google-Smtp-Source: AGRyM1vILImqoxI+XPXYorA79+gbb9/aQuvlixqEbc9z8PLEq/LVEujPJRcixg2Ry1FICHMy59Ao X-Received: by 2002:a17:906:98c8:b0:72b:41dc:c271 with SMTP id zd8-20020a17090698c800b0072b41dcc271mr38555651ejb.36.1658358179103; Wed, 20 Jul 2022 16:02:59 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1658358179; cv=none; d=google.com; s=arc-20160816; b=D3/KPen9DfI+VHF2tKeBO1SKkMguGXkVUG4zw0aHxWQt2xPznyZyBXciHcpEhvrOuh Bx3CjNNugbKsG+Z8H1VDWbj+Q48XR0/24TxjfWdn/Czd3qIWa2wNnd0rKc9euBVb/5eQ wHBK10ng2Z69/vqCkHQ/ws+TQY9vs5P9ZwI3iyoL2mwFFaDXI1wWZFLlou1p0M9O0yED dL9XdlI2kmMjGAD3Sr/+d92GnyvByQR+ymzFnOgEB8bbdFkGwrWIeA+sDsRBDxp6QxGm RL5jUiTIxVVCqfhsTAJ1m+zd+QTQsuPlBUjPoScaG58X5HzmFnB/lYC6tDt9P9XEZo81 gfvA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:reply-to:from:list-subscribe:list-help:list-post :list-archive:list-unsubscribe:list-id:precedence :content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:dmarc-filter:delivered-to:dkim-signature :dkim-filter; bh=rpvfRu0tTT+jedW+BiQVSSFbdugQrw08ak5XXRK9eN8=; b=uX6LDdEeB1hLz4aWVaSd3VkaLy0RDW10s7BLlfBoEv1+QO7FUTyiRC1eqRvsv8zk60 95P42dibi3Tpife0xPu/DYOSS7BL+47t5dLWldTQeJaYa9YaQwkqsXXFbk2PwdgP+j4a 0q4XbOz0HB58X2FCiSL/lgzJj8fj+kdh8OXTDFzqrS1nRt+n6NyB1NieFpv/LA4dtHSh 2w8MuLM6KP+6SKDTsS+yuDLWKhnI38wfVSESugEtNgxKBqlJedpXAYfXK/abY8/qwkUe M5yYNONjwl4BVob5UIeEX/XPszcrx3KEaP8RmXDtQ6+BWPJyOzTOV6UMq/U2iUP58ARD x+8A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=lNkMI4SU; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gnu.org Received: from sourceware.org (server2.sourceware.org. [2620:52:3:1:0:246e:9693:128c]) by mx.google.com with ESMTPS id b13-20020a056402084d00b0043b5531e9acsi384848edz.469.2022.07.20.16.02.58 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 20 Jul 2022 16:02:59 -0700 (PDT) Received-SPF: pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) client-ip=2620:52:3:1:0:246e:9693:128c; Authentication-Results: mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=lNkMI4SU; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gnu.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 07FF43857407 for ; Wed, 20 Jul 2022 23:02:02 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 07FF43857407 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1658358122; bh=rpvfRu0tTT+jedW+BiQVSSFbdugQrw08ak5XXRK9eN8=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=lNkMI4SUYKlqxbvzaigl7fjw/yUkDRoLWESdUtHPGlxM20wyX+q1wzQ0Vha3pshGv 55CaO93zxamLkWC58vWxDynSqKqkVHyyEhc+ASRYO9dndt1f2UA2BQB3Yqo5iWSpbm D1GvvHalDbly9dX+XjMXGTtNmipgDRCxnxAm6v2U= 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.133.124]) by sourceware.org (Postfix) with ESMTPS id 557493858C2C for ; Wed, 20 Jul 2022 23:00:21 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 557493858C2C Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-458-BqNoneFfMNyVnzDiXNAj0Q-1; Wed, 20 Jul 2022 19:00:14 -0400 X-MC-Unique: BqNoneFfMNyVnzDiXNAj0Q-1 Received: from smtp.corp.redhat.com (int-mx10.intmail.prod.int.rdu2.redhat.com [10.11.54.10]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id A86CC185A7BA; Wed, 20 Jul 2022 23:00:13 +0000 (UTC) Received: from localhost (unknown [10.33.36.32]) by smtp.corp.redhat.com (Postfix) with ESMTP id 7565F492C3B; Wed, 20 Jul 2022 23:00:13 +0000 (UTC) To: libstdc++@gcc.gnu.org, gcc-patches@gcc.gnu.org Subject: [committed 3/3] libstdc++: Fix std::common_iterator triviality [PR100823] Date: Thu, 21 Jul 2022 00:00:11 +0100 Message-Id: <20220720230011.2732391-3-jwakely@redhat.com> In-Reply-To: <20220720230011.2732391-1-jwakely@redhat.com> References: <20220720230011.2732391-1-jwakely@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.85 on 10.11.54.10 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, SPF_HELO_NONE, SPF_NONE, TXREP, URI_HEX autolearn=ham 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: "Li, Pan2 via Gcc-patches" Reply-To: Jonathan Wakely Errors-To: gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org Sender: "Gcc-patches" X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1738914585981909818?= X-GMAIL-MSGID: =?utf-8?q?1738914585981909818?= Tested powerpc64le-linux, pushed to trunk. -- >8 -- This fixes the remaining problem reported in the PR, that the special members should be trivial. This can be done by constraining the non-trivial versions and adding defaulted overloads that will be used when the union members are trivial. Making these members trivial alters the argument passing ABI and so isn't suitable for backporting to release branches. libstdc++-v3/ChangeLog: PR libstdc++/100823 * include/bits/stl_iterator.h (common_iterator): Define destructor, copy constructor and move constructor as trivial when the underlying types allow. * testsuite/24_iterators/common_iterator/100823.cc: Check triviality of special members. --- libstdc++-v3/include/bits/stl_iterator.h | 15 +++++++++++++++ .../24_iterators/common_iterator/100823.cc | 15 +++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/libstdc++-v3/include/bits/stl_iterator.h b/libstdc++-v3/include/bits/stl_iterator.h index a913c04deaa..9cd262cd1d9 100644 --- a/libstdc++-v3/include/bits/stl_iterator.h +++ b/libstdc++-v3/include/bits/stl_iterator.h @@ -1925,9 +1925,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } } + common_iterator(const common_iterator&) = default; + constexpr common_iterator(const common_iterator& __x) noexcept(_S_noexcept()) + requires (!is_trivially_copyable_v<_It> || !is_trivially_copyable_v<_Sent>) : _M_valueless(), _M_index(__x._M_index) { if (_M_index == 0) @@ -1946,9 +1949,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } } + common_iterator(common_iterator&&) = default; + constexpr common_iterator(common_iterator&& __x) noexcept(_S_noexcept<_It, _Sent>()) + requires (!is_trivially_copyable_v<_It> || !is_trivially_copyable_v<_Sent>) : _M_valueless(), _M_index(__x._M_index) { if (_M_index == 0) @@ -2017,8 +2023,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return *this; } +#if __cpp_concepts >= 202002L // Constrained special member functions + ~common_iterator() = default; + constexpr ~common_iterator() + requires (!is_trivially_destructible_v<_It> + || !is_trivially_destructible_v<_Sent>) +#else + constexpr + ~common_iterator() +#endif { if (_M_index == 0) _M_it.~_It(); diff --git a/libstdc++-v3/testsuite/24_iterators/common_iterator/100823.cc b/libstdc++-v3/testsuite/24_iterators/common_iterator/100823.cc index 4f2b23de8cc..b42dd087ab2 100644 --- a/libstdc++-v3/testsuite/24_iterators/common_iterator/100823.cc +++ b/libstdc++-v3/testsuite/24_iterators/common_iterator/100823.cc @@ -4,6 +4,21 @@ #include #include +void +test_triviality() +{ + using I = std::common_iterator; + + // Cannot be trivial, because it has to initialize members. + static_assert( ! std::is_trivially_default_constructible_v ); + + static_assert( std::is_trivially_destructible_v ); + static_assert( std::is_trivially_copy_constructible_v ); + static_assert( std::is_trivially_copy_assignable_v ); + static_assert( std::is_trivially_move_constructible_v ); + static_assert( std::is_trivially_move_assignable_v ); +} + void test_valueless_assignment() {