diff --git a/compiler/src/dmd/dmangle.d b/compiler/src/dmd/dmangle.d index 25794e2c21d1..47c739a4317e 100644 --- a/compiler/src/dmd/dmangle.d +++ b/compiler/src/dmd/dmangle.d @@ -833,6 +833,22 @@ public: printf(" parent = %s %s", s.parent.kind(), s.parent.toChars()); printf("\n"); } + if (s.parent) + { + if (auto m = s.parent.isModule()) + { + if (m.filetype == FileType.c) + { + /* C types at global level get mangled into the __C global namespace + * to get the same mangling regardless of which module it + * is declared in. This works because types are the same if the mangling + * is the same. + */ + mangleIdentifier(Id.ImportC, s); + return; + } + } + } mangleParent(s); if (s.ident) mangleIdentifier(s.ident, s); diff --git a/compiler/src/dmd/frontend.h b/compiler/src/dmd/frontend.h index c6a07ea106a2..080b8479d9b5 100644 --- a/compiler/src/dmd/frontend.h +++ b/compiler/src/dmd/frontend.h @@ -8522,6 +8522,7 @@ struct Id final static Identifier* udaMustUse; static Identifier* TRUE; static Identifier* FALSE; + static Identifier* ImportC; static Identifier* dllimport; static Identifier* dllexport; static Identifier* vector_size; diff --git a/compiler/src/dmd/id.d b/compiler/src/dmd/id.d index d603e5aeb76f..48ca7665eaef 100644 --- a/compiler/src/dmd/id.d +++ b/compiler/src/dmd/id.d @@ -512,6 +512,7 @@ immutable Msgtable[] msgtable = { "wchar_t" }, // for C compiler + { "ImportC", "__C" }, { "__tag" }, { "dllimport" }, { "dllexport" }, diff --git a/compiler/test/compilable/imports/cimports2a.i b/compiler/test/compilable/imports/cimports2a.i index 026e4801e542..c8ff97644c3a 100644 --- a/compiler/test/compilable/imports/cimports2a.i +++ b/compiler/test/compilable/imports/cimports2a.i @@ -1 +1,4 @@ extern int xx; + +typedef struct Foo *FooRef; +FooRef make_foo(void); diff --git a/compiler/test/compilable/imports/cimports2b.i b/compiler/test/compilable/imports/cimports2b.i index 026e4801e542..03b22b2a2163 100644 --- a/compiler/test/compilable/imports/cimports2b.i +++ b/compiler/test/compilable/imports/cimports2b.i @@ -1 +1,4 @@ extern int xx; + +typedef struct Foo *FooRef; +void free_foo(FooRef foo); diff --git a/compiler/test/compilable/test22674.d b/compiler/test/compilable/test22674.d new file mode 100644 index 000000000000..970b43eef5dd --- /dev/null +++ b/compiler/test/compilable/test22674.d @@ -0,0 +1,9 @@ +// https://issues.dlang.org/show_bug.cgi?id=22674 + +import imports.cimports2a; +import imports.cimports2b; + +void do_foo(){ + FooRef f = make_foo(); // use_foo.d(5) + free_foo(f); // use_foo.d(6) +}