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
+}

Reply via email to