Skip to content

Commit 517253e

Browse files
committed
fix Issue 18053 - Use stdint.h mangling for int64_t/uint64_t when mangling D long/ulong
1 parent 7114431 commit 517253e

File tree

6 files changed

+47
-30
lines changed

6 files changed

+47
-30
lines changed

changelog/fix18053.dd

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
Fix Issue 18053 - mangle long/ulong as int64_t/uint64_t
2+
3+
This is a breaking change (on OSX 64).
4+
5+
Due to the erratic implementation defined behavior of C++ name mangling, it was
6+
difficult to get D's long/ulong to portably match up with the corresponding
7+
C++ compiler.
8+
9+
By instead relying on how the corresponding C++ compiler mangled int64_t/uint64_t
10+
it makes the C++ side of the D<=>C++ interface much simpler.
11+
12+
For the current platforms dmd supports, only the OSX 64 bit mangling changes. In
13+
this case from 'm' to 'y'.
14+
15+
Note:
16+
int64_t and uint64_t are defined in stdint.h

src/dmd/cppmangle.d

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -815,10 +815,10 @@ public:
815815
case Tuns32: c = 'j'; break;
816816
case Tfloat32: c = 'f'; break;
817817
case Tint64:
818-
c = (Target.c_longsize == 8 ? 'l' : 'x');
818+
c = Target.c_longsize == 8 ? Target.int64Mangle : 'x';
819819
break;
820820
case Tuns64:
821-
c = (Target.c_longsize == 8 ? 'm' : 'y');
821+
c = Target.c_longsize == 8 ? Target.uint64Mangle : 'y';
822822
break;
823823
case Tint128: c = 'n'; break;
824824
case Tuns128: c = 'o'; break;

src/dmd/target.d

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
* Authors: $(LINK2 http://www.digitalmars.com, Walter Bright)
77
* License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
88
* Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/target.d, _target.d)
9+
* Documentation: https://dlang.org/phobos/ddmd_target.html
10+
* Coverage: https://codecov.io/gh/dlang/dmd/src/master/src/ddmd/target.d
911
*/
1012

1113
module dmd.target;
@@ -29,16 +31,21 @@ import dmd.root.outbuffer;
2931
*/
3032
struct Target
3133
{
32-
extern (C++) static __gshared int ptrsize;
33-
extern (C++) static __gshared int realsize; // size a real consumes in memory
34-
extern (C++) static __gshared int realpad; // 'padding' added to the CPU real size to bring it up to realsize
35-
extern (C++) static __gshared int realalignsize; // alignment for reals
36-
extern (C++) static __gshared bool reverseCppOverloads; // with dmc and cl, overloaded functions are grouped and in reverse order
37-
extern (C++) static __gshared bool cppExceptions; // set if catching C++ exceptions is supported
38-
extern (C++) static __gshared int c_longsize; // size of a C 'long' or 'unsigned long' type
39-
extern (C++) static __gshared int c_long_doublesize; // size of a C 'long double'
40-
extern (C++) static __gshared int classinfosize; // size of 'ClassInfo'
41-
extern (C++) static __gshared ulong maxStaticDataSize; // maximum size of static data
34+
extern (C++) __gshared
35+
{
36+
int ptrsize;
37+
int realsize; /// size a real consumes in memory
38+
int realpad; /// 'padding' added to the CPU real size to bring it up to realsize
39+
int realalignsize; /// alignment for reals
40+
bool reverseCppOverloads; /// with dmc and cl, overloaded functions are grouped and in reverse order
41+
bool cppExceptions; /// set if catching C++ exceptions is supported
42+
char int64Mangle; /// mangling character for C++ int64_t
43+
char uint64Mangle; /// mangling character for C++ uint64_t
44+
int c_longsize; /// size of a C 'long' or 'unsigned long' type
45+
int c_long_doublesize; /// size of a C 'long double'
46+
int classinfosize; /// size of 'ClassInfo'
47+
ulong maxStaticDataSize; /// maximum size of static data
48+
}
4249

4350
extern (C++) struct FPTypeProperties(T)
4451
{
@@ -135,6 +142,9 @@ struct Target
135142

136143
cppExceptions = global.params.isLinux || global.params.isFreeBSD ||
137144
global.params.isOSX;
145+
146+
int64Mangle = global.params.isOSX ? 'x' : 'l';
147+
uint64Mangle = global.params.isOSX ? 'y' : 'm';
138148
}
139149

140150
/******************************

src/dmd/target.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ struct Target
3333
static int realalignsize; // alignment for reals
3434
static bool reverseCppOverloads; // with dmc and cl, overloaded functions are grouped and in reverse order
3535
static bool cppExceptions; // set if catching C++ exceptions is supported
36+
static char int64Mangle; // mangling character for C++ int64_t
37+
static char uint64Mangle; // mangling character for C++ uint64_t
3638
static int c_longsize; // size of a C 'long' or 'unsigned long' type
3739
static int c_long_doublesize; // size of a C 'long double'
3840
static int classinfosize; // size of 'ClassInfo'

test/runnable/extra-files/cppb.cpp

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ headers.
3232
#define _GLIBCXX_USE_CXX11_ABI 0
3333

3434
#include <stdio.h>
35+
#include <stdint.h>
3536
#include <assert.h>
3637
#include <exception>
3738
#include <cstdarg>
@@ -567,20 +568,15 @@ Visitor2* getVisitor2()
567568

568569
/******************************************/
569570
// issues detected by fuzzer
570-
#if _LP64
571-
#define longlong long
572-
#else
573-
#define longlong long long
574-
#endif
575571

576-
void fuzz1_checkValues(longlong arg10, longlong arg11, bool arg12);
577-
void fuzz1_cppvararg(longlong arg10, longlong arg11, bool arg12)
572+
void fuzz1_checkValues(int64_t arg10, int64_t arg11, bool arg12);
573+
void fuzz1_cppvararg(int64_t arg10, int64_t arg11, bool arg12)
578574
{
579575
fuzz1_checkValues(arg10, arg11, arg12);
580576
}
581577

582-
void fuzz2_checkValues(unsigned longlong arg10, unsigned longlong arg11, bool arg12);
583-
void fuzz2_cppvararg(unsigned longlong arg10, unsigned longlong arg11, bool arg12)
578+
void fuzz2_checkValues(uint64_t arg10, uint64_t arg11, bool arg12);
579+
void fuzz2_cppvararg(uint64_t arg10, uint64_t arg11, bool arg12)
584580
{
585581
fuzz2_checkValues(arg10, arg11, arg12);
586582
}
@@ -805,7 +801,7 @@ void test15802b()
805801
// 16536 - mangling mismatch on OSX
806802

807803
#if defined(__APPLE__)
808-
__UINTMAX_TYPE__ pass16536(__UINTMAX_TYPE__ a)
804+
uint64_t pass16536(uint64_t a)
809805
{
810806
return a;
811807
}

test/runnable/extra-files/externmangle.cpp

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -194,17 +194,10 @@ int Module::dim(Array<Module*>* arr)
194194
return arr->dim;
195195
}
196196

197-
#if _LP64
198-
unsigned long testlongmangle(int32_t a, uint32_t b, long c, unsigned long d)
197+
uint64_t testlongmangle(int a, unsigned int b, int64_t c, uint64_t d)
199198
{
200199
return a + b + c + d;
201200
}
202-
#else
203-
unsigned long long testlongmangle(int a, unsigned int b, long long c, unsigned long long d)
204-
{
205-
return a + b + c + d;
206-
}
207-
#endif
208201

209202
int test31[2][2][2] = {1, 1, 1, 1, 1, 1, 1, 1};
210203
int *test32 = 0;

0 commit comments

Comments
 (0)