[Bug c++/92407] Destruction of objects returned from functions skipped by goto

2024-02-05 Thread jason at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92407

Jason Merrill  changed:

   What|Removed |Added

 CC||joerg.rich...@pdv-fs.de

--- Comment #14 from Jason Merrill  ---
*** Bug 113767 has been marked as a duplicate of this bug. ***

[Bug c++/92407] Destruction of objects returned from functions skipped by goto

2024-01-24 Thread cvs-commit at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92407

--- Comment #13 from GCC Commits  ---
The releases/gcc-12 branch has been updated by Jason Merrill
:

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)

[Bug c++/92407] Destruction of objects returned from functions skipped by goto

2023-12-20 Thread jason at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92407

Jason Merrill  changed:

   What|Removed |Added

 Resolution|--- |FIXED
 Status|ASSIGNED|RESOLVED
   Target Milestone|--- |11.5

--- Comment #12 from Jason Merrill  ---
Fixed for 11.5/12.4/13.3/14.

[Bug c++/92407] Destruction of objects returned from functions skipped by goto

2023-12-20 Thread cvs-commit at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92407

--- Comment #11 from GCC Commits  ---
The releases/gcc-11 branch has been updated by Jason Merrill
:

https://gcc.gnu.org/g:32bd8a1053d25cbb15172294e59a81bc134658aa

commit r11-11162-g32bd8a1053d25cbb15172294e59a81bc134658aa
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.c (check_goto): Set it.
* typeck.c (check_return_expr): Prevent NRV if set.

gcc/testsuite/ChangeLog:

* g++.dg/opt/nrv22.C: New test.

(cherry picked from commit a645347c19b07cc7abd7bf276c6769fc41afc932)

[Bug c++/92407] Destruction of objects returned from functions skipped by goto

2023-08-31 Thread cvs-commit at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92407

--- Comment #10 from CVS Commits  ---
The releases/gcc-13 branch has been updated by Jason Merrill
:

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.

[Bug c++/92407] Destruction of objects returned from functions skipped by goto

2023-06-06 Thread jason at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92407

--- Comment #9 from Jason Merrill  ---
Fixed for GCC 14 so far.

[Bug c++/92407] Destruction of objects returned from functions skipped by goto

2023-06-06 Thread cvs-commit at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92407

--- Comment #8 from CVS Commits  ---
The trunk branch has been updated by Jason Merrill :

https://gcc.gnu.org/g:7e0b65b239c3a0d68ce94896b236b03de666ffd6

commit r14-1593-g7e0b65b239c3a0d68ce94896b236b03de666ffd6
Author: Jason Merrill 
Date:   Sun Jun 4 12:09:11 2023 -0400

c++: enable NRVO from inner block [PR51571]

Our implementation of the named return value optimization has been limited
to variables declared in the outermost block of the function, to avoid
needing to handle the case where the variable needs to be destroyed due to
going out of scope.  PR92407 pointed out a case we were missing, where the
variable goes out of scope due to a goto and we were failing to destroy it.

It occurred to me that this problem is the flip side of PR33799, where we
need to be sure to destroy the return value if a cleanup throws on return;
here we want to avoid destroying the return value when exiting the
variable's scope on return.  We can use the same flag to indicate to both
cleanups that we're returning.

This implements the guaranteed copy elision specified by P2025 (which is
not
yet part of the draft standard).

PR c++/51571
PR c++/92407

gcc/cp/ChangeLog:

* decl.cc (finish_function): Simplify NRV handling.
* except.cc (maybe_set_retval_sentinel): Also set if NRV.
(maybe_splice_retval_cleanup): Don't add the cleanup region
if we don't need it.
* semantics.cc (nrv_data): Add simple field.
(finalize_nrv): Set it.
(finalize_nrv_r): Check it and retval sentinel.
* cp-tree.h (finalize_nrv): Adjust declaration.
* typeck.cc (check_return_expr): Remove named_labels check.

gcc/testsuite/ChangeLog:

* g++.dg/opt/nrv23.C: New test.

[Bug c++/92407] Destruction of objects returned from functions skipped by goto

2023-06-06 Thread cvs-commit at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92407

--- Comment #7 from CVS Commits  ---
The trunk branch has been updated by Jason Merrill :

https://gcc.gnu.org/g:b192e2007e1c98b548f4aa878523b485968d24a4

commit r14-1592-gb192e2007e1c98b548f4aa878523b485968d24a4
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.  The simplest fix is to
disable the optimization in the presence of user labels.

We could do better by disabling the optimization only if there is a
backward
goto across the variable declaration, but we don't currently track that.

PR c++/92407

gcc/cp/ChangeLog:

* typeck.cc (check_return_expr): Prevent NRV in the presence of
named labels.

gcc/testsuite/ChangeLog:

* g++.dg/opt/nrv22.C: New test.

[Bug c++/92407] Destruction of objects returned from functions skipped by goto

2023-06-05 Thread jason at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92407

Jason Merrill  changed:

   What|Removed |Added

   Assignee|unassigned at gcc dot gnu.org  |jason at gcc dot gnu.org
 Status|NEW |ASSIGNED

[Bug c++/92407] Destruction of objects returned from functions skipped by goto

2020-11-16 Thread sichert at in dot tum.de via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92407

Moritz Sichert  changed:

   What|Removed |Added

 CC||sichert at in dot tum.de

--- Comment #6 from Moritz Sichert  ---
We are also running into this bug when using RAII lock guards and goto to
"retry" the section guarded by the lock.

I think the standard is very clear that the destructor should be called:

"Transfer out of a loop, out of a block, or back past an initialized variable
with automatic storage duration involves the destruction of objects with
automatic storage duration that are in scope at the point transferred from but
not at the point transferred to."

N4861: Section 8.7 (2)

[Bug c++/92407] Destruction of objects returned from functions skipped by goto

2019-11-07 Thread jakub at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92407

Jakub Jelinek  changed:

   What|Removed |Added

 Status|UNCONFIRMED |NEW
   Last reconfirmed||2019-11-07
 Ever confirmed|0   |1

--- Comment #5 from Jakub Jelinek  ---
The problem is in finalize_nrv_r which does:
  /* Change all cleanups for the NRV to only run when an exception is
 thrown.  */
  else if (TREE_CODE (*tp) == CLEANUP_STMT
   && CLEANUP_DECL (*tp) == dp->var)
CLEANUP_EH_ONLY (*tp) = 1;
The reason that is done is that when NRV optimizing some variable, we don't
want to run the destructor if the scope is left through return statement,
obviously we still need to run it if exception is thrown, but we need to run
the destructor
also if the scope is left through other means like goto in this testcase;
unfortunately we don't have an IL construct that can do that, we have
TRY_FINALLY_EXPR (coming from CLEANUP_STMT with !CLEANUP_EH_ONLY) where the
cleanup is run always when leaving the scope, and TRY_CATCH_EXPR where the
cleanup is run only when leaving the scope through exceptions.
So, either we need some new construct that would run cleanup whenever not left
through RETURN_EXPR, or need to use TRY_FINALLY_EXPR with some helper bool
variable initialized to something and set to something else right before
RETURN_EXPRs and conditionallize the cleanup on that bool.  The worry here is
whether it could be optimized to whatever we used to emit soon if there are no
gotos and how much worse code it would emit at -O0.

[Bug c++/92407] Destruction of objects returned from functions skipped by goto

2019-11-07 Thread Dave.Poston at gs dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92407

--- Comment #4 from Dave Poston  ---
Yep, also changing problem()/foo() to void and not returning the struct, works
properly

[Bug c++/92407] Destruction of objects returned from functions skipped by goto

2019-11-07 Thread jakub at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92407

Jakub Jelinek  changed:

   What|Removed |Added

 CC||jakub at gcc dot gnu.org,
   ||jason at gcc dot gnu.org

--- Comment #3 from Jakub Jelinek  ---
I think it is well defined.
Simplified testcase:
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 ();
}

I believe the reason why this doesn't work is NRV, at least if return a; is
changed to return A ();, so that the a variable is not NRV optimized, it works
properly.

[Bug c++/92407] Destruction of objects returned from functions skipped by goto

2019-11-07 Thread rguenth at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92407

--- Comment #2 from Richard Biener  ---
The goto defeats finalization here but construction happens multiple times.
Not sure if that's allowed by the standard, but I'd say you invoke undefined
behavior here?

[Bug c++/92407] Destruction of objects returned from functions skipped by goto

2019-11-07 Thread Dave.Poston at gs dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92407

--- Comment #1 from Dave Poston  ---
In fact, fill() isn't even needed.

Smaller repro:
https://godbolt.org/z/ubXl7Y

---
#include

struct MyStruct
{
MyStruct() {
std::cout << "Constructed" << std::endl;
}
~MyStruct() {
std::cout << "Destructed" << std::endl;
}
int a;
};

MyStruct problem() {
int cnt = 100;
start:
MyStruct a;
if( cnt-- )
goto start;
return a;
}

int main( int argc, char** argv )
{
problem();
return 0;
}