From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2122) id D8EEC3858D37; Thu, 31 Aug 2023 22:40:02 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org D8EEC3858D37 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1693521602; bh=LfJN3nuSAZzF0fxOr8PSeJk18l2BZbJW6YeqByKjcoQ=; h=From:To:Subject:Date:From; b=d5NvKe0BL/Tyyh96wxu//OhF5uqQZxwBlU3t1uTO+zciMTDOMQqO8sic/iG1iRieT CvspGFF3VXz1jRUjheB3gBQotWJWsXkS1Bm+9oLoJKA4l5AOFh/v9Ipia0a6vCi+0+ etnMGF6Ou3WpNMMy1PA5utUaMtdK/e5ZMgI5AdUg= 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 r13-7770] c++: NRV and goto [PR92407] X-Act-Checkin: gcc X-Git-Author: Jason Merrill X-Git-Refname: refs/heads/releases/gcc-13 X-Git-Oldrev: b6786076d9588640db6bc01c467f9760e4c3059c X-Git-Newrev: a645347c19b07cc7abd7bf276c6769fc41afc932 Message-Id: <20230831224002.D8EEC3858D37@sourceware.org> Date: Thu, 31 Aug 2023 22:40:02 +0000 (GMT) List-Id: https://gcc.gnu.org/g:a645347c19b07cc7abd7bf276c6769fc41afc932 commit r13-7770-ga645347c19b07cc7abd7bf276c6769fc41afc932 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. 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 a14eb8d0b9a5..8fee4754604a 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -2111,6 +2111,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 5fe4c53523dc..30d89bba9e86 100644 --- a/gcc/cp/decl.cc +++ b/gcc/cp/decl.cc @@ -3768,6 +3768,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 ff3a49f01b3d..d448852764df 100644 --- a/gcc/cp/typeck.cc +++ b/gcc/cp/typeck.cc @@ -11155,6 +11155,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 000000000000..eb889fa615b1 --- /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 (); +}