The COFF linker errors with a multiple reference error before the
lto-wrapper process is started. If I understand correctly this is due
to how COMDAT works in PE/COFF as the associated string to the COMDAT
section is stored in the symbol table. When using the
--allow-multiple-definition flag as a workaround linkage succeeds.

On Fri, Jul 17, 2020 at 9:31 AM Richard Biener
<richard.guent...@gmail.com> wrote:
>
> On Thu, Jul 16, 2020 at 3:05 PM Markus Böck via Gcc-patches
> <gcc-patches@gcc.gnu.org> wrote:
> >
> > COFF targets currently do not support COMDAT groups. On MinGW targets
> > GCC instead puts symbols part of a COMDAT group inside of sections
> > annotated with the .linkonce GAS directive. This leads to GAS
> > generating a section so that the COMDAT name is the same as the name
> > of the actual symbol.
> >
> > When using LTO however we never go through any of those mechanisms and
> > instead output the COMDAT into the LTO IR.
>
> I think the intent is that the very same mechanism is then triggered during
> LTRANS - why does that not happen?
>
> Richard.
>
> > This patch fixes this by
> > basically replicating the above chain by instead writing the name into
> > the IR file.
> >
> > This case only occurs in cases where multiple inheritance is used and
> > non virtual thunks are created. This problem was found while trying to
> > compile Qt using LTO on a MinGW target. In the patch a minimal
> > reproducible testcase is added which fails to link without the patch
> > and links successfully with the patch. No regressions were observed in
> > the gcc and g++ testsuite after the patch has been added.
> >
> > gcc/ChangeLog:
> >
> > 2020-07-16  Markus Böck  <markus.boec...@gmail.com>
> >
> >     * lto-streamer-out.c (write_symol): Write symbol name instead of
> > COMDAT group
> >     on PE/COFF Targets
> >
> > gcc/testsuite/ChangeLog:
> >
> > 2020-07-16  Markus Böck  <markus.boec...@gmail.com>
> >
> >     * g++.dg/lto/virtual-thunk-comdat_0.C: New test.
> >     * g++.dg/lto/virtual-thunk-comdat.h: New test.
> >     * g++.dg/lto/virtual-thunk-comdat_1.C: New test.
> >
> > ------
> >
> > Index: gcc/lto-streamer-out.c
> > ===================================================================
> > --- gcc/lto-streamer-out.c (revision 
> > 932e9140d3268cf2033c1c3e93219541c53fcd29)
> > +++ gcc/lto-streamer-out.c (date 1594903384922)
> > @@ -2779,7 +2779,12 @@
> >      size = 0;
> >
> >    if (DECL_ONE_ONLY (t))
> > +    {
> > +      if (TARGET_PECOFF)
> > +    comdat = name;
> > +      else
> >      comdat = IDENTIFIER_POINTER (decl_comdat_group_id (t));
> > +    }
> >    else
> >      comdat = "";
> >
> > Index: gcc/testsuite/g++.dg/lto/virtual-thunk-comdat_0.C
> > ===================================================================
> > --- gcc/testsuite/g++.dg/lto/virtual-thunk-comdat_0.C  (date 1594903164805)
> > +++ gcc/testsuite/g++.dg/lto/virtual-thunk-comdat_0.C  (date 1594903164805)
> > @@ -0,0 +1,15 @@
> > +// { dg-lto-do link }
> > +#include "virtual-thunk-comdat.h"
> > +
> > +QAccessibleInterface::~QAccessibleInterface() {}
> > +
> > +QAccessibleActionInterface::~QAccessibleActionInterface() {}
> > +
> > +QAccessibleEditableTextInterface::~QAccessibleEditableTextInterface() {}
> > +
> > +bool QAccessibleObject::isValid() const
> > +{
> > +  return false;
> > +}
> > +
> > +void QAccessibleLineEdit::deleteText(const char* string) {}
> > Index: gcc/testsuite/g++.dg/lto/virtual-thunk-comdat.h
> > ===================================================================
> > --- gcc/testsuite/g++.dg/lto/virtual-thunk-comdat.h    (date 1594901724581)
> > +++ gcc/testsuite/g++.dg/lto/virtual-thunk-comdat.h    (date 1594901724581)
> > @@ -0,0 +1,39 @@
> > +
> > +class QAccessibleInterface
> > +{
> > +protected:
> > +  virtual ~QAccessibleInterface();
> > +
> > +public:
> > +  virtual bool isValid() const = 0;
> > +};
> > +
> > +class QAccessibleActionInterface
> > +{
> > +public:
> > +  virtual ~QAccessibleActionInterface();
> > +};
> > +
> > +class QAccessibleEditableTextInterface
> > +{
> > +public:
> > +  virtual ~QAccessibleEditableTextInterface();
> > +
> > +  virtual void deleteText(const char*) = 0;
> > +};
> > +
> > +class QAccessibleObject : public QAccessibleInterface
> > +{
> > +public:
> > +  bool isValid() const override;
> > +};
> > +
> > +class QAccessibleWidget : public QAccessibleObject, public
> > QAccessibleActionInterface
> > +{
> > +};
> > +
> > +class QAccessibleLineEdit : public QAccessibleWidget, public
> > QAccessibleEditableTextInterface
> > +{
> > +public:
> > +  void deleteText(const char* string) override;
> > +};
> > Index: gcc/testsuite/g++.dg/lto/virtual-thunk-comdat_1.C
> > ===================================================================
> > --- gcc/testsuite/g++.dg/lto/virtual-thunk-comdat_1.C  (date 1594903161383)
> > +++ gcc/testsuite/g++.dg/lto/virtual-thunk-comdat_1.C  (date 1594903161383)
> > @@ -0,0 +1,3 @@
> > +#include "virtual-thunk-comdat.h"
> > +
> > +int main(int argc, char **argv) { QAccessibleLineEdit lineEdit; }

Reply via email to