[Ada] Internal error on volatile array with VFA component

Message ID 3994059.azMvNnZEZJ@polaris
State New
Headers show
Series
  • [Ada] Internal error on volatile array with VFA component
Related show

Commit Message

Eric Botcazou Sept. 9, 2017, 12:09 p.m.
It's caused by a mode mismatch between variants of the same type.

Tested on x86_64-suse-linux, applied on the mainline and 7 branch.


2017-09-09  Eric Botcazou  <ebotcazou@adacore.com>

	* gcc-interface/decl.c (gnat_to_gnu_entity): Only set theTYPE_ALIGN_OK
	and TYPE_BY_REFERENCE_P flags on types after various promotions.
	* gcc-interface/trans.c (node_has_volatile_full_access)<N_Identifier>:
	Consider all kinds of entities.


2017-09-09  Eric Botcazou  <ebotcazou@adacore.com>

	* gnat.dg/specs/vfa.ads: Rename into...
	* gnat.dg/specs/vfa1.ads: ...this.
	* gnat.dg/specs/vfa2.ads: New test.

Patch

Index: gcc-interface/decl.c
===================================================================
--- gcc-interface/decl.c	(revision 251906)
+++ gcc-interface/decl.c	(working copy)
@@ -4277,18 +4277,6 @@  gnat_to_gnu_entity (Entity_Id gnat_entit
 	 already defined so we cannot pass true for IN_PLACE here.  */
       process_attributes (&gnu_type, &attr_list, false, gnat_entity);
 
-      /* Tell the middle-end that objects of tagged types are guaranteed to
-	 be properly aligned.  This is necessary because conversions to the
-	 class-wide type are translated into conversions to the root type,
-	 which can be less aligned than some of its derived types.  */
-      if (Is_Tagged_Type (gnat_entity)
-	  || Is_Class_Wide_Equivalent_Type (gnat_entity))
-	TYPE_ALIGN_OK (gnu_type) = 1;
-
-      /* Record whether the type is passed by reference.  */
-      if (!VOID_TYPE_P (gnu_type) && Is_By_Reference_Type (gnat_entity))
-	TYPE_BY_REFERENCE_P (gnu_type) = 1;
-
       /* ??? Don't set the size for a String_Literal since it is either
 	 confirming or we don't handle it properly (if the low bound is
 	 non-constant).  */
@@ -4498,17 +4486,29 @@  gnat_to_gnu_entity (Entity_Id gnat_entit
       /* If this is not an unconstrained array type, set some flags.  */
       if (TREE_CODE (gnu_type) != UNCONSTRAINED_ARRAY_TYPE)
 	{
+	  /* Tell the middle-end that objects of tagged types are guaranteed to
+	     be properly aligned.  This is necessary because conversions to the
+	     class-wide type are translated into conversions to the root type,
+	     which can be less aligned than some of its derived types.  */
+	  if (Is_Tagged_Type (gnat_entity)
+	      || Is_Class_Wide_Equivalent_Type (gnat_entity))
+	    TYPE_ALIGN_OK (gnu_type) = 1;
+
+	  /* Record whether the type is passed by reference.  */
+	  if (Is_By_Reference_Type (gnat_entity) && !VOID_TYPE_P (gnu_type))
+	    TYPE_BY_REFERENCE_P (gnu_type) = 1;
+
+	  /* Record whether an alignment clause was specified.  */
 	  if (Present (Alignment_Clause (gnat_entity)))
 	    TYPE_USER_ALIGN (gnu_type) = 1;
 
+	  /* Record whether a pragma Universal_Aliasing was specified.  */
 	  if (Universal_Aliasing (gnat_entity) && !TYPE_IS_DUMMY_P (gnu_type))
 	    TYPE_UNIVERSAL_ALIASING_P (gnu_type) = 1;
 
 	  /* If it is passed by reference, force BLKmode to ensure that
 	     objects of this type will always be put in memory.  */
-	  if (TYPE_MODE (gnu_type) != BLKmode
-	      && AGGREGATE_TYPE_P (gnu_type)
-	      && TYPE_BY_REFERENCE_P (gnu_type))
+	  if (AGGREGATE_TYPE_P (gnu_type) && TYPE_BY_REFERENCE_P (gnu_type))
 	    SET_TYPE_MODE (gnu_type, BLKmode);
 	}
 
Index: gcc-interface/trans.c
===================================================================
--- gcc-interface/trans.c	(revision 251906)
+++ gcc-interface/trans.c	(working copy)
@@ -4075,8 +4075,6 @@  node_has_volatile_full_access (Node_Id g
     case N_Identifier:
     case N_Expanded_Name:
       gnat_entity = Entity (gnat_node);
-      if (Ekind (gnat_entity) != E_Variable)
-	break;
       return Is_Volatile_Full_Access (gnat_entity)
 	     || Is_Volatile_Full_Access (Etype (gnat_entity));