[gcc r16-1411] libstdc++: Fix new tests for COW std::string ABI
https://gcc.gnu.org/g:bec57be12d91be684dd7e60ff7446513e96d4481 commit r16-1411-gbec57be12d91be684dd7e60ff7446513e96d4481 Author: Jonathan Wakely Date: Tue Jun 10 10:52:13 2025 +0100 libstdc++: Fix new tests for COW std::string ABI The std::basic_stringbuf::get_allocator() member is only available for the SSO std::string ABI. libstdc++-v3/ChangeLog: * testsuite/27_io/basic_istringstream/cons/char/string_view.cc: Only check get_allocator() for new string ABI. * testsuite/27_io/basic_ostringstream/cons/char/string_view.cc: Likewise. * testsuite/27_io/basic_stringbuf/cons/char/string_view.cc: Likewise. * testsuite/27_io/basic_stringstream/cons/char/string_view.cc: Likewise. Reviewed-by: Tomasz Kamiński Diff: --- .../testsuite/27_io/basic_istringstream/cons/char/string_view.cc| 6 ++ .../testsuite/27_io/basic_ostringstream/cons/char/string_view.cc| 6 ++ .../testsuite/27_io/basic_stringbuf/cons/char/string_view.cc| 6 ++ .../testsuite/27_io/basic_stringstream/cons/char/string_view.cc | 6 ++ 4 files changed, 24 insertions(+) diff --git a/libstdc++-v3/testsuite/27_io/basic_istringstream/cons/char/string_view.cc b/libstdc++-v3/testsuite/27_io/basic_istringstream/cons/char/string_view.cc index 27f65aa94375..f25b538b2fa8 100644 --- a/libstdc++-v3/testsuite/27_io/basic_istringstream/cons/char/string_view.cc +++ b/libstdc++-v3/testsuite/27_io/basic_istringstream/cons/char/string_view.cc @@ -151,20 +151,26 @@ void test03() alloc_type a{1}; { istringstream_with_alloc istr(cstr, a); +#if _GLIBCXX_USE_CXX11_ABI VERIFY( istr.rdbuf()->get_allocator() == a ); +#endif VERIFY( string_view{istr.str()} == cstr ); VERIFY( istr.get() == cstr.s[0] ); } { istringstream_with_alloc istr(cstr, std::ios::in, a); +#if _GLIBCXX_USE_CXX11_ABI VERIFY( istr.rdbuf()->get_allocator() == a ); +#endif VERIFY( string_view{istr.str()} == cstr ); VERIFY( istr.get() == cstr.s[0] ); VERIFY( istr.rdbuf()->sputc('X') != 'X' ); } { istringstream_with_alloc istr(cstr, std::ios::out, a); +#if _GLIBCXX_USE_CXX11_ABI VERIFY( istr.rdbuf()->get_allocator() == a ); +#endif VERIFY( string_view{istr.str()} == cstr ); VERIFY( istr.get() == cstr.s[0] ); VERIFY( istr.rdbuf()->sputc('X') == 'X' ); diff --git a/libstdc++-v3/testsuite/27_io/basic_ostringstream/cons/char/string_view.cc b/libstdc++-v3/testsuite/27_io/basic_ostringstream/cons/char/string_view.cc index 731e97e4aa2c..6279c19e54c5 100644 --- a/libstdc++-v3/testsuite/27_io/basic_ostringstream/cons/char/string_view.cc +++ b/libstdc++-v3/testsuite/27_io/basic_ostringstream/cons/char/string_view.cc @@ -149,21 +149,27 @@ void test03() alloc_type a{1}; { ostringstream_with_alloc ostrstr(cstr, a); +#if _GLIBCXX_USE_CXX11_ABI VERIFY( ostrstr.rdbuf()->get_allocator() == a ); +#endif VERIFY( string_view{ostrstr.str()} == cstr ); VERIFY( ostrstr.rdbuf()->sgetc() == ostringstream::traits_type::eof() ); VERIFY( ostrstr.put('X').good() ); } { ostringstream_with_alloc ostrstr(cstr, std::ios::in, a); +#if _GLIBCXX_USE_CXX11_ABI VERIFY( ostrstr.rdbuf()->get_allocator() == a ); +#endif VERIFY( string_view{ostrstr.str()} == cstr ); VERIFY( ostrstr.rdbuf()->sgetc() == cstr.s[0]); VERIFY( ostrstr.put('X').good() ); } { ostringstream_with_alloc ostrstr(cstr, std::ios::out, a); +#if _GLIBCXX_USE_CXX11_ABI VERIFY( ostrstr.rdbuf()->get_allocator() == a ); +#endif VERIFY( string_view{ostrstr.str()} == cstr ); VERIFY( ostrstr.rdbuf()->sgetc() == ostringstream::traits_type::eof() ); VERIFY( ostrstr.put('Y').rdstate() == ostrstr.goodbit ); diff --git a/libstdc++-v3/testsuite/27_io/basic_stringbuf/cons/char/string_view.cc b/libstdc++-v3/testsuite/27_io/basic_stringbuf/cons/char/string_view.cc index 7843269c48fd..14278b3faf83 100644 --- a/libstdc++-v3/testsuite/27_io/basic_stringbuf/cons/char/string_view.cc +++ b/libstdc++-v3/testsuite/27_io/basic_stringbuf/cons/char/string_view.cc @@ -161,20 +161,26 @@ void test03() alloc_type a{1}; { stringbuf_with_alloc sbuf(cstr, a); +#if _GLIBCXX_USE_CXX11_ABI VERIFY( sbuf.get_allocator() == a ); +#endif VERIFY( string_view{sbuf.str()} == cstr ); VERIFY( sbuf.sgetc() == cstr.s[0] ); } { stringbuf_with_alloc sbuf(cstr, std::ios::in, a); +#if _GLIBCXX_USE_CXX11_ABI VERIFY( sbuf.get_allocator() == a ); +#endif VERIFY( string_view{sbuf.str()} == cstr ); VERIFY( sbuf.sgetc() == cstr.s[0] ); VERIFY( sbuf.sputc('X') == stringbuf::traits_type::eof() ); } { stringbuf_with_alloc sbuf(cstr, std::ios::out, a); +#if _GLIBCXX_USE_CXX11_ABI VERIFY( sbuf.get_allocator() == a ); +#endif VERIFY( string_view{sbuf.str()} == cstr ); VERIFY( sbuf.sputc('X') == 'X' ); VERI
[gcc r16-1412] libstdc++: Improve diagnostics for ill-formed std::_Destroy and std::_Destroy_n [PR120390]
https://gcc.gnu.org/g:01789efaea25a48ac45dae8facb6db8abd8ebb14 commit r16-1412-g01789efaea25a48ac45dae8facb6db8abd8ebb14 Author: Jonathan Wakely Date: Wed May 21 23:48:34 2025 +0100 libstdc++: Improve diagnostics for ill-formed std::_Destroy and std::_Destroy_n [PR120390] By using std::is_trivially_destructible instead of the old __has_trivial_destructor built-in we no longer need the static_assert to deal with types with deleted destructors. All non-destructible types, including those with deleted destructors, will now give user-friendly diagnostics that clearly explain the problem. Also combine the _Destroy_aux and _Destroy_n_aux class templates used for C++98 into one, so that we perform fewer expensive class template instantiations. libstdc++-v3/ChangeLog: PR libstdc++/120390 * include/bits/stl_construct.h (_Destroy_aux::__destroy_n): New static member function. (_Destroy_aux::__destroy_n): Likewise. (_Destroy_n_aux): Remove. (_Destroy(ForwardIterator, ForwardIterator)): Remove static_assert. Use is_trivially_destructible instead of __has_trivial_destructor. (_Destroy_n): Likewise. Use _Destroy_aux::__destroy_n instead of _Destroy_n_aux::__destroy_n. * testsuite/20_util/specialized_algorithms/memory_management_tools/destroy_neg.cc: Adjust dg-error strings. Move destroy_n tests to ... * testsuite/20_util/specialized_algorithms/memory_management_tools/destroy_n_neg.cc: New test. * testsuite/23_containers/vector/cons/destructible_debug_neg.cc: Adjust dg-error strings. * testsuite/23_containers/vector/cons/destructible_neg.cc: Likewise. Reviewed-by: Tomasz Kamiński Diff: --- libstdc++-v3/include/bits/stl_construct.h | 56 .../memory_management_tools/destroy_n_neg.cc | 59 ++ .../memory_management_tools/destroy_neg.cc | 20 ++-- .../vector/cons/destructible_debug_neg.cc | 7 +-- .../23_containers/vector/cons/destructible_neg.cc | 7 +-- 5 files changed, 98 insertions(+), 51 deletions(-) diff --git a/libstdc++-v3/include/bits/stl_construct.h b/libstdc++-v3/include/bits/stl_construct.h index 23b8fb754710..3ac75715e0e0 100644 --- a/libstdc++-v3/include/bits/stl_construct.h +++ b/libstdc++-v3/include/bits/stl_construct.h @@ -181,6 +181,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION for (; __first != __last; ++__first) std::_Destroy(std::__addressof(*__first)); } + + template + static _GLIBCXX20_CONSTEXPR _ForwardIterator + __destroy_n(_ForwardIterator __first, _Size __count) + { + for (; __count > 0; (void)++__first, --__count) + std::_Destroy(std::__addressof(*__first)); + return __first; + } }; template<> @@ -189,6 +198,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template static void __destroy(_ForwardIterator, _ForwardIterator) { } + + template + static _ForwardIterator + __destroy_n(_ForwardIterator __first, _Size __count) + { + std::advance(__first, __count); + return __first; + } }; #endif @@ -204,10 +221,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION typedef typename iterator_traits<_ForwardIterator>::value_type _Value_type; #if __cplusplus >= 201103L - // A deleted destructor is trivial, this ensures we reject such types: - static_assert(is_destructible<_Value_type>::value, - "value type is destructible"); - if constexpr (!__has_trivial_destructor(_Value_type)) + if constexpr (!is_trivially_destructible<_Value_type>::value) for (; __first != __last; ++__first) std::_Destroy(std::__addressof(*__first)); #if __cpp_constexpr_dynamic_alloc // >= C++20 @@ -221,33 +235,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #endif } -#if __cplusplus < 201103L - template -struct _Destroy_n_aux -{ - template - static _GLIBCXX20_CONSTEXPR _ForwardIterator - __destroy_n(_ForwardIterator __first, _Size __count) - { - for (; __count > 0; (void)++__first, --__count) - std::_Destroy(std::__addressof(*__first)); - return __first; - } -}; - - template<> -struct _Destroy_n_aux -{ - template -static _ForwardIterator -__destroy_n(_ForwardIterator __first, _Size __count) - { - std::advance(__first, __count); - return __first; - } -}; -#endif - /** * Destroy a range of objects. If the value_type of the object has * a trivial destructor, the compiler should optimize all of this @@ -260,10 +247,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION typedef typename iterator_traits<_ForwardIterator>::
[gcc r16-1414] libstdc++: Remove unused 'test' variables in test cases
https://gcc.gnu.org/g:db0cee881f6c76921d614fc401f878b9e1b79640 commit r16-1414-gdb0cee881f6c76921d614fc401f878b9e1b79640 Author: Jonathan Wakely Date: Tue Jun 10 09:34:50 2025 +0100 libstdc++: Remove unused 'test' variables in test cases These variables could be used by custom definitions of the VERIFY macro prior to GCC 7.1 but serve no purpose now. They can be removed, along with the documentation with the historical note. libstdc++-v3/ChangeLog: * doc/xml/manual/test.xml: Remove note about unused 'test' variables for old definition of VERIFY. * doc/html/manual/test.html: Regenerate. * testsuite/experimental/net/buffer/arithmetic.cc: Remove unused variable. * testsuite/experimental/net/buffer/const.cc: Likewise. * testsuite/experimental/net/buffer/mutable.cc: Likewise. * testsuite/experimental/net/buffer/size.cc: Likewise. * testsuite/experimental/net/timer/waitable/cons.cc: Likewise. * testsuite/experimental/net/timer/waitable/dest.cc: Likewise. * testsuite/experimental/net/timer/waitable/ops.cc: Likewise. * testsuite/ext/special_functions/airy_ai/check_value.cc: Likewise. * testsuite/ext/special_functions/airy_bi/check_value.cc: Likewise. * testsuite/ext/special_functions/conf_hyperg/check_value.cc: Likewise. * testsuite/ext/special_functions/hyperg/check_value.cc: Likewise. * testsuite/special_functions/01_assoc_laguerre/check_value.cc: Likewise. * testsuite/special_functions/02_assoc_legendre/check_value.cc: Likewise. * testsuite/special_functions/02_assoc_legendre/pr86655.cc: Likewise. * testsuite/special_functions/03_beta/check_value.cc: Likewise. * testsuite/special_functions/04_comp_ellint_1/check_value.cc: Likewise. * testsuite/special_functions/05_comp_ellint_2/check_value.cc: Likewise. * testsuite/special_functions/06_comp_ellint_3/check_value.cc: Likewise. * testsuite/special_functions/07_cyl_bessel_i/check_value.cc: Likewise. * testsuite/special_functions/08_cyl_bessel_j/check_value.cc: Likewise. * testsuite/special_functions/09_cyl_bessel_k/check_value.cc: Likewise. * testsuite/special_functions/10_cyl_neumann/check_value.cc: Likewise. * testsuite/special_functions/11_ellint_1/check_value.cc: Likewise. * testsuite/special_functions/12_ellint_2/check_value.cc: Likewise. * testsuite/special_functions/13_ellint_3/check_value.cc: Likewise. * testsuite/special_functions/14_expint/check_value.cc: Likewise. * testsuite/special_functions/15_hermite/check_value.cc: Likewise. * testsuite/special_functions/16_laguerre/check_value.cc: Likewise. * testsuite/special_functions/17_legendre/check_value.cc: Likewise. * testsuite/special_functions/18_riemann_zeta/check_value.cc: Likewise. * testsuite/special_functions/19_sph_bessel/check_value.cc: Likewise. * testsuite/special_functions/20_sph_legendre/check_value.cc: Likewise. * testsuite/special_functions/20_sph_legendre/pr86655.cc: Likewise. * testsuite/special_functions/21_sph_neumann/check_value.cc: Likewise. * testsuite/tr1/5_numerical_facilities/special_functions/01_assoc_laguerre/check_value.cc: Likewise. * testsuite/tr1/5_numerical_facilities/special_functions/02_assoc_legendre/check_value.cc: Likewise. * testsuite/tr1/5_numerical_facilities/special_functions/02_assoc_legendre/pr86655.cc: Likewise. * testsuite/tr1/5_numerical_facilities/special_functions/03_beta/check_value.cc: Likewise. * testsuite/tr1/5_numerical_facilities/special_functions/04_comp_ellint_1/check_value.cc: Likewise. * testsuite/tr1/5_numerical_facilities/special_functions/05_comp_ellint_2/check_value.cc: Likewise. * testsuite/tr1/5_numerical_facilities/special_functions/06_comp_ellint_3/check_value.cc: Likewise. * testsuite/tr1/5_numerical_facilities/special_functions/07_conf_hyperg/check_value.cc: Likewise. * testsuite/tr1/5_numerical_facilities/special_functions/08_cyl_bessel_i/check_value.cc: Likewise. * testsuite/tr1/5_numerical_facilities/special_functions/09_cyl_bessel_j/check_value.cc: Likewise. * testsuite/tr1/5_numerical_
[gcc r16-1413] libstdc++: Fix whitespace before comments in
https://gcc.gnu.org/g:32f3698e5350b39250e949f676e411dec6d5c442 commit r16-1413-g32f3698e5350b39250e949f676e411dec6d5c442 Author: Jonathan Wakely Date: Tue Jun 10 11:31:14 2025 +0100 libstdc++: Fix whitespace before comments in libstdc++-v3/ChangeLog: * include/std/sstream: Adjust whitespace. Diff: --- libstdc++-v3/include/std/sstream | 12 ++-- 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/libstdc++-v3/include/std/sstream b/libstdc++-v3/include/std/sstream index aee09864cdfa..b1b41260ce3d 100644 --- a/libstdc++-v3/include/std/sstream +++ b/libstdc++-v3/include/std/sstream @@ -165,7 +165,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 { __rhs._M_sync(const_cast(__rhs._M_string.data()), 0, 0); } #if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI - // P0408 Efficient access to basic_stringbuf buffer + // P0408 Efficient access to basic_stringbuf buffer explicit basic_stringbuf(const allocator_type& __a) : basic_stringbuf(ios_base::in | std::ios_base::out, __a) @@ -233,7 +233,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 #endif // C++26 #if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI - // P0408 Efficient access to basic_stringbuf buffer + // P0408 Efficient access to basic_stringbuf buffer basic_stringbuf(basic_stringbuf&& __rhs, const allocator_type& __a) : basic_stringbuf(std::move(__rhs), __a, __xfer_bufptrs(__rhs, this)) { __rhs._M_sync(const_cast(__rhs._M_string.data()), 0, 0); } @@ -572,7 +572,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 { } #if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI - // P0408 Efficient access to basic_stringbuf buffer + // P0408 Efficient access to basic_stringbuf buffer // The move constructor initializes an __xfer_bufptrs temporary then // delegates to this constructor to performs moves during its lifetime. @@ -693,7 +693,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 { __istream_type::set_rdbuf(std::__addressof(_M_stringbuf)); } #if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI - // P0408 Efficient access to basic_stringbuf buffer + // P0408 Efficient access to basic_stringbuf buffer basic_istringstream(ios_base::openmode __mode, const allocator_type& __a) : __istream_type(), _M_stringbuf(__mode | ios_base::in, __a) { this->init(std::__addressof(_M_stringbuf)); } @@ -959,7 +959,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 { __ostream_type::set_rdbuf(std::__addressof(_M_stringbuf)); } #if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI - // P0408 Efficient access to basic_stringbuf buffer + // P0408 Efficient access to basic_stringbuf buffer basic_ostringstream(ios_base::openmode __mode, const allocator_type& __a) : __ostream_type(), _M_stringbuf(__mode | ios_base::out, __a) { this->init(std::__addressof(_M_stringbuf)); } @@ -1221,7 +1221,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 { __iostream_type::set_rdbuf(std::__addressof(_M_stringbuf)); } #if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI - // P0408 Efficient access to basic_stringbuf buffer + // P0408 Efficient access to basic_stringbuf buffer basic_stringstream(ios_base::openmode __mode, const allocator_type& __a) : __iostream_type(), _M_stringbuf(__mode, __a) { this->init(std::__addressof(_M_stringbuf)); }
[gcc r16-1415] libstdc++: Replace some uses of std::__addressof with std::addressof
https://gcc.gnu.org/g:1e8077634fbe80553003c857eb6d77d5b011843e commit r16-1415-g1e8077634fbe80553003c857eb6d77d5b011843e Author: Jonathan Wakely Date: Thu May 22 14:49:25 2025 +0100 libstdc++: Replace some uses of std::__addressof with std::addressof Since r16-154-gc91eb5a5c13f14 std::addressof is no less efficient than std::__addressof, so change some uses of the latter to the former. We can't change them all, because some uses need to compile as C++98 which only has std::__addressof. Similarly, since r16-848-gb2aeeb2803f97b std::is_constant_evaluated is no less efficient than std::__is_constant_evaluated. libstdc++-v3/ChangeLog: * include/bits/stl_construct.h: Replace std::__addressof with std::addressof in code that doesn't need to compile as C++98. Replace std::__is_constant_evaluated with std::is_constant_evaluated in code that doesn't need to compile as C++17 or earlier. * include/bits/stl_uninitialized.h: Likewise for __addressof. Diff: --- libstdc++-v3/include/bits/stl_construct.h | 16 +++ libstdc++-v3/include/bits/stl_uninitialized.h | 28 +-- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/libstdc++-v3/include/bits/stl_construct.h b/libstdc++-v3/include/bits/stl_construct.h index 3ac75715e0e0..217a0416d425 100644 --- a/libstdc++-v3/include/bits/stl_construct.h +++ b/libstdc++-v3/include/bits/stl_construct.h @@ -82,7 +82,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION if constexpr (__cplusplus > 201703L && is_array_v<_Tp>) { for (auto& __x : *__location) - std::destroy_at(std::__addressof(__x)); + std::destroy_at(std::addressof(__x)); } else __location->~_Tp(); @@ -123,7 +123,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _Construct(_Tp* __p, _Args&&... __args) { #if __cpp_constexpr_dynamic_alloc // >= C++20 - if (std::__is_constant_evaluated()) + if (std::is_constant_evaluated()) { // Allow std::_Construct to be used in constant expressions. std::construct_at(__p, std::forward<_Args>(__args)...); @@ -223,11 +223,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #if __cplusplus >= 201103L if constexpr (!is_trivially_destructible<_Value_type>::value) for (; __first != __last; ++__first) - std::_Destroy(std::__addressof(*__first)); + std::_Destroy(std::addressof(*__first)); #if __cpp_constexpr_dynamic_alloc // >= C++20 - else if (std::__is_constant_evaluated()) + else if (std::is_constant_evaluated()) for (; __first != __last; ++__first) - std::destroy_at(std::__addressof(*__first)); + std::destroy_at(std::addressof(*__first)); #endif #else std::_Destroy_aux<__has_trivial_destructor(_Value_type)>:: @@ -249,11 +249,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #if __cplusplus >= 201103L if constexpr (!is_trivially_destructible<_Value_type>::value) for (; __count > 0; (void)++__first, --__count) - std::_Destroy(std::__addressof(*__first)); + std::_Destroy(std::addressof(*__first)); #if __cpp_constexpr_dynamic_alloc // >= C++20 - else if (std::__is_constant_evaluated()) + else if (std::is_constant_evaluated()) for (; __count > 0; (void)++__first, --__count) - std::destroy_at(std::__addressof(*__first)); + std::destroy_at(std::addressof(*__first)); #endif else std::advance(__first, __count); diff --git a/libstdc++-v3/include/bits/stl_uninitialized.h b/libstdc++-v3/include/bits/stl_uninitialized.h index b1428db48b00..bde787c2beaa 100644 --- a/libstdc++-v3/include/bits/stl_uninitialized.h +++ b/libstdc++-v3/include/bits/stl_uninitialized.h @@ -839,7 +839,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { _UninitDestroyGuard<_ForwardIterator> __guard(__first); for (; __first != __last; ++__first) - std::_Construct(std::__addressof(*__first)); + std::_Construct(std::addressof(*__first)); __guard.release(); } }; @@ -856,7 +856,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return; typename iterator_traits<_ForwardIterator>::value_type* __val - = std::__addressof(*__first); + = std::addressof(*__first); std::_Construct(__val); if (++__first != __last) std::fill(__first, __last, *__val); @@ -873,7 +873,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { _UninitDestroyGuard<_ForwardIterator> __guard(__first); for (; __n > 0; --__n, (void) ++__first) - std::_Construct(std::__addressof(*__first)); + std::_Construct(std::addressof(*__first)); __guard.release(); return __first; } @@ -890,7 +890,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION if (__n > 0) { typename iterator_tra
[gcc r14-11838] libstdc++: Fix std::format thousands separators when sign present [PR120548]
https://gcc.gnu.org/g:c92bc1e435e48e85fecf08dafe9d62a30a46a773 commit r14-11838-gc92bc1e435e48e85fecf08dafe9d62a30a46a773 Author: Jonathan Wakely Date: Wed Jun 4 18:22:28 2025 +0100 libstdc++: Fix std::format thousands separators when sign present [PR120548] The leading sign character should be skipped when deciding whether to insert thousands separators into a floating-point format. libstdc++-v3/ChangeLog: PR libstdc++/120548 * include/std/format (__formatter_fp::_M_localize): Do not include a leading sign character in the string to be grouped. * testsuite/std/format/functions/format.cc: Check grouping when sign is present in the output. Reviewed-by: Tomasz Kamiński (cherry picked from commit 2c3559839d70df6311da18fd93237050405580c3) Diff: --- libstdc++-v3/include/std/format | 11 +-- libstdc++-v3/testsuite/std/format/functions/format.cc | 10 ++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/libstdc++-v3/include/std/format b/libstdc++-v3/include/std/format index 84f21281387c..ada62c26bcab 100644 --- a/libstdc++-v3/include/std/format +++ b/libstdc++-v3/include/std/format @@ -1838,9 +1838,16 @@ namespace __format const size_t __r = __str.size() - __e; // Length of remainder. auto __overwrite = [&](_CharT* __p, size_t) { // Apply grouping to the digits before the radix or exponent. - auto __end = std::__add_grouping(__p, __np.thousands_sep(), + int __off = 0; + if (auto __c = __str.front(); __c == '-' || __c == '+' || __c == ' ') + { + *__p = __c; + __off = 1; + } + auto __end = std::__add_grouping(__p + __off, __np.thousands_sep(), __grp.data(), __grp.size(), - __str.data(), __str.data() + __e); + __str.data() + __off, + __str.data() + __e); if (__r) // If there's a fractional part or exponent { if (__d != __str.npos) diff --git a/libstdc++-v3/testsuite/std/format/functions/format.cc b/libstdc++-v3/testsuite/std/format/functions/format.cc index d6575dabb6bc..677c0d1fe998 100644 --- a/libstdc++-v3/testsuite/std/format/functions/format.cc +++ b/libstdc++-v3/testsuite/std/format/functions/format.cc @@ -256,6 +256,16 @@ test_locale() s = std::format(eloc, "{0:Le} {0:Lf} {0:Lg}", -nan); VERIFY( s == "-nan -nan -nan" ); + // PR libstdc++/120548 format confuses a negative sign for a thousands digit + s = std::format(bloc, "{:L}", -123.45); + VERIFY( s == "-123.45" ); + s = std::format(bloc, "{:-L}", -876543.21); + VERIFY( s == "-876,543.21" ); + s = std::format(bloc, "{:+L}", 333.22); + VERIFY( s == "+333.22" ); + s = std::format(bloc, "{: L}", 999.44); + VERIFY( s == " 999.44" ); + // Restore std::locale::global(cloc); }
[gcc r14-11836] libstdc++: Make system_clock::to_time_t always_inline [PR99832]
https://gcc.gnu.org/g:b5d386495b3f8e638acaab3f7f2ada2c7a3d0f55 commit r14-11836-gb5d386495b3f8e638acaab3f7f2ada2c7a3d0f55 Author: Jonathan Wakely Date: Wed May 28 15:19:18 2025 +0100 libstdc++: Make system_clock::to_time_t always_inline [PR99832] For some 32-bit targets Glibc supports changing the size of time_t to be 64 bits by defining _TIME_BITS=64. That causes an ABI change which would affect std::chrono::system_clock::to_time_t. Because to_time_t is not a function template, its mangled name does not depend on the return type, so it has the same mangled name whether it returns a 32-bit time_t or a 64-bit time_t. On targets where the size of time_t can be selected at preprocessing time, that can cause ODR violations, e.g. the linker selects a definition of to_time_t that returns a 32-bit value but a caller expects 64-bit and so reads 32 bits of garbage from the stack. This commit adds always_inline to to_time_t so that all callers inline the conversion to time_t, and will do so using whatever type time_t happens to be in that translation unit. Existing objects compiled before this change will either have inlined the function anyway (which is likely if compiled with any optimization enabled) or will contain a COMDAT definition of the inline function and so still be able to find it at link-time. The attribute is also added to system_clock::from_time_t, because that's an equally simple function and it seems reasonable for them to both be always inlined. libstdc++-v3/ChangeLog: PR libstdc++/99832 * include/bits/chrono.h (system_clock::to_time_t): Add always_inline attribute to be agnostic to the underlying type of time_t. (system_clock::from_time_t): Add always_inline for consistency with to_time_t. * testsuite/20_util/system_clock/99832.cc: New test. (cherry picked from commit d045eb13b0b42870a1f081895df3901112a358f0) Diff: --- libstdc++-v3/include/bits/chrono.h | 2 ++ libstdc++-v3/testsuite/20_util/system_clock/99832.cc | 14 ++ 2 files changed, 16 insertions(+) diff --git a/libstdc++-v3/include/bits/chrono.h b/libstdc++-v3/include/bits/chrono.h index 0773867da716..a7157628a0a9 100644 --- a/libstdc++-v3/include/bits/chrono.h +++ b/libstdc++-v3/include/bits/chrono.h @@ -1239,6 +1239,7 @@ _GLIBCXX_BEGIN_INLINE_ABI_NAMESPACE(_V2) now() noexcept; // Map to C API + [[__gnu__::__always_inline__]] static std::time_t to_time_t(const time_point& __t) noexcept { @@ -1246,6 +1247,7 @@ _GLIBCXX_BEGIN_INLINE_ABI_NAMESPACE(_V2) (__t.time_since_epoch()).count()); } + [[__gnu__::__always_inline__]] static time_point from_time_t(std::time_t __t) noexcept { diff --git a/libstdc++-v3/testsuite/20_util/system_clock/99832.cc b/libstdc++-v3/testsuite/20_util/system_clock/99832.cc new file mode 100644 index ..693d4d647d9b --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/system_clock/99832.cc @@ -0,0 +1,14 @@ +// { dg-options "-O0 -g0" } +// { dg-do compile { target c++20 } } +// { dg-final { scan-assembler-not "system_clock9to_time_t" } } + +// Bug libstdc++/99832 +// std::chrono::system_clock::to_time_t needs ABI tag for 32-bit time_t + +#include + +std::time_t +test_pr99832(std::chrono::system_clock::time_point t) +{ + return std::chrono::system_clock::to_time_t(t); +}
[gcc r14-11837] libstdc++: Tweak localized formatting for floating-point types
https://gcc.gnu.org/g:627c08f72b4ebcbda321643622eb9c249f57869b commit r14-11837-g627c08f72b4ebcbda321643622eb9c249f57869b Author: Jonathan Wakely Date: Mon Apr 29 18:16:29 2024 +0100 libstdc++: Tweak localized formatting for floating-point types libstdc++-v3/ChangeLog: * include/std/format (__formatter_fp::_M_localize): Add comments and micro-optimize string copy. (cherry picked from commit 99b8be43d7c548db127ee4f4d0918c55edc68b3f) Diff: --- libstdc++-v3/include/std/format | 17 ++--- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/libstdc++-v3/include/std/format b/libstdc++-v3/include/std/format index 604f4cde3c47..84f21281387c 100644 --- a/libstdc++-v3/include/std/format +++ b/libstdc++-v3/include/std/format @@ -1831,25 +1831,28 @@ namespace __format if (__grp.empty() && __point == __dot) return __lstr; // Locale uses '.' and no grouping. - size_t __d = __str.find(__dot); - size_t __e = min(__d, __str.find(__exp)); + size_t __d = __str.find(__dot); // Index of radix character (if any). + size_t __e = min(__d, __str.find(__exp)); // First of radix or exponent if (__e == __str.npos) __e = __str.size(); - const size_t __r = __str.size() - __e; + const size_t __r = __str.size() - __e; // Length of remainder. auto __overwrite = [&](_CharT* __p, size_t) { + // Apply grouping to the digits before the radix or exponent. auto __end = std::__add_grouping(__p, __np.thousands_sep(), __grp.data(), __grp.size(), __str.data(), __str.data() + __e); - if (__r) + if (__r) // If there's a fractional part or exponent { if (__d != __str.npos) { - *__end = __point; + *__end = __point; // Add the locale's radix character. ++__end; ++__e; } - if (__r > 1) - __end += __str.copy(__end, __str.npos, __e); + const size_t __rlen = __str.size() - __e; + // Append fractional digits and/or exponent: + char_traits<_CharT>::copy(__end, __str.data() + __e, __rlen); + __end += __rlen; } return (__end - __p); };
[gcc r12-11134] libstdc++: Fix incorrect links to archived SGI STL docs
https://gcc.gnu.org/g:6ea0df6d52ac54a29dac948046f466ef8d1433cc commit r12-11134-g6ea0df6d52ac54a29dac948046f466ef8d1433cc Author: Jonathan Wakely Date: Tue May 20 10:53:41 2025 +0100 libstdc++: Fix incorrect links to archived SGI STL docs In r8--g25949ee33201f2 I updated some URLs to point to copies of the SGI STL docs in the Wayback Machine, because the original pags were no longer hosted on sgi.com. However, I incorrectly assumed that if one archived page was at https://web.archive.org/web/20171225062613/... then all the other pages would be too. Apparently that's not how the Wayback Machine works, and each page is archived on a different date. That meant that some of our links were redirecting to archived copies of the announcement that the SGI STL docs have gone away. This fixes each URL to refer to a correctly archived copy of the original docs. libstdc++-v3/ChangeLog: * doc/xml/faq.xml: Update URL for archived SGI STL docs. * doc/xml/manual/containers.xml: Likewise. * doc/xml/manual/extensions.xml: Likewise. * doc/xml/manual/using.xml: Likewise. * doc/xml/manual/utilities.xml: Likewise. * doc/html/*: Regenerate. (cherry picked from commit 501e6e786652748ff0ad9a322f74b9b47970031f) Diff: --- libstdc++-v3/doc/html/faq.html | 2 +- libstdc++-v3/doc/html/manual/containers.html| 2 +- libstdc++-v3/doc/html/manual/ext_numerics.html | 2 +- libstdc++-v3/doc/html/manual/ext_sgi.html | 4 ++-- libstdc++-v3/doc/html/manual/using_concurrency.html | 10 +- libstdc++-v3/doc/html/manual/utilities.html | 4 ++-- libstdc++-v3/doc/xml/faq.xml| 2 +- libstdc++-v3/doc/xml/manual/containers.xml | 2 +- libstdc++-v3/doc/xml/manual/extensions.xml | 6 +++--- libstdc++-v3/doc/xml/manual/using.xml | 10 +- libstdc++-v3/doc/xml/manual/utilities.xml | 4 ++-- 11 files changed, 24 insertions(+), 24 deletions(-) diff --git a/libstdc++-v3/doc/html/faq.html b/libstdc++-v3/doc/html/faq.html index f49b84c4c33a..8c103e2c142c 100644 --- a/libstdc++-v3/doc/html/faq.html +++ b/libstdc++-v3/doc/html/faq.html @@ -797,7 +797,7 @@ Libstdc++-v3 incorporates a lot of code from https://web.archive.org/web/20171225062613/http://www.sgi.com/tech/stl/"; target="_top">the SGI STL (the final merge was from -https://web.archive.org/web/20171225062613/http://www.sgi.com/tech/stl/whats_new.html"; target="_top">release 3.3). +https://web.archive.org/web/20171206110416/http://www.sgi.com/tech/stl/whats_new.html"; target="_top">release 3.3). The code in libstdc++ contains many fixes and changes compared to the original SGI code. diff --git a/libstdc++-v3/doc/html/manual/containers.html b/libstdc++-v3/doc/html/manual/containers.html index 7035a949074d..dcd609a6000d 100644 --- a/libstdc++-v3/doc/html/manual/containers.html +++ b/libstdc++-v3/doc/html/manual/containers.html @@ -11,7 +11,7 @@ Yes it is, at least using the old ABI, and that's okay. This is a decision that we preserved when we imported SGI's STL implementation. The following is - quoted from https://web.archive.org/web/20171225062613/http://www.sgi.com/tech/stl/FAQ.html"; target="_top">their FAQ: + quoted from https://web.archive.org/web/20161222192301/http://www.sgi.com/tech/stl/FAQ.html"; target="_top">their FAQ: The size() member function, for list and slist, takes time proportional to the number of elements in the list. This was a diff --git a/libstdc++-v3/doc/html/manual/ext_numerics.html b/libstdc++-v3/doc/html/manual/ext_numerics.html index 9b864e1dcf4a..c3a5623d1752 100644 --- a/libstdc++-v3/doc/html/manual/ext_numerics.html +++ b/libstdc++-v3/doc/html/manual/ext_numerics.html @@ -14,7 +14,7 @@ The operation functor must be associative. The iota function wins the award for Extension With the Coolest Name (the name comes from Ken Iverson's APL language.) As - described in the https://web.archive.org/web/20171225062613/http://www.sgi.com/tech/stl/iota.html"; target="_top">SGI + described in the https://web.archive.org/web/20170201044840/http://www.sgi.com/tech/stl/iota.html"; target="_top">SGI documentation, it "assigns sequentially increasing values to a range. That is, it assigns value to *first, value + 1 to *(first + 1) and so on." diff --git a/libstdc++-v3/doc/html/manual/ext_sgi.html b/libstdc++-v3/doc/html/manual/ext_sgi.html index ae2062954f4f..2310857804b3 100644 --- a/libstdc++-v3/doc/html/manual/ext_sgi.html +++ b/libstdc++-v3/doc/html/manual/ext_sgi.html @@ -28,12 +28,12 @@ and sets. Each of the associative containers map, multimap, set, and multiset have a counterpart which uses a - https://web.archive.org/web/20171225062613/http
[gcc r12-11135] libstdc++: Make system_clock::to_time_t always_inline [PR99832]
https://gcc.gnu.org/g:d14d9793bfb795193b3ed972c4930d75cf8a026b commit r12-11135-gd14d9793bfb795193b3ed972c4930d75cf8a026b Author: Jonathan Wakely Date: Wed May 28 15:19:18 2025 +0100 libstdc++: Make system_clock::to_time_t always_inline [PR99832] For some 32-bit targets Glibc supports changing the size of time_t to be 64 bits by defining _TIME_BITS=64. That causes an ABI change which would affect std::chrono::system_clock::to_time_t. Because to_time_t is not a function template, its mangled name does not depend on the return type, so it has the same mangled name whether it returns a 32-bit time_t or a 64-bit time_t. On targets where the size of time_t can be selected at preprocessing time, that can cause ODR violations, e.g. the linker selects a definition of to_time_t that returns a 32-bit value but a caller expects 64-bit and so reads 32 bits of garbage from the stack. This commit adds always_inline to to_time_t so that all callers inline the conversion to time_t, and will do so using whatever type time_t happens to be in that translation unit. Existing objects compiled before this change will either have inlined the function anyway (which is likely if compiled with any optimization enabled) or will contain a COMDAT definition of the inline function and so still be able to find it at link-time. The attribute is also added to system_clock::from_time_t, because that's an equally simple function and it seems reasonable for them to both be always inlined. libstdc++-v3/ChangeLog: PR libstdc++/99832 * include/bits/chrono.h (system_clock::to_time_t): Add always_inline attribute to be agnostic to the underlying type of time_t. (system_clock::from_time_t): Add always_inline for consistency with to_time_t. * testsuite/20_util/system_clock/99832.cc: New test. (cherry picked from commit d045eb13b0b42870a1f081895df3901112a358f0) Diff: --- libstdc++-v3/include/bits/chrono.h | 2 ++ libstdc++-v3/testsuite/20_util/system_clock/99832.cc | 14 ++ 2 files changed, 16 insertions(+) diff --git a/libstdc++-v3/include/bits/chrono.h b/libstdc++-v3/include/bits/chrono.h index 43d91b8713bb..d14bb995b355 100644 --- a/libstdc++-v3/include/bits/chrono.h +++ b/libstdc++-v3/include/bits/chrono.h @@ -1218,6 +1218,7 @@ _GLIBCXX_BEGIN_INLINE_ABI_NAMESPACE(_V2) now() noexcept; // Map to C API + [[__gnu__::__always_inline__]] static std::time_t to_time_t(const time_point& __t) noexcept { @@ -1225,6 +1226,7 @@ _GLIBCXX_BEGIN_INLINE_ABI_NAMESPACE(_V2) (__t.time_since_epoch()).count()); } + [[__gnu__::__always_inline__]] static time_point from_time_t(std::time_t __t) noexcept { diff --git a/libstdc++-v3/testsuite/20_util/system_clock/99832.cc b/libstdc++-v3/testsuite/20_util/system_clock/99832.cc new file mode 100644 index ..4bc361e21ad2 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/system_clock/99832.cc @@ -0,0 +1,14 @@ +// { dg-options "-O0 -g0 -std=gnu++20" } +// { dg-do compile { target c++20 } } +// { dg-final { scan-assembler-not "system_clock9to_time_t" } } + +// Bug libstdc++/99832 +// std::chrono::system_clock::to_time_t needs ABI tag for 32-bit time_t + +#include + +std::time_t +test_pr99832(std::chrono::system_clock::time_point t) +{ + return std::chrono::system_clock::to_time_t(t); +}
[gcc r12-11136] libstdc++: Fix Python deprecation warning in printers.py
https://gcc.gnu.org/g:4205c99e4fc9454b05ebd50e89553a287a8c094b commit r12-11136-g4205c99e4fc9454b05ebd50e89553a287a8c094b Author: Jonathan Wakely Date: Wed Oct 16 09:22:37 2024 +0100 libstdc++: Fix Python deprecation warning in printers.py python/libstdcxx/v6/printers.py:1355: DeprecationWarning: 'count' is passed as positional argument The Python docs say: Deprecated since version 3.13: Passing count and flags as positional arguments is deprecated. In future Python versions they will be keyword-only parameters. Using a keyword argument for count only became possible with Python 3.1 so introduce a new function to do the substitution. libstdc++-v3/ChangeLog: * python/libstdcxx/v6/printers.py (strip_fundts_namespace): New. (StdExpAnyPrinter, StdExpOptionalPrinter): Use it. (cherry picked from commit b9e98bb9919fa9f07782f23f79b3d35abb9ff542) Diff: --- libstdc++-v3/python/libstdcxx/v6/printers.py | 18 +- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/libstdc++-v3/python/libstdcxx/v6/printers.py b/libstdc++-v3/python/libstdcxx/v6/printers.py index ee25253d0040..2fbf65d3effb 100644 --- a/libstdc++-v3/python/libstdcxx/v6/printers.py +++ b/libstdc++-v3/python/libstdcxx/v6/printers.py @@ -194,6 +194,16 @@ def strip_versioned_namespace(typename): return typename.replace(_versioned_namespace, '') +def strip_fundts_namespace(typ): +"""Remove "fundamentals_vN" inline namespace from qualified type name.""" +pattern = r'^std::experimental::fundamentals_v\d::' +repl = 'std::experimental::' +if sys.version_info[0] == 2: +return re.sub(pattern, repl, typ, 1) +else: # Technically this needs Python 3.1 but nobody should be using 3.0 +return re.sub(pattern, repl, typ, count=1) + + def strip_inline_namespaces(type_str): """Remove known inline namespaces from the canonical name of a type.""" type_str = strip_versioned_namespace(type_str) @@ -1267,8 +1277,7 @@ class StdExpAnyPrinter(SingleObjContainerPrinter): def __init__(self, typename, val): self.typename = strip_versioned_namespace(typename) -self.typename = re.sub(r'^std::experimental::fundamentals_v\d::', - 'std::experimental::', self.typename, 1) +self.typename = strip_fundts_namespace(self.typename) self.val = val self.contained_type = None contained_value = None @@ -1363,9 +1372,8 @@ class StdExpOptionalPrinter(SingleObjContainerPrinter): def __init__(self, typename, val): valtype = self._recognize(val.type.template_argument(0)) typename = strip_versioned_namespace(typename) -self.typename = re.sub( -r'^std::(experimental::|)(fundamentals_v\d::|)(.*)', -r'std::\1\3<%s>' % valtype, typename, 1) +typename = strip_fundts_namespace(typename) +self.typename = '%s<%s>' % (typename, valtype) payload = val['_M_payload'] if self.typename.startswith('std::experimental'): engaged = val['_M_engaged']
[gcc r16-1423] libstdc++: Test for precision and floting point durations.
https://gcc.gnu.org/g:2f2e51b6596c3796b907c6289d3e631508d8774e commit r16-1423-g2f2e51b6596c3796b907c6289d3e631508d8774e Author: Tomasz Kamiński Date: Wed Jun 11 15:56:25 2025 +0200 libstdc++: Test for precision and floting point durations. libstdc++-v3/ChangeLog: * testsuite/std/time/format/empty_spec.cc: New tests. * testsuite/std/time/format/precision.cc: New test. Diff: --- .../testsuite/std/time/format/empty_spec.cc| 51 ++ .../testsuite/std/time/format/precision.cc | 107 + 2 files changed, 158 insertions(+) diff --git a/libstdc++-v3/testsuite/std/time/format/empty_spec.cc b/libstdc++-v3/testsuite/std/time/format/empty_spec.cc index 99cbd740d5f5..a94eee19f577 100644 --- a/libstdc++-v3/testsuite/std/time/format/empty_spec.cc +++ b/libstdc++-v3/testsuite/std/time/format/empty_spec.cc @@ -170,6 +170,13 @@ test_duration() verify( -di, WIDEN("-40ms") ); res = std::format(WIDEN("{:>6}"), -di); VERIFY( res == WIDEN(" -40ms") ); +} + +template +void +test_duration_fp() +{ + std::basic_string<_CharT> res; const duration df(11.22); verify( df, WIDEN("11.22s") ); @@ -179,6 +186,10 @@ test_duration() verify( -df, WIDEN("-11.22s") ); res = std::format(WIDEN("{:=^12}"), -df); VERIFY( res == WIDEN("==-11.22s===") ); + + // precision accepted but ignored + res = std::format(WIDEN("{:.6}"), df); + VERIFY( res == WIDEN("11.22s") ); } template @@ -292,6 +303,44 @@ test_hh_mm_ss() WIDEN("-14322:24:54.111222333") ); } +template +void +test_hh_mm_ss_fp() +{ + duration dt = 22h + 24min + 54s + 111222333ns; + // period controls number of subseconds + verify( hms(dt), + WIDEN("22:24:54.111222333") ); + verify( hms(dt), + WIDEN("22:24:54.111222") ); + verify( hms(dt), + WIDEN("22:24:54.111") ); + verify( hms(dt), + WIDEN("22:24:54.1") ); + verify( hms(dt), + WIDEN("22:24:54") ); + verify( hms(-dt), + WIDEN("-22:24:54.111222333") ); + verify( hms(-dt), + WIDEN("-22:24:54.111222") ); + verify( hms(-dt), + WIDEN("-22:24:54.111") ); + verify( hms(-dt), + WIDEN("-22:24:54.1") ); + verify( hms(-dt), + WIDEN("-22:24:54") ); + + // but hour and minutes are preserved + verify( hms(dt), + WIDEN("22:24:54") ); + verify( hms(dt), + WIDEN("22:24:54") ); + verify( hms(-dt), + WIDEN("-22:24:54") ); + verify( hms(-dt), + WIDEN("-22:24:54") ); +} + template void test_hh_mm_ss_cust() @@ -339,9 +388,11 @@ void test_durations() { test_duration(); + test_duration_fp(); test_duration_cust(); test_hh_mm_ss(); + test_hh_mm_ss_fp(); test_hh_mm_ss_cust(); } diff --git a/libstdc++-v3/testsuite/std/time/format/precision.cc b/libstdc++-v3/testsuite/std/time/format/precision.cc new file mode 100644 index ..5a9acbfe1e08 --- /dev/null +++ b/libstdc++-v3/testsuite/std/time/format/precision.cc @@ -0,0 +1,107 @@ +// { dg-do run { target c++20 } } + +#include +#include +#include + +using namespace std::chrono; + +#define WIDEN_(C, S) ::std::__format::_Widen(S, L##S) +#define WIDEN(S) WIDEN_(_CharT, S) + +template +void +test_empty() +{ + std::basic_string<_CharT> res; + + const duration d(33.111222); + res = std::format(WIDEN("{:.3}"), d); + VERIFY( res == WIDEN("33.1112s") ); + res = std::format(WIDEN("{:.6}"), d); + VERIFY( res == WIDEN("33.1112s") ); + res = std::format(WIDEN("{:.9}"), d); + VERIFY( res == WIDEN("33.1112s") ); + + // Uses ostream operator<< + const duration nd = d; + res = std::format(WIDEN("{:.3}"), nd); + VERIFY( res == WIDEN("3.31112e+10ns") ); + res = std::format(WIDEN("{:.6}"), nd); + VERIFY( res == WIDEN("3.31112e+10ns") ); + res = std::format(WIDEN("{:.9}"), nd); + VERIFY( res == WIDEN("3.31112e+10ns") ); +} + +template +void +test_Q() +{ + std::basic_string<_CharT> res; + + const duration d(7.111222); + res = std::format(WIDEN("{:.3%Q}"), d); + VERIFY( res == WIDEN("7.111222") ); + res = std::format(WIDEN("{:.6%Q}"), d); + VERIFY( res == WIDEN("7.111222") ); + res = std::format(WIDEN("{:.9%Q}"), d); + VERIFY( res == WIDEN("7.111222") ); + + const duration nd = d; + res = std::format(WIDEN("{:.3%Q}"), nd); + VERIFY( res == WIDEN("7111222000") ); + res = std::format(WIDEN("{:.6%Q}"), nd); + VERIFY( res == WIDEN("7111222000") ); + res = std::format(WIDEN("{:.9%Q}"), nd); + VERIFY( res == WIDEN("7111222000") ); +} + +template +void +test_S() +{ + std::basic_string<_CharT> res; + + // Precision is ignored, but period affects output + const duration d(5.111222); + res = std::format(WIDEN("{:.3%S}"), d); + VERIFY( res == WIDEN("05") ); + res = std::format(WIDEN("{:.6%S}"), d); + VERIFY( res == WIDEN("05") ); + res = std::format(WIDEN("{:.9%S}"), d); + VERIFY( res == WIDEN("05") ); + + const duration md = d; + res = std::format(WIDEN("{:.3%S}"), md); + VERIFY( res == WIDEN("05.111") ); + res
[gcc(refs/users/meissner/heads/work210-sha)] Update ChangeLog.*
https://gcc.gnu.org/g:6ee741609fd3b90da7aa7b5dc3ea7dd070a2fe04 commit 6ee741609fd3b90da7aa7b5dc3ea7dd070a2fe04 Author: Michael Meissner Date: Wed Jun 11 16:14:06 2025 -0400 Update ChangeLog.* Diff: --- gcc/ChangeLog.sha | 2310 + 1 file changed, 2310 insertions(+) diff --git a/gcc/ChangeLog.sha b/gcc/ChangeLog.sha index 3b49e9eb6ee0..100eb4b602e5 100644 --- a/gcc/ChangeLog.sha +++ b/gcc/ChangeLog.sha @@ -1,3 +1,2313 @@ + Branch work210-sha, patch #345 + +PR target/117251: Add tests + +This is patch #45 of 45 to generate the 'XXEVAL' instruction on power10 and +power11 instead of using the Altivec 'VAND' instruction feeding into 'VNAND'. +The 'XXEVAL' instruction can use all 64 vector registers, instead of the 32 +registers that traditional Altivec vector instructions use. By allowing all of +the vector registers to be used, it reduces the amount of spilling that a large +benchmark generated. + +This patch adds the tests for generating 'XXEVAL' to the testsuite. + +I have tested these patches on both big endian and little endian PowerPC +servers, with no regressions. Can I check these patchs into the trunk? + +2025-06-11 Michael Meissner + +gcc/testsuite/ + + PR target/117251 + * gcc.target/powerpc/p10-vector-fused-1.c: New test. + * gcc.target/powerpc/p10-vector-fused-2.c: Likewise. + + Branch work210-sha, patch #344 + +PR target/117251: Improve vector and to vector nand fusion + +See the following post for a complete explanation of what the patches for +PR target/117251: + + * https://gcc.gnu.org/pipermail/gcc-patches/2025-June/686474.html + +This is patch #44 of 45 to generate the 'XXEVAL' instruction on power10 and +power11 instead of using the Altivec 'VAND' instruction feeding into 'VNAND'. +The 'XXEVAL' instruction can use all 64 vector registers, instead of the 32 +registers that traditional Altivec vector instructions use. By allowing all of +the vector registers to be used, it reduces the amount of spilling that a large +benchmark generated. + +Currently the following code: + + vector int a, b, c, d; + a = ~ ((c & d) & b); + +Generates: + + vand t,c,d + vnand a,t,b + +Now in addition with this patch, if the arguments or result is allocated to a +traditional FPR register, the GCC compiler will now generate the following +code instead of adding vector move instructions: + + xxeval a,b,c,254 + +Since fusion using 2 Altivec instructions is slightly faster than using the +'XXEVAL' instruction we prefer to generate the Altivec instructions if we can. +In addition, because 'XXEVAL' is a prefixed instruction, it possibly might +generate an extra NOP instruction to align the 'XXEVAL' instruction. + +I have tested these patches on both big endian and little endian PowerPC +servers, with no regressions. Can I check these patchs into the trunk? + +2025-06-11 Michael Meissner + +gcc/ + + PR target/117251 + * config/rs6000/fusion.md: Regenerate. + * config/rs6000/genfusion.pl (gen_logical_addsubf): Add support to + generate vector and => nand fusion if XXEVAL is supported. + + Branch work210-sha, patch #343 + +PR target/117251: Improve vector andc to vector nand fusion + +See the following post for a complete explanation of what the patches for +PR target/117251: + + * https://gcc.gnu.org/pipermail/gcc-patches/2025-June/686474.html + +This is patch #43 of 45 to generate the 'XXEVAL' instruction on power10 and +power11 instead of using the Altivec 'VANDC' instruction feeding into 'VNAND'. +The 'XXEVAL' instruction can use all 64 vector registers, instead of the 32 +registers that traditional Altivec vector instructions use. By allowing all of +the vector registers to be used, it reduces the amount of spilling that a large +benchmark generated. + +Currently the following code: + + vector int a, b, c, d; + a = ~ ((c & ~ d) & b); + +Generates: + + vandc t,c,d + vnand a,t,b + +Now in addition with this patch, if the arguments or result is allocated to a +traditional FPR register, the GCC compiler will now generate the following +code instead of adding vector move instructions: + + xxeval a,b,c,253 + +Since fusion using 2 Altivec instructions is slightly faster than using the +'XXEVAL' instruction we prefer to generate the Altivec instructions if we can. +In addition, because 'XXEVAL' is a prefixed instruction, it possibly might +generate an extra NOP instruction to align the 'XXEVAL' instruction. + +I have tested these patches on both big endian and little endian PowerPC +servers, with no regressions. Can I check these patchs into the trunk? + +2025-06-11 Michael Meissner + +gcc/ + + PR target/117251 + * config/rs6000/fusion.md: Regenerate. + * config/rs6000/genfusion.pl (gen_logical_addsubf): A
[gcc r16-1421] RISC-V: Prevent speculative vsetvl insn scheduling
https://gcc.gnu.org/g:1c5e99ce8744c166d82cb96bbb2d58392b5fb8d7 commit r16-1421-g1c5e99ce8744c166d82cb96bbb2d58392b5fb8d7 Author: Edwin Lu Date: Tue Jun 10 13:26:42 2025 -0700 RISC-V: Prevent speculative vsetvl insn scheduling The instruction scheduler appears to be speculatively hoisting vsetvl insns outside of their basic block without checking for data dependencies. This resulted in a situation where the following occurs vsetvli a5,a1,e32,m1,tu,ma vle32.v v2,0(a0) sub a1,a1,a5 <-- a1 potentially set to 0 sh2add a0,a5,a0 vfmacc.vv v1,v2,v2 vsetvli a5,a1,e32,m1,tu,ma <-- incompatible vinfo. update vl to 0 beq a1,zero,.L12 <-- check if avl is 0 This patch would essentially delay the vsetvl update to after the branch to prevent unnecessarily updating the vinfo at the end of a basic block. PR/117974 gcc/ChangeLog: * config/riscv/riscv.cc (struct riscv_tune_param): Add tune param. (riscv_sched_can_speculate_insn): Implement. (TARGET_SCHED_CAN_SPECULATE_INSN): Ditto. gcc/testsuite/ChangeLog: * gcc.target/riscv/rvv/vsetvl/pr117974.c: New test. Signed-off-by: Edwin Lu Diff: --- gcc/config/riscv/riscv.cc | 35 ++ .../gcc.target/riscv/rvv/vsetvl/pr117974.c | 19 2 files changed, 54 insertions(+) diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index 0c99850c14d8..c6e0ffb0755e 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -302,6 +302,7 @@ struct riscv_tune_param bool vector_unaligned_access; bool use_divmod_expansion; bool overlap_op_by_pieces; + bool speculative_sched_vsetvl; unsigned int fusible_ops; const struct cpu_vector_cost *vec_costs; const char *function_align; @@ -464,6 +465,7 @@ static const struct riscv_tune_param rocket_tune_info = { false, /* vector_unaligned_access */ false, /* use_divmod_expansion */ false, /* overlap_op_by_pieces */ + false, /* speculative_sched_vsetvl */ RISCV_FUSE_NOTHING, /* fusible_ops */ NULL,/* vector cost */ NULL,/* function_align */ @@ -486,6 +488,7 @@ static const struct riscv_tune_param sifive_7_tune_info = { false, /* vector_unaligned_access */ false, /* use_divmod_expansion */ false, /* overlap_op_by_pieces */ + false, /* speculative_sched_vsetvl */ RISCV_FUSE_NOTHING, /* fusible_ops */ NULL,/* vector cost */ NULL,/* function_align */ @@ -508,6 +511,7 @@ static const struct riscv_tune_param sifive_p400_tune_info = { false, /* vector_unaligned_access */ false, /* use_divmod_expansion */ false, /* overlap_op_by_pieces */ + false, /* speculative_sched_vsetvl */ RISCV_FUSE_LUI_ADDI | RISCV_FUSE_AUIPC_ADDI, /* fusible_ops */ &generic_vector_cost,/* vector cost */ NULL,/* function_align */ @@ -530,6 +534,7 @@ static const struct riscv_tune_param sifive_p600_tune_info = { false, /* vector_unaligned_access */ false, /* use_divmod_expansion */ false, /* overlap_op_by_pieces */ + false, /* speculative_sched_vsetvl */ RISCV_FUSE_LUI_ADDI | RISCV_FUSE_AUIPC_ADDI, /* fusible_ops */ &generic_vector_cost,/* vector cost */ NULL,/* function_align */ @@ -552,6 +557,7 @@ static const struct riscv_tune_param thead_c906_tune_info = { false, /* vector_unaligned_access */ false, /* use_divmod_expansion */ false, /* overlap_op_by_pieces */ + false, /* speculative_sched_vsetvl */ RISCV_FUSE_NOTHING, /* fusible_ops */ NULL,/* vector cost */ NULL,/* function_align */ @@ -574,6 +580,7 @
[gcc r16-1428] libstdc++: Add _GLIBCXX_USE_BUILTIN_TRAIT to Doxygen config
https://gcc.gnu.org/g:72a98dc6e517eb7cdff1ac1cef11a18702aa6771 commit r16-1428-g72a98dc6e517eb7cdff1ac1cef11a18702aa6771 Author: Jonathan Wakely Date: Thu May 29 13:49:04 2025 +0100 libstdc++: Add _GLIBCXX_USE_BUILTIN_TRAIT to Doxygen config This ensures that Doxygen sees the simpler definitions of type traits, which are implemented using the built-ins. Also add _GLIBCXX_HAVE_ICONV (which is less important) and fix some typos for _GLIBCXX_BEGIN_INLINE_ABI_NAMESPACE and _GLIBCXX_END_INLINE_ABI_NAMESPACE. libstdc++-v3/ChangeLog: * doc/doxygen/user.cfg.in (PREDEFINED): Remove -D prefixes from some macros. Define _GLIBCXX_USE_BUILTIN_TRAIT and _GLIBCXX_HAVE_ICONV macros. Diff: --- libstdc++-v3/doc/doxygen/user.cfg.in | 6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/libstdc++-v3/doc/doxygen/user.cfg.in b/libstdc++-v3/doc/doxygen/user.cfg.in index e926c6707f67..536e035b0238 100644 --- a/libstdc++-v3/doc/doxygen/user.cfg.in +++ b/libstdc++-v3/doc/doxygen/user.cfg.in @@ -2350,8 +2350,8 @@ PREDEFINED = __cplusplus=202002L \ "_GLIBCXX_END_NAMESPACE_CONTAINER= " \ "_GLIBCXX_END_NAMESPACE_CXX11= " \ "_GLIBCXX_END_NAMESPACE_LDBL= " \ -"-D_GLIBCXX_BEGIN_INLINE_ABI_NAMESPACE(X)= " \ -"-D_GLIBCXX_END_INLINE_ABI_NAMESPACE(X)= " \ +"_GLIBCXX_BEGIN_INLINE_ABI_NAMESPACE(X)= " \ +"_GLIBCXX_END_INLINE_ABI_NAMESPACE(X)= " \ "_GLIBCXX_TEMPLATE_ARGS=... " \ "_GLIBCXX_DEPRECATED= " \ "_GLIBCXX_DEPRECATED_SUGGEST(E)= " \ @@ -2414,6 +2414,8 @@ PREDEFINED = __cplusplus=202002L \ _GLIBCXX_HAVE_BUILTIN_IS_AGGREGATE \ _GLIBCXX_HAVE_IS_CONSTANT_EVALUATED \ _GLIBCXX_HAVE_BUILTIN_LAUNDER \ +"_GLIBCXX_USE_BUILTIN_TRAIT(X)=1" \ +_GLIBCXX_HAVE_ICONV=1 \ "_GLIBCXX_DOXYGEN_ONLY(X)=X " \ __exception_ptr=__unspecified__ \
[gcc r16-1426] libstdc++: Fix mismatched @cond and @endcond in
https://gcc.gnu.org/g:606f25a2d6206dd8769e998164268f038ccd3424 commit r16-1426-g606f25a2d6206dd8769e998164268f038ccd3424 Author: Jonathan Wakely Date: Wed Jun 11 13:21:24 2025 +0100 libstdc++: Fix mismatched @cond and @endcond in I messed up the Doxygen conditionals in r16-1077-gb32bf304793047. libstdc++-v3/ChangeLog: * include/std/type_traits: Restore @cond and @endcond balance. Diff: --- libstdc++-v3/include/std/type_traits | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libstdc++-v3/include/std/type_traits b/libstdc++-v3/include/std/type_traits index c8907fe4d382..abff9f880001 100644 --- a/libstdc++-v3/include/std/type_traits +++ b/libstdc++-v3/include/std/type_traits @@ -1036,6 +1036,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION struct __is_array_unknown_bounds<_Tp[]> : public true_type { }; + /// @endcond // Destructible and constructible type properties. @@ -1046,6 +1047,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION : public __bool_constant<__is_destructible(_Tp)> { }; #else + /// @cond undocumented + // In N3290 is_destructible does not say anything about function // types and abstract types, see LWG 2049. This implementation // describes function types as non-destructible and all complete
[gcc r16-1427] libstdc++: Remove redundant parentheses in preprocessor condition
https://gcc.gnu.org/g:2202c6a9769ec3f9e0a066355eaae8b4a2d98c0c commit r16-1427-g2202c6a9769ec3f9e0a066355eaae8b4a2d98c0c Author: Jonathan Wakely Date: Wed Jun 11 13:29:30 2025 +0100 libstdc++: Remove redundant parentheses in preprocessor condition Also indent the group controlled by the condition. libstdc++-v3/ChangeLog: * libsupc++/exception: Remove redundant parentheses and adjust whitespace. Diff: --- libstdc++-v3/libsupc++/exception | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libstdc++-v3/libsupc++/exception b/libstdc++-v3/libsupc++/exception index 246c9b185638..8c3bb33c831b 100644 --- a/libstdc++-v3/libsupc++/exception +++ b/libstdc++-v3/libsupc++/exception @@ -164,9 +164,9 @@ _GLIBCXX_END_NAMESPACE_VERSION } // extern "C++" -#if (__cplusplus >= 201103L) -#include -#include +#if __cplusplus >= 201103L +# include +# include #endif #endif
[gcc r16-1424] cobol: Eliminate unguarded clock_gettime dependencies. [PR119975]
https://gcc.gnu.org/g:582dda08eabc8f7dc9c504c0010d778bd6ff09b2 commit r16-1424-g582dda08eabc8f7dc9c504c0010d778bd6ff09b2 Author: Robert Dubner Date: Wed Jun 11 15:49:41 2025 -0400 cobol: Eliminate unguarded clock_gettime dependencies. [PR119975] These changes are help make it possible to compile on MacOS. In addition to guarding clock_settime() calls, it removes the use of structures and constants needed for clock_settime(). libgcobol/ChangeLog: PR cobol/119975 * intrinsic.cc (__gg__current_date): Eliminate CLOCK_REALTIME. (__gg__seconds_past_midnight): Likewise. (__gg__formatted_current_date): Likewise. (__gg__random): Likewise. (__gg__random_next): Likewise. * libgcobol.cc: include . (__gg__abort): Eliminate CLOCK_REALTIME. (cobol_time): Likewise. (get_time_nanoseconds): Rename. (get_time_nanoseconds_local): Comment; Eliminate CLOCK_REALTIME. (__gg__clock_gettime): Likewise. (__gg__get_date_hhmmssff): Likewise. * libgcobol.h (__gg__clock_gettime): Eliminate clockid_t from declaration. Diff: --- libgcobol/intrinsic.cc | 12 ++-- libgcobol/libgcobol.cc | 44 ++-- libgcobol/libgcobol.h | 2 +- 3 files changed, 37 insertions(+), 21 deletions(-) diff --git a/libgcobol/intrinsic.cc b/libgcobol/intrinsic.cc index 2d8d79c1c7c7..81ae638630f1 100644 --- a/libgcobol/intrinsic.cc +++ b/libgcobol/intrinsic.cc @@ -1219,7 +1219,7 @@ __gg__current_date(cblc_field_t *dest) { // FUNCTION CURRENT-DATE struct cbl_timespec tp = {}; - __gg__clock_gettime(CLOCK_REALTIME, &tp); // time_t tv_sec; long tv_nsec + __gg__clock_gettime(&tp); // time_t tv_sec; long tv_nsec char retval[DATE_STRING_BUFFER_SIZE]; timespec_to_string(retval, tp); @@ -1236,7 +1236,7 @@ __gg__seconds_past_midnight(cblc_field_t *dest) struct tm tm; __int128 retval=0; - __gg__clock_gettime(CLOCK_REALTIME, &tp); // time_t tv_sec; long tv_nsec + __gg__clock_gettime(&tp); // time_t tv_sec; long tv_nsec localtime_r(&tp.tv_sec, &tm); retval += tm.tm_hour; @@ -1460,7 +1460,7 @@ __gg__formatted_current_date( cblc_field_t *dest, // Destination string size_t input_offset, size_t input_size) { - // FUNCTION CURRENT-DATE + // FUNCTION FORMATTED-CURRENT-DATE // Establish the destination, and set it to spaces char *d= PTRCAST(char, dest->data); @@ -1485,7 +1485,7 @@ __gg__formatted_current_date( cblc_field_t *dest, // Destination string } struct cbl_timespec ts = {}; - __gg__clock_gettime(CLOCK_REALTIME, &ts); + __gg__clock_gettime(&ts); struct tm tm = {}; #ifdef HAVE_STRUCT_TM_TM_ZONE @@ -3433,7 +3433,7 @@ __gg__random( cblc_field_t *dest, state = (char *)malloc(state_len); struct cbl_timespec ts; -__gg__clock_gettime(CLOCK_REALTIME, &ts); +__gg__clock_gettime(&ts); initstate_r( ts.tv_nsec, state, state_len, buf); } int seed = (int)__gg__binary_value_from_qualified_field(&rdigits, @@ -3473,7 +3473,7 @@ __gg__random_next(cblc_field_t *dest) buf->state = NULL; state = (char *)malloc(state_len); struct cbl_timespec ts; -__gg__clock_gettime(CLOCK_REALTIME, &ts); +__gg__clock_gettime(&ts); initstate_r( ts.tv_nsec, state, state_len, buf); } random_r(buf, &retval_31); diff --git a/libgcobol/libgcobol.cc b/libgcobol/libgcobol.cc index f8697afd59cb..81b5b7af8121 100644 --- a/libgcobol/libgcobol.cc +++ b/libgcobol/libgcobol.cc @@ -69,6 +69,7 @@ #include #include #include +#include #include #include "exceptl.h" @@ -264,7 +265,7 @@ class ec_status_t { , operation(file_op_none) , mode(file_mode_none_e) , user_status(nullptr) -, filename(nullptr) +, filename(nullptr) {} explicit file_status_t( const cblc_file_t *file ) : ifile(file->symbol_table_index) @@ -558,7 +559,7 @@ __gg__abort(const char *msg) abort(); } -void +void __gg__mabort() { __gg__abort("Memory allocation error\n"); @@ -2290,7 +2291,7 @@ static time_t cobol_time() { struct cbl_timespec tp; - __gg__clock_gettime(CLOCK_REALTIME, &tp); + __gg__clock_gettime(&tp); return tp.tv_sec; } @@ -2402,12 +2403,28 @@ int_from_digits(const char * &p, int ndigits) return retval; } -uint64_t -get_time_nanoseconds() +// For testing purposes, this undef causes the use of gettimeofday(). +// #undef HAVE_CLOCK_GETTIME + +static uint64_t +get_time_nanoseconds_local() { // This code was unabashedly stolen from gcc/timevar.cc. // It returns the Unix epoch with nine decimal places. + /* Note: I am perplexed. I have been examining the gcc Makefiles and + config
[gcc r16-1425] c: remaining fix for the composite type inconsistency [PR120510]
https://gcc.gnu.org/g:0ede0508cc6e249f6759ac1e51b34d0e905eae80 commit r16-1425-g0ede0508cc6e249f6759ac1e51b34d0e905eae80 Author: Martin Uecker Date: Mon Jun 9 18:48:43 2025 +0200 c: remaining fix for the composite type inconsistency [PR120510] There is an old GNU extension which allows overriding the promoted old-style arguments when there is an earlier prototype An example (from a test added for PR1) is the following. float dremf (float, float); float dremf (x, y) float x, y; { return x + y; } The types of the two declarations are not compatible, because the arguments are not self-promoting. Add a special case to function_types_compatible_p that can be toggled via a flag for comptypes_internal and add a helper function to be able to add the checking assertions to composite_type. PR c/120510 gcc/c/ChangeLog: * c-typeck.cc (composite_type_internal): Activate checking assertions for all types and also inputs. (comptypes_for_composite_check): New helper function. (function_types_compatible_p): Add exception. gcc/testsuite/ChangeLog: * gcc.dg/old-style-prom-4.c: New test. Diff: --- gcc/c/c-typeck.cc | 51 +++-- gcc/testsuite/gcc.dg/old-style-prom-4.c | 25 2 files changed, 67 insertions(+), 9 deletions(-) diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc index ae3e7068729e..e24629be918b 100644 --- a/gcc/c/c-typeck.cc +++ b/gcc/c/c-typeck.cc @@ -136,6 +136,7 @@ static int lvalue_or_else (location_t, const_tree, enum lvalue_use); static void record_maybe_used_decl (tree); static bool comptypes_internal (const_tree, const_tree, struct comptypes_data *data); +static bool comptypes_check_for_composite (tree t1, tree t2); /* Return true if EXP is a null pointer constant, false otherwise. */ @@ -1002,15 +1003,13 @@ composite_type_internal (tree t1, tree t2, struct composite_cache* cache) tree composite_type (tree t1, tree t2) { + gcc_checking_assert (comptypes_check_for_composite (t1, t2)); + struct composite_cache cache = { }; tree n = composite_type_internal (t1, t2, &cache); - /* For function types there are some cases where qualifiers do - not match. See PR120510. */ - if (FUNCTION_TYPE != TREE_CODE (n)) -{ - gcc_checking_assert (comptypes (n, t1)); - gcc_checking_assert (comptypes (n, t2)); -} + + gcc_checking_assert (comptypes_check_for_composite (n, t1)); + gcc_checking_assert (comptypes_check_for_composite (n, t2)); return n; } @@ -1454,16 +1453,39 @@ comptypes_verify (tree type1, tree type2) } struct comptypes_data { + + /* output */ bool enum_and_int_p; bool different_types_p; bool warning_needed; + + /* context */ bool anon_field; bool pointedto; + + /* configuration */ bool equiv; + bool ignore_promoting_args; const struct tagged_tu_seen_cache* cache; }; + +/* Helper function for composite_type. This function ignores when the + function type of an old-style declaration is incompatible with a type + of a declaration with prototype because some are arguments are not + self-promoting. This is ignored only for function types but not + ignored in a nested context. */ + +static bool +comptypes_check_for_composite (tree t1, tree t2) +{ + struct comptypes_data data = { }; + data.ignore_promoting_args = FUNCTION_TYPE == TREE_CODE (t1); + return comptypes_internal (t1, t2, &data); +} + + /* C implementation of compatible_types_for_indirection_note_p. */ bool @@ -1593,6 +1615,10 @@ comptypes_equiv_p (tree type1, tree type2) permitted in C11 typedef redeclarations, then this sets 'different_types_p' in DATA to true; it is never set to false, but may or may not be set if the types are incompatible. + If two functions types are not compatible only because one is + an old-style definition that does not have self-promoting arguments, + then this can be ignored by setting 'ignore_promoting_args_p'. + For 'equiv' we can compute equivalency classes (see above). This differs from comptypes, in that we don't free the seen types. */ @@ -2030,9 +2056,14 @@ function_types_compatible_p (const_tree f1, const_tree f2, ret2 = build_qualified_type (TYPE_MAIN_VARIANT (ret2), TYPE_QUALS (ret2) & ~TYPE_QUAL_VOLATILE); + bool ignore_pargs = data->ignore_promoting_args; + data->ignore_promoting_args = false; + if (!comptypes_internal (ret1, ret2, data)) return false; + data->ignore_promoting_args = ignore_pargs; + tree args1 = TYPE_ARG_TYPES (f1); tree args2 = TYPE_ARG_TYPES (f2); @@ -2046,8 +2077,9 @@ function_types_compatible_p (const_tree f1, const_tree f2, { if (TYPE_NO_NAMED_ARGS_STDARG_P (f1) != TYPE_NO_NAMED_ARGS_STDARG_P (f2))
[gcc r16-1429] c/c++: Handle '#pragma GCC target optimize' early [PR48026]
https://gcc.gnu.org/g:dcb9af06212e8bb36e84a1b8498c625c29abeb6f commit r16-1429-gdcb9af06212e8bb36e84a1b8498c625c29abeb6f Author: Gwenole Beauchesne Date: Mon Jun 2 14:44:55 2025 -0700 c/c++: Handle '#pragma GCC target optimize' early [PR48026] Handle '#pragma GCC optimize' earlier as the __OPTIMIZE__ macro may need to be defined as well for certain usages. Add additional tests for the '#pragma GCC target' case with auto-vectorization enabled and multiple combinations of namespaces and/or class member functions. This is similar to what was done for `#pramga GCC target` in r14-4967-g8697d3a1dcf327, to fix the similar issue there. Add more complete tests for PR c++/41201 after git commit r14-4967-g8697d3a1dcf327. PR c++/41201 PR c++/48026 gcc/c-family/ChangeLog: * c-pragma.cc (init_pragma): Use c_register_pragma_with_early_handler instead of c_register_pragma for `#pragma GCC optimize`. gcc/testsuite/ChangeLog: * c-c++-common/pragma-optimize-1.c: New test. * g++.target/i386/vect-pragma-target-1.C: New test. * g++.target/i386/vect-pragma-target-2.C: New test. * gcc.target/i386/vect-pragma-target-1.c: New test. * gcc.target/i386/vect-pragma-target-2.c: New test. Signed-off-by: Gwenole Beauchesne Co-authored-by: Andrew Pinski Diff: --- gcc/c-family/c-pragma.cc | 4 +- gcc/testsuite/c-c++-common/pragma-optimize-1.c | 10 ++ .../g++.target/i386/vect-pragma-target-1.C | 6 + .../g++.target/i386/vect-pragma-target-2.C | 6 + .../gcc.target/i386/vect-pragma-target-1.c | 194 + .../gcc.target/i386/vect-pragma-target-2.c | 7 + 6 files changed, 226 insertions(+), 1 deletion(-) diff --git a/gcc/c-family/c-pragma.cc b/gcc/c-family/c-pragma.cc index 8b5cdcc56ea8..137b83bf5b15 100644 --- a/gcc/c-family/c-pragma.cc +++ b/gcc/c-family/c-pragma.cc @@ -1847,7 +1847,9 @@ init_pragma (void) c_register_pragma_with_early_handler ("GCC", "target", handle_pragma_target, handle_pragma_target); - c_register_pragma ("GCC", "optimize", handle_pragma_optimize); + c_register_pragma_with_early_handler ("GCC", "optimize", + handle_pragma_optimize, + handle_pragma_optimize); c_register_pragma_with_early_handler ("GCC", "push_options", handle_pragma_push_options, handle_pragma_push_options); diff --git a/gcc/testsuite/c-c++-common/pragma-optimize-1.c b/gcc/testsuite/c-c++-common/pragma-optimize-1.c new file mode 100644 index ..1446e5aee054 --- /dev/null +++ b/gcc/testsuite/c-c++-common/pragma-optimize-1.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-options "-Ofast" } */ + +/* PR c++/48026 */ +/* Make sure `#pragma GCC optimize` affects the pre-defined macros too */ + +#pragma GCC optimize ("no-fast-math") +#ifdef __FAST_MATH__ +# error Hey yo, What you doing on FAST_MATH?? +#endif diff --git a/gcc/testsuite/g++.target/i386/vect-pragma-target-1.C b/gcc/testsuite/g++.target/i386/vect-pragma-target-1.C new file mode 100644 index ..2f360cf50e1d --- /dev/null +++ b/gcc/testsuite/g++.target/i386/vect-pragma-target-1.C @@ -0,0 +1,6 @@ +/* { dg-do compile { target { i?86-*-* x86_64-*-* } } } */ +/* { dg-options "-O0" } */ +/* { dg-final { scan-assembler-times "paddd.+xmm\[0-9]+"1 } } */ +/* { dg-final { scan-assembler-times "vfmadd132ps.+ymm\[0-9]+" 1 } } */ +/* { dg-final { scan-assembler-times "vpaddw.+zmm\[0-9]+" 1 } } */ +#include "../../gcc.target/i386/vect-pragma-target-1.c" diff --git a/gcc/testsuite/g++.target/i386/vect-pragma-target-2.C b/gcc/testsuite/g++.target/i386/vect-pragma-target-2.C new file mode 100644 index ..b85bc93d8456 --- /dev/null +++ b/gcc/testsuite/g++.target/i386/vect-pragma-target-2.C @@ -0,0 +1,6 @@ +/* { dg-do compile { target { i?86-*-* x86_64-*-* } } } */ +/* { dg-options "-O0" } */ +/* { dg-final { scan-assembler-times "paddd.+xmm\[0-9]+"1 } } */ +/* { dg-final { scan-assembler-times "vfmadd132ps.+ymm\[0-9]+" 1 } } */ +/* { dg-final { scan-assembler-times "vpaddw.+zmm\[0-9]+" 1 } } */ +#include "../../gcc.target/i386/vect-pragma-target-2.c" diff --git a/gcc/testsuite/gcc.target/i386/vect-pragma-target-1.c b/gcc/testsuite/gcc.target/i386/vect-pragma-target-1.c new file mode 100644 index ..f5e71e453ec1 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/vect-pragma-target-1.c @@ -0,0 +1,194 @@ +/* { dg-do compile { target { i?86-*-* x86_64-*-* } } }
[gcc r16-1419] libfortran: Simplify Makefile logic
https://gcc.gnu.org/g:94e0f29b6b216a85a03b732a90f900b8b0e99c6b commit r16-1419-g94e0f29b6b216a85a03b732a90f900b8b0e99c6b Author: Francois-Xavier Coudert Date: Tue Jun 10 12:37:02 2025 +0200 libfortran: Simplify Makefile logic Simplify the structure of the Makefile, because now we don't need so many different variables. Also, list the m4 directory entirely in EXTRA_DIST instead of individual files, to reduce information duplication. I also introduce some level of checking the regenerate.sh script. It should catch cases where the list of generated files gets out of sync between Makefile.am and regenerate.sh 2025-06-10 François-Xavier Coudert libgfortran/ChangeLog: PR libfortran/116400 * Makefile.am: Simplify logic. * Makefile.in: Regenerate. * regenerate.sh: Add some checks. Diff: --- libgfortran/Makefile.am | 706 + libgfortran/Makefile.in | 1531 - libgfortran/regenerate.sh | 21 +- 3 files changed, 990 insertions(+), 1268 deletions(-) diff --git a/libgfortran/Makefile.am b/libgfortran/Makefile.am index ce35a67a3594..4f3b30332245 100644 --- a/libgfortran/Makefile.am +++ b/libgfortran/Makefile.am @@ -240,102 +240,61 @@ runtime/stop.c endif -i_all_c= \ +i_matmul_c= \ +generated/matmul_i1.c \ +generated/matmul_i2.c \ +generated/matmul_i4.c \ +generated/matmul_i8.c \ +generated/matmul_i16.c \ +generated/matmul_r4.c \ +generated/matmul_r8.c \ +generated/matmul_r10.c \ +generated/matmul_r16.c \ +generated/matmul_r17.c \ +generated/matmul_c4.c \ +generated/matmul_c8.c \ +generated/matmul_c10.c \ +generated/matmul_c16.c \ +generated/matmul_c17.c + +i_matmulavx128_c= \ +generated/matmulavx128_i1.c \ +generated/matmulavx128_i2.c \ +generated/matmulavx128_i4.c \ +generated/matmulavx128_i8.c \ +generated/matmulavx128_i16.c \ +generated/matmulavx128_r4.c \ +generated/matmulavx128_r8.c \ +generated/matmulavx128_r10.c \ +generated/matmulavx128_r16.c \ +generated/matmulavx128_r17.c \ +generated/matmulavx128_c4.c \ +generated/matmulavx128_c8.c \ +generated/matmulavx128_c10.c \ +generated/matmulavx128_c16.c \ +generated/matmulavx128_c17.c + +i_matmull_c= \ +generated/matmul_l4.c \ +generated/matmul_l8.c \ +generated/matmul_l16.c + +gfor_built_src= \ generated/all_l1.c \ generated/all_l2.c \ generated/all_l4.c \ generated/all_l8.c \ -generated/all_l16.c - -i_any_c= \ +generated/all_l16.c \ generated/any_l1.c \ generated/any_l2.c \ generated/any_l4.c \ generated/any_l8.c \ -generated/any_l16.c - -i_bessel_c= \ -generated/bessel_r4.c \ -generated/bessel_r8.c \ -generated/bessel_r10.c \ -generated/bessel_r16.c \ -generated/bessel_r17.c - -i_count_c= \ +generated/any_l16.c \ generated/count_1_l.c \ generated/count_2_l.c \ generated/count_4_l.c \ generated/count_8_l.c \ -generated/count_16_l.c - -i_iall_c= \ -generated/iall_i1.c \ -generated/iall_i2.c \ -generated/iall_i4.c \ -generated/iall_i8.c \ -generated/iall_i16.c - -i_iany_c= \ -generated/iany_i1.c \ -generated/iany_i2.c \ -generated/iany_i4.c \ -generated/iany_i8.c \ -generated/iany_i16.c - -i_iparity_c= \ -generated/iparity_i1.c \ -generated/iparity_i2.c \ -generated/iparity_i4.c \ -generated/iparity_i8.c \ -generated/iparity_i16.c - -i_findloc0_c= \ -generated/findloc0_i1.c \ -generated/findloc0_i2.c \ -generated/findloc0_i4.c \ -generated/findloc0_i8.c \ -generated/findloc0_i16.c \ -generated/findloc0_r4.c \ -generated/findloc0_r8.c \ -generated/findloc0_r10.c \ -generated/findloc0_r16.c \ -generated/findloc0_r17.c \ -generated/findloc0_c4.c \ -generated/findloc0_c8.c \ -generated/findloc0_c10.c \ -generated/findloc0_c16.c \ -generated/findloc0_c17.c - -i_findloc0s_c= \ -generated/findloc0_s1.c \ -generated/findloc0_s4.c - -i_findloc1_c= \ -generated/findloc1_i1.c \ -generated/findloc1_i2.c \ -generated/findloc1_i4.c \ -generated/findloc1_i8.c \ -generated/findloc1_i16.c \ -generated/findloc1_r4.c \ -generated/findloc1_r8.c \ -generated/findloc1_r10.c \ -generated/findloc1_r16.c \ -generated/findloc1_r17.c \ -generated/findloc1_c4.c \ -generated/findloc1_c8.c \ -generated/findloc1_c10.c \ -generated/findloc1_c16.c \ -generated/findloc1_c17.c - -i_findloc1s_c= \ -generated/findloc1_s1.c \ -generated/findloc1_s4.c - -i_findloc2s_c= \ -generated/findloc2_s1.c \ -generated/findloc2_s4.c - -i_maxloc0_c= \ +generated/count_16_l.c \ generated/maxloc0_4_i1.c \ generated/maxloc0_8_i1.c \ generated/maxloc0_16_i1.c \ @@ -380,17 +339,7 @@ generated/maxloc0_8_r16.c \ generated/maxloc0_16_r16.c \ generated/maxloc0_4_r17.c \ generated/maxloc0_8_r17.c \ -generated/maxloc0_16_r17.c - -i_maxloc0s_c = \ -generated/maxloc0_4_s1.c \ -generated/maxloc0_4_s4.c \ -generated/maxloc0_8_s1.c \ -generated/maxloc0_8_s4.c \ -generated/maxloc0_16_s1.c \ -generated/maxloc0_16_s4.c - -i_maxloc1_c= \ +generated/maxloc0_16_r17.c \ generated/maxloc1_4_i1.c \ generated/maxloc1_8_i1.c \ ge
[gcc r16-1420] i386: Fix signed integer overflow in ix86_expand_int_movcc [PR120604]
https://gcc.gnu.org/g:76cbd678d123ed93f99c4c52456bc14290f19b7f commit r16-1420-g76cbd678d123ed93f99c4c52456bc14290f19b7f Author: Uros Bizjak Date: Wed Jun 11 14:12:33 2025 +0200 i386: Fix signed integer overflow in ix86_expand_int_movcc [PR120604] Patch for PR120553 enabled full 64-bit DImode immediates in ix86_expand_int_movcc. However, the function calculates the difference between two immediate arguments using signed 64-bit HOST_WIDE_INT subtractions that can cause signed integer overflow. Avoid the overflow by casting operands of subtractions to (unsigned HOST_WIDE_INT). PR target/120604 gcc/ChangeLog: * config/i386/i386-expand.cc (ix86_expand_int_movcc): Cast operands of signed 64-bit HOST_WIDE_INT subtractions to (unsigned HOST_WIDE_INT). Diff: --- gcc/config/i386/i386-expand.cc | 18 -- 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/gcc/config/i386/i386-expand.cc b/gcc/config/i386/i386-expand.cc index 181e64a86bf6..5c8c18f98834 100644 --- a/gcc/config/i386/i386-expand.cc +++ b/gcc/config/i386/i386-expand.cc @@ -3609,7 +3609,7 @@ ix86_expand_int_movcc (rtx operands[]) negate_cc_compare_p = true; } - diff = ct - cf; + diff = (unsigned HOST_WIDE_INT) ct - (unsigned HOST_WIDE_INT) cf; /* Sign bit compares are better done using shifts than we do by using sbb. */ if (sign_bit_compare_p @@ -3667,7 +3667,8 @@ ix86_expand_int_movcc (rtx operands[]) PUT_CODE (compare_op, reverse_condition (GET_CODE (compare_op))); } - diff = ct - cf; + + diff = (unsigned HOST_WIDE_INT) ct - (unsigned HOST_WIDE_INT) cf; if (reg_overlap_mentioned_p (out, compare_op)) tmp = gen_reg_rtx (mode); @@ -3685,7 +3686,8 @@ ix86_expand_int_movcc (rtx operands[]) else { std::swap (ct, cf); - diff = ct - cf; + diff = (unsigned HOST_WIDE_INT) ct +- (unsigned HOST_WIDE_INT) cf; } tmp = emit_store_flag (tmp, code, op0, op1, VOIDmode, 0, -1); } @@ -3752,9 +3754,11 @@ ix86_expand_int_movcc (rtx operands[]) tmp = expand_simple_unop (mode, NOT, tmp, copy_rtx (tmp), 1); } + HOST_WIDE_INT ival = (unsigned HOST_WIDE_INT) cf + - (unsigned HOST_WIDE_INT) ct; tmp = expand_simple_binop (mode, AND, copy_rtx (tmp), -gen_int_mode (cf - ct, mode), +gen_int_mode (ival, mode), copy_rtx (tmp), 1, OPTAB_DIRECT); if (ct) tmp = expand_simple_binop (mode, PLUS, @@ -3791,7 +3795,7 @@ ix86_expand_int_movcc (rtx operands[]) if (new_code != UNKNOWN) { std::swap (ct, cf); - diff = -diff; + diff = (unsigned HOST_WIDE_INT) ct - (unsigned HOST_WIDE_INT) cf; code = new_code; } } @@ -3994,8 +3998,10 @@ ix86_expand_int_movcc (rtx operands[]) copy_rtx (out), 1, OPTAB_DIRECT); } + HOST_WIDE_INT ival = (unsigned HOST_WIDE_INT) cf + - (unsigned HOST_WIDE_INT) ct; out = expand_simple_binop (mode, AND, copy_rtx (out), -gen_int_mode (cf - ct, mode), +gen_int_mode (ival, mode), copy_rtx (out), 1, OPTAB_DIRECT); if (ct) out = expand_simple_binop (mode, PLUS, copy_rtx (out), GEN_INT (ct),
[gcc r16-1418] RISC-V: Add patterns for vector-scalar negate-(multiply-add/sub) [PR119100]
https://gcc.gnu.org/g:3ada458d344b13a49183278435d372fe9c7fef4b commit r16-1418-g3ada458d344b13a49183278435d372fe9c7fef4b Author: Paul-Antoine Arras Date: Wed Jun 4 14:51:17 2025 +0200 RISC-V: Add patterns for vector-scalar negate-(multiply-add/sub) [PR119100] This pattern enables the combine pass (or late-combine, depending on the case) to merge a vec_duplicate into a (possibly negated) minus-mult RTL instruction. Before this patch, we have two instructions, e.g.: vfmv.v.fv6,fa0 vfnmadd.vv v2,v6,v4 After, we get only one: vfnmadd.vf v2,fa0,v4 This also fixes a sign mistake in the handling of vfmsub. PR target/119100 gcc/ChangeLog: * config/riscv/autovec-opt.md (*_vf_): Only handle vfmadd and vfmsub. (*vfnmsub_): New pattern. (*vfnmadd_): New pattern. * config/riscv/riscv.cc (get_vector_binary_rtx_cost): Add cost model for NEG and VEC_DUPLICATE. gcc/testsuite/ChangeLog: * gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f16.c: Add vfnmadd and vfnmsub. * gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f32.c: Likewise. * gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f64.c: Likewise. * gcc.target/riscv/rvv/autovec/vx_vf/vf-2-f16.c: Likewise. * gcc.target/riscv/rvv/autovec/vx_vf/vf-2-f32.c: Likewise. * gcc.target/riscv/rvv/autovec/vx_vf/vf-2-f64.c: Likewise. * gcc.target/riscv/rvv/autovec/vx_vf/vf-3-f16.c: Likewise. * gcc.target/riscv/rvv/autovec/vx_vf/vf-3-f32.c: Likewise. * gcc.target/riscv/rvv/autovec/vx_vf/vf-3-f64.c: Likewise. * gcc.target/riscv/rvv/autovec/vx_vf/vf-4-f16.c: Likewise. * gcc.target/riscv/rvv/autovec/vx_vf/vf-4-f32.c: Likewise. * gcc.target/riscv/rvv/autovec/vx_vf/vf-4-f64.c: Likewise. * gcc.target/riscv/rvv/autovec/vx_vf/vf_mulop.h: Add support for neg variants. Fix sign for sub. * gcc.target/riscv/rvv/autovec/vx_vf/vf_mulop_data.h: Add data for neg variants. Fix data for sub. * gcc.target/riscv/rvv/autovec/vx_vf/vf_mulop_run.h: Rename x to f. * gcc.target/riscv/rvv/autovec/vx_vf/vf_vfmadd-run-1-f16.c: Add neg argument. * gcc.target/riscv/rvv/autovec/vx_vf/vf_vfmadd-run-1-f32.c: Likewise. * gcc.target/riscv/rvv/autovec/vx_vf/vf_vfmadd-run-1-f64.c: Likewise. * gcc.target/riscv/rvv/autovec/vx_vf/vf_vfmsub-run-1-f16.c: Likewise. * gcc.target/riscv/rvv/autovec/vx_vf/vf_vfmsub-run-1-f32.c: Likewise. * gcc.target/riscv/rvv/autovec/vx_vf/vf_vfmsub-run-1-f64.c: Likewise. * gcc.target/riscv/rvv/autovec/vx_vf/vf_vfnmadd-run-1-f16.c: New test. * gcc.target/riscv/rvv/autovec/vx_vf/vf_vfnmadd-run-1-f32.c: New test. * gcc.target/riscv/rvv/autovec/vx_vf/vf_vfnmadd-run-1-f64.c: New test. * gcc.target/riscv/rvv/autovec/vx_vf/vf_vfnmsub-run-1-f16.c: New test. * gcc.target/riscv/rvv/autovec/vx_vf/vf_vfnmsub-run-1-f32.c: New test. * gcc.target/riscv/rvv/autovec/vx_vf/vf_vfnmsub-run-1-f64.c: New test. Diff: --- gcc/config/riscv/autovec-opt.md| 35 +- gcc/config/riscv/riscv.cc | 2 + .../gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f16.c | 8 +- .../gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f32.c | 8 +- .../gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f64.c | 8 +- .../gcc.target/riscv/rvv/autovec/vx_vf/vf-2-f16.c | 8 +- .../gcc.target/riscv/rvv/autovec/vx_vf/vf-2-f32.c | 8 +- .../gcc.target/riscv/rvv/autovec/vx_vf/vf-2-f64.c | 8 +- .../gcc.target/riscv/rvv/autovec/vx_vf/vf-3-f16.c | 8 +- .../gcc.target/riscv/rvv/autovec/vx_vf/vf-3-f32.c | 8 +- .../gcc.target/riscv/rvv/autovec/vx_vf/vf-3-f64.c | 8 +- .../gcc.target/riscv/rvv/autovec/vx_vf/vf-4-f16.c | 8 +- .../gcc.target/riscv/rvv/autovec/vx_vf/vf-4-f32.c | 8 +- .../gcc.target/riscv/rvv/autovec/vx_vf/vf-4-f64.c | 8 +- .../gcc.target/riscv/rvv/autovec/vx_vf/vf_mulop.h | 74 ++-- .../riscv/rvv/autovec/vx_vf/vf_mulop_data.h| 406 - .../riscv/rvv/autovec/vx_vf/vf_mulop_run.h | 4 +- .../riscv/rvv/autovec/vx_vf/vf_vfmadd-run-1-f16.c | 2 +- .../riscv/rvv/autovec/vx_vf/vf_vfmadd-run-1-f32.c | 2 +- .../riscv/rvv/autovec/vx_vf/vf_vfmadd-run-1-f64.c | 2 +- .../riscv/rvv/autovec/vx_vf/vf_vfmsub-run-1-f16.c | 2 +- .../riscv/rvv/autovec/vx_vf/vf_vfmsub-run-1-f32.c | 2 +- .../riscv/rvv/autovec/vx_vf/vf_vfmsub-run-1-f64.c | 2 +- .../riscv/rvv/autovec/vx_vf/vf_vfnmadd-run-1-f16.c | 15 + .../riscv/rvv/autovec/vx_vf/vf_vfnmadd-run-1-f32.c | 15 + .../riscv/rvv/autovec/vx_vf/vf_vfnmadd-run-1-f64.c | 15 + .../riscv/rvv/autovec/vx_vf/vf_vfnmsub-run-1-f16.c | 15 + .../riscv/r
[gcc r16-1417] c: clean up some functions in c-typeck.cc
https://gcc.gnu.org/g:9ae1af9fca4b354fe0b4d10eca3424a7471cf7b6 commit r16-1417-g9ae1af9fca4b354fe0b4d10eca3424a7471cf7b6 Author: Martin Uecker Date: Mon Jun 9 11:30:04 2025 +0200 c: clean up some functions in c-typeck.cc This removes two unnecessary variables and replaces 1/0 with true/false for two functions with boolean return type. gcc/c/ChangeLog: * c-typeck.cc (function_types_compatible_p): Remove unused variables and return true/false instead of 1/0. (type_lists_compatible_p): Return false instead of 0. Diff: --- gcc/c/c-typeck.cc | 63 +-- 1 file changed, 24 insertions(+), 39 deletions(-) diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc index 539d4815ae4f..ae3e7068729e 100644 --- a/gcc/c/c-typeck.cc +++ b/gcc/c/c-typeck.cc @@ -2016,14 +2016,8 @@ static bool function_types_compatible_p (const_tree f1, const_tree f2, struct comptypes_data *data) { - tree args1, args2; - /* 1 if no need for warning yet, 2 if warning cause has been seen. */ - int val = 1; - int val1; - tree ret1, ret2; - - ret1 = TREE_TYPE (f1); - ret2 = TREE_TYPE (f2); + tree ret1 = TREE_TYPE (f1); + tree ret2 = TREE_TYPE (f2); /* 'volatile' qualifiers on a function's return type used to mean the function is noreturn. */ @@ -2035,12 +2029,12 @@ function_types_compatible_p (const_tree f1, const_tree f2, if (TYPE_VOLATILE (ret2)) ret2 = build_qualified_type (TYPE_MAIN_VARIANT (ret2), TYPE_QUALS (ret2) & ~TYPE_QUAL_VOLATILE); - val = comptypes_internal (ret1, ret2, data); - if (val == 0) -return 0; - args1 = TYPE_ARG_TYPES (f1); - args2 = TYPE_ARG_TYPES (f2); + if (!comptypes_internal (ret1, ret2, data)) +return false; + + tree args1 = TYPE_ARG_TYPES (f1); + tree args2 = TYPE_ARG_TYPES (f2); if ((args1 == NULL_TREE) != (args2 == NULL_TREE)) data->different_types_p = true; @@ -2051,40 +2045,31 @@ function_types_compatible_p (const_tree f1, const_tree f2, if (args1 == NULL_TREE) { if (TYPE_NO_NAMED_ARGS_STDARG_P (f1) != TYPE_NO_NAMED_ARGS_STDARG_P (f2)) - return 0; + return false; if (!self_promoting_args_p (args2)) - return 0; + return false; /* If one of these types comes from a non-prototype fn definition, compare that with the other type's arglist. If they don't match, ask for a warning (but no error). */ if (TYPE_ACTUAL_ARG_TYPES (f1) - && type_lists_compatible_p (args2, TYPE_ACTUAL_ARG_TYPES (f1), - data) != 1) - { - val = 1; - data->warning_needed = true; - } - return val; + && !type_lists_compatible_p (args2, TYPE_ACTUAL_ARG_TYPES (f1), data)) +data->warning_needed = true; + return true; } if (args2 == NULL_TREE) { if (TYPE_NO_NAMED_ARGS_STDARG_P (f1) != TYPE_NO_NAMED_ARGS_STDARG_P (f2)) - return 0; + return false; if (!self_promoting_args_p (args1)) - return 0; + return false; if (TYPE_ACTUAL_ARG_TYPES (f2) - && type_lists_compatible_p (args1, TYPE_ACTUAL_ARG_TYPES (f2), - data) != 1) - { - val = 1; - data->warning_needed = true; - } - return val; + && !type_lists_compatible_p (args1, TYPE_ACTUAL_ARG_TYPES (f2), data)) + data->warning_needed = true; + return true; } /* Both types have argument lists: compare them and propagate results. */ - val1 = type_lists_compatible_p (args1, args2, data); - return val1; + return type_lists_compatible_p (args1, args2, data); } /* Check two lists of types for compatibility, returning false for @@ -2101,7 +2086,7 @@ type_lists_compatible_p (const_tree args1, const_tree args2, /* If one list is shorter than the other, they fail to match. */ if (args1 == NULL_TREE || args2 == NULL_TREE) - return 0; + return false; tree a1 = TREE_VALUE (args1); tree a2 = TREE_VALUE (args2); tree mv1 = remove_qualifiers (a1); @@ -2115,12 +2100,12 @@ type_lists_compatible_p (const_tree args1, const_tree args2, if (a1 == NULL_TREE) { if (c_type_promotes_to (a2) != a2) - return 0; + return false; } else if (a2 == NULL_TREE) { if (c_type_promotes_to (a1) != a1) - return 0; + return false; } /* If one of the lists has an error marker, ignore this arg. */ else if (TREE_CODE (a1) == ERROR_MARK @@ -2147,7 +2132,7 @@ type_lists_compatible_p (const_tree args1, const_tree args2, break; } if (memb == NULL_TREE) - return 0; + return false; } else if (TREE_CODE (a2) == UN
[gcc r16-1416] c: fix ICE for invalid code in generic selection [PR120303]
https://gcc.gnu.org/g:556a882feeaa7be7518fed3d97a3986a61ca9e45 commit r16-1416-g556a882feeaa7be7518fed3d97a3986a61ca9e45 Author: Martin Uecker Date: Wed Jun 4 20:07:11 2025 +0200 c: fix ICE for invalid code in generic selection [PR120303] Fix an error recovery ICE that occurs when a typename can not be parsed correctly in the controlling expression of a generic selection. PR c/120303 gcc/c/ChangeLog: * c-parser.cc (c_parser_generic_selection): Handle error condition. gcc/testsuite/ChangeLog: * gcc.dg/pr120303.c: New test. Diff: --- gcc/c/c-parser.cc | 8 +++- gcc/testsuite/gcc.dg/pr120303.c | 5 + 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/gcc/c/c-parser.cc b/gcc/c/c-parser.cc index 85580c57abfe..faa50a4fd86b 100644 --- a/gcc/c/c-parser.cc +++ b/gcc/c/c-parser.cc @@ -11146,8 +11146,14 @@ c_parser_generic_selection (c_parser *parser) "ISO C does not support use of type name as %<_Generic%> " "controlling operand before C2Y"); struct c_type_name *type = c_parser_type_name (parser); - selector_type = groktypename (type, NULL, NULL); + if (type) + selector_type = groktypename (type, NULL, NULL); c_inhibit_evaluation_warnings--; + if (!type) + { + c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); + return error_expr; + } } else { diff --git a/gcc/testsuite/gcc.dg/pr120303.c b/gcc/testsuite/gcc.dg/pr120303.c new file mode 100644 index ..caeff9290abd --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr120303.c @@ -0,0 +1,5 @@ +/* { dg-do compile } */ +/* { dg-options "-std=c2y" } */ + +int t = _Generic (char(1));/* { dg-error "before numeric constant" } */ +
[gcc(refs/users/mikael/heads/refactor_descriptor_v05)] gimple-exec: implementation memcpy et correction gestion mémoire
https://gcc.gnu.org/g:f6788211809dab7ba4568bcefe620ca11f448a32 commit f6788211809dab7ba4568bcefe620ca11f448a32 Author: Mikael Morin Date: Wed Jun 11 11:24:05 2025 +0200 gimple-exec: implementation memcpy et correction gestion mémoire Diff: --- gcc/cgraphunit.cc | 262 +- 1 file changed, 221 insertions(+), 41 deletions(-) diff --git a/gcc/cgraphunit.cc b/gcc/cgraphunit.cc index 268e4d66a419..2a50ea931b44 100644 --- a/gcc/cgraphunit.cc +++ b/gcc/cgraphunit.cc @@ -2450,6 +2450,7 @@ namespace selftest void exec_context_evaluate_unary_tests (); void exec_context_evaluate_binary_tests (); void exec_context_execute_assign_tests (); + void exec_context_print_call_tests (); void exec_context_execute_call_tests (); void exec_context_allocate_tests (); void exec_context_evaluate_condition_tests (); @@ -2462,7 +2463,7 @@ class data_value wide_int constant_mask; wide_int address_mask; wide_int constant_value; - vec addresses; + auto_vec addresses; void set_cst_at (unsigned dest_offset, unsigned value_width, const wide_int &val, unsigned src_offset); stored_address *find_address (HOST_WIDE_INT offset) const; @@ -2583,6 +2584,7 @@ class context_printer friend void selftest::context_printer_print_tests (); friend void selftest::context_printer_print_first_data_ref_part_tests (); friend void selftest::context_printer_print_value_update_tests (); + friend void selftest::exec_context_print_call_tests (); public: context_printer (); @@ -2595,7 +2597,9 @@ public: void print_function_exit (struct function * func); void print_bb_jump (edge e); void print_bb_entry (basic_block bb); - tree print_first_data_ref_part (exec_context & context, tree data_ref, unsigned offset, int * ignored_bits); + tree print_first_data_ref_part (exec_context & context, tree data_ref, + unsigned offset, int * ignored_bits, + enum value_type); void print_ignored_stmt (); void print_value_update (exec_context & context, tree, const data_value &); void end_stmt (gimple *); @@ -2976,7 +2980,8 @@ context_printer::print_bb_entry (basic_block bb) static tree -pick_subref_at (tree var_ref, unsigned offset, int * ignored_bits) +pick_subref_at (tree var_ref, unsigned offset, int * ignored_bits, + unsigned min_size) { tree ref = var_ref; unsigned remaining_offset = offset; @@ -2988,11 +2993,15 @@ pick_subref_at (tree var_ref, unsigned offset, int * ignored_bits) tree elt_type = TREE_TYPE (var_type); unsigned elt_width; gcc_assert (get_constant_type_size (elt_type, elt_width)); + if (elt_width < min_size) + return NULL_TREE; unsigned HOST_WIDE_INT hw_idx = remaining_offset / elt_width; tree t_idx = build_int_cst (integer_type_node, hw_idx); ref = build4 (ARRAY_REF, elt_type, ref, t_idx, NULL_TREE, NULL_TREE); remaining_offset -= hw_idx * elt_width; + if (elt_width == min_size) + break; } else if (TREE_CODE (var_type) == RECORD_TYPE) { @@ -3029,7 +3038,15 @@ pick_subref_at (tree var_ref, unsigned offset, int * ignored_bits) gcc_assert (field != NULL_TREE && field_position >= 0); - ref = build3 (COMPONENT_REF, TREE_TYPE (field), + tree field_type = TREE_TYPE (field); + + unsigned field_width; + if (!get_constant_type_size (field_type, field_width)) + gcc_unreachable (); + else if (field_width < min_size) + return NULL_TREE; + + ref = build3 (COMPONENT_REF, field_type, ref, field, NULL_TREE); if (field_position > remaining_offset) { @@ -3039,6 +3056,9 @@ pick_subref_at (tree var_ref, unsigned offset, int * ignored_bits) } else remaining_offset -= field_position; + + if (field_width == min_size) + break; } else break; @@ -3057,7 +3077,7 @@ pick_subref_at (tree var_ref, unsigned offset, int * ignored_bits) static tree find_mem_ref_replacement (exec_context & context, tree data_ref, - unsigned offset) + unsigned offset, unsigned min_size) { tree ptr = TREE_OPERAND (data_ref, 0); data_value ptr_val = context.evaluate (ptr); @@ -3076,42 +3096,76 @@ find_mem_ref_replacement (exec_context & context, tree data_ref, if (var_type == access_type) return var_ref; else - { -tree access_offset = TREE_OPERAND (data_ref, 1); -gcc_assert (TREE_CONSTANT (access_offset)); -gcc_assert (tree_fits_shwi_p (access_offset)); -HOST_WIDE_INT shwi_offset = tree_to_shwi (access_offset); -gcc_assert (offset < UINT_MAX - shwi_offset); -HOST_WIDE_INT remaining_offset = shwi_offset * CHAR_
[gcc(refs/users/mikael/heads/refactor_descriptor_v05)] Correction partielle régression reduce_1
https://gcc.gnu.org/g:7a229520e372f76c13146df242b35bc70a3a1d7e commit 7a229520e372f76c13146df242b35bc70a3a1d7e Author: Mikael Morin Date: Fri Jun 6 13:16:33 2025 +0200 Correction partielle régression reduce_1 Diff: --- libgfortran/intrinsics/reduce.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libgfortran/intrinsics/reduce.c b/libgfortran/intrinsics/reduce.c index a475813792db..8e1ab3b8c2f7 100644 --- a/libgfortran/intrinsics/reduce.c +++ b/libgfortran/intrinsics/reduce.c @@ -160,7 +160,7 @@ reduce (parray *ret, { off = idx0 * spc0 + idx2 * spc2; if (mask_present) - maskR = *(mask->base_addr + (size_t) off); + maskR = *((GFC_LOGICAL_4 *) (((char*)mask->base_addr) + (size_t) off)); started = (mask_present && maskR) || !mask_present; @@ -175,7 +175,7 @@ reduce (parray *ret, first element in the reduction. */ off = idx0 * spc0 + idx1 * spc1 + idx2 * spc2; if (mask_present) - maskR = *(mask->base_addr + (size_t) off); + maskR = *((GFC_LOGICAL_4 *) (((char*)mask->base_addr) + (size_t) off)); array_ptr = array->base_addr + (size_t)(idx0 * spc0 + idx1 * spc1 + idx2 * spc2);
[gcc(refs/users/mikael/heads/refactor_descriptor_v05)] gimple-exec: Implémentation memset et correction offset affichage MEM_REF
https://gcc.gnu.org/g:cd2bea6618e18da570a54c1004c98fabca0686b3 commit cd2bea6618e18da570a54c1004c98fabca0686b3 Author: Mikael Morin Date: Mon Jun 9 11:05:14 2025 +0200 gimple-exec: Implémentation memset et correction offset affichage MEM_REF Diff: --- gcc/cgraphunit.cc | 133 +- 1 file changed, 132 insertions(+), 1 deletion(-) diff --git a/gcc/cgraphunit.cc b/gcc/cgraphunit.cc index 3b0556a2ead8..268e4d66a419 100644 --- a/gcc/cgraphunit.cc +++ b/gcc/cgraphunit.cc @@ -3082,7 +3082,8 @@ find_mem_ref_replacement (exec_context & context, tree data_ref, gcc_assert (tree_fits_shwi_p (access_offset)); HOST_WIDE_INT shwi_offset = tree_to_shwi (access_offset); gcc_assert (offset < UINT_MAX - shwi_offset); -HOST_WIDE_INT remaining_offset = shwi_offset * CHAR_BIT + offset; +HOST_WIDE_INT remaining_offset = shwi_offset * CHAR_BIT ++ offset + ptr_address->offset; return pick_subref_at (var_ref, remaining_offset, nullptr); } @@ -4447,6 +4448,36 @@ exec_context::execute_call (gcall *g) src, addr1.offset); storage0.set (dest_val); } + else if (gimple_call_builtin_p (g, BUILT_IN_MEMSET)) +{ + gcc_assert (gimple_call_num_args (g) == 3); + tree arg0 = gimple_call_arg (g, 0); + tree arg1 = gimple_call_arg (g, 1); + tree arg2 = gimple_call_arg (g, 2); + data_value ptr0 = evaluate (arg0); + data_value val1 = evaluate (arg1); + data_value len2 = evaluate (arg2); + gcc_assert (ptr0.classify () == VAL_ADDRESS); + gcc_assert (val1.classify () == VAL_CONSTANT); + gcc_assert (len2.classify () == VAL_CONSTANT); + storage_address addr0 = *ptr0.get_address (); + data_storage & storage0 = addr0.storage.get (); + data_value dest_val = storage0.get_value (); + + wide_int wi_val1 = val1.get_cst (); + gcc_assert (wi::fits_uhwi_p (wi_val1)); + data_value byte1 (CHAR_BIT); + byte1.set_cst (wi::uhwi (wi_val1.to_uhwi (), CHAR_BIT)); + + wide_int wi_len2 = len2.get_cst (); + gcc_assert (wi::fits_uhwi_p (wi_len2)); + unsigned HOST_WIDE_INT uhwi_len2 = wi_len2.to_uhwi (); + + for (unsigned HOST_WIDE_INT i = 0; i < uhwi_len2; i++) + dest_val.set_at (byte1, i * CHAR_BIT + addr0.offset); + + storage0.set (dest_val); +} else { tree fn = gimple_call_fn (g); @@ -6608,6 +6639,45 @@ context_printer_print_value_update_tests () const char *str7 = pp_formatted_text (&pp7); ASSERT_STREQ (str7, "# var1c1i.der1c1i_c1 = 3\n# var1c1i.der1c1i_i2 = 11\n"); + + + heap_memory mem8; + context_printer printer8; + pretty_printer & pp8 = printer8.pp; + pp_buffer (&pp8)->m_flush_p = false; + + tree c5i_8 = build_array_type_nelts (char_type_node, 5); + tree v5c_8 = create_var (c5i_8, "v5c"); + tree p_8 = create_var (ptr_type_node, "p"); + + vec decls8{}; + decls8.safe_push (v5c_8); + decls8.safe_push (p_8); + + context_builder builder8; + builder8.add_decls (&decls8); + exec_context ctx8 = builder8.build (mem8, printer8); + + data_storage *strg8_v5c = ctx8.find_reachable_var (v5c_8); + gcc_assert (strg8_v5c != nullptr); + storage_address addr8_v5c_p1 (strg8_v5c->get_ref (), CHAR_BIT); + data_value val8_addr (ptr_type_node); + val8_addr.set_address (addr8_v5c_p1); + + data_storage *strg8_p = ctx8.find_reachable_var (p_8); + gcc_assert (strg8_p != nullptr); + strg8_p->set (val8_addr); + + data_value val8_17 (char_type_node); + wide_int wi8_17 = wi::shwi (17, CHAR_BIT); + val8_17.set_cst (wi8_17); + + tree ref8 = build2 (MEM_REF, char_type_node, p_8, + build_zero_cst (build_pointer_type (char_type_node))); + + printer8.print_value_update (ctx8, ref8, val8_17); + const char *str8 = pp_formatted_text (&pp8); + ASSERT_STREQ (str8, "# v5c[1] = 17\n"); } @@ -8789,6 +8859,67 @@ exec_context_execute_call_tests () wide_int wi_c92 = c92_after.get_cst (); ASSERT_PRED1 (wi::fits_shwi_p, wi_c92); ASSERT_EQ (wi_c92.to_shwi (), 3); + + + tree i101 = create_var (integer_type_node, "i101"); + tree p102 = create_var (ptr_type_node, "p102"); + tree c5 = build_array_type_nelts (char_type_node, 5); + tree ac105 = create_var (c5, "ac105"); + + vec decls10{}; + decls10.safe_push (i101); + decls10.safe_push (p102); + decls10.safe_push (ac105); + + heap_memory mem10; + context_builder builder10 {}; + builder10.add_decls (&decls10); + exec_context ctx10 = builder10.build (mem10, printer); + + wide_int hwi10_17 = wi::shwi (17, HOST_BITS_PER_INT); + + data_value val10_17 (integer_type_node); + val10_17.set_cst (hwi10_17); + + data_storage * storage_i101 = ctx10.find_reachable_var (i101); + gcc_assert (storage_i101 != nullptr); + storage_i101->set (val10_17); + + data_storage * storage_ac105 = ctx10.find_reachable_var (ac105); + gcc_assert (storage_ac105 != nullptr); + + storage_address addr105_1 (storage_ac105-
[gcc(refs/users/mikael/heads/refactor_descriptor_v05)] Correction régression dtio_1
https://gcc.gnu.org/g:f4294293411be609c3c4ce568c1f93964dce7f6f commit f4294293411be609c3c4ce568c1f93964dce7f6f Author: Mikael Morin Date: Fri Jun 6 12:33:22 2025 +0200 Correction régression dtio_1 Diff: --- libgfortran/io/format.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libgfortran/io/format.c b/libgfortran/io/format.c index 7eb7d6f7acc7..52f44ef3fe70 100644 --- a/libgfortran/io/format.c +++ b/libgfortran/io/format.c @@ -1112,7 +1112,7 @@ parse_format_list (st_parameter_dt *dtp, bool *seen_dd) array descriptor and save it in the format node. */ gfc_full_array_i4 *vp = tail->u.udf.vlist; GFC_DESCRIPTOR_DATA(vp) = xmalloc (i * sizeof(GFC_INTEGER_4)); - GFC_DESCRIPTOR_DIMENSION_SET(vp, 0,1, i, 1); + GFC_DESCRIPTOR_DIMENSION_SET(vp, 0,1, i, sizeof(GFC_INTEGER_4)); memcpy (GFC_DESCRIPTOR_DATA(vp), temp, i * sizeof(GFC_INTEGER_4)); break; }
[gcc(refs/users/mikael/heads/refactor_descriptor_v05)] Correction partielle régression reduce_1
https://gcc.gnu.org/g:5a88e7c7f7d41e15beb1164406b03e397a55d9f7 commit 5a88e7c7f7d41e15beb1164406b03e397a55d9f7 Author: Mikael Morin Date: Mon Jun 9 11:07:30 2025 +0200 Correction partielle régression reduce_1 Diff: --- libgfortran/intrinsics/reduce.c | 59 ++--- 1 file changed, 38 insertions(+), 21 deletions(-) diff --git a/libgfortran/intrinsics/reduce.c b/libgfortran/intrinsics/reduce.c index 8e1ab3b8c2f7..de0c264323d4 100644 --- a/libgfortran/intrinsics/reduce.c +++ b/libgfortran/intrinsics/reduce.c @@ -50,11 +50,12 @@ reduce (parray *ret, void *buffer; void *res; index_type ext0, ext1, ext2; - index_type spc0, spc1, spc2; + index_type aspc0, aspc1, aspc2; + index_type rspc0, rspc2; + index_type mspc0, mspc1, mspc2; index_type idx0, idx1, idx2; - index_type dimen, dimen_m1, off, ext, spc; + index_type dimen, dimen_m1, moff, ext, spc; bool started; - bool masked = false; bool dim_present = dim != NULL; bool mask_present = mask != NULL; bool identity_present = identity != NULL; @@ -95,18 +96,20 @@ reduce (parray *ret, painless by the use of pointer arithmetic throughout (except for MASK, whose type is known. */ ext0 = ext1 = ext2 = 1; - spc0 = spc1 = spc2 = elem_len; + aspc0 = aspc1 = aspc2 = elem_len; + rspc0 = rspc2 = elem_len; + mspc0 = mspc1 = mspc2 = sizeof (GFC_LOGICAL_4); scalar_result = (!dim_present && array_rank > 1) || array_rank == 1; + spc = elem_len; j = 0; for (i = 0; i < array_rank; i++) { /* Obtain the shape of the reshaped ARRAY. */ ext = GFC_DESCRIPTOR_EXTENT (array,i); - spc = GFC_DESCRIPTOR_SPACING (array,i); - if (masked && (ext != GFC_DESCRIPTOR_EXTENT (mask, i))) + if (mask_present && (ext != GFC_DESCRIPTOR_EXTENT (mask, i))) { int mext = (int)GFC_DESCRIPTOR_EXTENT (mask, i); runtime_error ("shape mismatch between ARRAY and MASK in the REDUCE " @@ -126,28 +129,39 @@ reduce (parray *ret, ext2 *= ext; /* The dimensions of the return array. */ - if (i != (int)dimen_m1) + if (!scalar_result && ret->base_addr == NULL && i != (int)dimen_m1) { - spc = GFC_DESCRIPTOR_SPACING (array, j); GFC_DESCRIPTOR_DIMENSION_SET (ret, j, 0, ext - 1, spc); + spc *= ext; j++; } } if (!scalar_result) { - spc1 = GFC_DESCRIPTOR_SPACING (array, dimen_m1); + aspc1 = GFC_DESCRIPTOR_SPACING (array, dimen_m1); + if (mask_present) + mspc1 = GFC_DESCRIPTOR_SPACING (mask, dimen_m1); if (dimen < array_rank) - spc2 = GFC_DESCRIPTOR_SPACING (array, dimen); + { + aspc2 = GFC_DESCRIPTOR_SPACING (array, dimen); + rspc2 = GFC_DESCRIPTOR_SPACING (ret, dimen_m1); + if (mask_present) + mspc2 = GFC_DESCRIPTOR_SPACING (mask, dimen); + } else - spc2 = elem_len; + { + aspc2 = 1; + rspc2 = 1; + mspc2 = 1; + } } /* Allocate the result data, the result buffer and zero. */ if (ret->base_addr == NULL) { ret->base_addr = calloc ((size_t)(ext0 * ext2), elem_len); - GFC_DESCRIPTOR_SPAN (ret) = GFC_DESCRIPTOR_SIZE (ret); + GFC_DESCRIPTOR_SPAN (ret) = GFC_DESCRIPTOR_SIZE (ret) = elem_len; } buffer = calloc (1, elem_len); @@ -158,14 +172,16 @@ reduce (parray *ret, { for (idx2 = 0; idx2 < ext2; idx2++) { - off = idx0 * spc0 + idx2 * spc2; if (mask_present) - maskR = *((GFC_LOGICAL_4 *) (((char*)mask->base_addr) + (size_t) off)); + { + moff = idx0 * mspc0 + idx2 * mspc2; + maskR = *((GFC_LOGICAL_4 *) (((char*)mask->base_addr) + (size_t) moff)); + } started = (mask_present && maskR) || !mask_present; buffer_ptr = array->base_addr - + (size_t)(idx0 * spc0 + idx2 * spc2); + + (size_t)(idx0 * aspc0 + idx2 * aspc2); /* Start the iteration over the second dimension of ARRAY. */ for (idx1 = 1; idx1 < ext1; idx1++) @@ -173,12 +189,14 @@ reduce (parray *ret, /* If masked, cycle until after first element that is not masked out. Then set 'started' and cycle so that this becomes the first element in the reduction. */ - off = idx0 * spc0 + idx1 * spc1 + idx2 * spc2; if (mask_present) - maskR = *((GFC_LOGICAL_4 *) (((char*)mask->base_addr) + (size_t) off)); + { + moff = idx0 * mspc0 + idx1 * mspc1 + idx2 * mspc2; + maskR = *((GFC_LOGICAL_4 *) (((char*)mask->base_addr) + (size_t) moff)); + } array_ptr = array->base_addr - + (size_t)(idx0 * spc0 + idx1 * spc1 + idx2 * spc2); + + (size_t)(idx0 * aspc0 + idx1 * aspc1 + idx2 * a
[gcc(refs/users/mikael/heads/refactor_descriptor_v05)] Correction régression reduce_1
https://gcc.gnu.org/g:f71f392bfe5b8acac6698f1f1858288f04cd44c9 commit f71f392bfe5b8acac6698f1f1858288f04cd44c9 Author: Mikael Morin Date: Wed Jun 11 11:48:04 2025 +0200 Correction régression reduce_1 Diff: --- libgfortran/intrinsics/reshape_generic.c | 7 ++- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/libgfortran/intrinsics/reshape_generic.c b/libgfortran/intrinsics/reshape_generic.c index 62eea713fe21..c9298caef74f 100644 --- a/libgfortran/intrinsics/reshape_generic.c +++ b/libgfortran/intrinsics/reshape_generic.c @@ -104,13 +104,10 @@ reshape_internal (parray *ret, parray *source, shape_type *shape, } ret->offset = 0; - if (unlikely (spacing < 1)) - alloc_size = 0; /* xmalloc will allocate 1 byte. */ - else - alloc_size = spacing; - ret->base_addr = xmalloc (spacing); ret->dtype.rank = rdim; + ret->dtype.elem_len = GFC_DESCRIPTOR_SIZE (source); + ret->span = GFC_DESCRIPTOR_SIZE (source); } if (shape_empty)
[gcc r16-1422] diagnostics: add selftests for html_token_printer [PR116792]
https://gcc.gnu.org/g:f867196566c8aa51fd8b18dc5956daeea49e7518 commit r16-1422-gf867196566c8aa51fd8b18dc5956daeea49e7518 Author: David Malcolm Date: Wed Jun 11 14:21:41 2025 -0400 diagnostics: add selftests for html_token_printer [PR116792] No functional change intended. gcc/ChangeLog: PR other/116792 * diagnostic-format-html.cc: Include "selftest-xml.h". (html_builder::make_element_for_diagnostic): Move... (class html_token_printer): ...from local to the function to the global namespace. (struct selftest::token_printer_test): New. (selftest::test_token_printer): New. (selftest::test_simple_log): Simplify using ASSERT_XML_PRINT_EQ. (selftest::test_metadata): Likewise. (selftest::diagnostic_format_html_cc_tests): Run the new test. * selftest-xml.h: New file. * xml.cc: Include "selftest-xml.h". (selftest::assert_xml_print_eq): New. (selftest::test_no_dtd): Simplify using ASSERT_XML_PRINT_EQ. (selftest::test_printer): Likewise. (selftest::test_attribute_ordering): Likewise. Signed-off-by: David Malcolm Diff: --- gcc/diagnostic-format-html.cc | 219 +- gcc/selftest-xml.h| 50 ++ gcc/xml.cc| 29 +++--- 3 files changed, 198 insertions(+), 100 deletions(-) diff --git a/gcc/diagnostic-format-html.cc b/gcc/diagnostic-format-html.cc index 22bf6b965df7..45d088150dd6 100644 --- a/gcc/diagnostic-format-html.cc +++ b/gcc/diagnostic-format-html.cc @@ -42,6 +42,7 @@ along with GCC; see the file COPYING3. If not see #include "xml.h" #include "xml-printer.h" #include "json.h" +#include "selftest-xml.h" // struct html_generation_options @@ -729,6 +730,82 @@ add_labelled_value (xml::printer &xp, xp.pop_tag ("div"); } +class html_token_printer : public token_printer +{ +public: + html_token_printer (xml::element &parent_element) +/* Ideally pp_token_lists that reach a token_printer should be + "balanced", but for now they can have mismatching pp_tokens + e.g. a begin_color without an end_color (PR other/120610). + Give html_token_printer its own xml::printer as a firewall to + limit the scope of the mismatches in the HTML. */ +: m_xp (parent_element, + /* Similarly we don't check that the popped tags match. */ + false) + { + } + void print_tokens (pretty_printer */*pp*/, +const pp_token_list &tokens) final override + { +/* Implement print_tokens by adding child elements to + m_parent_element. */ +for (auto iter = tokens.m_first; iter; iter = iter->m_next) + switch (iter->m_kind) + { + default: + gcc_unreachable (); + + case pp_token::kind::text: + { + pp_token_text *sub = as_a (iter); + /* The value might be in the obstack, so we may need to + copy it. */ + m_xp.add_text (sub->m_value.get ()); + } + break; + + case pp_token::kind::begin_color: + { + pp_token_begin_color *sub = as_a (iter); + gcc_assert (sub->m_value.get ()); + m_xp.push_tag_with_class ("span", sub->m_value.get ()); + } + break; + + case pp_token::kind::end_color: + m_xp.pop_tag ("span"); + break; + + case pp_token::kind::begin_quote: + { + m_xp.add_text (open_quote); + m_xp.push_tag_with_class ("span", "gcc-quoted-text"); + } + break; + case pp_token::kind::end_quote: + { + m_xp.pop_tag ("span"); + m_xp.add_text (close_quote); + } + break; + + case pp_token::kind::begin_url: + { + pp_token_begin_url *sub = as_a (iter); + m_xp.push_tag ("a", true); + m_xp.set_attr ("href", sub->m_value.get ()); + } + break; + case pp_token::kind::end_url: + m_xp.pop_tag ("a"); + break; + } + } + +private: + xml::printer m_xp; +}; + /* Make a for DIAGNOSTIC. If ALERT is true, make it be a PatternFly alert (see @@ -744,82 +821,6 @@ html_builder::make_element_for_diagnostic (const diagnostic_info &diagnostic, diagnostic_t orig_diag_kind, bool alert) { - class html_token_printer : public token_printer - { - public: -html_token_printer (xml::element &parent_element) - /* Ideally pp_token_lists that reach a token_printer should be -"balanced", but for now they can have mismatching pp_tokens -e.g. a begin_color without an end_color (PR other/120610). -Give html_token_printer its own xml::printer as a firewall to -limit the scope of the mismatches in the HTML. */
[gcc r16-1430] fortran: add intrinsic doc for trig functions with half revolutions
https://gcc.gnu.org/g:25f5e60eaa8b9ab7938c3e1a9c8ad4ffa444d997 commit r16-1430-g25f5e60eaa8b9ab7938c3e1a9c8ad4ffa444d997 Author: Yuao Ma Date: Wed Jun 11 23:33:35 2025 +0800 fortran: add intrinsic doc for trig functions with half revolutions This patch is a follow-up to commit r16-938-ge8fdd55ec90749. In this patch, we add intrinsic documentation for the newly added trig functions with half revolutions. We also reorder the documentation for `atand` to place it in correct alphabetical order. PR fortran/113152 gcc/fortran/ChangeLog: * intrinsic.texi: Document new half-revolution trigonometric functions. Reorder doc for atand. Signed-off-by: Yuao Ma Co-authored-by: Steven G. Kargl Diff: --- gcc/fortran/intrinsic.texi | 526 +++-- 1 file changed, 458 insertions(+), 68 deletions(-) diff --git a/gcc/fortran/intrinsic.texi b/gcc/fortran/intrinsic.texi index 48c2d60826b7..583199564e4b 100644 --- a/gcc/fortran/intrinsic.texi +++ b/gcc/fortran/intrinsic.texi @@ -24,15 +24,22 @@ Some basic guidelines for editing this document: @tex \gdef\acosd{\mathop{\rm acosd}\nolimits} -\gdef\asind{\mathop{\rm asind}\nolimits} -\gdef\atand{\mathop{\rm atand}\nolimits} -\gdef\acos{\mathop{\rm acos}\nolimits} -\gdef\asin{\mathop{\rm asin}\nolimits} -\gdef\atan{\mathop{\rm atan}\nolimits} \gdef\acosh{\mathop{\rm acosh}\nolimits} +\gdef\acospi{\mathop{\rm acospi}\nolimits} +\gdef\acos{\mathop{\rm acos}\nolimits} +\gdef\asind{\mathop{\rm asind}\nolimits} \gdef\asinh{\mathop{\rm asinh}\nolimits} +\gdef\asinpi{\mathop{\rm asinpi}\nolimits} +\gdef\asin{\mathop{\rm asin}\nolimits} +\gdef\atan2pi{\mathop{\rm atan2pi}\nolimits} +\gdef\atand{\mathop{\rm atand}\nolimits} \gdef\atanh{\mathop{\rm atanh}\nolimits} +\gdef\atanpi{\mathop{\rm atanpi}\nolimits} +\gdef\atan{\mathop{\rm atan}\nolimits} \gdef\cosd{\mathop{\rm cosd}\nolimits} +\gdef\cospi{\mathop{\rm cospi}\nolimits} +\gdef\sinpi{\mathop{\rm sinpi}\nolimits} +\gdef\tanpi{\mathop{\rm tanpi}\nolimits} @end tex @@ -49,6 +56,7 @@ Some basic guidelines for editing this document: * @code{ACOS}: ACOS, Arccosine function * @code{ACOSD}: ACOSD, Arccosine function, degrees * @code{ACOSH}: ACOSH, Inverse hyperbolic cosine function +* @code{ACOSPI}:ACOSPI,Circular arc cosine function * @code{ADJUSTL}: ADJUSTL, Left adjust a string * @code{ADJUSTR}: ADJUSTR, Right adjust a string * @code{AIMAG}: AIMAG, Imaginary part of complex number @@ -62,12 +70,15 @@ Some basic guidelines for editing this document: * @code{ASIN}: ASIN, Arcsine function * @code{ASIND}: ASIND, Arcsine function, degrees * @code{ASINH}: ASINH, Inverse hyperbolic sine function +* @code{ASINPI}:ASINPI,Circular arc sine function * @code{ASSOCIATED}:ASSOCIATED, Status of a pointer or pointer/target pair * @code{ATAN}: ATAN, Arctangent function -* @code{ATAND}: ATAND, Arctangent function, degrees * @code{ATAN2}: ATAN2, Arctangent function * @code{ATAN2D}:ATAN2D,Arctangent function, degrees +* @code{ATAN2PI}: ATAN2PI, Circular arc tangent function +* @code{ATAND}: ATAND, Arctangent function, degrees * @code{ATANH}: ATANH, Inverse hyperbolic tangent function +* @code{ATANPI}:ATANPI,Circular arc tangent function * @code{ATOMIC_ADD}:ATOMIC_ADD, Atomic ADD operation * @code{ATOMIC_AND}:ATOMIC_AND, Atomic bitwise AND operation * @code{ATOMIC_CAS}:ATOMIC_CAS, Atomic compare and swap @@ -116,6 +127,7 @@ Some basic guidelines for editing this document: * @code{COS}: COS, Cosine function * @code{COSD}: COSD, Cosine function, degrees * @code{COSH}: COSH, Hyperbolic cosine function +* @code{COSPI}: COSPI, Circular cosine function * @code{COTAN}: COTAN, Cotangent function * @code{COTAND}:COTAND,Cotangent function, degrees * @code{COUNT}: COUNT, Count occurrences of TRUE in an array @@ -296,6 +308,7 @@ Some basic guidelines for editing this document: * @code{SIN}: SIN, Sine function * @code{SIND}: SIND, Sine function, degrees * @code{SINH}: SINH, Hyperbolic sine function +* @code{SINPI}: SINPI, Circular sine function * @code{SIZE}: SIZE, Function to determine the size of an array * @code{SIZEOF}:SIZEOF,Determine the size in bytes of an expression * @code{SLEEP}: SLEEP, Sleep for the specified number of seconds @@ -312,6 +325,7 @@ Some basic guidelines for editing this document: * @code{TAN}: TAN, Tangent function * @code{TAND}: TAND, Tangent function, degrees * @code{TANH}: TANH, Hyperbolic tangent function
[gcc r16-1431] c, c++: Save 8 bytes of memory in lang_type for non-ObjC*
https://gcc.gnu.org/g:3ce7b67bc53ecc07da7eddcf13d815e4733376c8 commit r16-1431-g3ce7b67bc53ecc07da7eddcf13d815e4733376c8 Author: Jakub Jelinek Date: Thu Jun 12 08:33:38 2025 +0200 c, c++: Save 8 bytes of memory in lang_type for non-ObjC* For C++26 P2786R13 I'm afraid I'll need 4-6 new flags on class types in struct lang_type (1 bit for trivially_relocatable_if_eligible, 1 for replaceable_if_eligible, 1 for not_trivially_relocatable and 1 for not_replaceable and perhaps 2 bits whether the last 2 have been computed already) and there are just 2 bits left. The following patch is an attempt to save 8 bytes of memory in those structures when not compiling ObjC or ObjC++ (I think those are used fairly rarely and the patch keeps the sizes unmodified for those 2). The old allocations were 32 bytes for C and 120 bytes for C++. The patch moves the objc_info member last in the C++ case (it was already last in the C case), arranges for GC to skip it for C and C++ but walk for ObjC and ObjC++ and allocates or copies over just offsetof bytes instead of sizeof. 2025-06-12 Jakub Jelinek gcc/c/ * c-lang.h (union lang_type::maybe_objc_info): New type. (struct lang_type): Use union maybe_objc_info info member instead of tree objc_info. * c-decl.cc (finish_struct): Allocate struct lang_type using ggc_internal_cleared_alloc instead of ggc_cleared_alloc, and use sizeof (struct lang_type) for ObjC and otherwise offsetof (struct lang_type, info) as size. (finish_enum): Likewise. gcc/cp/ * cp-tree.h (union lang_type::maybe_objc_info): New type. (struct lang_type): Use union maybe_objc_info info member instead of tree objc_info. * lex.cc (copy_lang_type): Use sizeof (struct lang_type) just for ObjC++ and otherwise offsetof (struct lang_type, info). (maybe_add_lang_type_raw): Likewise. (cxx_make_type): Formatting fix. gcc/objc/ * objc-act.h (TYPE_OBJC_INFO): Define to info.objc_info instead of objc_info. gcc/objcp/ * objcp-decl.h (TYPE_OBJC_INFO): Define to info.objc_info instead of objc_info. Diff: --- gcc/c/c-decl.cc| 22 +++--- gcc/c/c-lang.h | 12 gcc/cp/cp-tree.h | 12 gcc/cp/lex.cc | 19 +++ gcc/objc/objc-act.h| 2 +- gcc/objcp/objcp-decl.h | 2 +- 6 files changed, 44 insertions(+), 25 deletions(-) diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc index 2b0bd663ba91..8bbd6ebc66ad 100644 --- a/gcc/c/c-decl.cc +++ b/gcc/c/c-decl.cc @@ -9790,12 +9790,17 @@ finish_struct (location_t loc, tree t, tree fieldlist, tree attributes, len += list_length (x); /* Use the same allocation policy here that make_node uses, to - ensure that this lives as long as the rest of the struct decl. - All decls in an inline function need to be saved. */ - - space = ggc_cleared_alloc (); - space2 = (sorted_fields_type *) ggc_internal_alloc - (sizeof (struct sorted_fields_type) + len * sizeof (tree)); + ensure that this lives as long as the rest of the struct decl. + All decls in an inline function need to be saved. */ + + space = ((struct lang_type *) +ggc_internal_cleared_alloc (c_dialect_objc () +? sizeof (struct lang_type) +: offsetof (struct lang_type, +info))); + space2 = ((sorted_fields_type *) + ggc_internal_alloc (sizeof (struct sorted_fields_type) + + len * sizeof (tree))); len = 0; space->s = space2; @@ -10269,7 +10274,10 @@ finish_enum (tree enumtype, tree values, tree attributes) /* Record the min/max values so that we can warn about bit-field enumerations that are too small for the values. */ - lt = ggc_cleared_alloc (); + lt = ((struct lang_type *) + ggc_internal_cleared_alloc (c_dialect_objc () + ? sizeof (struct lang_type) + : offsetof (struct lang_type, info))); lt->enum_min = minnode; lt->enum_max = maxnode; TYPE_LANG_SPECIFIC (enumtype) = lt; diff --git a/gcc/c/c-lang.h b/gcc/c/c-lang.h index 4b93d184dbca..2e99b4d86176 100644 --- a/gcc/c/c-lang.h +++ b/gcc/c/c-lang.h @@ -35,10 +35,14 @@ struct GTY(()) lang_type { /* In an ENUMERAL_TYPE, the min and max values. */ tree enum_min; tree enum_max; - /* In a RECORD_TYPE, information specific to Objective-C, such - as a list of adopted protocols or a pointer to a corresponding - @interface. See objc/objc-act.h for details. */ - tree objc_info;