From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1984) id 1703E3945C28; Fri, 17 Jul 2020 15:00:05 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 1703E3945C28 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1594998005; bh=Gn71tEggbzsYTQa06H8htxN/zuGXb9zvSLe52r7hm7E=; h=From:To:Subject:Date:From; b=IW09oH2X7yU/IdUjp9WI/rFPCPLEwR4A6eo7K6hWYAdmdX7ps8q1AKt97upvh3zrH 4JGUgPp+cTOnLEUdDwO0RV6YD/dxxaLeLSXCBaTiYRGwwKGeOFu/BQxupcK9ZfQRmi OusQffOWKjLEYZ8FHkmGZIFf/TcC+0Qd4XQuZdjM= Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: Tamar Christina To: gcc-cvs@gcc.gnu.org, libstdc++-cvs@gcc.gnu.org Subject: [gcc(refs/vendors/ARM/heads/arm-struct-reorg-wip)] libstdc++: Make byte-sized std::fill_n a constant expression (PR 94933) X-Act-Checkin: gcc X-Git-Author: Jonathan Wakely X-Git-Refname: refs/vendors/ARM/heads/arm-struct-reorg-wip X-Git-Oldrev: fbfa806e65c552e81b363756fd8e2925651f7333 X-Git-Newrev: 8836c35d5d6fefa514cb78cb6800670869fb1df2 Message-Id: <20200717150005.1703E3945C28@sourceware.org> Date: Fri, 17 Jul 2020 15:00:05 +0000 (GMT) X-BeenThere: libstdc++-cvs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libstdc++-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 17 Jul 2020 15:00:05 -0000 https://gcc.gnu.org/g:8836c35d5d6fefa514cb78cb6800670869fb1df2 commit 8836c35d5d6fefa514cb78cb6800670869fb1df2 Author: Jonathan Wakely Date: Tue May 12 09:54:24 2020 +0100 libstdc++: Make byte-sized std::fill_n a constant expression (PR 94933) The overload for byte types uses memset and isn't constexpr. This adds the specifier and uses std::is_constant_evaluated() to provide a compile-time alternative. Backport from mainline 2020-05-03 Jonathan Wakely PR libstdc++/94933 * include/bits/stl_algobase.h (__fill_a1): Make overload for byte types usable in constant expressions. * testsuite/25_algorithms/fill_n/constexpr.cc: Test with bytes and non-scalars. Diff: --- libstdc++-v3/ChangeLog | 11 ++++++++ libstdc++-v3/include/bits/stl_algobase.h | 9 ++++++ .../testsuite/25_algorithms/fill_n/constexpr.cc | 32 +++++++++++++++++++++- 3 files changed, 51 insertions(+), 1 deletion(-) diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 55d975b84fc..b37c19ace3b 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,14 @@ +2020-05-12 Jonathan Wakely + + Backport from mainline + 2020-05-03 Jonathan Wakely + + PR libstdc++/94933 + * include/bits/stl_algobase.h (__fill_a1): Make overload for byte types + usable in constant expressions. + * testsuite/25_algorithms/fill_n/constexpr.cc: Test with bytes and + non-scalars. + 2020-05-07 Jonathan Wakely Backport from mainline diff --git a/libstdc++-v3/include/bits/stl_algobase.h b/libstdc++-v3/include/bits/stl_algobase.h index a7e92d4b473..bed61fd9d00 100644 --- a/libstdc++-v3/include/bits/stl_algobase.h +++ b/libstdc++-v3/include/bits/stl_algobase.h @@ -875,11 +875,20 @@ _GLIBCXX_END_NAMESPACE_CONTAINER // Specialization: for char types we can use memset. template + _GLIBCXX20_CONSTEXPR inline typename __gnu_cxx::__enable_if<__is_byte<_Tp>::__value, void>::__type __fill_a1(_Tp* __first, _Tp* __last, const _Tp& __c) { const _Tp __tmp = __c; +#if __cpp_lib_is_constant_evaluated + if (std::is_constant_evaluated()) + { + for (; __first != __last; ++__first) + *__first = __tmp; + return; + } +#endif if (const size_t __len = __last - __first) __builtin_memset(__first, static_cast(__tmp), __len); } diff --git a/libstdc++-v3/testsuite/25_algorithms/fill_n/constexpr.cc b/libstdc++-v3/testsuite/25_algorithms/fill_n/constexpr.cc index c18b6c99eda..17c9aa5a8d7 100644 --- a/libstdc++-v3/testsuite/25_algorithms/fill_n/constexpr.cc +++ b/libstdc++-v3/testsuite/25_algorithms/fill_n/constexpr.cc @@ -28,7 +28,37 @@ test() const auto outd = std::fill_n(ma0.begin(), 6, 77); - return outd == ma0.begin() + 6; + return outd == ma0.begin() + 6 && ma0[5] == 77 && ma0[6] == 0; } static_assert(test()); + +constexpr bool +test_byte() +{ + // PR libstdc++/94933 + std::array ma0{}; + + const auto outd = std::fill_n(ma0.begin(), 6, 77); + + return outd == ma0.begin() + 6 && ma0[5] == 77 && ma0[6] == 0; +} + +static_assert( test_byte() ); + +struct S +{ + int i = 0; +}; + +constexpr bool +test_nonscalar() +{ + std::array ma0{}; + + const auto outd = std::fill_n(ma0.begin(), 6, S{77}); + + return outd == ma0.begin() + 6 && ma0[5].i == 77 && ma0[6].i == 0; +} + +static_assert( test_nonscalar() );