commit: f29cc45282812f48bdabb4c0e59020515ed13e17 Author: Sam James <sam <AT> gentoo <DOT> org> AuthorDate: Tue Apr 1 22:42:28 2025 +0000 Commit: Sam James <sam <AT> gentoo <DOT> org> CommitDate: Tue Apr 1 22:42:53 2025 +0000 URL: https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=f29cc452
sys-devel/gcc: disable musttail again; C++ lifetime fix for 15.0.1_pre20250330 Hopefully the remaining musttail bits will land soon. Bug: https://bugs.gentoo.org/952964 Signed-off-by: Sam James <sam <AT> gentoo.org> ...gcc-15.0.1_pre20250330-lifetime-extension.patch | 168 +++++++++++++++++++++ sys-devel/gcc/gcc-15.0.1_pre20250330-r1.ebuild | 55 +++++++ 2 files changed, 223 insertions(+) diff --git a/sys-devel/gcc/files/gcc-15.0.1_pre20250330-lifetime-extension.patch b/sys-devel/gcc/files/gcc-15.0.1_pre20250330-lifetime-extension.patch new file mode 100644 index 000000000000..42eed3f6bb86 --- /dev/null +++ b/sys-devel/gcc/files/gcc-15.0.1_pre20250330-lifetime-extension.patch @@ -0,0 +1,168 @@ +https://inbox.sourceware.org/gcc-patches/[email protected]/ + +From d1ddf83b25fbe6c7c247007c754b7858cfaea916 Mon Sep 17 00:00:00 2001 +Message-ID: <d1ddf83b25fbe6c7c247007c754b7858cfaea916.1743458566.git....@gentoo.org> +From: Marek Polacek <[email protected]> +Date: Mon, 31 Mar 2025 16:59:08 -0400 +Subject: [PATCH] c++: fix missing lifetime extension [PR119383] + +Since r15-8011 cp_build_indirect_ref_1 won't do the *&TARGET_EXPR -> +TARGET_EXPR folding not to change its value category. That fix seems +correct but it made us stop extending the lifetime in this testcase, +causing a wrong-code issue -- extend_ref_init_temps_1 did not see +through the extra *& because it doesn't use a tree walk. + +This patch reverts r15-8011 and instead handles the problem in +build_over_call by calling force_lvalue in the is_really_empty_class +case as well as in the general case. + + PR c++/119383 + +gcc/cp/ChangeLog: + + * call.cc (build_over_call): Use force_lvalue to ensure op= returns + an lvalue. + * cp-tree.h (force_lvalue): Declare. + * cvt.cc (force_lvalue): New. + * typeck.cc (cp_build_indirect_ref_1): Revert r15-8011. + +gcc/testsuite/ChangeLog: + +* g++.dg/cpp0x/temp-extend3.C: New test. +--- + gcc/cp/call.cc | 9 ++++--- + gcc/cp/cp-tree.h | 1 + + gcc/cp/cvt.cc | 13 +++++++++ + gcc/cp/typeck.cc | 10 +++---- + gcc/testsuite/g++.dg/cpp0x/temp-extend3.C | 32 +++++++++++++++++++++++ + 5 files changed, 55 insertions(+), 10 deletions(-) + create mode 100644 gcc/testsuite/g++.dg/cpp0x/temp-extend3.C + +diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc +index c1c8987ec8b1..b1469cb5a4c9 100644 +--- a/gcc/cp/call.cc ++++ b/gcc/cp/call.cc +@@ -10828,10 +10828,8 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain) + if (is_really_empty_class (type, /*ignore_vptr*/true)) + { + /* Avoid copying empty classes, but ensure op= returns an lvalue even +- if the object argument isn't one. This isn't needed in other cases +- since MODIFY_EXPR is always considered an lvalue. */ +- to = cp_build_addr_expr (to, tf_none); +- to = cp_build_indirect_ref (input_location, to, RO_ARROW, complain); ++ if the object argument isn't one. */ ++ to = force_lvalue (to, complain); + val = build2 (COMPOUND_EXPR, type, arg, to); + suppress_warning (val, OPT_Wunused); + } +@@ -10852,6 +10850,9 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain) + tree array_type, alias_set; + + arg2 = TYPE_SIZE_UNIT (as_base); ++ /* Ensure op= returns an lvalue even if the object argument isn't ++ one. */ ++ to = force_lvalue (to, complain); + to = cp_stabilize_reference (to); + arg0 = cp_build_addr_expr (to, complain); + +diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h +index 2f2122dcf241..927f51b116b3 100644 +--- a/gcc/cp/cp-tree.h ++++ b/gcc/cp/cp-tree.h +@@ -7079,6 +7079,7 @@ extern tree convert_to_reference (tree, tree, int, int, tree, + tsubst_flags_t); + extern tree convert_from_reference (tree); + extern tree force_rvalue (tree, tsubst_flags_t); ++extern tree force_lvalue (tree, tsubst_flags_t); + extern tree ocp_convert (tree, tree, int, int, + tsubst_flags_t); + extern tree cp_convert (tree, tree, tsubst_flags_t); +diff --git a/gcc/cp/cvt.cc b/gcc/cp/cvt.cc +index bd1f147f2c56..f663a6d08c89 100644 +--- a/gcc/cp/cvt.cc ++++ b/gcc/cp/cvt.cc +@@ -575,6 +575,19 @@ force_rvalue (tree expr, tsubst_flags_t complain) + return expr; + } + ++/* Force EXPR to be an lvalue, if it isn't already. */ ++ ++tree ++force_lvalue (tree expr, tsubst_flags_t complain) ++{ ++ if (!lvalue_p (expr)) ++ { ++ expr = cp_build_addr_expr (expr, complain); ++ expr = cp_build_indirect_ref (input_location, expr, RO_ARROW, complain); ++ } ++ return expr; ++} ++ + + /* If EXPR and ORIG are INTEGER_CSTs, return a version of EXPR that has + TREE_OVERFLOW set only if it is set in ORIG. Otherwise, return EXPR +diff --git a/gcc/cp/typeck.cc b/gcc/cp/typeck.cc +index c8e4441fb8b4..4f4dc683b5a0 100644 +--- a/gcc/cp/typeck.cc ++++ b/gcc/cp/typeck.cc +@@ -3870,13 +3870,11 @@ cp_build_indirect_ref_1 (location_t loc, tree ptr, ref_operator errorstring, + return error_mark_node; + } + else if (do_fold && TREE_CODE (pointer) == ADDR_EXPR +- && same_type_p (t, TREE_TYPE (TREE_OPERAND (pointer, 0))) +- /* Don't let this change the value category. '*&TARGET_EXPR' +- is an lvalue, but folding it into 'TARGET_EXPR' would turn +- it into a prvalue of class type. */ +- && lvalue_p (TREE_OPERAND (pointer, 0))) ++ && same_type_p (t, TREE_TYPE (TREE_OPERAND (pointer, 0)))) + /* The POINTER was something like `&x'. We simplify `*&x' to +- `x'. */ ++ `x'. This change the value category: '*&TARGET_EXPR' ++ is an lvalue and folding it into 'TARGET_EXPR' turns it into ++ a prvalue of class type. */ + return TREE_OPERAND (pointer, 0); + else + { +diff --git a/gcc/testsuite/g++.dg/cpp0x/temp-extend3.C b/gcc/testsuite/g++.dg/cpp0x/temp-extend3.C +new file mode 100644 +index 000000000000..3eab88d0076e +--- /dev/null ++++ b/gcc/testsuite/g++.dg/cpp0x/temp-extend3.C +@@ -0,0 +1,32 @@ ++// PR c++/119383 ++// { dg-do run { target c++11 } } ++ ++int g; ++ ++struct base { ++ virtual base *clone() const = 0; ++ ~base() { } ++}; ++ ++struct impl : virtual base { ++ base *clone() const { return new impl; } // #1 ++ impl() { ++g; } ++ ~impl() { --g; } ++}; ++ ++const base * ++make_a_clone () ++{ ++ const base &base = impl{}; // #2 ++ return base.clone(); ++} ++ ++int ++main () ++{ ++ make_a_clone (); ++ // impl::impl() is called twice (#1 and #2), impl::~impl() once, ++ // at the end of make_a_clone. ++ if (g != 1) ++ __builtin_abort (); ++} + +base-commit: aa3aaf2bfb8fcc17076993df4297597b68bc5f60 +-- +2.49.0 + diff --git a/sys-devel/gcc/gcc-15.0.1_pre20250330-r1.ebuild b/sys-devel/gcc/gcc-15.0.1_pre20250330-r1.ebuild new file mode 100644 index 000000000000..795b82277a85 --- /dev/null +++ b/sys-devel/gcc/gcc-15.0.1_pre20250330-r1.ebuild @@ -0,0 +1,55 @@ +# Copyright 1999-2025 Gentoo Authors +# Distributed under the terms of the GNU General Public License v2 + +EAPI=8 + +TOOLCHAIN_PATCH_DEV="sam" +TOOLCHAIN_HAS_TESTS=1 +PATCH_GCC_VER="15.0.0" +PATCH_VER="50" +MUSL_VER="2" +MUSL_GCC_VER="15.0.0" +PYTHON_COMPAT=( python3_{10..13} ) + +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 + 80_all_PR119376-tailc-Don-t-fail-musttail-calls-if-they-use-or-could.patch + ) + for p in "${upstreamed_patches[@]}"; do + rm -v "${WORKDIR}/patch/${p}" || die + done + + toolchain_src_prepare + eapply "${FILESDIR}"/${P}-lifetime-extension.patch + eapply "${FILESDIR}"/${PN}-15.0.1_pre20250323-disable-musttail.patch + eapply_user +}
