commit: 0f42333c225b04ca215276ee4edae596a8000708 Author: Sam James <sam <AT> gentoo <DOT> org> AuthorDate: Mon Mar 31 22:03:32 2025 +0000 Commit: Sam James <sam <AT> gentoo <DOT> org> CommitDate: Mon Mar 31 22:03:53 2025 +0000 URL: https://gitweb.gentoo.org/proj/gcc-patches.git/commit/?id=0f42333c
15.0.0: add 81_all_PR119383-missing-lifetime-extension.patch Fixes Boost. Bug: https://gcc.gnu.org/PR119383 Signed-off-by: Sam James <sam <AT> gentoo.org> ...1_all_PR119383-missing-lifetime-extension.patch | 166 +++++++++++++++++++++ 15.0.0/gentoo/README.history | 4 + 2 files changed, 170 insertions(+) diff --git a/15.0.0/gentoo/81_all_PR119383-missing-lifetime-extension.patch b/15.0.0/gentoo/81_all_PR119383-missing-lifetime-extension.patch new file mode 100644 index 0000000..ff534d7 --- /dev/null +++ b/15.0.0/gentoo/81_all_PR119383-missing-lifetime-extension.patch @@ -0,0 +1,166 @@ +From d1ddf83b25fbe6c7c247007c754b7858cfaea916 Mon Sep 17 00:00:00 2001 +Message-ID: <d1ddf83b25fbe6c7c247007c754b7858cfaea916.1743458566.git....@gentoo.org> +From: Marek Polacek <pola...@redhat.com> +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/15.0.0/gentoo/README.history b/15.0.0/gentoo/README.history index 88fe306..e54ab8b 100644 --- a/15.0.0/gentoo/README.history +++ b/15.0.0/gentoo/README.history @@ -1,3 +1,7 @@ +51 ???? + + + 81_all_PR119383-missing-lifetime-extension.patch + 50 31 March 2025 + 35_all_checking-gc-use-heuristics.patch