Bug 4059 – Incorrect C++ name mangling

Status
RESOLVED
Resolution
FIXED
Severity
blocker
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
Other
OS
Linux
Creation time
2010-04-03T14:08:00Z
Last change time
2014-02-15T02:42:13Z
Keywords
link-failure
Assigned to
nobody
Creator
robert

Attachments

IDFilenameSummaryContent-TypeSize
805cppmangle.diffDifftext/plain1351

Comments

Comment #0 by robert — 2010-04-03T14:08:14Z
b.cpp: ---- struct elem { }; void foobar(elem*, elem*) {} ---- a.d: ---- struct elem { } extern(C++)void foobar(elem*, elem*); void main(){ elem *a; foobar(a, a); } ---- Compile with: $ gcc -c b.cpp -ob.o $ dmd a.d b.o This gives linking errors, as dmd does not mangle foobar properly. According to nm, the correct mangle (found in b.cpp) is: _Z6foobarP4elem But dmd mangles it as: _Z6foobarP4elemS_ Again, this is a blocker for ddmd on linux.
Comment #1 by ellery-newcomer — 2010-04-03T14:58:02Z
What version of gcc do you use? with version 4.4.3, I get _Z6foobarP4elemS0_ from nm b.o (as well as a __gxx_personality_v0, which causes more problems) and dmd 1.058 doesn't seem to want to mangle foobar at all.
Comment #2 by robert — 2010-04-03T15:01:50Z
I'm using gcc 4.4.3 too, and dmd 1.x won't mangle it as dmd 1.x does not support C++ name mangling. Even with the mangle you give it doesn't match what dmd outputs.
Comment #3 by 2korden — 2010-04-12T06:02:09Z
Rising the severity as it is indeed a blocker
Comment #4 by robert — 2010-04-23T14:01:13Z
The following patch seems to fix the issue, I haven't tested to see if this breaks mangling in other cases though: --- cppmangle.c 2010-03-18 18:58:06.000000000 +0000 +++ cppmangle.c 2010-04-23 21:59:47.000000000 +0100 @@ -69,11 +69,10 @@ { if (p == components.data[i]) { - /* Sequence is S_, S0_, .., S9_, SA_, ..., SZ_, S10_, ... + /* Sequence is S0_, .., S9_, SA_, ..., SZ_, S10_, ... */ buf->writeByte('S'); - if (i) - writeBase36(buf, i - 1); + writeBase36(buf, i); buf->writeByte('_'); return 1; }
Comment #5 by robert — 2010-04-24T11:24:44Z
It seems there are other cases that this patch breaks, so there's obviously a different way of fixing this.
Comment #6 by luk.wrzosek — 2010-11-03T21:24:34Z
In DMD complex types 'save-points' are created in wrong order. This patch should fix the issue. I believe also that there is much more work needed in c++ mangling. The is no easy way to call external C++ function from DMD when one of its arguments types is long. The equivalent of long from C/C++ in D is int, but it is being mangled differently, so cannot be linked after compilation faze. Index: cppmangle.c =================================================================== --- cppmangle.c (wersja 737) +++ cppmangle.c (kopia robocza) @@ -43,6 +43,10 @@ static Array components; int substitute(OutBuffer *buf, void *p); + + int exist(void *p); + + void store(void *p); }; Array CppMangleState::components; @@ -82,6 +86,23 @@ return 0; } +int CppMangleState::exist(void *p) +{ + for (size_t i = 0; i < components.dim; i++) + { + if (p == components.data[i]) + { + return 1; + } + } + return 0; +} + +void CppMangleState::store(void *p) +{ + components.push(p); +} + void source_name(OutBuffer *buf, Dsymbol *s) { char *name = s->ident->toChars(); @@ -266,19 +287,25 @@ void TypePointer::toCppMangle(OutBuffer *buf, CppMangleState *cms) { - if (!cms->substitute(buf, this)) + if (!cms->exist(this)) { buf->writeByte('P'); next->toCppMangle(buf, cms); + cms->store(this); } + else + cms->substitute(buf, this); } void TypeReference::toCppMangle(OutBuffer *buf, CppMangleState *cms) { - if (!cms->substitute(buf, this)) + if (!cms->exist(this)) { buf->writeByte('R'); next->toCppMangle(buf, cms); + cms->store(this); } + else + cms->substitute(buf, this); }
Comment #7 by doob — 2010-11-04T02:02:34Z
(In reply to comment #6) > In DMD complex types 'save-points' are created in wrong order. This patch > should fix the issue. > I believe also that there is much more work needed in c++ mangling. The is no > easy way to call external C++ function from DMD when one of its arguments types > is long. The equivalent of long from C/C++ in D is int, but it is being mangled > differently, so cannot be linked after compilation faze. The size of long in C/C++ depends on if the system is 64bit or not and what data model is used. To make the explanation short: On Windows long is 32 bits and on Unix-like systems long is 64 bits.
Comment #8 by luk.wrzosek — 2010-11-08T08:44:55Z
AFAIK it is not so general. On my Linux 32bit system long is 32bit.
Comment #9 by luk.wrzosek — 2010-11-08T08:50:17Z
Created attachment 805 Diff
Comment #10 by doob — 2010-11-08T08:53:43Z
(In reply to comment #8) > AFAIK it is not so general. On my Linux 32bit system long is 32bit. Maybe I was unclear but I was referring to 64bit systems. Lets try it once more: 32bit: Windows - "long" will be 32 bits long Unix-like - "long" will be 32 bits long 64bit: Windows - "long" will be 32 bits long Unix-like - "long" will be 64 bits long Again, this is simplified explanation as can be seen in the reference below. For reference: http://en.wikipedia.org/wiki/64-bit - The header is "Specific C-language data models"
Comment #11 by bugzilla — 2010-11-10T01:15:43Z