Bug 4237 – Typedefs of the same name cause initializer conflict
Status
RESOLVED
Resolution
FIXED
Severity
normal
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
x86
OS
All
Creation time
2010-05-26T12:35:00Z
Last change time
2014-02-15T02:46:34Z
Keywords
link-failure, patch
Assigned to
nobody
Creator
rsinfu
Comments
Comment #0 by rsinfu — 2010-05-26T12:35:19Z
Typedefs in function scope don't get fully mangled with scope information. As a result, the following code won't link:
-------------------- test.d
struct Struct(T)
{
T value;
}
void main()
{
{
typedef int Number = 1;
Struct!Number s;
pragma(msg, "1: ", typeof(s).mangleof);
}
{
typedef real Number = 2;
Struct!Number s;
pragma(msg, "2: ", typeof(s).mangleof);
}
}
--------------------
On Linux and FreeBSD:
--------------------
1: S4test20__T6StructTT6NumberZ6Struct
2: S4test20__T6StructTT6NumberZ6Struct
test.o(.rodata+0x18): multiple definition of `_Dmain6Number6__initZ'
test.o(.rodata+0x14): first defined here
--------------------
On Windows:
--------------------
1: S4test20__T6StructTT6NumberZ6Struct
2: S4test20__T6StructTT6NumberZ6Struct
OPTLINK (R) for Win32 Release 8.00.2
Copyright (C) Digital Mars 1989-2009 All rights reserved.
http://www.digitalmars.com/ctg/optlink.html
test.obj(test) Offset 0027DH Record Type 0091
Error 1: Previous Definition Different : _Dmain6Number6__initZ
--- errorlevel 1
--------------------
Comment #1 by rsinfu — 2010-05-28T04:51:17Z
Maybe the example in #0 should be error. I filed a separate bug 4245.
Still the problem exists. As shown in the output example below, the two distinct typedefs get mangled to the same name. Then the assertion fails due to the corrupted initial value.
-------------------- test.d
struct Struct(T) { T value; }
void foo()
{
typedef int Number = 1;
Struct!Number s;
pragma(msg, typeof(s).mangleof);
assert(s.value == 1);
}
void bar()
{
typedef real Number = 2;
Struct!Number s;
pragma(msg, typeof(s).mangleof);
assert(s.value == 2); // Assertion failure
}
void main() { foo(); bar(); }
--------------------
% dmd -run test
S4test20__T6StructTT6NumberZ6Struct
S4test20__T6StructTT6NumberZ6Struct
core.exception.AssertError@test(14): Assertion failure
--------------------
Comment #2 by rsinfu — 2010-05-28T04:54:49Z
Here's a trivial patch to dmd svn r502.
--- src/declaration.c
+++ src/declaration.c
@@ -296,6 +296,7 @@ Dsymbol *TypedefDeclaration::syntaxCopy(Dsymbol *s)
void TypedefDeclaration::semantic(Scope *sc)
{
//printf("TypedefDeclaration::semantic(%s) sem = %d\n", toChars(), sem);
+ parent = sc->parent;
if (sem == 0)
{ sem = 1;
basetype = basetype->semantic(loc, sc);
Comment #3 by rsinfu — 2010-05-28T06:02:42Z
The comment #2 patch set ->parent everytime = wrong. This one is better:
--- src/declaration.c
+++ src/declaration.c
@@ -298,6 +298,7 @@ void TypedefDeclaration::semantic(Scope *sc)
//printf("TypedefDeclaration::semantic(%s) sem = %d\n", toChars(), sem);
if (sem == 0)
{ sem = 1;
+ parent = sc->parent;
basetype = basetype->semantic(loc, sc);
sem = 2;
#if DMDV2
Comment #4 by k.hara.pg — 2011-10-10T19:35:56Z
(In reply to comment #3)
> The comment #2 patch set ->parent everytime = wrong. This one is better:
>
> --- src/declaration.c
> +++ src/declaration.c
> @@ -298,6 +298,7 @@ void TypedefDeclaration::semantic(Scope *sc)
> //printf("TypedefDeclaration::semantic(%s) sem = %d\n", toChars(), sem);
> if (sem == 0)
> { sem = 1;
> + parent = sc->parent;
> basetype = basetype->semantic(loc, sc);
> sem = 2;
> #if DMDV2
Pushed as pull request:
https://github.com/D-Programming-Language/dmd/pull/445