From patchwork Thu Jan 18 02:48:06 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Palka X-Patchwork-Id: 1887669 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=DKVe1hdZ; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=server2.sourceware.org; envelope-from=gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=patchwork.ozlabs.org) Received: from server2.sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4TFnJ05NPPz23dx for ; Thu, 18 Jan 2024 13:48:48 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id A3FF13858C54 for ; Thu, 18 Jan 2024 02:48:46 +0000 (GMT) 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 AF8503858D33 for ; Thu, 18 Jan 2024 02:48:16 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org AF8503858D33 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org AF8503858D33 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1705546107; cv=none; b=itkYS78BqkZ+hIpYZZhTKnlA6g+lp/nDeuHIXoL5pgkyly0JH59HNnkt/kRGAT3I2gtHMfr+i8dLwZibRuiMxtq6DY8Tw3OQH95JswIiMquCCMXaVK4lU/C6fR0XxukanmOB209xI4Z6c67ZHhfR2FA6iUdCHHODWPOLF4zJ5+c= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1705546107; c=relaxed/simple; bh=XX53WafKU6wvvpY4PO294s/zsjDGlrrqLsnozoTab8g=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=p7xECCaZ6uB1yRKKAwM+OURF+v94wTaSCiJrJG2RLhVlhdVOV9lsL0uuVYcJN9zEPckoXWERyztwRYxF+5NO1kFvrDAZN7qCLygmuNR37FZQBEXku5FgzUgMC4DPMLoBIgBHPnVMw6/qLaPMm9BrHOPmT+5XwrEedr2tjgqDPwI= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1705546096; 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: content-transfer-encoding:content-transfer-encoding; bh=0GE13KOcItgh9BqBxqctaYd5dXyXNqGmC6zr58y4CmI=; b=DKVe1hdZrQT3zo7tHoold7QTMOs3pjWLrDJ1oSGtyaInLRY1IokdM/Dodg6zhQfExRuj1k zXFE0OF9FNXuP6dn0QTrutj4b2r9L0rqbBm7iTC4sMX4AAy1Yj90jHSa7g3w3VjtLxJ6/B iK/3WV+WQVZVFLDQpAcNtqL4qUnlMYY= Received: from mail-qt1-f197.google.com (mail-qt1-f197.google.com [209.85.160.197]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-614-muK_6gMkOF29rI1docQsog-1; Wed, 17 Jan 2024 21:48:15 -0500 X-MC-Unique: muK_6gMkOF29rI1docQsog-1 Received: by mail-qt1-f197.google.com with SMTP id d75a77b69052e-429a1b96ad2so5847281cf.0 for ; Wed, 17 Jan 2024 18:48:14 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1705546093; x=1706150893; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=0GE13KOcItgh9BqBxqctaYd5dXyXNqGmC6zr58y4CmI=; b=P5NihaSCoxyORvqfbFLcFURs+j0MuemutoPfifNLvQDt0W7KLZxHmDlG0TeTJgTpjE +F/Uk82320xiPu90RZ/uBGP7vkQiaPEqXa2ajRJfYluj3uMqQZzG8f9Xfxo57PKpJzgn DS+k4ybmjsDATraqku7W8jzbHoQ9nhvp5hmxkbldhEgiiKrlar7gsSpZT5aO1GUWK3T6 Q3VmKtGTc9etUa3+tb/COMCRT+J+RSMFYk3JRQAW/Vnb4VT7BwokpWMLoGXno6sqCZc3 39AEDk83JBfkd2S7hvUveK82YcXAOS3DkYnZSbxA9tkEaRBKNqGvdSjJo8JKay/PwAAh LAmw== X-Gm-Message-State: AOJu0Yyi7YwS5Ey8DoNdCVB1k42QyXDXGkD2Rz9n7wiGljt3IRXTCcQ9 yP0brVswAe89g5jHwMnsdiM3KSZk/kCTxtam4CsF35C3a8WGfLcFCfroIcAoyXVrbkw4qPxmYPv 1tCGZGakb4LqnJ7G6zlKMBSsfKm8kAU+EWU/EVpxuujwZsnRhDBeQzNoZi4y3R+vTrRdIFMQeyw jCTrwrimhy2cXaj63NPEwrfVNtcvIxpZcYBhCt X-Received: by 2002:a05:622a:38e:b0:429:c8b0:e4fd with SMTP id j14-20020a05622a038e00b00429c8b0e4fdmr374844qtx.64.1705546092955; Wed, 17 Jan 2024 18:48:12 -0800 (PST) X-Google-Smtp-Source: AGHT+IEGne2JS+E+8iYX/i/mA3/y195yyohnBY5waGGgsB0DXfnLok33Cab2Xo0YVDcm//fmq58KMw== X-Received: by 2002:a05:622a:38e:b0:429:c8b0:e4fd with SMTP id j14-20020a05622a038e00b00429c8b0e4fdmr374831qtx.64.1705546092649; Wed, 17 Jan 2024 18:48:12 -0800 (PST) Received: from localhost.localdomain (ool-457670bb.dyn.optonline.net. [69.118.112.187]) by smtp.gmail.com with ESMTPSA id e7-20020ac81307000000b00429e6f1cc0csm3871899qtj.80.2024.01.17.18.48.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Jan 2024 18:48:12 -0800 (PST) From: Patrick Palka To: gcc-patches@gcc.gnu.org Cc: libstdc++@gcc.gnu.org, Patrick Palka Subject: [PATCH] libstdc++: Fix constexpr _Safe_iterator in C++20 mode Date: Wed, 17 Jan 2024 21:48:06 -0500 Message-ID: <20240118024806.436235-1-ppalka@redhat.com> X-Mailer: git-send-email 2.43.0.367.g186b115d30 MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com 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, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, TXREP, T_SCC_BODY_TEXT_LINE 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.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org Tested on x86_64-pc-linux-gnu, does this look OK for trunk? -- >8 -- Some _Safe_iterator member functions define a variable of non-literal type __gnu_cxx::__scoped_lock, which automatically disqualifies them from being constexpr in C++20 mode even if that code path is never constant evaluated. This restriction was lifted by P2242R3 for C++23, but we need to work around it in C++20 mode. To that end this patch defines a pair of macros that encapsulate the lambda-based workaround mentioned in that paper and uses them to make the functions valid C++20 constexpr functions. The augmented std::vector test element_access/constexpr.cc now successfully compiles in C++20 mode with -D_GLIBCXX_DEBUG (and it tests all modified member functions). libstdc++-v3/ChangeLog: * include/debug/safe_base.h (_Safe_sequence_base::_M_swap): Remove _GLIBCXX20_CONSTEXPR. * include/debug/safe_iterator.h (_GLIBCXX20_CONSTEXPR_NON_LITERAL_SCOPE_BEGIN): (_GLIBCXX20_CONSTEXPR_NON_LITERAL_SCOPE_END): Define. (_Safe_iterator::operator=): Use them around the code path that defines a variable of type __gnu_cxx::__scoped_lock. (_Safe_iterator::operator++): Likewise. (_Safe_iterator::operator--): Likewise. (_Safe_iterator::operator+=): Likewise. (_Safe_iterator::operator-=): Likewise. * testsuite/23_containers/vector/element_access/constexpr.cc (test_iterators): Also test copy and move assignment. * testsuite/std/ranges/adaptors/all.cc (test08) [_GLIBCXX_DEBUG]: Use std::vector unconditionally. --- libstdc++-v3/include/debug/safe_base.h | 1 - libstdc++-v3/include/debug/safe_iterator.h | 48 ++++++++++++++----- .../vector/element_access/constexpr.cc | 2 + .../testsuite/std/ranges/adaptors/all.cc | 4 -- 4 files changed, 38 insertions(+), 17 deletions(-) diff --git a/libstdc++-v3/include/debug/safe_base.h b/libstdc++-v3/include/debug/safe_base.h index 107fef3cb02..d5fbe4b1320 100644 --- a/libstdc++-v3/include/debug/safe_base.h +++ b/libstdc++-v3/include/debug/safe_base.h @@ -268,7 +268,6 @@ namespace __gnu_debug * operation is complete all iterators that originally referenced * one container now reference the other container. */ - _GLIBCXX20_CONSTEXPR void _M_swap(_Safe_sequence_base& __x) _GLIBCXX_USE_NOEXCEPT; diff --git a/libstdc++-v3/include/debug/safe_iterator.h b/libstdc++-v3/include/debug/safe_iterator.h index 1bc7c904ee0..929fd9b0ade 100644 --- a/libstdc++-v3/include/debug/safe_iterator.h +++ b/libstdc++-v3/include/debug/safe_iterator.h @@ -65,6 +65,20 @@ _GLIBCXX_DEBUG_VERIFY_OPERANDS(_Lhs, _Rhs, __msg_distance_bad, \ __msg_distance_different) +// This pair of macros helps with writing valid C++20 constexpr functions that +// contain a non-constexpr code path that defines a non-literal variable, which +// was otherwise disallowed until P2242R3 for C++23. We use them below for +// __gnu_cxx::__scoped_lock so that the containing functions are still +// considered valid C++20 constexpr functions. + +#if __cplusplus >= 202002L && __cpp_constexpr < 202110L +# define _GLIBCXX20_CONSTEXPR_NON_LITERAL_SCOPE_BEGIN [&]() -> void { do +# define _GLIBCXX20_CONSTEXPR_NON_LITERAL_SCOPE_END while(false); }(); +#else +# define _GLIBCXX20_CONSTEXPR_NON_LITERAL_SCOPE_BEGIN +# define _GLIBCXX20_CONSTEXPR_NON_LITERAL_SCOPE_END +#endif + namespace __gnu_debug { /** Helper struct to deal with sequence offering a before_begin @@ -266,11 +280,11 @@ namespace __gnu_debug ._M_iterator(__x, "other")); if (this->_M_sequence && this->_M_sequence == __x._M_sequence) - { + _GLIBCXX20_CONSTEXPR_NON_LITERAL_SCOPE_BEGIN { __gnu_cxx::__scoped_lock __l(this->_M_get_mutex()); base() = __x.base(); _M_version = __x._M_sequence->_M_version; - } + } _GLIBCXX20_CONSTEXPR_NON_LITERAL_SCOPE_END else { _M_detach(); @@ -306,11 +320,11 @@ namespace __gnu_debug return *this; if (this->_M_sequence && this->_M_sequence == __x._M_sequence) - { + _GLIBCXX20_CONSTEXPR_NON_LITERAL_SCOPE_BEGIN { __gnu_cxx::__scoped_lock __l(this->_M_get_mutex()); base() = __x.base(); _M_version = __x._M_sequence->_M_version; - } + } _GLIBCXX20_CONSTEXPR_NON_LITERAL_SCOPE_END else { _M_detach(); @@ -378,8 +392,10 @@ namespace __gnu_debug _GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(), _M_message(__msg_bad_inc) ._M_iterator(*this, "this")); - __gnu_cxx::__scoped_lock __l(this->_M_get_mutex()); - ++base(); + _GLIBCXX20_CONSTEXPR_NON_LITERAL_SCOPE_BEGIN { + __gnu_cxx::__scoped_lock __l(this->_M_get_mutex()); + ++base(); + } _GLIBCXX20_CONSTEXPR_NON_LITERAL_SCOPE_END return *this; } @@ -697,8 +713,10 @@ namespace __gnu_debug _GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(), _M_message(__msg_bad_dec) ._M_iterator(*this, "this")); - __gnu_cxx::__scoped_lock __l(this->_M_get_mutex()); - --this->base(); + _GLIBCXX20_CONSTEXPR_NON_LITERAL_SCOPE_BEGIN { + __gnu_cxx::__scoped_lock __l(this->_M_get_mutex()); + --this->base(); + } _GLIBCXX20_CONSTEXPR_NON_LITERAL_SCOPE_END return *this; } @@ -912,8 +930,10 @@ namespace __gnu_debug _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n), _M_message(__msg_advance_oob) ._M_iterator(*this)._M_integer(__n)); - __gnu_cxx::__scoped_lock __l(this->_M_get_mutex()); - this->base() += __n; + _GLIBCXX20_CONSTEXPR_NON_LITERAL_SCOPE_BEGIN { + __gnu_cxx::__scoped_lock __l(this->_M_get_mutex()); + this->base() += __n; + } _GLIBCXX20_CONSTEXPR_NON_LITERAL_SCOPE_END return *this; } @@ -930,8 +950,10 @@ namespace __gnu_debug _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(-__n), _M_message(__msg_retreat_oob) ._M_iterator(*this)._M_integer(__n)); - __gnu_cxx::__scoped_lock __l(this->_M_get_mutex()); - this->base() -= __n; + _GLIBCXX20_CONSTEXPR_NON_LITERAL_SCOPE_BEGIN { + __gnu_cxx::__scoped_lock __l(this->_M_get_mutex()); + this->base() -= __n; + } _GLIBCXX20_CONSTEXPR_NON_LITERAL_SCOPE_END return *this; } @@ -1156,6 +1178,8 @@ _GLIBCXX_END_NAMESPACE_VERSION } #endif +#undef _GLIBCXX20_CONSTEXPR_NON_LITERAL_SCOPE_END +#undef _GLIBCXX20_CONSTEXPR_NON_LITERAL_SCOPE_BEGIN #undef _GLIBCXX_DEBUG_VERIFY_DIST_OPERANDS #undef _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS #undef _GLIBCXX_DEBUG_VERIFY_EQ_OPERANDS diff --git a/libstdc++-v3/testsuite/23_containers/vector/element_access/constexpr.cc b/libstdc++-v3/testsuite/23_containers/vector/element_access/constexpr.cc index ee93d2fd95e..ab1e7f1bb70 100644 --- a/libstdc++-v3/testsuite/23_containers/vector/element_access/constexpr.cc +++ b/libstdc++-v3/testsuite/23_containers/vector/element_access/constexpr.cc @@ -25,6 +25,8 @@ test_iterators() it -= 2; it += 1; VERIFY( (it + 1) == v.end() ); + it = it + 1; + it = it; auto rit = v.rbegin(); VERIFY( &*rit == &v.back() ); diff --git a/libstdc++-v3/testsuite/std/ranges/adaptors/all.cc b/libstdc++-v3/testsuite/std/ranges/adaptors/all.cc index e7010f80e18..5f7206dc8c3 100644 --- a/libstdc++-v3/testsuite/std/ranges/adaptors/all.cc +++ b/libstdc++-v3/testsuite/std/ranges/adaptors/all.cc @@ -156,11 +156,7 @@ test07() constexpr bool test08() { -#ifdef _GLIBCXX_DEBUG - using std::_GLIBCXX_STD_C::vector; -#else using std::vector; -#endif // Verify P2415R2 "What is a view?" changes. // In particular, rvalue non-view non-borrowed ranges are now viewable.