Comment #0 by ellery-newcomer — 2015-11-13T03:27:43Z
when building pyd, e.g. here:
https://travis-ci.org/ariovistus/pyd/jobs/90655229
the linker complains:
/usr/bin/ld: Warning: size of symbol `_D4util11multi_index276__T19MultiIndexContainerTC4core6thread6ThreadTS4util11multi_index127__T9IndexedByS1094util11multi_index89__T6HashedVbi0VAyaa1_61VAyaa21_7479706569642861292e6765744861736828266129VAyaa4_613d3d62ZZ9IndexedByTS4util11multi_index15MallocAllocatorTS4util11multi_index11MutableViewZ19MultiIndexContainer6index08containsMxFC4core6thread6ThreadZb' changed from 127 in build/temp.linux-x86_64-3.2/infra/temp.o to 119 in build/temp.linux-x86_64-3.2/infra/temp.o
but this doesn't stop compilation.
when building with gdc, e.g. here:
https://travis-ci.org/ariovistus/pyd/jobs/90001785
compilation fails:
/tmp/ccZ8LnGz.s: Assembler messages:
/tmp/ccZ8LnGz.s:131179: Error: symbol `_D4util11multi_index276__T19MultiIndexContainerTC4core6thread6ThreadTS4util11multi_index127__T9IndexedByS1094util11multi_index89__T6HashedVbi0VAyaa1_61VAyaa21_7479706569642861292e6765744861736828266129VAyaa4_613d3d62ZZ9IndexedByTS4util11multi_index15MallocAllocatorTS4util11multi_index11MutableViewZ19MultiIndexContainer6index08containsMxFC4core6thread6ThreadZb' is already defined
Comment #1 by johannespfau — 2015-11-13T17:18:47Z
Created attachment 1567
reduced test case
I've added a dustmite reduced test case. Compile like this:
dmd main.d
/usr/bin/ld: Warning: size of symbol `_D4main179__T19MultiIndexContainerTC4core6thread6ThreadTS4main113__T9IndexedByS964main89__T6HashedVbi0VAyaa1_61VAyaa21_7479706569642861292e6765744861736828266129VAyaa4_613d3d62ZZ9IndexedByZ19MultiIndexContainer9__mixin108containsMxFC4core6thread6ThreadZb' changed from 111 in main.o to 103 in main.o
gdc main.d
/tmp/cczTwcpO.s: Assembler messages:
/tmp/cczTwcpO.s:195: Error: symbol `_D4main179__T19MultiIndexContainerTC4core6thread6ThreadTS4main113__T9IndexedByS964main89__T6HashedVbi0VAyaa1_61VAyaa21_7479706569642861292e6765744861736828266129VAyaa4_613d3d62ZZ9IndexedByZ19MultiIndexContainer9__mixin108containsMxFC4core6thread6ThreadZb' is already defined
It seems scary that the size of the symbol changes. But maybe the bigger issue is that the template is actually emitted twice to the same object file. This seems to be tolerated by ld (dmd only gets a warning) but not by the assembler (gdc outputs asm and calls the assembler which refuses to assemble this).
Pinging Iain as I'm not sure if the assembler only complains because the size differs or whether it will still complain even if the size difference is fixed.
Comment #2 by johannespfau — 2015-11-13T17:20:31Z
Raised importance to critical as this prevents some of the bigger D projects from sucessfully compiling with GDC (pyd, wxD).
Comment #3 by ibuclaw — 2015-11-16T10:35:32Z
(In reply to Johannes Pfau from comment #1)
> Pinging Iain as I'm not sure if the assembler only complains because the
> size differs or whether it will still complain even if the size difference
> is fixed.
My understanding is that GAS will complain and error for *any* duplicate symbol, regardless of what flags are associated with it, or size it has.
Comment #4 by v.richomme — 2016-01-06T10:40:34Z
Any progress ??
Comment #5 by ibuclaw — 2016-03-20T21:47:57Z
I don't think it's a compiler bug, but it would help indefinitely if only the compiler semantic passes checked for conflicting function overrides upon declaration, rather than when they are called.
I can distil test case down to:
---
struct MultiIndexContainer()
{
bool contains(int k) const
{
auto r = true;
return r;
}
bool contains(int k) const
{
return false;
}
}
void main()
{
MultiIndexContainer!() m;
}
---
If these were not templates, you'd get multiple definition errors. But as that is not the case, these instead get put on comdat and merged. This as you've discovered gives you an entirely different kind of linker error, but it's simply a different side of the same coin.
The real bug is in the program logic. Somehow, you have done the following (abridged)
---
alias Value ValueView;
alias typeof(Value.init) KeyType;
bool contains(ValueView value) const { ... }
bool contains(KeyType k) const { ... }
---
You should add a constraint to ensure that ValueView != KeyType, or rename the methods so as they don't conflict, such as containsValue() and containsKey().
Comment #6 by ellery-newcomer — 2016-05-29T19:06:41Z
Reducing importance: As explained by Iain, the reported example is invalid D code. DMD should still warn about this.
Additionally, there are cases where DMD passes template symbols multiple times to the backend. I don't have a test case right now, but we added a workaround for this to GDC and GDC will now compile such code. So this is no longer a blocker for GDC.
Comment #8 by razvan.nitu1305 — 2023-06-28T10:02:12Z
I now get a compiler error using the latest version of the compiler for both the reduced example provided in comment 1 (https://issues.dlang.org/show_bug.cgi?id=15324#c1) and for the extra-reduced example provided in comment 5 (https://issues.dlang.org/show_bug.cgi?id=15324#c1). The error is:
test.d(9): Error: function `test.MultiIndexContainer!().MultiIndexContainer.contains(int k)` conflicts with previous declaration at test.d(3)
test.d(17): Error: template instance `test.MultiIndexContainer!()` error instantiating
So the compiler now catches this case. Closing as WORKSFORME.