An object created in a do-while(1) loop for possible use as the return object of the function does not get destructed each time through the loop. The erroneous output of the supplied program is: Constructed with index 0 Constructed with index 1 Constructed with index 2 Destructed with index 2 The apparently correct output is: Constructed with index 0 Destructed with index 0 Constructed with index 1 Destructed with index 1 Constructed with index 2 Copy constructed reusing index 2 Destructed with index 2 Destructed with index 2 One workaround is to explicitly return a dummy object after the loop even though the code will never be reached. I'm guessing that with only the one return point inside the loop the compiler tries to create the object on the stack and return it without destructing it, forgetting to do the destruction when the return does not occur, and that putting in a second return point eliminates this optimization. This problem does not exist on some previous versions of gcc that I am using, including: gcc version 2.96 20000731 (Red Hat Linux 7.1 2.96-85) (i686) gcc version 2.95.2 19991024 (release) (SunOS 5.8) Release: 3.1 Environment: i686-pc-linux-gnu How-To-Repeat: g++ temp.ii a.out
State-Changed-From-To: open->analyzed State-Changed-Why: Indeed: --------------------------- extern "C" void printf (const char *, ...); #define PRINT printf ("%s\n", __PRETTY_FUNCTION__) struct Object { Object() { PRINT; } Object(const Object&) { PRINT; } void operator=(const Object&) { PRINT; } ~Object() { PRINT; } }; Object function() { int i = 0; do { Object b; if (i++ == 2) return b; } while (1); } int main() { function(); } ----------------------------- This is the output with 3.2/3.3/3.4: g/x> /home/bangerth/bin/gcc-3.4-pre/bin/c++ x.cc g/x> ./a.out Object::Object() Object::Object() Object::Object() Object::~Object() Ups. Not right. 2.95 generates g/x> ./a.out Object::Object() Object::~Object() Object::Object() Object::~Object() Object::Object() Object::Object(const Object &) Object::~Object() Object::~Object() So this is a regression. W.
Responsible-Changed-From-To: unassigned->jason Responsible-Changed-Why: nrvo
From: jason@gcc.gnu.org To: gcc-gnats@gcc.gnu.org Cc: Subject: c++/9993 Date: 17 Mar 2003 15:43:47 -0000 CVSROOT: /cvs/gcc Module name: gcc Changes by: jason@gcc.gnu.org 2003-03-17 15:43:47 Added files: gcc/testsuite/g++.dg/opt: nrv6.C Log message: PR c++/9993 * decl.c (finish_function): Only allow the NRVO to use variables declared at function scope. Patches: http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/opt/nrv6.C.diff?cvsroot=gcc&r1=NONE&r2=1.1
From: jason@gcc.gnu.org To: gcc-gnats@gcc.gnu.org Cc: Subject: c++/9993 Date: 17 Mar 2003 15:45:30 -0000 CVSROOT: /cvs/gcc Module name: gcc Changes by: jason@gcc.gnu.org 2003-03-17 15:45:30 Modified files: gcc/cp : ChangeLog decl.c Log message: PR c++/9993 * decl.c (finish_function): Only allow the NRVO to use variables declared at function scope. Patches: http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/ChangeLog.diff?cvsroot=gcc&r1=1.3280&r2=1.3281 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/decl.c.diff?cvsroot=gcc&r1=1.1022&r2=1.1023
From: jason@gcc.gnu.org To: gcc-gnats@gcc.gnu.org Cc: Subject: c++/9993 Date: 17 Mar 2003 15:46:38 -0000 CVSROOT: /cvs/gcc Module name: gcc Branch: gcc-3_2-branch Changes by: jason@gcc.gnu.org 2003-03-17 15:46:38 Modified files: gcc/cp : ChangeLog decl.c Log message: PR c++/9993 * decl.c (finish_function): Only allow the NRVO to use variables declared at function scope. Patches: http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/ChangeLog.diff?cvsroot=gcc&only_with_tag=gcc-3_2-branch&r1=1.2685.2.114.2.71&r2=1.2685.2.114.2.72 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/decl.c.diff?cvsroot=gcc&only_with_tag=gcc-3_2-branch&r1=1.866.2.36.2.17&r2=1.866.2.36.2.18
From: jason@gcc.gnu.org To: gcc-gnats@gcc.gnu.org Cc: Subject: c++/9993 Date: 17 Mar 2003 15:47:39 -0000 CVSROOT: /cvs/gcc Module name: gcc Branch: gcc-3_3-branch Changes by: jason@gcc.gnu.org 2003-03-17 15:47:39 Modified files: gcc/cp : ChangeLog decl.c Log message: PR c++/9993 * decl.c (finish_function): Only allow the NRVO to use variables declared at function scope. Patches: http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/ChangeLog.diff?cvsroot=gcc&only_with_tag=gcc-3_3-branch&r1=1.3076.2.86&r2=1.3076.2.87 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/decl.c.diff?cvsroot=gcc&only_with_tag=gcc-3_3-branch&r1=1.965.2.31&r2=1.965.2.32
State-Changed-From-To: analyzed->closed State-Changed-Why: fixed