diff options
author | Tom Tromey <tom@tromey.com> | 2024-04-10 16:49:51 -0600 |
---|---|---|
committer | Tom Tromey <tom@tromey.com> | 2024-05-14 13:28:39 -0600 |
commit | 843d1820007ce64f5a69a64102a6607dcff2ce27 (patch) | |
tree | 76d9ff368240b554fc85aa349a0aa3b65c9e6ea9 | |
parent | 6921816e5ecdf5ef01db2b96a4f744476752332b (diff) | |
download | gdb-843d1820007ce64f5a69a64102a6607dcff2ce27.zip gdb-843d1820007ce64f5a69a64102a6607dcff2ce27.tar.gz gdb-843d1820007ce64f5a69a64102a6607dcff2ce27.tar.bz2 |
Fix C++ name canonicalizations of character literals
The names "void C<(char)1>::m()" and "void C<'\001'>::m()" should
canonicalize to the same string, but currently they do not -- the
former remains unchanged and the latter is transformed to
"void C<(char)'\001'>::m()".
This patch fixes the bug and also adds some unit tests.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=16843
Approved-By: John Baldwin <jhb@FreeBSD.org>
-rw-r--r-- | gdb/cp-name-parser.y | 49 |
1 files changed, 43 insertions, 6 deletions
diff --git a/gdb/cp-name-parser.y b/gdb/cp-name-parser.y index 3bfa88c..e0b34aa 100644 --- a/gdb/cp-name-parser.y +++ b/gdb/cp-name-parser.y @@ -44,6 +44,7 @@ #include "cp-support.h" #include "c-support.h" #include "parser-defs.h" +#include "gdbsupport/selftest.h" #define GDB_YY_REMAP_PREFIX cpname #include "yy-remap.h" @@ -1514,6 +1515,7 @@ yylex (YYSTYPE *lvalp, cpname_state *state) int c; int namelen; const char *tokstart; + char *copy; retry: state->prev_lexptr = state->lexptr; @@ -1544,6 +1546,10 @@ yylex (YYSTYPE *lvalp, cpname_state *state) return ERROR; } + /* We over-allocate here, but it doesn't really matter . */ + copy = (char *) obstack_alloc (&state->demangle_info->obstack, 30); + xsnprintf (copy, 30, "%d", c); + c = *state->lexptr++; if (c != '\'') { @@ -1551,15 +1557,10 @@ yylex (YYSTYPE *lvalp, cpname_state *state) return ERROR; } - /* FIXME: We should refer to a canonical form of the character, - presumably the same one that appears in manglings - the decimal - representation. But if that isn't in our input then we have to - allocate memory for it somewhere. */ lvalp->comp = state->fill_comp (DEMANGLE_COMPONENT_LITERAL, state->make_builtin_type ("char"), - state->make_name (tokstart, - state->lexptr - tokstart)); + state->make_name (copy, strlen (copy))); return INT; @@ -1966,3 +1967,39 @@ cp_demangled_name_to_comp (const char *demangled_name, return result; } + +#if GDB_SELF_TEST + +static void +should_be_the_same (const char *one, const char *two) +{ + gdb::unique_xmalloc_ptr<char> cpone = cp_canonicalize_string (one); + gdb::unique_xmalloc_ptr<char> cptwo = cp_canonicalize_string (two); + + if (cpone != nullptr) + one = cpone.get (); + if (cptwo != nullptr) + two = cptwo.get (); + + SELF_CHECK (strcmp (one, two) == 0); +} + +static void +canonicalize_tests () +{ + should_be_the_same ("short int", "short"); + should_be_the_same ("int short", "short"); + + should_be_the_same ("C<(char) 1>::m()", "C<(char) '\\001'>::m()"); +} + +#endif + +void _initialize_cp_name_parser (); +void +_initialize_cp_name_parser () +{ +#if GDB_SELF_TEST + selftests::register_test ("canonicalize", canonicalize_tests); +#endif +} |