diff mbox series

[Ada] Fix crash on instantiation of Vectors package at -O3

Message ID 4034715.75IqBAYnSB@polaris
State New
Headers show
Series [Ada] Fix crash on instantiation of Vectors package at -O3 | expand

Commit Message

Eric Botcazou June 2, 2018, 10:52 a.m. UTC
This is a regression present on the mainline, 8 and 7 branches.  It's a latent 
tree sharing issue exposed by the use of SSA names during gimplification that 
has been introduced in the GCC 7 development phase.

Fixed thusly, tested on x86-64/Linux, applied on mainline, 8 and 7 branches.


2018-06-02  Eric Botcazou  <ebotcazou@adacore.com>

	* gcc-interface/ada-tree.h (TYPE_PADDING_FOR_COMPONENT): New macro.
	* gcc-interface/decl.c (gnat_to_gnu_component_type): Cache the padding
	type built for an aliased component with variable size.


2018-06-02  Eric Botcazou  <ebotcazou@adacore.com>

	* gnat.dg/specs/opt3.ads: New test.
	* gnat.dg/specs/opt3_pkg.ads: New helper.
diff mbox series

Patch

Index: gcc-interface/ada-tree.h
===================================================================
--- gcc-interface/ada-tree.h	(revision 261101)
+++ gcc-interface/ada-tree.h	(working copy)
@@ -6,7 +6,7 @@ 
  *                                                                          *
  *                              C Header File                               *
  *                                                                          *
- *          Copyright (C) 1992-2017, Free Software Foundation, Inc.         *
+ *          Copyright (C) 1992-2018, Free Software Foundation, Inc.         *
  *                                                                          *
  * GNAT is free software;  you can  redistribute it  and/or modify it under *
  * terms of the  GNU General Public License as published  by the Free Soft- *
@@ -235,6 +235,11 @@  do {							 \
    refer to the routine gnat_to_gnu_entity.  */
 #define TYPE_CI_CO_LIST(NODE) TYPE_LANG_SLOT_1 (FUNCTION_TYPE_CHECK (NODE))
 
+/* For an ARRAY_TYPE with variable size, this is the padding type built for
+   the array type when it is itself the component type of another array.  */
+#define TYPE_PADDING_FOR_COMPONENT(NODE) \
+  (TYPE_LANG_SLOT_1 (ARRAY_TYPE_CHECK (NODE)))
+
 /* For a VECTOR_TYPE, this is the representative array type.  */
 #define TYPE_REPRESENTATIVE_ARRAY(NODE) \
   TYPE_LANG_SLOT_1 (VECTOR_TYPE_CHECK (NODE))
Index: gcc-interface/decl.c
===================================================================
--- gcc-interface/decl.c	(revision 261101)
+++ gcc-interface/decl.c	(working copy)
@@ -5031,17 +5031,6 @@  gnat_to_gnu_component_type (Entity_Id gn
 		     Is_Bit_Packed_Array (gnat_array) ? TYPE_DECL : VAR_DECL,
 		     true, Has_Component_Size_Clause (gnat_array));
 
-  /* If the array has aliased components and the component size can be zero,
-     force at least unit size to ensure that the components have distinct
-     addresses.  */
-  if (!gnu_comp_size
-      && Has_Aliased_Components (gnat_array)
-      && (integer_zerop (TYPE_SIZE (gnu_type))
-	  || (TREE_CODE (gnu_type) == ARRAY_TYPE
-	      && !TREE_CONSTANT (TYPE_SIZE (gnu_type)))))
-    gnu_comp_size
-      = size_binop (MAX_EXPR, TYPE_SIZE (gnu_type), bitsize_unit_node);
-
   /* If the component type is a RECORD_TYPE that has a self-referential size,
      then use the maximum size for the component size.  */
   if (!gnu_comp_size
@@ -5049,6 +5038,13 @@  gnat_to_gnu_component_type (Entity_Id gn
       && CONTAINS_PLACEHOLDER_P (TYPE_SIZE (gnu_type)))
     gnu_comp_size = max_size (TYPE_SIZE (gnu_type), true);
 
+  /* If the array has aliased components and the component size is zero, force
+     the unit size to ensure that the components have distinct addresses.  */
+  if (!gnu_comp_size
+      && Has_Aliased_Components (gnat_array)
+      && integer_zerop (TYPE_SIZE (gnu_type)))
+    gnu_comp_size = bitsize_unit_node;
+
   /* Honor the component size.  This is not needed for bit-packed arrays.  */
   if (gnu_comp_size && !Is_Bit_Packed_Array (gnat_array))
     {
@@ -5071,6 +5067,30 @@  gnat_to_gnu_component_type (Entity_Id gn
 			  gnat_array);
     }
 
+  /* This is a very special case where the array has aliased components and the
+     component size might be zero at run time.  As explained above, we force at
+     least the unit size but we don't want to build a distinct padding type for
+     each invocation (they are not canonicalized if they have variable size) so
+     we cache this special padding type as TYPE_PADDING_FOR_COMPONENT.  */
+  else if (Has_Aliased_Components (gnat_array)
+	   && TREE_CODE (gnu_type) == ARRAY_TYPE
+	   && !TREE_CONSTANT (TYPE_SIZE (gnu_type)))
+    {
+      if (TYPE_PADDING_FOR_COMPONENT (gnu_type))
+	gnu_type = TYPE_PADDING_FOR_COMPONENT (gnu_type);
+      else
+	{
+	  gnu_comp_size
+	    = size_binop (MAX_EXPR, TYPE_SIZE (gnu_type), bitsize_unit_node);
+	  TYPE_PADDING_FOR_COMPONENT (gnu_type)
+	    = maybe_pad_type (gnu_type, gnu_comp_size, 0, gnat_array,
+			      true, false, definition, true);
+	  gnu_type = TYPE_PADDING_FOR_COMPONENT (gnu_type);
+	  create_type_decl (TYPE_NAME (gnu_type), gnu_type, true, debug_info_p,
+			    gnat_array);
+	}
+    }
+
   if (Has_Atomic_Components (gnat_array) || Is_Atomic_Or_VFA (gnat_type))
     check_ok_for_atomic_type (gnu_type, gnat_array, true);