Skip to content

Commit

Permalink
fix Issue 13289 - wchar and dchar C++ mangling is incorrect
Browse files Browse the repository at this point in the history
Conflicts:
	test/runnable/cppa.d
	test/runnable/extra-files/cppb.cpp
  • Loading branch information
dragoon2014 committed Aug 29, 2014
1 parent 1f9abd5 commit cc89ff6
Show file tree
Hide file tree
Showing 3 changed files with 124 additions and 34 deletions.
8 changes: 4 additions & 4 deletions src/cppmangle.c
Expand Up @@ -550,8 +550,8 @@ class CppMangleVisitor : public Visitor
case Tfloat80: c = (Target::realsize - Target::realpad == 16) ? 'g' : 'e'; break;
case Tbool: c = 'b'; break;
case Tchar: c = 'c'; break;
case Twchar: c = 't'; break;
case Tdchar: c = 'w'; break;
case Twchar: c = 't'; break; // unsigned short
case Tdchar: c = 'w'; break; // wchar_t (UTF-32)

case Timaginary32: p = 'G'; c = 'f'; break;
case Timaginary64: p = 'G'; c = 'd'; break;
Expand Down Expand Up @@ -883,7 +883,7 @@ class VisualCPPMangler : public Visitor
case Tfloat64: buf.writeByte('N'); break;
case Tbool: buf.writestring("_N"); break;
case Tchar: buf.writeByte('D'); break;
case Twchar: buf.writeByte('G'); break; // unsigned short
case Tdchar: buf.writeByte('I'); break; // unsigned int

case Tfloat80:
if (flags & IS_DMC)
Expand All @@ -892,7 +892,7 @@ class VisualCPPMangler : public Visitor
buf.writestring("_T"); // Intel long double
break;

case Tdchar:
case Twchar:
if (flags & IS_DMC)
buf.writestring("_Y"); // DigitalMars wchar_t
else
Expand Down
109 changes: 79 additions & 30 deletions test/runnable/cppa.d
Expand Up @@ -340,37 +340,37 @@ void test12825()

extern(C++) class C13161
{
void dummyfunc() {}
long val_5;
uint val_9;
void dummyfunc() {}
long val_5;
uint val_9;
}

extern(C++) class Test : C13161
{
uint val_0;
long val_1;
uint val_0;
long val_1;
}

extern(C++) size_t getoffset13161();

extern(C++) class C13161a
{
void dummyfunc() {}
c_long_double val_5;
uint val_9;
void dummyfunc() {}
c_long_double val_5;
uint val_9;
}

extern(C++) class Testa : C13161a
{
bool val_0;
bool val_0;
}

extern(C++) size_t getoffset13161a();

void test13161()
{
assert(getoffset13161() == Test.val_0.offsetof);
assert(getoffset13161a() == Testa.val_0.offsetof);
assert(getoffset13161() == Test.val_0.offsetof);
assert(getoffset13161a() == Testa.val_0.offsetof);
}

/****************************************/
Expand All @@ -379,32 +379,32 @@ version (linux)
{
extern(C++, __gnu_cxx)
{
struct new_allocator(T)
{
alias size_type = size_t;
void deallocate(T*, size_type);
}
struct new_allocator(T)
{
alias size_type = size_t;
void deallocate(T*, size_type);
}
}
}

extern (C++, std)
{
struct allocator(T)
{
version (linux)
{
alias size_type = size_t;
void deallocate(T* p, size_type sz)
{ (cast(__gnu_cxx.new_allocator!T*)&this).deallocate(p, sz); }
}
version (linux)
{
alias size_type = size_t;
void deallocate(T* p, size_type sz)
{ (cast(__gnu_cxx.new_allocator!T*)&this).deallocate(p, sz); }
}
}

version (linux)
{
class vector(T, A = allocator!T)
{
final void push_back(ref const T);
}
class vector(T, A = allocator!T)
{
final void push_back(ref const T);
}
}
}

Expand All @@ -418,7 +418,7 @@ void test14()
{
version (linux)
{
std.vector!int p;
std.vector!int p;
foo14(p);
}
}
Expand All @@ -427,13 +427,61 @@ version (linux)
{
void test14a(std.allocator!int * pa)
{
pa.deallocate(null, 0);
pa.deallocate(null, 0);
}

void gun(std.vector!int pa)
{
int x = 42;
pa.push_back(x);
int x = 42;
pa.push_back(x);
}
}

void test13289()
{
assert(f13289_cpp_wchar_t('a') == 'A');
assert(f13289_cpp_wchar_t('B') == 'B');
assert(f13289_d_wchar('c') == 'C');
assert(f13289_d_wchar('D') == 'D');
assert(f13289_d_dchar('e') == 'E');
assert(f13289_d_dchar('F') == 'F');
assert(f13289_cpp_test());
}

extern(C++)
{
bool f13289_cpp_test();

version(Posix)
{
dchar f13289_cpp_wchar_t(dchar);
}
else version(Windows)
{
wchar f13289_cpp_wchar_t(wchar);
}

wchar f13289_d_wchar(wchar ch)
{
if (ch <= 'z' && ch >= 'a')
{
return cast(wchar)(ch - ('a' - 'A'));
}
else
{
return ch;
}
}
dchar f13289_d_dchar(dchar ch)
{
if (ch <= 'z' && ch >= 'a')
{
return ch - ('a' - 'A');
}
else
{
return ch;
}
}
}

Expand All @@ -458,6 +506,7 @@ void main()
test12825();
test13161();
test14();
test13289();

printf("Success\n");
}
41 changes: 41 additions & 0 deletions test/runnable/extra-files/cppb.cpp
Expand Up @@ -300,3 +300,44 @@ void foo15()
void foo14(std::vector<int, std::allocator<int> > *p) { }

#endif

/**************************************/

wchar_t f13289_cpp_wchar_t(wchar_t ch)
{
if (ch <= L'z' && ch >= L'a')
{
return ch - (L'a' - L'A');
}
else
{
return ch;
}
}

#if __linux__ || __APPLE__ || __FreeBSD__ || __OpenBSD__ || __sun
unsigned short f13289_d_wchar(unsigned short ch);
wchar_t f13289_d_dchar(wchar_t ch);
#elif _WIN32
wchar_t f13289_d_wchar(wchar_t ch);
unsigned int f13289_d_dchar(unsigned int ch);
#endif

bool f13289_cpp_test()
{
#if __linux__ || __APPLE__ || __FreeBSD__ || __OpenBSD__ || __sun
if (!(f13289_d_wchar((unsigned short)'c') == (unsigned short)'C')) return false;
if (!(f13289_d_wchar((unsigned short)'D') == (unsigned short)'D')) return false;
if (!(f13289_d_dchar(L'e') == L'E')) return false;
if (!(f13289_d_dchar(L'F') == L'F')) return false;
return true;
#elif _WIN32
if (!(f13289_d_wchar(L'c') == L'C')) return false;
if (!(f13289_d_wchar(L'D') == L'D')) return false;
if (!(f13289_d_dchar((unsigned int)'e') == (unsigned int)'E')) return false;
if (!(f13289_d_dchar((unsigned int)'F') == (unsigned int)'F')) return false;
return true;
#else
return false;
#endif
}

0 comments on commit cc89ff6

Please sign in to comment.