From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2122) id 0B8783858C20; Wed, 24 Jan 2024 19:40:38 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 0B8783858C20 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1706125239; bh=17ohd5+qegLhX1U0yVHTGCp40zBOBxQX/dhKYCsMowU=; h=From:To:Subject:Date:From; b=XsR1JdmbllrllooIZnkVKkqALT+186tNdQD3SebmL4VfVZujzGjd7okrkhtIFdfpo +PVlMTHv6GmKMycruGyWZqBWEL7UEU966N+528xtn93mTggLSAG1c3nHmXC0wIZSeu uZLWGY+oppheod0NytyD1i+NkAD+zYXp0/6E3upY= MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: Jason Merrill To: gcc-cvs@gcc.gnu.org Subject: [gcc r12-10109] c++: NRV and goto [PR92407] X-Act-Checkin: gcc X-Git-Author: Jason Merrill X-Git-Refname: refs/heads/releases/gcc-12 X-Git-Oldrev: de3cc9af64b19ad64bce00c1a20b0989db29bf3e X-Git-Newrev: 193321d2649a818c3b322c8db79a2805cfdd7095 Message-Id: <20240124194039.0B8783858C20@sourceware.org> Date: Wed, 24 Jan 2024 19:40:38 +0000 (GMT) List-Id: https://gcc.gnu.org/g:193321d2649a818c3b322c8db79a2805cfdd7095 commit r12-10109-g193321d2649a818c3b322c8db79a2805cfdd7095 Author: Jason Merrill Date: Sun Jun 4 12:00:55 2023 -0400 c++: NRV and goto [PR92407] Here our named return value optimization was breaking the required destructor when the goto takes 'a' out of scope. A simple fix for the release branches is to disable the optimization in the presence of backward goto. We could do better by disabling the optimization only if there is a backward goto across the variable declaration, but we don't track that, and in GCC 14 we instead make the goto work with NRV. PR c++/92407 gcc/cp/ChangeLog: * cp-tree.h (struct language_function): Add backward_goto. * decl.cc (check_goto): Set it. * typeck.cc (check_return_expr): Prevent NRV if set. gcc/testsuite/ChangeLog: * g++.dg/opt/nrv22.C: New test. (cherry picked from commit a645347c19b07cc7abd7bf276c6769fc41afc932) Diff: --- gcc/cp/cp-tree.h | 1 + gcc/cp/decl.cc | 2 ++ gcc/cp/typeck.cc | 3 +++ gcc/testsuite/g++.dg/opt/nrv22.C | 30 ++++++++++++++++++++++++++++++ 4 files changed, 36 insertions(+) diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 5b3836422d6..132929375ea 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -2077,6 +2077,7 @@ struct GTY(()) language_function { BOOL_BITFIELD invalid_constexpr : 1; BOOL_BITFIELD throwing_cleanup : 1; + BOOL_BITFIELD backward_goto : 1; hash_table *x_named_labels; diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc index 22060b11176..878b14fe771 100644 --- a/gcc/cp/decl.cc +++ b/gcc/cp/decl.cc @@ -3650,6 +3650,8 @@ check_goto (tree decl) return; } + cp_function_chain->backward_goto = true; + bool saw_catch = false, complained = false; int identified = 0; tree bad; diff --git a/gcc/cp/typeck.cc b/gcc/cp/typeck.cc index 3be59f47179..6ca240fe40a 100644 --- a/gcc/cp/typeck.cc +++ b/gcc/cp/typeck.cc @@ -10678,6 +10678,9 @@ check_return_expr (tree retval, bool *no_warning) if (fn_returns_value_p && flag_elide_constructors) { if (named_return_value_okay_p + /* The current NRV implementation breaks if a backward goto needs to + destroy the object (PR92407). */ + && !cp_function_chain->backward_goto && (current_function_return_value == NULL_TREE || current_function_return_value == bare_retval)) current_function_return_value = bare_retval; diff --git a/gcc/testsuite/g++.dg/opt/nrv22.C b/gcc/testsuite/g++.dg/opt/nrv22.C new file mode 100644 index 00000000000..eb889fa615b --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/nrv22.C @@ -0,0 +1,30 @@ +// PR c++/92407 +// { dg-do run } + +struct A +{ + A () { a++; } + A (const A &) { a++; } + ~A () { a--; } + static int a; +}; +int A::a = 0; + +A +foo () +{ + int cnt = 10; +lab: + A a; + if (cnt--) + goto lab; + return a; +} + +int +main () +{ + foo (); + if (A::a) + __builtin_abort (); +}