From: Pierre-Marie de Rodat Date: Thu, 1 Jun 2017 08:36:57 +0000 (+0000) Subject: DWARF: for variants, produce unsigned discr. when debug type is unsigned X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=9285616cbd8a079a6a72f07b47880244114ee4b2;p=gcc.git DWARF: for variants, produce unsigned discr. when debug type is unsigned In Ada, the Character type is supposed to be unsigned. However, depending on the sign of C char types, GNAT can materialize it as a signed type for code generation purposes. When this is the case, GNAT also attach a debug type to it so it is represented as an unsigned base type in the debug information. This change adapts record variant parts processing in the DWARF back-end so that when the debug type of discriminant is unsigned while discriminant values are signed themselves, we output unsigned discriminant values in DWARF. gcc/ * dwarf2out.c (get_discr_value): Call the get_debug_type hook on the type of the input discriminant value. Convert the discriminant value of signedness vary. gcc/testsuite/ * gnat.dg/debug11.adb: New testcase. From-SVN: r248773 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b24b239e557..789095ee844 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2017-06-01 Pierre-Marie de Rodat + + * dwarf2out.c (get_discr_value): Call the get_debug_type hook on + the type of the input discriminant value. Convert the + discriminant value of signedness vary. + 2017-06-01 Volker Reichelt * doc/invoke.texi (-Wcatch-value): Document new shortcut. diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index 5ff45eb4efd..7983f52c5ef 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -23701,14 +23701,33 @@ analyze_discr_in_predicate (tree operand, tree struct_type) static bool get_discr_value (tree src, dw_discr_value *dest) { - bool is_unsigned = TYPE_UNSIGNED (TREE_TYPE (src)); + tree discr_type = TREE_TYPE (src); - if (TREE_CODE (src) != INTEGER_CST - || !(is_unsigned ? tree_fits_uhwi_p (src) : tree_fits_shwi_p (src))) + if (lang_hooks.types.get_debug_type) + { + tree debug_type = lang_hooks.types.get_debug_type (discr_type); + if (debug_type != NULL) + discr_type = debug_type; + } + + if (TREE_CODE (src) != INTEGER_CST || !INTEGRAL_TYPE_P (discr_type)) + return false; + + /* Signedness can vary between the original type and the debug type. This + can happen for character types in Ada for instance: the character type + used for code generation can be signed, to be compatible with the C one, + but from a debugger point of view, it must be unsigned. */ + bool is_orig_unsigned = TYPE_UNSIGNED (TREE_TYPE (src)); + bool is_debug_unsigned = TYPE_UNSIGNED (discr_type); + + if (is_orig_unsigned != is_debug_unsigned) + src = fold_convert (discr_type, src); + + if (!(is_debug_unsigned ? tree_fits_uhwi_p (src) : tree_fits_shwi_p (src))) return false; - dest->pos = is_unsigned; - if (is_unsigned) + dest->pos = is_debug_unsigned; + if (is_debug_unsigned) dest->v.uval = tree_to_uhwi (src); else dest->v.sval = tree_to_shwi (src); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 4795d412d47..1390c6a4371 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2017-06-01 Pierre-Marie de Rodat + + * gnat.dg/debug11.adb: New testcase. + 2017-06-01 Richard Biener PR middle-end/66313 diff --git a/gcc/testsuite/gnat.dg/debug11.adb b/gcc/testsuite/gnat.dg/debug11.adb new file mode 100644 index 00000000000..5f60697a536 --- /dev/null +++ b/gcc/testsuite/gnat.dg/debug11.adb @@ -0,0 +1,25 @@ +-- { dg-options "-cargs -O0 -g -dA -fgnat-encodings=minimal -margs" } +-- +-- This testcase checks that in the DWARF description of the variant type +-- below, the C discriminant is properly described as unsigned, hence the 0x5a +-- ('Z') and 0x80 (128) values in the DW_AT_discr_list attribute. If it was +-- described as signed, we would have instead 90 and -128. +-- +-- { dg-final { scan-assembler-times "0x5a.*DW_AT_discr_list" 1 } } +-- { dg-final { scan-assembler-times "0x80.*DW_AT_discr_list" 1 } } + +with Ada.Text_IO; + +procedure Debug11 is + type Rec_Type (C : Character) is record + case C is + when 'Z' .. Character'Val (128) => I : Integer; + when others => null; + end case; + end record; + -- R : Rec_Type := ('Z', 2); + R : Rec_Type ('Z'); +begin + R.I := 0; + Ada.Text_IO.Put_Line ("" & R.C); +end Debug11;