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]

Re: [Bug c++/14639] New: Incorrect emission of unused compiler-generateddestructor 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.

--
Mark Mitchell
CodeSourcery, LLC
(916) 791-8304
mark@codesourcery.com


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