diff mbox

DWARF: for variants, produce unsigned discr. when debug type is unsigned

Message ID 20170530090656.29330-1-derodat@adacore.com
State New
Headers show

Commit Message

Pierre-Marie de Rodat May 30, 2017, 9:06 a.m. UTC
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

Comments

Jason Merrill May 31, 2017, 8:34 p.m. UTC | #1
On 05/30/2017 05:06 AM, Pierre-Marie de Rodat wrote:
> 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.

OK.

Jason
Pierre-Marie de Rodat June 1, 2017, 8:37 a.m. UTC | #2
On 05/31/2017 10:34 PM, Jason Merrill wrote:
> OK.
> 
> Jason

Committed. Thank you!
diff mbox

Patch

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;