From 9d0862343a5ceea2e63be12a29b8a525428f093b Mon Sep 17 00:00:00 2001 From: Jacob Carlborg Date: Wed, 27 Dec 2017 01:07:49 +0100 Subject: [PATCH] Fix Issue 19050 - Fix invalid characters in mangling Running the DMD test suite with a compiler compiled in debug mode fails due to invalid characters, `-`, exist in the mangled names of some unittest blocks. This fix centralizes the validation of mangled characters and properly replaces `-` in the mangled names of unittest blocks with `_`. --- src/dmd/dmangle.d | 36 ++++++++++++++++++++++++++++++------ src/dmd/dsymbolsem.d | 3 ++- 2 files changed, 32 insertions(+), 7 deletions(-) diff --git a/src/dmd/dmangle.d b/src/dmd/dmangle.d index 1ba23c11e5c6..9833dbb3eba9 100644 --- a/src/dmd/dmangle.d +++ b/src/dmd/dmangle.d @@ -591,12 +591,8 @@ public: assert(slice.length); foreach (const char c; slice) { - assert(c == '_' || - c == '@' || - c == '?' || - c == '$' || - isalnum(c) || - c & 0x80); + assert(c.isValidMangling, "The mangled name '" ~ slice ~ "' " ~ + "contains an invalid character: " ~ c); } } } @@ -1101,6 +1097,34 @@ public: } } +/// Returns: `true` if the given character is a valid mangled character +package bool isValidMangling(dchar c) +{ + return + c >= 'A' && c <= 'Z' || + c >= 'a' && c <= 'z' || + c >= '0' && c <= '9' || + c != 0 && strchr("$%().:?@[]_", c); +} + +// valid mangled characters +unittest +{ + assert('a'.isValidMangling); + assert('B'.isValidMangling); + assert('2'.isValidMangling); + assert('@'.isValidMangling); + assert('_'.isValidMangling); +} + +// invalid mangled characters +unittest +{ + assert(!'-'.isValidMangling); + assert(!0.isValidMangling); + assert(!'/'.isValidMangling); + assert(!'\\'.isValidMangling); +} /****************************************************************************** * Returns exact mangled name of function. diff --git a/src/dmd/dsymbolsem.d b/src/dmd/dsymbolsem.d index ecf54d901751..0cac3692d82c 100644 --- a/src/dmd/dsymbolsem.d +++ b/src/dmd/dsymbolsem.d @@ -28,6 +28,7 @@ import dmd.declaration; import dmd.denum; import dmd.dimport; import dmd.dinterpret; +import dmd.dmangle; import dmd.dmodule; import dmd.dscope; import dmd.dstruct; @@ -1744,7 +1745,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor dchar c = p[i]; if (c < 0x80) { - if (c >= 'A' && c <= 'Z' || c >= 'a' && c <= 'z' || c >= '0' && c <= '9' || c != 0 && strchr("$%().:?@[]_", c)) + if (c.isValidMangling) { ++i; continue;