DWARF: for variants, produce unsigned discr. when debug type is unsigned
authorPierre-Marie de Rodat <derodat@adacore.com>
Thu, 1 Jun 2017 08:36:57 +0000 (08:36 +0000)
committerPierre-Marie de Rodat <pmderodat@gcc.gnu.org>
Thu, 1 Jun 2017 08:36:57 +0000 (08:36 +0000)
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

gcc/ChangeLog
gcc/dwarf2out.c
gcc/testsuite/ChangeLog
gcc/testsuite/gnat.dg/debug11.adb [new file with mode: 0644]

index b24b239e5572fc8b8b13980082a487c7ce65f4aa..789095ee8448f1d0b55d40c72f641410ac9c3224 100644 (file)
@@ -1,3 +1,9 @@
+2017-06-01  Pierre-Marie de Rodat  <derodat@adacore.com>
+
+       * 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  <v.reichelt@netcologne.de>
 
        * doc/invoke.texi (-Wcatch-value): Document new shortcut.
index 5ff45eb4efdc611ec38621fcb4872e4c227d7b1f..7983f52c5efff88a4d6bfd913f7fb368cde5ef94 100644 (file)
@@ -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);
index 4795d412d4735fc2d644a2c2ae290a24e55e9c12..1390c6a4371ea982deb01cbc1bf72c180426a02d 100644 (file)
@@ -1,3 +1,7 @@
+2017-06-01  Pierre-Marie de Rodat  <derodat@adacore.com>
+
+       * gnat.dg/debug11.adb: New testcase.
+
 2017-06-01  Richard Biener  <rguenther@suse.de>
 
        PR middle-end/66313
diff --git a/gcc/testsuite/gnat.dg/debug11.adb b/gcc/testsuite/gnat.dg/debug11.adb
new file mode 100644 (file)
index 0000000..5f60697
--- /dev/null
@@ -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;