From patchwork Thu Jun 27 08:55:55 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Wakely X-Patchwork-Id: 1953078 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=cm+GO+zl; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=8.43.85.97; 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 [8.43.85.97]) (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 4W8sxl33ndz20Xm for ; Thu, 27 Jun 2024 19:01:31 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 911823835C22 for ; Thu, 27 Jun 2024 09:01:29 +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 E06013836E84 for ; Thu, 27 Jun 2024 09:00:45 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org E06013836E84 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 E06013836E84 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=1719478848; cv=none; b=BLrVIh0N70lTd1fv1n/4Vx+Ze8ZOy2JDfPdtA3oTvsZF3zz39KOmrYqMdIlFSuX93RykOrDj2IRLj+q34RqPfzZXEDy8n14CJXuBv2F7w3Y5GCj9fzFagAFooLDABWRIP0hYI+ctKxldQFm+RqdHKr0puHgB3/WAWP6annhAfyY= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1719478848; c=relaxed/simple; bh=RA/XWn0hAJ5mUKL9+X2AYoHDJMQ4GQlrVN/GVfLmDAQ=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=J/p87JzT9xrm4F6WmW+a7m+B0PKp4GP7g2Mqf6Jw0k40qEZrw3ZtBaaJeGJsN5SjcgY0pEIAdE8wGz42N0X3hvBp/2puc0Yz86e+w59UdjTQk9/h7yI6MmQQW4tFcN0xZrSEdRhtByj9UKAosys4NLUL47TvA8bYrF8lcQKq80M= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1719478845; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=LDZVerQ1LvEbZ2UB/9JbPGN2eTd79JSkPYybWsPsglg=; b=cm+GO+zlLZPNx09Lu/Wjk887JSj2CO1/I5PcEzVzG8yIMsZZrS9XzU3bcc0gzU/TrelA+u vTg5Au44aEWFcDz+b1aTkg3tSvz5XV83od8JrH+yHT0TkCfJCSCD3JVAcjPqUBgmqGAufj xoH9gHAPizrUZFXDlObrZlnJPVP+Cvo= Received: from mx-prod-mc-02.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-302-6RpCKq_JNtiw5WaEQCeauA-1; Thu, 27 Jun 2024 05:00:43 -0400 X-MC-Unique: 6RpCKq_JNtiw5WaEQCeauA-1 Received: from mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.12]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-02.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 945911944EAE; Thu, 27 Jun 2024 09:00:42 +0000 (UTC) Received: from localhost (unknown [10.42.28.171]) by mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 0088219560AA; Thu, 27 Jun 2024 09:00:41 +0000 (UTC) From: Jonathan Wakely To: libstdc++@gcc.gnu.org, gcc-patches@gcc.gnu.org Subject: [PATCH 1/2] libstdc++: Simplify class templates Date: Thu, 27 Jun 2024 09:55:55 +0100 Message-ID: <20240627090040.95665-1-jwakely@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.12 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-12.4 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_H4, RCVD_IN_MSPIKE_WL, 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.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 I'm planning to push this, although arguably the first change isn't worth doing if we can't use it everywhere. If we need to keep the old code for EDG, maybe we should just keep using that? The new version probably compiles faster though. Removing the dependency on std::aligned_storage and adding the test is surely useful though. Tested x86_64-linux. -- >8 -- As noted in a comment, the __gnu_cxx::__aligned_membuf class template can be simplified, because alignof(T) and alignas(T) use the correct alignment for a data member. That's true since GCC 8 and Clang 8. The EDG front end (as used by Intel icc, aka "Intel C++ Compiler Classic") does not implement the PR c++/69560 change, so keep using the old implementation when __EDG__ is defined, to avoid an ABI change for icc. For __gnu_cxx::__aligned_buffer all supported compilers agree on the value of __alignof__(T), but we can still simplify it by removing the dependency on std::aligned_storage. Add a test that checks that the aligned buffer types have the expected alignment, so that we can tell if changes like this affect their ABI properties. libstdc++-v3/ChangeLog: * include/ext/aligned_buffer.h (__aligned_membuf): Use alignas(T) directly instead of defining a struct and using 9its alignment. (__aligned_buffer): Remove use of std::aligned_storage. * testsuite/abi/aligned_buffers.cc: New test. --- libstdc++-v3/include/ext/aligned_buffer.h | 20 ++++----- libstdc++-v3/testsuite/abi/aligned_buffers.cc | 42 +++++++++++++++++++ 2 files changed, 52 insertions(+), 10 deletions(-) create mode 100644 libstdc++-v3/testsuite/abi/aligned_buffers.cc diff --git a/libstdc++-v3/include/ext/aligned_buffer.h b/libstdc++-v3/include/ext/aligned_buffer.h index 26b36609fa5..9c2c628e54a 100644 --- a/libstdc++-v3/include/ext/aligned_buffer.h +++ b/libstdc++-v3/include/ext/aligned_buffer.h @@ -49,11 +49,15 @@ namespace __gnu_cxx // Target macro ADJUST_FIELD_ALIGN can produce different alignment for // types when used as class members. __aligned_membuf is intended // for use as a class member, so align the buffer as for a class member. - // Since GCC 8 we could just use alignof(_Tp) instead, but older - // versions of non-GNU compilers might still need this trick. + // Since GCC 8 we can just use alignas(_Tp) to get the right alignment. +#ifdef __EDG__ + // The EDG front end does not implement the PR c++/69560 alignof change. struct _Tp2 { _Tp _M_t; }; - - alignas(__alignof__(_Tp2::_M_t)) unsigned char _M_storage[sizeof(_Tp)]; + alignas(__alignof__(_Tp2::_M_t)) +#else + alignas(_Tp) +#endif + unsigned char _M_storage[sizeof(_Tp)]; __aligned_membuf() = default; @@ -81,8 +85,6 @@ namespace __gnu_cxx template using __aligned_buffer = __aligned_membuf<_Tp>; #else -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" // Similar to __aligned_membuf but aligned for complete objects, not members. // This type is used in , , // and , but ideally they would use __aligned_membuf @@ -90,10 +92,9 @@ namespace __gnu_cxx // This type is still used to avoid an ABI change. template struct __aligned_buffer - : std::aligned_storage { - typename - std::aligned_storage::type _M_storage; + // Using __alignof__ gives the alignment for a complete object. + alignas(__alignof__(_Tp)) unsigned char _M_storage[sizeof(_Tp)]; __aligned_buffer() = default; @@ -120,7 +121,6 @@ namespace __gnu_cxx _M_ptr() const noexcept { return static_cast(_M_addr()); } }; -#pragma GCC diagnostic pop #endif } // namespace diff --git a/libstdc++-v3/testsuite/abi/aligned_buffers.cc b/libstdc++-v3/testsuite/abi/aligned_buffers.cc new file mode 100644 index 00000000000..b4b8ea13970 --- /dev/null +++ b/libstdc++-v3/testsuite/abi/aligned_buffers.cc @@ -0,0 +1,42 @@ +// { dg-do compile { target c++11 } } + +// Check alignment of the buffer types used for uninitialized storage. + +#include + +template using membuf = __gnu_cxx::__aligned_membuf; +template using objbuf = __gnu_cxx::__aligned_buffer; + +template +constexpr bool +check_alignof_membuf() +{ + return alignof(membuf) == alignof(T) + && __alignof__(membuf) == alignof(T); +} + +template +constexpr bool +check_alignof_objbuf() +{ +#if _GLIBCXX_INLINE_VERSION + // For the gnu-versioned-namespace ABI __aligned_buffer == __aligned_membuf. + return check_alignof_membuf(); +#else + return alignof(objbuf) == __alignof__(T) + && __alignof__(objbuf) == __alignof__(T); +#endif +} + +struct S { long long l; }; +struct alignas(128) X { char x; }; +static_assert( check_alignof_membuf(), "membuf" ); +static_assert( check_alignof_membuf(), "membuf" ); +static_assert( check_alignof_membuf(), "membuf" ); +static_assert( check_alignof_membuf(), "membuf" ); +static_assert( check_alignof_membuf(), "membuf" ); +static_assert( check_alignof_objbuf(), "objbuf" ); +static_assert( check_alignof_objbuf(), "objbuf" ); +static_assert( check_alignof_objbuf(), "objbuf" ); +static_assert( check_alignof_objbuf(), "objbuf" ); +static_assert( check_alignof_objbuf(), "objbuf" );