Bug creation and email sending has been disabled, file new bugs at gcc.gnu.org/bugzilla
Bug 231 - Some template mixins symbols get defined in output object files, although they shouldn't
Summary: Some template mixins symbols get defined in output object files, although the...
Status: RESOLVED FIXED
Alias: None
Product: GDC
Classification: Unclassified
Component: gdc (show other bugs)
Version: 5.x
Hardware: All All
: --- normal
Assignee: Iain Buclaw
URL:
Depends on:
Blocks:
 
Reported: 2016-06-20 06:18 CEST by Sebastien Alaiwan
Modified: 2016-10-01 09:35 CEST (History)
2 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Sebastien Alaiwan 2016-06-20 06:18:02 CEST
I stumbled upon this while trying to build latest GtkD with gdc 5.4.
It seems like the symbols related to template mixins get included twice.

$ git clone 'https://github.com/gtkd-developers/GtkD.git'
$ cd GtkD
$ export DC=gdc
$ make
[...]
ar rcs libgtkdgl-3.a  srcgl/glgtk/GLCapability.o srcgl/glgtk/GLtInit.o srcgl/glgtk/GLWidget.o srcgl/glgdk/GLDrawable.o srcgl/glgdk/GLDrawableT.o srcgl/glgdk/GLQuery.o srcgl/glgdk/GLDrawableIF.o srcgl/glgdk/GLVersion.o srcgl/glgdk/GLWindow.o srcgl/glgdk/GLdInit.o srcgl/glgdk/GLConfig.o srcgl/glgdk/GLContext.o srcgl/gtkglc/gl.o srcgl/gtkglc/glgtktypes.o srcgl/gtkglc/glgtk.o srcgl/gtkglc/glgdk.o srcgl/gtkglc/glu.o srcgl/gtkglc/glgdktypes.o
ar rcs libgtkdsv-3.a  srcsv/gsv/SourceFileSaver.o srcsv/gsv/StyleSchemeChooserWidget.o srcsv/gsv/SourceUndoManagerT.o srcsv/gsv/SourceStyleSchemeManager.o srcsv/gsv/SourceSearchContext.o srcsv/gsv/SourceEncoding.o srcsv/gsv/SourceCompletionProviderT.o srcsv/gsv/SourceMap.o srcsv/gsv/SourceCompletionProvider.o srcsv/gsv/SourceCompletionItem.o srcsv/gsv/SourceGutterRendererText.o srcsv/gsv/SourceGutter.o srcsv/gsv/SourceMarkAttributes.o srcsv/gsv/SourceUndoManager.o srcsv/gsv/SourceBuffer.o srcsv/gsv/StyleSchemeChooserT.o srcsv/gsv/SourceCompletionInfo.o srcsv/gsv/SourceCompletionWords.o srcsv/gsv/Tag.o srcsv/gsv/SourceFileLoader.o srcsv/gsv/SourceStyle.o srcsv/gsv/SourcePrintCompositor.o srcsv/gsv/SourceGutterRenderer.o srcsv/gsv/SourceSearchSettings.o srcsv/gsv/SourceView.o srcsv/gsv/SourceFile.o srcsv/gsv/SourceCompletionProposalT.o srcsv/gsv/StyleSchemeChooserIF.o srcsv/gsv/SourceLanguage.o srcsv/gsv/SourceCompletion.o srcsv/gsv/Utils.o srcsv/gsv/SourceStyleScheme.o srcsv/gsv/SourceCompletionContext.o srcsv/gsv/SourceLanguageManager.o srcsv/gsv/SourceUndoManagerIF.o srcsv/gsv/SourceGutterRendererPixbuf.o srcsv/gsv/SourceCompletionProviderIF.o srcsv/gsv/SourceCompletionProposalIF.o srcsv/gsv/SourceMark.o srcsv/gsv/StyleSchemeChooserButton.o srcsv/gsvc/gsvtypes.o srcsv/gsvc/gsv.o
gdc demos/gtkD/TestWindow/TestThemes.o demos/gtkD/TestWindow/TEditableCells.o demos/gtkD/TestWindow/TestEntries.o demos/gtkD/TestWindow/TestAspectFrame.o demos/gtkD/TestWindow/TestText.o demos/gtkD/TestWindow/TestScales.o demos/gtkD/TestWindow/TestImage.o demos/gtkD/TestWindow/TestIdle.o demos/gtkD/TestWindow/TestTreeView1.o demos/gtkD/TestWindow/TTextView.o demos/gtkD/TestWindow/TestWindow.o demos/gtkD/TestWindow/TestTreeView.o demos/gtkD/TestWindow/TestDrawingArea.o demos/gtkD/TestWindow/TestStock.o  -o TestWindow -Xlinker -L. -Xlinker -lgtkd-3 -Xlinker -ldl -m64
ranlib libgtkdgl-3.a
ranlib libgtkdsv-3.a
./libgtkd-3.a(Entry.o): In function `_D3gtk6Widget6Widget10__mixin56514customTagStartMFC3gtk7Builder7BuilderC7gobject7ObjectG7ObjectGAyaJS4gtkc9glibtypes13GMarkupParserJPvZb':
Entry.d:(.text+0x1d40): multiple definition of `_D3gtk6Widget6Widget10__mixin56514customTagStartMFC3gtk7Builder7BuilderC7gobject7ObjectG7ObjectGAyaJS4gtkc9glibtypes13GMarkupParserJPvZb'
./libgtkd-3.a(Layout.o):Layout.d:(.text+0x60): first defined here
./libgtkd-3.a(Entry.o): In function `_DT1584_D3gtk6Widget6Widget10__mixin56514customTagStartMFC3gtk7Builder7BuilderC7gobject7ObjectG7ObjectGAyaJS4gtkc9glibtypes13GMarkupParserJPvZb':
Entry.d:(.text+0x1e30): multiple definition of `_DT1584_D3gtk6Widget6Widget10__mixin56514customTagStartMFC3gtk7Builder7BuilderC7gobject7ObjectG7ObjectGAyaJS4gtkc9glibtypes13GMarkupParserJPvZb'
./libgtkd-3.a(Layout.o):Layout.d:(.text+0x150): first defined here
./libgtkd-3.a(Entry.o): In function `_D3gtk6Widget6Widget10__mixin56516buildableSetNameMFAyaZv':
Entry.d:(.text+0x1ed0): multiple definition of `_D3gtk6Widget6Widget10__mixin56516buildableSetNameMFAyaZv'
./libgtkd-3.a(Layout.o):Layout.d:(.text+0x160): first defined here
./libgtkd-3.a(Entry.o): In function `_DT1584_D3gtk6Widget6Widget10__mixin56516buildableSetNameMFAyaZv':
Entry.d:(.text+0x1f30): multiple definition of `_DT1584_D3gtk6Widget6Widget10__mixin56516buildableSetNameMFAyaZv'
./libgtkd-3.a(Layout.o):Layout.d:(.text+0x1c0): first defined here
[...]

And so on.

When looking at the contents of object files, indeed, Entry.o and Layout.o are both defining symbols belonging to "gtk.Widget" module namespace:

$ nm src/gtk/Entry.o | ddemangle | grep 'refAccessible()' -C 1
                 U bool gtk.Widget.Widget.isToplevel()
0000000000002920 T atk.ObjectAtk.ObjectAtk gtk.Widget.Widget.__mixin564.refAccessible()
0000000000000025 t atk.ObjectAtk.ObjectAtk gtk.Widget.Widget.__mixin564.refAccessible().part.75
00000000000028e0 T gtkc.atktypes.AtkImplementor* gtk.Widget.Widget.__mixin564.getImplementorStruct()

$ nm src/gtk/Widget.o | ddemangle | grep 'refAccessible()' -C 1 
0000000000000000 t bool gtk.Widget.Widget.isToplevel().part.138
000000000000eb40 T atk.ObjectAtk.ObjectAtk gtk.Widget.Widget.__mixin564.refAccessible()
0000000000000000 t atk.ObjectAtk.ObjectAtk gtk.Widget.Widget.__mixin564.refAccessible().part.363
000000000000bc90 T gtkc.atktypes.AtkImplementor* gtk.Widget.Widget.__mixin564.getImplementorStruct()

This seems related to template mixins.
Comment 1 Johannes Pfau 2016-07-26 10:29:17 CEST
I've tracked this down:

widget.d
--------------------------------------
interface ImplementorIF
{
    void* getImplementorStruct();
    void* getStruct();
}
template ImplementorT()
{
    void* getImplementorStruct()
    {
        return null;
    }
}
class Widget : ImplementorIF
{
    mixin ImplementorT;
    void* getStruct()
    {
        return null;
    }
}
--------------------------------------

range.d
--------------------------------------
import Widget;
class Range : Widget
{
    void* getStruct()
    {
        return null;
    }
}
void main() {}
--------------------------------------
gdc range.d widget.d


The problem is our thunk emission. We call toObjfile in FuncDeclaration::toThunkSymbol, DMD does not. This code was initially added in cbd6d919559697bba6bb210acc2761ae43dbaf8a to fix issue 27. Back then we had a output_declaration_p check in toObjfile that prevented emitting getImplementorStruct. 9766ddee234a3db05b24d071bd15987373d962f5 changed the output_declaration_p check into a simple gcc_attribute_p(this) check which caused this regression.

I wonder how dmd handles issue 27 without calling toObjfile and whether we should do the same thing. If we have to keep calling toObjfile I think we need to re-add this code to toObjfile:

--------------------------------------
FuncDeclaration *fd = dsym->isFuncDeclaration();
if (fd != NULL)
  {
    for (FuncDeclaration *fdp = fd; fdp != NULL;)
      {
	if (!fdp->isInstantiated() && fdp->inNonRoot())
	  return false;

	if (!fdp->isNested())
	  break;

	fdp = fdp->toParent2()->isFuncDeclaration();
      }
  }

  if (!flag_emit_templates)
    return !D_DECL_IS_TEMPLATE (dsym->toSymbol()->Stree);
--------------------------------------

What do you think, Iain?
Comment 2 Johannes Pfau 2016-09-26 16:53:46 CEST
https://github.com/D-Programming-GDC/GDC/pull/245