This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Ada] Fix ICE on discriminated record type with -O


The compiler aborts on an aggregate of a record type which contains a private 
discriminated record type with default as a subcomponent, when the unit is 
compiled with optimization.

Tested on x86_64-suse-linux, applied on the mainline.


2017-10-21  Eric Botcazou  <ebotcazou@adacore.com>

	* gcc-interface/utils.c (pad_type_hash): Use hashval_t for hash value.
	(convert): Do not use an unchecked conversion for converting from a
	type to another type padding it.


2017-10-21  Eric Botcazou  <ebotcazou@adacore.com>

	* gnat.dg/specs/discr4.ads: New test.
	* gnat.dg/specs/discr4_pkg.ads: New helper.

-- 
Eric Botcazou
Index: gcc-interface/utils.c
===================================================================
--- gcc-interface/utils.c	(revision 253968)
+++ gcc-interface/utils.c	(working copy)
@@ -101,7 +101,7 @@ static tree handle_vector_type_attribute
 
 /* Fake handler for attributes we don't properly support, typically because
    they'd require dragging a lot of the common-c front-end circuitry.  */
-static tree fake_attribute_handler      (tree *, tree, tree, int, bool *);
+static tree fake_attribute_handler (tree *, tree, tree, int, bool *);
 
 /* Table of machine-independent internal attributes for Ada.  We support
    this minimal set of attributes to accommodate the needs of builtins.  */
@@ -222,8 +222,9 @@ static GTY((deletable)) tree free_block_
 /* A hash table of padded types.  It is modelled on the generic type
    hash table in tree.c, which must thus be used as a reference.  */
 
-struct GTY((for_user)) pad_type_hash {
-  unsigned long hash;
+struct GTY((for_user)) pad_type_hash
+{
+  hashval_t hash;
   tree type;
 };
 
@@ -4249,10 +4250,13 @@ convert (tree type, tree expr)
 	return convert (type, TREE_OPERAND (expr, 0));
 
       /* If the inner type is of self-referential size and the expression type
-	 is a record, do this as an unchecked conversion.  But first pad the
-	 expression if possible to have the same size on both sides.  */
+	 is a record, do this as an unchecked conversion unless both types are
+	 essentially the same.  But first pad the expression if possible to
+	 have the same size on both sides.  */
       if (ecode == RECORD_TYPE
-	  && CONTAINS_PLACEHOLDER_P (DECL_SIZE (TYPE_FIELDS (type))))
+	  && CONTAINS_PLACEHOLDER_P (DECL_SIZE (TYPE_FIELDS (type)))
+	  && TYPE_MAIN_VARIANT (etype)
+	     != TYPE_MAIN_VARIANT (TREE_TYPE (TYPE_FIELDS (type))))
 	{
 	  if (TREE_CODE (TYPE_SIZE (etype)) == INTEGER_CST)
 	    expr = convert (maybe_pad_type (etype, TYPE_SIZE (type), 0, Empty,
-- { dg-do compile }
-- { dg-options "-O" }

with Disc4_Pkg; use Disc4_Pkg;

package Disc4 is

   type Data is record
      Val : Rec;
      Set : Boolean;
   end record;

   type Pair is record
      Lower, Upper : Data;
   end record;

   function Build (L, U : Rec) return Pair is ((L, True), (U, False));

   C1 : constant Pair := Build (Rec_One, Rec_Three);

   C2 : constant Pair := Build (Get (0), Rec_Three);

end Disc4;
package Disc4_Pkg is

   type Enum is (One, Two, Three);

   type Rec is private;

   Rec_One : constant Rec;
   Rec_Three  : constant Rec;

   function Get (Value : Integer) return Rec;

private

   type Rec (D : Enum := Two) is record
      case D is
         when One => null;
         when Two => Value : Integer;
         when Three => null;
      end case;
   end record;

   Rec_One   : constant Rec := (D => One);
   Rec_Three : constant Rec := (D => Three);

   function Get (Value : Integer) return Rec is (Two, Value);

end Disc4_Pkg;

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]