This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug c++/14639] [3.4/3.5 Regression] [unit-at-a-time] Incorrect emission of unused compiler-generated destructor at -O2
- From: "mark at codesourcery dot com" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 21 Mar 2004 19:25:21 -0000
- Subject: [Bug c++/14639] [3.4/3.5 Regression] [unit-at-a-time] Incorrect emission of unused compiler-generated destructor at -O2
- References: <20040318204634.14639.austern@apple.com>
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
------- 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