commit: ab96d6ae8338cf8a786dba11a5a08194a373b7ef Author: Sam James <sam <AT> gentoo <DOT> org> AuthorDate: Mon Jun 2 23:14:43 2025 +0000 Commit: Sam James <sam <AT> gentoo <DOT> org> CommitDate: Mon Jun 2 23:15:15 2025 +0000 URL: https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=ab96d6ae
sys-devel/gcc: backport C++ FE fixes for is_constructible to 16 Closes: https://bugs.gentoo.org/956977 Closes: https://bugs.gentoo.org/956978 Closes: https://bugs.gentoo.org/956989 Closes: https://bugs.gentoo.org/956990 Closes: https://bugs.gentoo.org/957048 Signed-off-by: Sam James <sam <AT> gentoo.org> ...001-c-__has_trivial_destructor-regression.patch | 66 ++++++++++++++ .../0002-c-__is_destructible-fixes-PR107600.patch | 101 +++++++++++++++++++++ ...-constinit-diagnostic-regression-PR120506.patch | 78 ++++++++++++++++ ...4-c-more-__is_destructible-fixes-PR107600.patch | 71 +++++++++++++++ sys-devel/gcc/gcc-16.0.0_p20250601-r1.ebuild | 60 ++++++++++++ 5 files changed, 376 insertions(+) diff --git a/sys-devel/gcc/files/0001-c-__has_trivial_destructor-regression.patch b/sys-devel/gcc/files/0001-c-__has_trivial_destructor-regression.patch new file mode 100644 index 000000000000..7cfa23463595 --- /dev/null +++ b/sys-devel/gcc/files/0001-c-__has_trivial_destructor-regression.patch @@ -0,0 +1,66 @@ +From 089e4f426502a620deb9efc0d80118931fd951d2 Mon Sep 17 00:00:00 2001 +Message-ID: <089e4f426502a620deb9efc0d80118931fd951d2.1748905952.git....@gentoo.org> +From: Jason Merrill <[email protected]> +Date: Mon, 2 Jun 2025 08:36:22 -0400 +Subject: [PATCH 1/4] c++: __has_trivial_destructor regression + +We don't want the new call to get_dtor to cause function instantiation. + + PR c++/107600 + +gcc/cp/ChangeLog: + + * semantics.cc (trait_expr_value) [CPTK_HAS_TRIVIAL_DESTRUCTOR]: + Add cp_unevaluated. + +gcc/testsuite/ChangeLog: + + * g++.dg/ext/has_trivial_destructor-3.C: New test. +--- + gcc/cp/semantics.cc | 1 + + .../g++.dg/ext/has_trivial_destructor-3.C | 21 +++++++++++++++++++ + 2 files changed, 22 insertions(+) + create mode 100644 gcc/testsuite/g++.dg/ext/has_trivial_destructor-3.C + +diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc +index cafc9d0ee2c3..18a2b4709cf1 100644 +--- a/gcc/cp/semantics.cc ++++ b/gcc/cp/semantics.cc +@@ -13420,6 +13420,7 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree type2) + if (CLASS_TYPE_P (type1) && type_build_dtor_call (type1)) + { + deferring_access_check_sentinel dacs (dk_no_check); ++ cp_unevaluated un; + tree fn = get_dtor (type1, tf_none); + if (!fn && !seen_error ()) + warning (0, "checking %qs for type %qT with a destructor that " +diff --git a/gcc/testsuite/g++.dg/ext/has_trivial_destructor-3.C b/gcc/testsuite/g++.dg/ext/has_trivial_destructor-3.C +new file mode 100644 +index 000000000000..a179be52e936 +--- /dev/null ++++ b/gcc/testsuite/g++.dg/ext/has_trivial_destructor-3.C +@@ -0,0 +1,21 @@ ++// { dg-do compile { target c++11 } } ++ ++struct X; ++ ++template<class T> ++struct default_delete ++{ ++ void operator()(T*) { static_assert(sizeof(T), "type is not incomplete"); } ++}; ++ ++template<class T, class D = default_delete<T>> ++struct unique_ptr ++{ ++ ~unique_ptr() { del(ptr); } ++ ++ T* ptr; ++ D del; ++}; ++ ++ ++constexpr bool b = __has_trivial_destructor(unique_ptr<X>); +-- +2.49.0 + diff --git a/sys-devel/gcc/files/0002-c-__is_destructible-fixes-PR107600.patch b/sys-devel/gcc/files/0002-c-__is_destructible-fixes-PR107600.patch new file mode 100644 index 000000000000..70f13b838a5d --- /dev/null +++ b/sys-devel/gcc/files/0002-c-__is_destructible-fixes-PR107600.patch @@ -0,0 +1,101 @@ +From 1de6c1abe44b77aa5a253df9da57130a55e8d907 Mon Sep 17 00:00:00 2001 +Message-ID: <1de6c1abe44b77aa5a253df9da57130a55e8d907.1748905952.git....@gentoo.org> +In-Reply-To: <089e4f426502a620deb9efc0d80118931fd951d2.1748905952.git....@gentoo.org> +References: <089e4f426502a620deb9efc0d80118931fd951d2.1748905952.git....@gentoo.org> +From: Jason Merrill <[email protected]> +Date: Mon, 2 Jun 2025 10:09:07 -0400 +Subject: [PATCH 2/4] c++: __is_destructible fixes [PR107600] + +destructible_expr was wrongly assuming that TO is a class type. + +When is_xible_helper was added in r8-742 it returned early for abstract +class types, which is correct for __is_constructible, but not +__is_assignable or (now) __is_destructible. + + PR c++/107600 + +gcc/cp/ChangeLog: + + * method.cc (destructible_expr): Handle non-classes. + (constructible_expr): Check for abstract class here... + (is_xible_helper): ...not here. + +gcc/testsuite/ChangeLog: + + * g++.dg/ext/is_destructible2.C: New test. +--- + gcc/cp/method.cc | 21 ++++++++++++++++----- + gcc/testsuite/g++.dg/ext/is_destructible2.C | 15 +++++++++++++++ + 2 files changed, 31 insertions(+), 5 deletions(-) + create mode 100644 gcc/testsuite/g++.dg/ext/is_destructible2.C + +diff --git a/gcc/cp/method.cc b/gcc/cp/method.cc +index 3a675d9f8723..bb6790f13cdb 100644 +--- a/gcc/cp/method.cc ++++ b/gcc/cp/method.cc +@@ -2251,6 +2251,8 @@ constructible_expr (tree to, tree from) + const int len = TREE_VEC_LENGTH (from); + if (CLASS_TYPE_P (to)) + { ++ if (ABSTRACT_CLASS_TYPE_P (to)) ++ return error_mark_node; + tree ctype = to; + vec<tree, va_gc> *args = NULL; + if (!TYPE_REF_P (to)) +@@ -2337,10 +2339,19 @@ destructible_expr (tree to) + { + cp_unevaluated cp_uneval_guard; + int flags = LOOKUP_NORMAL|LOOKUP_DESTRUCTOR; +- to = build_trait_object (to); +- tree r = build_delete (input_location, TREE_TYPE (to), to, +- sfk_complete_destructor, flags, 0, tf_none); +- return r; ++ to = strip_array_types (to); ++ if (CLASS_TYPE_P (to)) ++ { ++ to = build_trait_object (to); ++ return build_delete (input_location, TREE_TYPE (to), to, ++ sfk_complete_destructor, flags, 0, tf_none); ++ } ++ /* [expr.prim.id.dtor] If the id-expression names a pseudo-destructor, T ++ shall be a scalar type.... */ ++ else if (scalarish_type_p (to)) ++ return void_node; ++ else ++ return error_mark_node; + } + + /* Returns a tree iff TO is assignable (if CODE is MODIFY_EXPR) or +@@ -2352,7 +2363,7 @@ is_xible_helper (enum tree_code code, tree to, tree from, bool trivial) + { + to = complete_type (to); + deferring_access_check_sentinel acs (dk_no_deferred); +- if (VOID_TYPE_P (to) || ABSTRACT_CLASS_TYPE_P (to) ++ if (VOID_TYPE_P (to) + || (from && FUNC_OR_METHOD_TYPE_P (from) + && (TYPE_READONLY (from) || FUNCTION_REF_QUALIFIED (from)))) + return error_mark_node; +diff --git a/gcc/testsuite/g++.dg/ext/is_destructible2.C b/gcc/testsuite/g++.dg/ext/is_destructible2.C +new file mode 100644 +index 000000000000..7f15fc786848 +--- /dev/null ++++ b/gcc/testsuite/g++.dg/ext/is_destructible2.C +@@ -0,0 +1,15 @@ ++// PR c++/107600 ++// { dg-additional-options -Wno-c++17-extensions } ++// { dg-do compile { target c++11 } } ++ ++struct A ++{ ++ A& operator= (const A&); ++ virtual ~A() = 0; ++}; ++ ++static_assert( __is_destructible(A) ); ++static_assert( __is_assignable(A, A) ); ++static_assert( not __is_destructible(int()) ); ++static_assert( not __is_nothrow_destructible(int()) ); ++static_assert( not __is_trivially_destructible(int()) ); +-- +2.49.0 + diff --git a/sys-devel/gcc/files/0003-c-constinit-diagnostic-regression-PR120506.patch b/sys-devel/gcc/files/0003-c-constinit-diagnostic-regression-PR120506.patch new file mode 100644 index 000000000000..6f6a96fcec70 --- /dev/null +++ b/sys-devel/gcc/files/0003-c-constinit-diagnostic-regression-PR120506.patch @@ -0,0 +1,78 @@ +From 3fd9983fede89f1a996d44439d0938ee0d9ff76c Mon Sep 17 00:00:00 2001 +Message-ID: <3fd9983fede89f1a996d44439d0938ee0d9ff76c.1748905952.git....@gentoo.org> +In-Reply-To: <089e4f426502a620deb9efc0d80118931fd951d2.1748905952.git....@gentoo.org> +References: <089e4f426502a620deb9efc0d80118931fd951d2.1748905952.git....@gentoo.org> +From: Jason Merrill <[email protected]> +Date: Mon, 2 Jun 2025 10:59:02 -0400 +Subject: [PATCH 3/4] c++: constinit diagnostic regression [PR120506] + +In r16-57 I thought it was unnecessary to mention incomplete initialization +after another diagnostic, but actually it's useful elaboration. + + PR c++/120506 + +gcc/cp/ChangeLog: + + * constexpr.cc (cxx_eval_outermost_constant_expr): Always check + CONSTRUCTOR_NO_CLEARING. + +gcc/testsuite/ChangeLog: + + * g++.dg/cpp2a/constinit21.C: New test. +--- + gcc/cp/constexpr.cc | 3 +-- + gcc/testsuite/g++.dg/cpp2a/constinit21.C | 28 ++++++++++++++++++++++++ + 2 files changed, 29 insertions(+), 2 deletions(-) + create mode 100644 gcc/testsuite/g++.dg/cpp2a/constinit21.C + +diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc +index 61481c6f7a02..c107b338344c 100644 +--- a/gcc/cp/constexpr.cc ++++ b/gcc/cp/constexpr.cc +@@ -9278,8 +9278,7 @@ cxx_eval_outermost_constant_expr (tree t, bool allow_non_constant, + + /* After verify_constant because reduced_constant_expression_p can unset + CONSTRUCTOR_NO_CLEARING. */ +- if (!non_constant_p +- && TREE_CODE (r) == CONSTRUCTOR && CONSTRUCTOR_NO_CLEARING (r)) ++ if (TREE_CODE (r) == CONSTRUCTOR && CONSTRUCTOR_NO_CLEARING (r)) + { + if (!allow_non_constant) + error ("%qE is not a constant expression because it refers to " +diff --git a/gcc/testsuite/g++.dg/cpp2a/constinit21.C b/gcc/testsuite/g++.dg/cpp2a/constinit21.C +new file mode 100644 +index 000000000000..18bca9012024 +--- /dev/null ++++ b/gcc/testsuite/g++.dg/cpp2a/constinit21.C +@@ -0,0 +1,28 @@ ++// PR c++/120506 ++// { dg-do compile { target c++20 } } ++// Test that we give more information about why the init is non-constant ++ ++struct A ++{ ++ constexpr A(int c) : counter(c) { } ++ ++ int counter; ++}; ++ ++ ++struct B : A ++{ ++ constexpr B(int c) : A(c) { } ++ ++ int i; // OOPS, not initialized ++}; ++ ++struct C ++{ ++ B sem; ++ ++ constexpr C(int c) : sem(c) { } ++}; ++ ++constinit C s(0); // { dg-error "incompletely initialized" } ++// { dg-prune-output "constant" } +-- +2.49.0 + diff --git a/sys-devel/gcc/files/0004-c-more-__is_destructible-fixes-PR107600.patch b/sys-devel/gcc/files/0004-c-more-__is_destructible-fixes-PR107600.patch new file mode 100644 index 000000000000..1cc68e223054 --- /dev/null +++ b/sys-devel/gcc/files/0004-c-more-__is_destructible-fixes-PR107600.patch @@ -0,0 +1,71 @@ +From f712fd80cb1c29b1111184c2e9c1784861d0f788 Mon Sep 17 00:00:00 2001 +Message-ID: <f712fd80cb1c29b1111184c2e9c1784861d0f788.1748905952.git....@gentoo.org> +In-Reply-To: <089e4f426502a620deb9efc0d80118931fd951d2.1748905952.git....@gentoo.org> +References: <089e4f426502a620deb9efc0d80118931fd951d2.1748905952.git....@gentoo.org> +From: Jason Merrill <[email protected]> +Date: Mon, 2 Jun 2025 14:58:42 -0400 +Subject: [PATCH 4/4] c++: more __is_destructible fixes [PR107600] + + PR c++/107600 + +gcc/cp/ChangeLog: + + * method.cc (destructible_expr): Fix refs and arrays of unknown + bound. + +gcc/testsuite/ChangeLog: + + * g++.dg/ext/is_destructible2.C: Add more cases. +--- + gcc/cp/method.cc | 11 ++++++++++- + gcc/testsuite/g++.dg/ext/is_destructible2.C | 9 +++++++++ + 2 files changed, 19 insertions(+), 1 deletion(-) + +diff --git a/gcc/cp/method.cc b/gcc/cp/method.cc +index bb6790f13cdb..67a80a387ba7 100644 +--- a/gcc/cp/method.cc ++++ b/gcc/cp/method.cc +@@ -2332,13 +2332,22 @@ constructible_expr (tree to, tree from) + return expr; + } + +-/* Return declval<T>().~T() treated as an unevaluated operand. */ ++/* Valid if "Either T is a reference type, or T is a complete object type for ++ which the expression declval<U&>().~U() is well-formed when treated as an ++ unevaluated operand ([expr.context]), where U is remove_all_extents_t<T>." ++ ++ For a class U, return the destructor call; otherwise return void_node if ++ valid or error_mark_node if not. */ + + static tree + destructible_expr (tree to) + { + cp_unevaluated cp_uneval_guard; + int flags = LOOKUP_NORMAL|LOOKUP_DESTRUCTOR; ++ if (TYPE_REF_P (to)) ++ return void_node; ++ if (!COMPLETE_TYPE_P (complete_type (to))) ++ return error_mark_node; + to = strip_array_types (to); + if (CLASS_TYPE_P (to)) + { +diff --git a/gcc/testsuite/g++.dg/ext/is_destructible2.C b/gcc/testsuite/g++.dg/ext/is_destructible2.C +index 7f15fc786848..2edf440ef44b 100644 +--- a/gcc/testsuite/g++.dg/ext/is_destructible2.C ++++ b/gcc/testsuite/g++.dg/ext/is_destructible2.C +@@ -13,3 +13,12 @@ static_assert( __is_assignable(A, A) ); + static_assert( not __is_destructible(int()) ); + static_assert( not __is_nothrow_destructible(int()) ); + static_assert( not __is_trivially_destructible(int()) ); ++static_assert( __is_destructible(int&) ); ++static_assert( __is_destructible(int&&) ); ++static_assert( __is_destructible(int(&)[1]) ); ++static_assert( __is_destructible(const int(&)[1]) ); ++static_assert( __is_destructible(void(&)()) ); ++static_assert( not __is_destructible(int[]) ); ++static_assert( not __is_destructible(const int[]) ); ++static_assert( not __is_destructible(int[][1]) ); ++static_assert( not __is_destructible(const int[][1]) ); +-- +2.49.0 + diff --git a/sys-devel/gcc/gcc-16.0.0_p20250601-r1.ebuild b/sys-devel/gcc/gcc-16.0.0_p20250601-r1.ebuild new file mode 100644 index 000000000000..38b0634bd9e0 --- /dev/null +++ b/sys-devel/gcc/gcc-16.0.0_p20250601-r1.ebuild @@ -0,0 +1,60 @@ +# Copyright 1999-2025 Gentoo Authors +# Distributed under the terms of the GNU General Public License v2 + +EAPI=8 + +# Maintenance notes and explanations of GCC handling are on the wiki: +# https://wiki.gentoo.org/wiki/Project:Toolchain/sys-devel/gcc + +TOOLCHAIN_PATCH_DEV="sam" +TOOLCHAIN_HAS_TESTS=1 +PATCH_GCC_VER="16.0.0" +PATCH_VER="3" +MUSL_VER="1" +MUSL_GCC_VER="16.0.0" +PYTHON_COMPAT=( python3_{10..14} ) + +if [[ -n ${TOOLCHAIN_GCC_RC} ]] ; then + # Cheesy hack for RCs + MY_PV=$(ver_cut 1).$((($(ver_cut 2) + 1))).$((($(ver_cut 3) - 1)))-RC-$(ver_cut 5) + MY_P=${PN}-${MY_PV} + GCC_TARBALL_SRC_URI="mirror://gcc/snapshots/${MY_PV}/${MY_P}.tar.xz" + TOOLCHAIN_SET_S=no + S="${WORKDIR}"/${MY_P} +fi + +inherit toolchain + +if tc_is_live ; then + # Needs to be after inherit (for now?), bug #830908 + EGIT_BRANCH=master +elif [[ -z ${TOOLCHAIN_USE_GIT_PATCHES} ]] ; then + # Don't keyword live ebuilds + #KEYWORDS="~alpha ~amd64 ~arm ~arm64 ~hppa ~loong ~m68k ~mips ~ppc ~ppc64 ~riscv ~s390 ~sparc ~x86" + :; +fi + +if [[ ${CATEGORY} != cross-* ]] ; then + # Technically only if USE=hardened *too* right now, but no point in complicating it further. + # If GCC is enabling CET by default, we need glibc to be built with support for it. + # bug #830454 + RDEPEND="elibc_glibc? ( sys-libs/glibc[cet(-)?] )" + DEPEND="${RDEPEND}" +fi + +src_prepare() { + local p upstreamed_patches=( + # add them here + ) + for p in "${upstreamed_patches[@]}"; do + rm -v "${WORKDIR}/patch/${p}" || die + done + + toolchain_src_prepare + eapply "${FILESDIR}"/${PN}-13-fix-cross-fixincludes.patch + eapply "${FILESDIR}"/0001-c-__has_trivial_destructor-regression.patch + eapply "${FILESDIR}"/0002-c-__is_destructible-fixes-PR107600.patch + eapply "${FILESDIR}"/0003-c-constinit-diagnostic-regression-PR120506.patch + eapply "${FILESDIR}"/0004-c-more-__is_destructible-fixes-PR107600.patch + eapply_user +}
