Sometime between 2010-12-22 and rev.167484, something changed in the behaviour of the C++ compiler w.r.t the way it handles non-virtual thunks. I have just discovered this while working on a patch for PR43601; a compiler built from trunk on the earlier date reproduces the problem described there, ending in an out-of-memory error during the final link: Creating library file: /tmp/wx/obj-x-ming-new/lib/libwx_mswd_core-2.8.dll.a/opt/ mingw-new/lib/gcc/i686-pc-mingw32/4.6.0/../../../../i686-pc-mingw32/bin/ld: fina l link failed: Memory exhausted collect2: ld returned 1 exit status ... whereas a compiler built from r.167484 emits a whole lot of multiple-definition errors, and stops before trying to complete the link: Creating library file: /tmp/wx/obj-x-ming-clean/lib/libwx_based-2.8.dll.abasedll_wfstream.o:/tmp/wx/wxWidgets-2.8.11/src/common/wfstream.cpp:407: multiple definition of `non-virtual thunk to wxFFileStream::~wxFFileStream()' basedll_filesys.o:/tmp/wx/wxWidgets-2.8.11/src/common/filesys.cpp:697: first defined here basedll_wfstream.o:/tmp/wx/wxWidgets-2.8.11/src/common/wfstream.cpp:407: multiple definition of `non-virtual thunk to wxFFileStream::~wxFFileStream()' basedll_filesys.o:/tmp/wx/wxWidgets-2.8.11/src/common/filesys.cpp:697: first defined here basedll_wfstream.o:/tmp/wx/wxWidgets-2.8.11/src/common/wfstream.cpp:407: multiple definition of `non-virtual thunk to wxFileStream::~wxFileStream()' basedll_filesys.o:/tmp/wx/wxWidgets-2.8.11/src/common/filesys.cpp:697: first defined here basedll_wfstream.o:/tmp/wx/wxWidgets-2.8.11/src/common/wfstream.cpp:407: multiple definition of `non-virtual thunk to wxFileStream::~wxFileStream()' basedll_filesys.o:/tmp/wx/wxWidgets-2.8.11/src/common/filesys.cpp:697: first defined here basedll_zipstrm.o:/tmp/wx/wxWidgets-2.8.11/src/common/zipstrm.cpp:2423: multiple definition of `non-virtual thunk to wxFFileStream::~wxFFileStream()' basedll_filesys.o:/tmp/wx/wxWidgets-2.8.11/src/common/filesys.cpp:697: first defined here basedll_zipstrm.o:/tmp/wx/wxWidgets-2.8.11/src/common/zipstrm.cpp:2423: multiple definition of `non-virtual thunk to wxFFileStream::~wxFFileStream()' basedll_filesys.o:/tmp/wx/wxWidgets-2.8.11/src/common/filesys.cpp:697: first defined here basedll_zipstrm.o:/tmp/wx/wxWidgets-2.8.11/src/common/zipstrm.cpp:2423: multiple definition of `non-virtual thunk to wxFileStream::~wxFileStream()' basedll_filesys.o:/tmp/wx/wxWidgets-2.8.11/src/common/filesys.cpp:697: first defined here basedll_zipstrm.o:/tmp/wx/wxWidgets-2.8.11/src/common/zipstrm.cpp:2423: multiple definition of `non-virtual thunk to wxFileStream::~wxFileStream()' basedll_filesys.o:/tmp/wx/wxWidgets-2.8.11/src/common/filesys.cpp:697: first defined here basedll_registry.o:/tmp/wx/wxWidgets-2.8.11/src/msw/registry.cpp:1428: multiple definition of `non-virtual thunk to wxFFileStream::~wxFFileStream()' basedll_filesys.o:/tmp/wx/wxWidgets-2.8.11/src/common/filesys.cpp:697: first defined here basedll_registry.o:/tmp/wx/wxWidgets-2.8.11/src/msw/registry.cpp:1428: multiple definition of `non-virtual thunk to wxFFileStream::~wxFFileStream()' basedll_filesys.o:/tmp/wx/wxWidgets-2.8.11/src/common/filesys.cpp:697: first defined here basedll_registry.o:/tmp/wx/wxWidgets-2.8.11/src/msw/registry.cpp:1428: multiple definition of `non-virtual thunk to wxFileStream::~wxFileStream()' basedll_filesys.o:/tmp/wx/wxWidgets-2.8.11/src/common/filesys.cpp:697: first defined here basedll_registry.o:/tmp/wx/wxWidgets-2.8.11/src/msw/registry.cpp:1428: multiple definition of `non-virtual thunk to wxFileStream::~wxFileStream()' basedll_filesys.o:/tmp/wx/wxWidgets-2.8.11/src/common/filesys.cpp:697: first defined here collect2: ld returned 1 exit status In both cases the build was configured with a cygwin-x-mingw cross compiler using the same command line: $ /tmp/wx/wxWidgets-2.8.11/configure --with-msw --enable-debug --enable-debug_gdb --enable-shared 2>&1 --host=i686-pc-mingw32 More once I've diagnosed what's going on in some of the generated object files. I've marked this major as it could easily affect a whole lot of c++ library builds, but may reduce that severity if it turns out to be something unusual that wx is doing. However it's still a regression.
Yeah, confirmed that. With the older compiler the NVT is emitted in a comdat section as you'd expect: the symbols ... [6421](sec 2101)(fl 0x00)(ty 20)(scl 2) (nx 0) 0x00000000 __ZThn32_N13wxFFileStreamD1Ev [6427](sec 2103)(fl 0x00)(ty 20)(scl 2) (nx 0) 0x00000000 __ZThn32_N13wxFFileStreamD0Ev ... point to sections (note MS numbers sections from 1, objdump from zero) like so: 2100 .text$_ZThn32_N13wxFFileStreamD1Ev 0000000c 00000000 00000000 0002d368 2**2 CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE, LINK_ONCE_DISCARD (COMDAT __ZThn32_N13wxFFileStreamD1Ev 6421) 2102 .text$_ZThn32_N13wxFFileStreamD0Ev 0000000c 00000000 00000000 0002d3e0 2**2 CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE, LINK_ONCE_DISCARD (COMDAT __ZThn32_N13wxFFileStreamD0Ev 6427) With the latest trunk however, the same symbols ... [6419](sec 1)(fl 0x00)(ty 20)(scl 2) (nx 0) 0x00000fa8 __ZThn32_N13wxFFileStreamD1Ev [6423](sec 1)(fl 0x00)(ty 20)(scl 2) (nx 0) 0x00000fb2 __ZThn32_N13wxFFileStreamD0Ev ... both point to section 1: the .text section. 0 .text 00000fd0 00000000 00000000 0001633c 2**2 CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE This being replicated across all object files, no wonder we have multiple defintion errors. It's a bug that the NVT doesn't get emitted in a comdat, I expect. (I think I remember some kind of recent change to section handling that I saw fly past on the patches list, wonder if it could be related.)
*** Bug 47116 has been marked as a duplicate of this bug. ***
A simple test in PR47116: http://gcc.gnu.org/bugzilla/attachment.cgi?id=22866
(In reply to comment #3) > A simple test in PR47116: > http://gcc.gnu.org/bugzilla/attachment.cgi?id=22866 Thankyou, that should make debugging it easier :)
Bug is caused by the change at rev 167795 applied to fix PR46667. http://gcc.gnu.org/viewcvs?view=revision&revision=167795
(In reply to comment #5) > Bug is caused by the change at rev 167795 applied to fix PR46667. > > http://gcc.gnu.org/viewcvs?view=revision&revision=167795 Full details at http://gcc.gnu.org/ml/gcc-patches/2011-01/msg00446.html: >" It turns out that resolve_unique_function() is not called at all for the thunk function any more, where previously it was called from assemble_start_function called from cgraph_expand_function. This is because gimple_expand_cfg() isn't called for these thunk functions; they are emitted through a call chain that looks like: > (gdb) bt > #0 assemble_start_function (decl=0x7fe32f00, > fnname=0x7fe41860 "_ZThn4_N7FooBase3BarEv") > at /gnu/gcc/gcc-patched/gcc/varasm.c:1524 > #1 0x007aa73c in cgraph_expand_function (node=0x7ff80c30) > at /gnu/gcc/gcc-patched/gcc/cgraphunit.c:1328 > #2 0x007ad210 in cgraph_optimize () > at /gnu/gcc/gcc-patched/gcc/cgraphunit.c:1567 > #3 0x007ad69a in cgraph_finalize_compilation_unit () > at /gnu/gcc/gcc-patched/gcc/cgraphunit.c:1031 > #4 0x004ce825 in cp_write_global_declarations () > at /gnu/gcc/gcc-patched/gcc/cp/decl2.c:3974 > #5 0x0080ed6d in toplev_main (argc=14, argv=0x5079f78) > at /gnu/gcc/gcc-patched/gcc/toplev.c:591 > #6 0x0060699f in main (argc=Cannot access memory at address 0x0 > ) at /gnu/gcc/gcc-patched/gcc/main.c:36 " That's the main part of it.
Created attachment 22932 [details] proposed patch Ensures thunks get a section name assigned in cgraphunit.c#assemble_thunk(). Taking this for a bootstrap/test cycle.
Consider the patch pre-approved if it passes testing. Thanks!
Author: davek Date: Mon Jan 10 00:33:32 2011 New Revision: 168624 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=168624 Log: gcc/ChangeLog: PR c++/47218 * cgraphunit.c (assemble_thunk): Call resolve_unique_section. gcc/testsuite/ChangeLog: PR c++/47218 * g++.dg/other/pr47218-1.C: New test file. * g++.dg/other/pr47218.C: Likewise. * g++.dg/other/pr47218.h: New supporting header. Added: trunk/gcc/testsuite/g++.dg/other/pr47218-1.C trunk/gcc/testsuite/g++.dg/other/pr47218.C trunk/gcc/testsuite/g++.dg/other/pr47218.h Modified: trunk/gcc/ChangeLog trunk/gcc/cgraphunit.c trunk/gcc/testsuite/ChangeLog
Done.