Bug 18955 – extern(C++) default struct mangling is overridden when interacting with a `cppmangle = class` template

Status
RESOLVED
Resolution
FIXED
Severity
normal
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
x86_64
OS
Windows
Creation time
2018-06-08T04:29:44Z
Last change time
2018-09-29T16:28:02Z
Keywords
C++, industry
Assigned to
No Owner
Creator
Manu

Comments

Comment #0 by turkeyman — 2018-06-08T04:29:44Z
test.c: ------------------------------------------------ extern (C++, std) { extern (C++) struct char_traits(Char) { } extern (C++, class) struct basic_string(T, Traits, Alloc) { } alias string = basic_string!(char, char_traits!char); } extern (C++) void test(ref const(std.string) str) {} ------------------------------------------------ char_traits has no mangle spec, so it should mangle as struct, and it does... except in this case where it's used an a template argument to basic_string which is mangled as a class, char_traits gets promoted to mangle as a class too, not only in the instantiation of basic_string but even when it appears on its own too. char_traits should mangle as a struct, because that's how it's declared.
Comment #1 by turkeyman — 2018-06-08T04:32:06Z
This symptom is a result of the same logic that causes the related ICE at typesem.d:~1310 I don't understand the logic, perhaps Walter can take a look who understands the intent of that code?
Comment #2 by slavo5150 — 2018-07-12T11:11:20Z
`alias string = basic_string!(char, char_traits!char);` has two template arguments, but `extern (C++, class) struct basic_string(T, Traits, Alloc)` had 3. This results in: Error: template instance `basic_string!(char, char_traits!char)` does not match template declaration I'm not sure what I should be doing to reproduce the problem.
Comment #3 by turkeyman — 2018-07-12T18:45:58Z
I'm sorry. I think I must have cut&paste fail-ed. Remove the `Alloc` arg: ------------------------------- extern (C++, std) { struct char_traits(Char) { } extern (C++, class) struct basic_string(T, Traits) { } alias test_string = basic_string!(char, char_traits!char); } extern (C++) void test(ref const(std.test_string) str) {} pragma(msg, test.mangleof); ------------------------------- Compile that, it will emit: ?test@@YAXAEBV?$basic_string@DV?$char_traits@D@std@@@std@@@Z But it should emit: ?test@@YAXAEBV?$basic_string@DU?$char_traits@D@std@@@std@@@Z Notice the 'V?$char_traits' (class) should be a 'U?$char_traits' (struct); char_traits is a struct. If you add: extern (C++, struct) struct char_traits(Char) ie, tell it explicitly to mangle the struct as a struct, it mangles correctly. Of course, a struct should mangle as a struct naturally though.
Comment #4 by schveiguy — 2018-07-13T17:51:22Z
Saw the name in the D blog, had to fix it... Darn OCD.
Comment #5 by turkeyman — 2018-07-13T18:21:42Z
Not sure what that post means..
Comment #6 by schveiguy — 2018-07-13T18:44:58Z
Sorry, I fixed a typo in the title of the bug report "tamplate".
Comment #7 by slavo5150 — 2018-08-28T13:41:42Z
Comment #8 by github-bugzilla — 2018-09-17T14:07:45Z
Commits pushed to master at https://github.com/dlang/dmd https://github.com/dlang/dmd/commit/768198c87f562de08c3dfb8b1d32ace9287d1617 Fix Issue 18955 - extern(C++) default struct mangling is overridden when interacting with a cppmangle = class template https://github.com/dlang/dmd/commit/51c1138fae497b11f05890413ec9e323d2948bee Merge pull request #8631 from JinShil/fix_18955 Fix Issue 18955 - extern(C++) default struct mangling is overridden when interacting with a cppmangle = class template
Comment #9 by github-bugzilla — 2018-09-29T16:28:02Z
Commits pushed to master at https://github.com/dlang/dmd https://github.com/dlang/dmd/commit/a1a87203a1f01c79a96ffbc1a45cece2fed6501e add test for issue 18955 https://github.com/dlang/dmd/commit/00f4c42c92da7fd590a8edf8dc6c6562fe988fe4 Merge pull request #8708 from rainers/test_18955 add test for issue 18955 merged-on-behalf-of: Petar Kirov <[email protected]>