Comment #0 by simon.vanbernem — 2020-02-07T12:09:57Z
Minimized Repro:
//--------------------------------------
struct A_Attributes{
int attr;
}
struct A{
@A_Attributes(2)
int a;
@A_Attributes(2)
int b;
}
import std.traits, core.stdc.stdio;
void main(){
static foreach(string field_name; FieldNameTuple!A){{
alias member = __traits(getMember, A, field_name);
void temp(Attribute_Type)(){ printf("hello"); }
static if(hasUDA!(member, A_Attributes)){{ temp!A_Attributes(); }}
}}
}
//--------------------------------------
Compiling this with DMD32 D Compiler v2.087.0 will yield the following error:
test.obj : fatal error LNK1179: Ungültige oder beschädigte Datei: COMDAT "_D4test4mainFZ__T4tempTSQw12A_AttributesZQyMFNbNiZv" doppelt vorhanden.
Error: linker exited with status 1179
(The german means: "invalid or corrupt file: COMDAT -mangled- exists twice")
It gets even weirder: If you comment out one of the lines that say "@A_Attributes(2)" it compiles. If you then uncomment that line again, the code still compiles. No link error. The link error reappears as soon as I delete the files that were built.
Comment #1 by simon.vanbernem — 2020-02-07T12:17:06Z
This only seems to repro with the -m64 compiler switch activated.
Comment #2 by bugzilla — 2021-01-02T10:48:10Z
MS-COFF is alone in not allowing two identical COMDATs from residing in the same object file, which is what is happening here. The two identical COMDATs are still generated for other targets, and the linker helpfully just merges them.
Can't fix the Microsoft linker, so I'll have to find out just why the two COMDATs are being generated and fix it.
Comment #3 by bugzilla — 2021-01-03T09:48:02Z
A simpler demonstration of the problem:
void main()
{
{
int temp(T)() { return 3; }
temp!int();
}
{
int temp(T)() { return 4; }
temp!int();
}
}
which affects all targets. Both functions are generated, the mangled names of the two functions are the same, and on non-MSCOFF targets one of the two functions is picked. Changing this to All platforms.
Comment #4 by bugzilla — 2021-01-03T09:52:34Z
Rewriting the bug example with functions instead of templates, an error is correctly generated:
void main()
{
{
int temp() { return 3; }
temp();
}
{
int temp() { return 4; }
temp(); // Error: declaration test.main.temp is already defined in another scope in main at line 6
}
}
This suggests the obvious fix of extending the check for functions to include template functions.
Comment #5 by dlang-bot — 2021-01-04T08:46:12Z
@WalterBright created dlang/dmd pull request #12095 "fix Issue 20565 - Local template declarations in different scopes pro…" fixing this issue:
- fix Issue 20565 - Local template declarations in different scopes produce uncaught name collisions
https://github.com/dlang/dmd/pull/12095
Comment #6 by dlang-bot — 2021-01-10T10:23:51Z
@WalterBright created dlang/dmd pull request #12119 "Issue 20565 - Local template declarations in different scopes produce…" mentioning this issue:
- Issue 20565 - Local template declarations in different scopes produce uncaught name collisions
https://github.com/dlang/dmd/pull/12119
Comment #7 by dlang-bot — 2021-01-12T11:04:46Z
dlang/dmd pull request #12119 "fix Issue 20565 - Local template declarations in different scopes produce…" was merged into master:
- 96049dc779989d3d27c5fbaf58cc30681a305fa7 by Walter Bright:
fix Issue 20565 - Local template declarations in different scopes produce uncaught name collisions
https://github.com/dlang/dmd/pull/12119
Comment #8 by dlang-bot — 2021-12-06T08:40:30Z
dlang/dlang.org pull request #3124 "spec: abi: add function-local parent symbols to the mangling grammar" was merged into master:
- ece81e055af027041d0e7d765a67b2c7720a4d41 by Luís Ferreira:
spec: abi: add function-local parent symbols to the mangling grammar
Related to the issue #20565.
Signed-off-by: Luís Ferreira <[email protected]>
https://github.com/dlang/dlang.org/pull/3124