From 5fe90b63d3fe244db24a865a30be1a10c932b728 Mon Sep 17 00:00:00 2001 From: Dennis Korpel Date: Thu, 25 Jan 2024 10:59:45 +0100 Subject: [PATCH] Fix hex strings being printed as regular strings --- compiler/src/dmd/common/outbuffer.d | 27 ++++++++++++++++++++++ compiler/src/dmd/dmangle.d | 9 +------- compiler/src/dmd/hdrgen.d | 10 ++++++++ compiler/test/fail_compilation/fail136.d | 2 +- compiler/test/fail_compilation/hexstring.d | 6 ++--- compiler/test/runnable/literal.d | 4 ++++ 6 files changed, 46 insertions(+), 12 deletions(-) diff --git a/compiler/src/dmd/common/outbuffer.d b/compiler/src/dmd/common/outbuffer.d index cff08ec5d4..cb2439ff74 100644 --- a/compiler/src/dmd/common/outbuffer.d +++ b/compiler/src/dmd/common/outbuffer.d @@ -755,6 +755,25 @@ struct OutBuffer } while (value); } + /** + * Write an array as a string of hexadecimal digits + * Params: + * data = bytes to write + * upperCase = whether to upper case hex digits A-F + */ + void writeHexString(scope const(ubyte)[] data, bool upperCase) pure nothrow @safe + { + auto slice = this.allocate(2 * data.length); + const a = upperCase ? 'A' : 'a'; + foreach (i, c; data) + { + char hi = (c >> 4) & 0xF; + slice[i * 2] = cast(char)(hi < 10 ? hi + '0' : hi - 10 + a); + char lo = c & 0xF; + slice[i * 2 + 1] = cast(char)(lo < 10 ? lo + '0' : lo - 10 + a); + } + } + /** Destructively saves the contents of `this` to `filename`. As an optimization, if the file already has identical contents with the buffer, @@ -943,3 +962,11 @@ unittest else assert(buf[] == "\nabc\n\n"); } + +unittest +{ + OutBuffer buf; + buf.writeHexString([0xAA, 0xBB], false); + buf.writeHexString([0xCC], true); + assert(buf[] == "aabbCC"); +} diff --git a/compiler/src/dmd/dmangle.d b/compiler/src/dmd/dmangle.d index baf05c61fc..5bd1379d17 100644 --- a/compiler/src/dmd/dmangle.d +++ b/compiler/src/dmd/dmangle.d @@ -1004,14 +1004,7 @@ public: buf.writeByte(m); buf.print(q.length); buf.writeByte('_'); // nbytes <= 11 - auto slice = buf.allocate(2 * q.length); - foreach (i, c; q) - { - char hi = (c >> 4) & 0xF; - slice[i * 2] = cast(char)(hi < 10 ? hi + '0' : hi - 10 + 'a'); - char lo = c & 0xF; - slice[i * 2 + 1] = cast(char)(lo < 10 ? lo + '0' : lo - 10 + 'a'); - } + buf.writeHexString(cast(const(ubyte)[]) q, false); } override void visit(ArrayLiteralExp e) diff --git a/compiler/src/dmd/hdrgen.d b/compiler/src/dmd/hdrgen.d index d30aaaef18..030153c91d 100644 --- a/compiler/src/dmd/hdrgen.d +++ b/compiler/src/dmd/hdrgen.d @@ -2276,6 +2276,16 @@ private void expressionPrettyPrint(Expression e, ref OutBuffer buf, ref HdrGenSt void visitString(StringExp e) { + if (e.hexString || e.sz == 8) + { + buf.writeByte('x'); + buf.writeByte('"'); + buf.writeHexString(e.peekData, true); + buf.writeByte('"'); + if (e.postfix) + buf.writeByte(e.postfix); + return; + } buf.writeByte('"'); const o = buf.length; foreach (i; 0 .. e.len) diff --git a/compiler/test/fail_compilation/fail136.d b/compiler/test/fail_compilation/fail136.d index 3bc86537ed..3fa42e6cc8 100644 --- a/compiler/test/fail_compilation/fail136.d +++ b/compiler/test/fail_compilation/fail136.d @@ -1,7 +1,7 @@ /* TEST_OUTPUT: --- -fail_compilation\fail136.d(10): Error: `"\xef\xbb\xbf"` has no effect +fail_compilation/fail136.d(10): Error: `x"EFBBBF"` has no effect --- */ diff --git a/compiler/test/fail_compilation/hexstring.d b/compiler/test/fail_compilation/hexstring.d index 87f00f1dfa..caca3b3e97 100644 --- a/compiler/test/fail_compilation/hexstring.d +++ b/compiler/test/fail_compilation/hexstring.d @@ -2,8 +2,8 @@ TEST_OUTPUT: --- fail_compilation/hexstring.d(29): Error: cannot implicitly convert expression `"123F"` of type `string` to `immutable(ubyte[])` -fail_compilation/hexstring.d(30): Error: cannot implicitly convert expression `"\x12?"c` of type `string` to `immutable(ubyte[])` -fail_compilation/hexstring.d(31): Error: cannot implicitly convert expression `"\x12?"` of type `string` to `immutable(ubyte[])` +fail_compilation/hexstring.d(30): Error: cannot implicitly convert expression `x"123F"c` of type `string` to `immutable(ubyte[])` +fail_compilation/hexstring.d(31): Error: cannot implicitly convert expression `x"123F"` of type `string` to `immutable(ubyte[])` fail_compilation/hexstring.d(33): Error: hex string length 1 must be a multiple of 2 to cast to `immutable(ushort[])` fail_compilation/hexstring.d(34): Error: hex string length 3 must be a multiple of 4 to cast to `immutable(uint[])` fail_compilation/hexstring.d(35): Error: hex string length 5 must be a multiple of 8 to cast to `immutable(ulong[])` @@ -13,7 +13,7 @@ fail_compilation/hexstring.d(37): Error: array cast from `string` to `immutable( fail_compilation/hexstring.d(38): Error: array cast from `string` to `immutable(ushort[])` is not supported at compile time fail_compilation/hexstring.d(39): Error: array cast from `string` to `immutable(uint[])` is not supported at compile time fail_compilation/hexstring.d(39): perhaps remove postfix `c` from hex string -fail_compilation/hexstring.d(28): Error: cannot implicitly convert expression `"\x12?"` of type `string` to `ubyte[]` +fail_compilation/hexstring.d(28): Error: cannot implicitly convert expression `x"123F"` of type `string` to `ubyte[]` --- */ diff --git a/compiler/test/runnable/literal.d b/compiler/test/runnable/literal.d index af2029e904..69971240d9 100644 --- a/compiler/test/runnable/literal.d +++ b/compiler/test/runnable/literal.d @@ -256,6 +256,10 @@ void testHexstring() // Test that mangling of StringExp with size 8 is the same as array literal mangling: void f(immutable ulong[] a)() {} static assert(f!y.mangleof == f!([0x1122334455667788, 0xAABBCCDDEEFF0099]).mangleof); + + // Test printing StringExp with size 8 + enum toStr(immutable ulong[] v) = v.stringof; + static assert(toStr!y == `x"88776655443322119900FFEEDDCCBBAA"`); } /***************************************************/