From patchwork Wed Nov 17 17:25:49 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Wakely X-Patchwork-Id: 47840 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 B99493858017 for ; Wed, 17 Nov 2021 17:27:52 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org B99493858017 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1637170072; bh=OuewImL6tlZnVSUQ3fArlM7iPxrajhptWIAZ338HOKM=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=njWwQHFGzUUjz0+Uo1NsddHVpCBZJw5S/VH/15AIOQUMomqwi9+p8Wp2jt1EWwQBY vvTkHsx0nZs59ixIlxdEg0B+9y53jU4Gf3FF/bVDfdTVJ+g870kZpH0+pB7+GvJLv6 9xFlumBi4vOI06XNqCkpy5B/51+fhdYgidpVkKCM= 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 3E7083858406 for ; Wed, 17 Nov 2021 17:25:55 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 3E7083858406 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-324-DC2UeiphMf-_KIME8b5siQ-1; Wed, 17 Nov 2021 12:25:51 -0500 X-MC-Unique: DC2UeiphMf-_KIME8b5siQ-1 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id C837880DDE9; Wed, 17 Nov 2021 17:25:50 +0000 (UTC) Received: from localhost (unknown [10.33.36.17]) by smtp.corp.redhat.com (Postfix) with ESMTP id 7916B5C1BB; Wed, 17 Nov 2021 17:25:50 +0000 (UTC) To: libstdc++@gcc.gnu.org, gcc-patches@gcc.gnu.org Subject: [committed] libstdc++: Set active member of union in std::string [PR103295] Date: Wed, 17 Nov 2021 17:25:49 +0000 Message-Id: <20211117172549.4166645-1-jwakely@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 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_LOW, RCVD_IN_MSPIKE_H2, 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 powerpc64le-linux, pushed to trunk. Clang diagnoses that the new constexpr std::string constructors are not usable in constant expressions, because they start to write to members of the union without setting an active member. This adds a new helper function which returns the address of the local buffer after making it the active member. This doesn't fix all problems with Clang, because it still refuses to write to memory returned by the allocator. libstdc++-v3/ChangeLog: PR libstdc++/103295 * include/bits/basic_string.h (_M_use_local_data()): New member function to make local buffer the active member. (assign(const basic_string&)): Use it. * include/bits/basic_string.tcc (_M_construct, reserve()): Likewise. --- libstdc++-v3/include/bits/basic_string.h | 15 ++++++++++++++- libstdc++-v3/include/bits/basic_string.tcc | 10 ++++++++-- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/libstdc++-v3/include/bits/basic_string.h b/libstdc++-v3/include/bits/basic_string.h index 0b7d6c0a981..9d281f5daf2 100644 --- a/libstdc++-v3/include/bits/basic_string.h +++ b/libstdc++-v3/include/bits/basic_string.h @@ -325,6 +325,19 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 _M_get_allocator() const { return _M_dataplus; } + // Ensure that _M_local_buf is the active member of the union. + __attribute__((__always_inline__)) + _GLIBCXX14_CONSTEXPR + pointer + _M_use_local_data() _GLIBCXX_NOEXCEPT + { +#if __cpp_lib_is_constant_evaluated + if (__builtin_is_constant_evaluated()) + _M_local_buf[0] = _CharT(); +#endif + return _M_local_data(); + } + private: #ifdef _GLIBCXX_DISAMBIGUATE_REPLACE_INST @@ -1487,7 +1500,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 if (__str.size() <= _S_local_capacity) { _M_destroy(_M_allocated_capacity); - _M_data(_M_local_data()); + _M_data(_M_use_local_data()); _M_set_length(0); } else diff --git a/libstdc++-v3/include/bits/basic_string.tcc b/libstdc++-v3/include/bits/basic_string.tcc index 5743770b42a..5a51f7e21b5 100644 --- a/libstdc++-v3/include/bits/basic_string.tcc +++ b/libstdc++-v3/include/bits/basic_string.tcc @@ -170,9 +170,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION size_type __len = 0; size_type __capacity = size_type(_S_local_capacity); + pointer __p = _M_use_local_data(); + while (__beg != __end && __len < __capacity) { - _M_data()[__len++] = *__beg; + __p[__len++] = *__beg; ++__beg; } @@ -223,6 +225,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _M_data(_M_create(__dnew, size_type(0))); _M_capacity(__dnew); } + else + _M_use_local_data(); // Check for out_of_range and length_error exceptions. __try @@ -247,6 +251,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _M_data(_M_create(__n, size_type(0))); _M_capacity(__n); } + else + _M_use_local_data(); if (__n) this->_S_assign(_M_data(), __n, __c); @@ -355,7 +361,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION if (__length <= size_type(_S_local_capacity)) { - this->_S_copy(_M_local_data(), _M_data(), __length + 1); + this->_S_copy(_M_use_local_data(), _M_data(), __length + 1); _M_destroy(__capacity); _M_data(_M_local_data()); }