This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] DWARF: for variants, produce unsigned discr. when debug type is unsigned
- From: Pierre-Marie de Rodat <derodat at adacore dot com>
- To: gcc-patches at gcc dot gnu dot org
- Cc: Pierre-Marie de Rodat <derodat at adacore dot com>
- Date: Tue, 30 May 2017 11:06:56 +0200
- Subject: [PATCH] DWARF: for variants, produce unsigned discr. when debug type is unsigned
- Authentication-results: sourceware.org; auth=none
Hello,
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.
Bootstrapped and reg-tested on x86_64-linux. Ok to commit? Thanks!
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/debug12.adb: New testcase.
---
gcc/dwarf2out.c | 29 ++++++++++++++++++++++++-----
gcc/testsuite/gnat.dg/debug12.adb | 25 +++++++++++++++++++++++++
2 files changed, 49 insertions(+), 5 deletions(-)
create mode 100644 gcc/testsuite/gnat.dg/debug12.adb
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/gnat.dg/debug12.adb b/gcc/testsuite/gnat.dg/debug12.adb
new file mode 100644
index 00000000000..a3d6d3d266a
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/debug12.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 Debug12 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 Debug12;
--
2.13.0