From 53e710acd249e1861029b19b7a3d8195e7f28929 Mon Sep 17 00:00:00 2001 From: Pedro Alves Date: Wed, 12 Apr 2017 14:00:49 +0100 Subject: Fix PR c++/21323: GDB thinks char16_t and char32_t are signed in C++ While the C++ standard says that char16_t and char32_t are unsigned types: Types char16_t and char32_t denote distinct types with the same size, signedness, and alignment as uint_least16_t and uint_least32_t, respectively, in , called the underlying types. ... gdb treats them as signed currently: (gdb) p (char16_t)-1 $1 = -1 u'\xffff' There are actually two places in gdb that hardcode these types: - gdbtypes.c:gdbtypes_post_init, when creating the built-in types, seemingly used by the "x /s" command (judging from commit 9a22f0d0). - dwarf2read.c, when reading base types with DW_ATE_UTF encoding (which is what is used for these types, when compiling for C++11 and up). Despite the comment, the type created does end up used. Both places need fixing. But since I couldn't tell why dwarf2read.c needs to create a new type, I've made it use the per-arch built-in types instead, so that the types are only created once per arch instead of once per objfile. That seems to work fine. While writting the test, I noticed that the C++ language parser isn't actually aware of these built-in types, so if you try to use them without a program that uses them, you get: (gdb) set language c++ (gdb) ptype char16_t No symbol table is loaded. Use the "file" command. (gdb) ptype u"hello" No type named char16_t. (gdb) p u"hello" No type named char16_t. That's fixed by simply adding a couple entries to C++'s built-in types array in c-lang.c. With that, we get the expected: (gdb) ptype char16_t type = char16_t (gdb) ptype u"hello" type = char16_t [6] (gdb) p u"hello" $1 = u"hello" gdb/ChangeLog: 2017-04-12 Pedro Alves PR c++/21323 * c-lang.c (cplus_primitive_types) : New enum values. (cplus_language_arch_info): Register cplus_primitive_type_char16_t and cplus_primitive_type_char32_t. * dwarf2read.c (read_base_type) : If bit size is 16 or 32, use the archtecture's built-in type for char16_t and char32_t, respectively. Otherwise, fallback to init_integer_type as before, but make the type unsigned, and issue a complaint. * gdbtypes.c (gdbtypes_post_init): Make char16_t and char32_t unsigned. gdb/testsuite/ChangeLog: 2017-04-12 Pedro Alves PR c++/21323 * gdb.cp/wide_char_types.c: New file. * gdb.cp/wide_char_types.exp: New file. --- gdb/dwarf2read.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) (limited to 'gdb/dwarf2read.c') diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index 966e1ee..e390b32 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -15125,9 +15125,22 @@ read_base_type (struct die_info *die, struct dwarf2_cu *cu) type = init_integer_type (objfile, bits, 1, name); break; case DW_ATE_UTF: - /* We just treat this as an integer and then recognize the - type by name elsewhere. */ - type = init_integer_type (objfile, bits, 0, name); + { + gdbarch *arch = get_objfile_arch (objfile); + + if (bits == 16) + type = builtin_type (arch)->builtin_char16; + else if (bits == 32) + type = builtin_type (arch)->builtin_char32; + else + { + complaint (&symfile_complaints, + _("unsupported DW_ATE_UTF bit size: '%d'"), + bits); + type = init_integer_type (objfile, bits, 1, name); + } + return set_die_type (die, type, cu); + } break; default: -- cgit v1.1