This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug c++/14639] [3.4/3.5 Regression] [unit-at-a-time] Incorrect emission of unused compiler-generated destructor at -O2


------- Additional Comments From mark at codesourcery dot com  2004-03-21 19:25 -------
Subject: Re:  New: Incorrect emission of unused compiler-generated
 destructor at -O2

Jan Hubicka wrote:

>>Consider the following file:
>>class AAA {
>>public:
>>  virtual ~AAA();
>>};
>>
>>class BBB {
>>public:
>>  virtual ~BBB();
>>};
>>
>>class xyz : public AAA, public BBB {
>>public:
>>  xyz() : AAA(), BBB() { }
>>};
>>
>>
>>
>>
>>Class xyz has no key method, so its vtable should be emitted only in translation units where it's used.  
>>With "gcc -O0 -c foo.cc" I get what I expect: the compiler doesn't emit _ZTV3xyz, _ZN3xyzD0Ev, or 
>>anything else.  With "gcc -O2 -c foo.cc" I get incorrect behavior: the compiler emits xyz's destructor 
>>and vtable, thunks, and all of the things in AAA and BBB that are required to support them.
>>
>>This is a regression.  In 3.2.2, O0 and O2 both behave correctly.
>>    
>>
>
>This can be avoided by disabling following mark_referenced call:
>
>Index: cp/method.c
>===================================================================
>RCS file: /cvs/gcc/gcc/gcc/cp/method.c,v
>retrieving revision 1.279
>diff -c -3 -p -r1.279 method.c
>*** cp/method.c	12 Mar 2004 17:09:01 -0000	1.279
>--- cp/method.c	20 Mar 2004 15:27:33 -0000
>*************** use_thunk (tree thunk_fndecl, bool emit_
>*** 359,365 ****
>       this translation unit.  */
>    TREE_ADDRESSABLE (function) = 1;
>    mark_used (function);
>!   mark_referenced (DECL_ASSEMBLER_NAME (function));
>    if (!emit_p)
>      return;
>  
>--- 359,365 ----
>       this translation unit.  */
>    TREE_ADDRESSABLE (function) = 1;
>    mark_used (function);
>!   /*mark_referenced (DECL_ASSEMBLER_NAME (function));*/
>    if (!emit_p)
>      return;
>  
>The problem is that C++ frotnend manages thunks "on the side" and does
>not show to backend what DECLs will be used by thunks and what thunks
>will be emit.  This is dealt with handling the depenedencies
>conservativly.   This line comes from replacing DECL_REFERENCED.* = 1 by
>mark_referenced call so I am not quite sure it is still necesary
>(testsuite passes without this line).
>
>However we likely need some way to explain backend the hidden
>dependencies.  Would it be possible to explain me why exactly the thunk
>needs to be output and what DECLs will it reference?
>(I know that the thunks are associated to functions and are output at
>the same time the function is output and they become needed by
>use_thunk, but this all can be overly conservative now)
>  
>
Every thunk references exactly one function.  The thunk is just a little 
stub that adjusts one incoming parameter, and then transfers control to 
the referenced function.

 From a FUNCTION_DECL, you can look at DECL_THUNKS to find all of its 
thunks.  From a thunk, you can look at THUNK_TARGET to find the function 
to which it transfers control.  It does make sense to me that we call 
mark_referenced in the case that emit_p is zero.  If emit_p is 1, that 
does make sense.  In the emit_p == 0 case, we should wait to emit the 
thunk until we know that we need to emit the vtable referencing it, 
which is what we used to do.



-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=14639


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]