diff --git a/changelog/osx64_long_cppmangling.dd b/changelog/osx64_long_cppmangling.dd new file mode 100644 index 000000000000..7fb47e9ac151 --- /dev/null +++ b/changelog/osx64_long_cppmangling.dd @@ -0,0 +1,11 @@ +64-bit OS X: Revert C++ mangling of `long` to pre-2.079 to restore `size_t` interop + +Direct interop of D `size_t` and C++ `size_t` was working before 2.079, on all platforms +except for 32-bit OS X. By mangling D `long` as C++ `long long` on 64-bit OS X starting +with 2.079, `size_t` interop broke on a more relevant platform. +With new/fixed aliases, e.g., $(REF int64_t, core, stdc, stdint), +$(REF uint64_t, core, stdc, stdint) and $(REF cpp_size_t, core, stdc, config), there are +now proper tools for portable C++ interop wrt. integers. +Reverting to the previous C++ mangling on 64-bit OS X (C++ `long`) may save mixed D/C++ +code bases from the need of manual adaptations by skipping the 2.079 and 2.080 DMD +versions. diff --git a/src/dmd/cppmangle.d b/src/dmd/cppmangle.d index 55a86531194e..32126dbe063c 100644 --- a/src/dmd/cppmangle.d +++ b/src/dmd/cppmangle.d @@ -1179,10 +1179,10 @@ extern(C++): case Tuns32: c = 'j'; break; case Tfloat32: c = 'f'; break; case Tint64: - c = Target.c_longsize == 8 ? Target.int64Mangle : 'x'; + c = Target.c_longsize == 8 ? 'l' : 'x'; break; case Tuns64: - c = Target.c_longsize == 8 ? Target.uint64Mangle : 'y'; + c = Target.c_longsize == 8 ? 'm' : 'y'; break; case Tint128: c = 'n'; break; case Tuns128: c = 'o'; break; diff --git a/src/dmd/target.d b/src/dmd/target.d index 4abed5b3a05a..c6b17f781877 100644 --- a/src/dmd/target.d +++ b/src/dmd/target.d @@ -59,8 +59,6 @@ struct Target // C++ ABI bool reverseCppOverloads; /// set if overloaded functions are grouped and in reverse order (such as in dmc and cl) bool cppExceptions; /// set if catching C++ exceptions is supported - char int64Mangle; /// mangling character for C++ int64_t - char uint64Mangle; /// mangling character for C++ uint64_t bool twoDtorInVtable; /// target C++ ABI puts deleting and non-deleting destructor into vtable } @@ -184,9 +182,6 @@ struct Target cppExceptions = global.params.isLinux || global.params.isFreeBSD || global.params.isDragonFlyBSD || global.params.isOSX; - - int64Mangle = global.params.isOSX ? 'x' : 'l'; - uint64Mangle = global.params.isOSX ? 'y' : 'm'; } /** diff --git a/src/dmd/target.h b/src/dmd/target.h index 0e122de5fd9c..cde7b3ecef5d 100644 --- a/src/dmd/target.h +++ b/src/dmd/target.h @@ -43,8 +43,6 @@ struct Target // C++ ABI static bool reverseCppOverloads; // with dmc and cl, overloaded functions are grouped and in reverse order static bool cppExceptions; // set if catching C++ exceptions is supported - static char int64Mangle; // mangling character for C++ int64_t - static char uint64Mangle; // mangling character for C++ uint64_t static bool twoDtorInVtable; // target C++ ABI puts deleting and non-deleting destructor into vtable template diff --git a/test/runnable/cppa.d b/test/runnable/cppa.d index 3d1a3a1c8305..08b49785fab0 100644 --- a/test/runnable/cppa.d +++ b/test/runnable/cppa.d @@ -4,6 +4,7 @@ import core.stdc.stdio; import core.stdc.stdarg; import core.stdc.config; +import core.stdc.stdint; extern (C++) int foob(int i, int j, int k); @@ -887,13 +888,13 @@ void testVtable() /****************************************/ /* problems detected by fuzzer */ -extern(C++) void fuzz1_cppvararg(long arg10, long arg11, bool arg12); -extern(C++) void fuzz1_dvararg(long arg10, long arg11, bool arg12) +extern(C++) void fuzz1_cppvararg(int64_t arg10, int64_t arg11, bool arg12); +extern(C++) void fuzz1_dvararg(int64_t arg10, int64_t arg11, bool arg12) { fuzz1_checkValues(arg10, arg11, arg12); } -extern(C++) void fuzz1_checkValues(long arg10, long arg11, bool arg12) +extern(C++) void fuzz1_checkValues(int64_t arg10, int64_t arg11, bool arg12) { assert(arg10 == 103); assert(arg11 == 104); @@ -910,13 +911,13 @@ void fuzz1() } //////// -extern(C++) void fuzz2_cppvararg(ulong arg10, ulong arg11, bool arg12); -extern(C++) void fuzz2_dvararg(ulong arg10, ulong arg11, bool arg12) +extern(C++) void fuzz2_cppvararg(uint64_t arg10, uint64_t arg11, bool arg12); +extern(C++) void fuzz2_dvararg(uint64_t arg10, uint64_t arg11, bool arg12) { fuzz2_checkValues(arg10, arg11, arg12); } -extern(C++) void fuzz2_checkValues(ulong arg10, ulong arg11, bool arg12) +extern(C++) void fuzz2_checkValues(uint64_t arg10, uint64_t arg11, bool arg12) { assert(arg10 == 103); assert(arg11 == 104); @@ -1257,7 +1258,7 @@ void test15802() /****************************************/ // 16536 - mangling mismatch on OSX -version(OSX) extern(C++) ulong pass16536(ulong); +version(OSX) extern(C++) uint64_t pass16536(uint64_t); void test16536() { diff --git a/test/runnable/externmangle.d b/test/runnable/externmangle.d index bb2381b113c3..a2477344183c 100644 --- a/test/runnable/externmangle.d +++ b/test/runnable/externmangle.d @@ -1,5 +1,8 @@ // EXTRA_CPP_SOURCES: externmangle.cpp +import core.stdc.config; +import core.stdc.stdint; + extern(C++): struct Foo(X) @@ -122,12 +125,16 @@ interface Module public static int dim(Array!Module*); }; -ulong testlongmangle(int a, uint b, long c, ulong d); - -import core.stdc.config; +uint64_t testlongmangle(int a, uint b, int64_t c, uint64_t d); cpp_ulong testCppLongMangle(cpp_long a, cpp_ulong b); cpp_ulonglong testCppLongLongMangle(cpp_longlong a, cpp_ulonglong b); -cpp_size_t testCppSizeTMangle(cpp_ptrdiff_t a, cpp_size_t b); + +// direct size_t/ptrdiff_t interop is fine except on 32-bit OS X +version (OSX) { version (D_LP64) {} else version = OSX_32; } +version (OSX_32) + cpp_size_t testCppSizeTMangle(cpp_ptrdiff_t a, cpp_size_t b); +else + size_t testCppSizeTMangle(ptrdiff_t a, size_t b); __gshared extern int[2][2][2] test31; __gshared extern int* test32;