aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Tromey <tromey@adacore.com>2025-07-03 12:35:11 -0600
committerTom Tromey <tromey@adacore.com>2025-07-07 08:52:09 -0600
commit0a082f5cf8a5e42b7c947b377c117ec3451dcce8 (patch)
tree786ddbde32807985d456c3e6473266962d0438db
parent392f8c40f0d3d9cbd4ee38d94bde06cf1b845e9f (diff)
downloadbinutils-0a082f5cf8a5e42b7c947b377c117ec3451dcce8.zip
binutils-0a082f5cf8a5e42b7c947b377c117ec3451dcce8.tar.gz
binutils-0a082f5cf8a5e42b7c947b377c117ec3451dcce8.tar.bz2
Correctly handle L'\\'
Hannes filed a bug that pointed out that: print L'\\' ... did not work correctly. The bug is in convert_escape, which simply transcribes the backslash character, rather than convert it between encodings. This patch fixes the error. I also turned a macro into a lambda to clean up this code a little. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=33124 Reviewed-By: Tom de Vries <tdevries@suse.de> Tested-By: Hannes Domani <ssbssa@yahoo.de>
-rw-r--r--gdb/c-lang.c26
-rw-r--r--gdb/testsuite/gdb.base/wchar.exp4
2 files changed, 19 insertions, 11 deletions
diff --git a/gdb/c-lang.c b/gdb/c-lang.c
index f052401..9fccc1f 100644
--- a/gdb/c-lang.c
+++ b/gdb/c-lang.c
@@ -484,13 +484,6 @@ convert_hex (struct type *type, const char *p,
return p;
}
-#define ADVANCE \
- do { \
- ++p; \
- if (p == limit) \
- error (_("Malformed escape sequence")); \
- } while (0)
-
/* Convert an escape sequence to a target format. TYPE is the target
character type to use, and DEST_CHARSET is the name of the target
character set. The backslash of the escape sequence is at *P, and
@@ -502,18 +495,29 @@ static const char *
convert_escape (struct type *type, const char *dest_charset,
const char *p, const char *limit, struct obstack *output)
{
+ auto advance = [&] ()
+ {
+ ++p;
+ if (p == limit)
+ error (_("Malformed escape sequence"));
+ };
+
/* Skip the backslash. */
- ADVANCE;
+ advance ();
switch (*p)
{
case '\\':
- obstack_1grow (output, '\\');
+ /* Convert the backslash itself. This is probably overkill but
+ it doesn't hurt to do the full conversion. */
+ convert_between_encodings (host_charset (), dest_charset,
+ (const gdb_byte *) p, 1, 1,
+ output, translit_none);
++p;
break;
case 'x':
- ADVANCE;
+ advance ();
if (!ISXDIGIT (*p))
error (_("\\x used with no following hex digits."));
p = convert_hex (type, p, limit, output);
@@ -535,7 +539,7 @@ convert_escape (struct type *type, const char *dest_charset,
{
int length = *p == 'u' ? 4 : 8;
- ADVANCE;
+ advance ();
if (!ISXDIGIT (*p))
error (_("\\u used with no following hex digits"));
p = convert_ucn (p, limit, dest_charset, output, length);
diff --git a/gdb/testsuite/gdb.base/wchar.exp b/gdb/testsuite/gdb.base/wchar.exp
index 70f738c..7f09e81 100644
--- a/gdb/testsuite/gdb.base/wchar.exp
+++ b/gdb/testsuite/gdb.base/wchar.exp
@@ -72,3 +72,7 @@ gdb_test "print repeat_p" "= $hex L\"A$cent$cent\"\.\.\." \
# From PR cli/14977, but here because it requires wchar_t.
gdb_test "printf \"%ls\\n\", 0" "\\(null\\)"
+
+# From PR exp/33124 - a bug when converting escapes.
+set result [string_to_regexp {L'\\'}]
+gdb_test "print L'\\\\'" " = $decimal $result"