Bug 18 - bad ctor/dtor call ordering
Summary: bad ctor/dtor call ordering
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 2.96
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: wrong-code
Depends on:
Blocks:
 
Reported: 2000-03-02 13:06 UTC by martin
Modified: 2020-03-31 22:13 UTC (History)
4 users (show)

See Also:
Host: i586-pc-linux-gnu
Target: i586-pc-linux-gnu
Build: i586-pc-linux-gnu
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description martin 2000-03-02 13:06:00 UTC
hi -

The CVS version of g++ (2.96 20000229)  on a i686-pc-linux-gnu platform
generates invalid code for the following input:

-- egcsbug8.cc ---------------------------------------------------------
extern "C" int printf (...);

class allocator {
public:
  allocator()  {}
  allocator(const allocator&)  {}
  ~allocator()  {}
};

class basic_string
{
public:
  struct _Alloc_hider : allocator {};
  _Alloc_hider _M_dataplus;
};


class d0_String
  : public basic_string
{
public:
  d0_String (const char* s) { printf ("ctor %x\n", this); }
  ~d0_String () { printf ("dtor %x\n", this); }
};


struct pair {
  pair(const d0_String& __a) {}
};



int main ()
{
  pair pp[] = {
    pair (d0_String ("i")),
    pair (d0_String ("j"))
  };
  return 0;
}
------------------------------------------------------------------------

The code in main() will create two temporaries of type `d0_String' and
then destroy them.  I put in code to trace the constructor and destructor
calls; what i would expect to see is something like

  ctor A
  dtor A
  ctor A
  dtor A

where A is some address, or possibly

  ctor A
  ctor B
  dtor A
  dtor B

where A and B are different addresses.  Instead, here's what i see:

$ g++ -o egcsbug8 egcsbug8.cc
$ ./egcsbug8
ctor bfffe8f0
ctor bfffe8f0
dtor bfffe8f0
dtor bfffe8f0

First, the constructor is called twice, _on the same object_.
Then, the destructor is called twice, also on the same object.
Here's the section of the generated code which calls the destructors.
One can see that the destructor is explicitly being called twice
for the same stack slot:

.LEHE41:
	subl	$8, %esp
	pushl	$2
	leal	-8(%ebp), %eax
	subl	$32, %eax
	pushl	%eax
	call	_._9d0_String
	addl	$16, %esp
.LEHE40:
	subl	$8, %esp
	pushl	$2
	leal	-8(%ebp), %eax
	subl	$32, %eax
	pushl	%eax
	call	_._9d0_String
	addl	$16, %esp
	movl	$0, %eax
	jmp	.L39

Release:
2.96 20000229

Environment:
System: Linux mira 2.3.48 #4 Sun Feb 27 23:26:02 CET 2000 i586 unknown
Architecture: i586

	
host: i586-pc-linux-gnu
build: i586-pc-linux-gnu
target: i586-pc-linux-gnu
Comment 1 martin 2000-03-02 13:06:00 UTC
Fix:
[nathan] 
The current CVS [20000626] produces on i686-pc-linux-gnu
ctor bffff650
ctor bffff640
dtor bffff640
dtor bffff650

Please confirm whether the bug is fixed, or more information#
if not.
Comment 2 Martin v. Loewis 2000-03-08 23:12:44 UTC
State-Changed-From-To: open->analyzed
State-Changed-Why: Confirmed as a bug
Comment 3 Martin v. Loewis 2000-03-09 07:12:44 UTC
From: loewis@gcc.gnu.org
To: gcc-gnats@gcc.gnu.org, martin@loewis.home.cs.tu-berlin.de,
  nobody@gcc.gnu.org, snyder@fnal.gov
Cc:  
Subject: Re: c++/18
Date: 9 Mar 2000 07:12:44 -0000

 Old Synopsis: [bad code] bad ctor/dtor call ordering
 New Synopsis: bad ctor/dtor call ordering
 
 State-Changed-From-To: open->analyzed
 State-Changed-By: loewis
 State-Changed-When: Wed Mar  8 23:12:44 2000
 State-Changed-Why:
     Confirmed as a bug
 
 http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view&pr=18&database=gcc
Comment 4 Nathan Sidwell 2000-06-26 08:56:59 UTC
State-Changed-From-To: analyzed->feedback
State-Changed-Why: Appears fixed
Comment 5 Nathan Sidwell 2000-06-26 15:56:59 UTC
From: nathan@gcc.gnu.org
To: gcc-gnats@gcc.gnu.org, martin@loewis.home.cs.tu-berlin.de,
  nobody@gcc.gnu.org, snyder@fnal.gov
Cc:  
Subject: Re: c++/18
Date: 26 Jun 2000 15:56:59 -0000

 Synopsis: bad ctor/dtor call ordering
 
 State-Changed-From-To: analyzed->feedback
 State-Changed-By: nathan
 State-Changed-When: Mon Jun 26 08:56:59 2000
 State-Changed-Why:
     Appears fixed
 
 http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view&pr=18&database=gcc
Comment 6 Neil Booth 2001-01-13 14:43:18 UTC
State-Changed-From-To: feedback->closed
State-Changed-Why: Fixed in CVS.
Comment 7 Neil Booth 2001-01-13 22:43:18 UTC
From: neil@gcc.gnu.org
To: gcc-gnats@gcc.gnu.org, martin@loewis.home.cs.tu-berlin.de,
  nobody@gcc.gnu.org, snyder@fnal.gov
Cc:  
Subject: Re: c++/18
Date: 13 Jan 2001 22:43:18 -0000

 Synopsis: bad ctor/dtor call ordering
 
 State-Changed-From-To: feedback->closed
 State-Changed-By: neil
 State-Changed-When: Sat Jan 13 14:43:18 2001
 State-Changed-Why:
     Fixed in CVS.
 
 http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view&pr=18&database=gcc
Comment 8 GCC Commits 2020-03-31 22:13:43 UTC
The master branch has been updated by Iain Buclaw <ibuclaw@gcc.gnu.org>:

https://gcc.gnu.org/g:013fca64fc17ba646c3564eab52fac50f0751188

commit r10-7487-g013fca64fc17ba646c3564eab52fac50f0751188
Author: Iain Buclaw <ibuclaw@gdcproject.org>
Date:   Thu Apr 18 09:50:56 2019 +0200

    d: Merge UDAs between function prototype and definitions (PR90136)
    
    This change fixes the symbol merging in get_symbol_decl to also consider
    prototypes.  This allows the ability to set user defined attributes on
    the prototype of a function, which then get applied to the definition,
    if found later in the compilation.
    
    The lowering of UDAs to GCC attributes has been commonized into a single
    function called apply_user_attributes.
    
    gcc/d/ChangeLog:
    
            PR d/90136
            * d-attribs.cc: Include dmd/attrib.h.
            (build_attributes): Redeclare as static.
            (apply_user_attributes): New function.
            * d-tree.h (class UserAttributeDeclaration): Remove.
            (build_attributes): Remove.
            (apply_user_attributes): Declare.
            (finish_aggregate_type): Remove attrs argument.
            * decl.cc (get_symbol_decl): Merge declaration prototypes with
            definitions.  Use apply_user_attributes.
            * modules.cc (layout_moduleinfo_fields): Remove last argument to
            finish_aggregate_type.
            * typeinfo.cc (layout_classinfo_interfaces): Likewise.
            * types.cc (layout_aggregate_members): Likewise.
            (finish_aggregate_type): Remove attrs argument.
            (TypeVisitor::visit (TypeEnum *)): Use apply_user_attributes.
            (TypeVisitor::visit (TypeStruct *)): Remove last argument to
            finish_aggregate_type.  Use apply_user_attributes.
            (TypeVisitor::visit (TypeClass *)): Likewise.
    
    gcc/testsuite/ChangeLog:
    
            PR d/90136
            * gdc.dg/pr90136a.d: New test.
            * gdc.dg/pr90136b.d: New test.
            * gdc.dg/pr90136c.d: New test.