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  <ebotca...@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  <ebotca...@adacore.com>

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

-- 
Eric Botcazou
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));
 
-- { dg-do compile }
-- { dg-options "-O" }

package VFA2 is

   type Bit is mod 2**1
     with Size => 1;
   type UInt2 is mod 2**2
     with Size => 2;
   type UInt22 is mod 2**22
     with Size => 22;

   type MODE_ENUM is
     (
      Function_0_Default,
      Function_1,
      Function_2,
      Function_3,
      Function_4,
      Function_5,
      Function_6,
      Function_7)
     with Size => 3;

   type EPD_ENUM is
     (
      Disable_Pull_Down,
      Enable_Pull_Down)
     with Size => 1;

   type EPUN_ENUM is
     (
      Enable_Pull_Up,
      Disable_Pull_Up)
     with Size => 1;

   type EHS_ENUM is
     (
      Slow_Low_Noise_With,
      Fast_Medium_Noise_W)
     with Size => 1;

   type EZI_ENUM is
     (
      Disable_Input_Buffer,
      Enable_Input_Buffer)
     with Size => 1;

   type ZIF_ENUM is
     (
      Enable_Input_Glitch,
      Disable_Input_Glitch)
     with Size => 1;

   type EHD_ENUM is
     (
      Normal_Drive_4_Ma_D,
      Medium_Drive_8_Ma_D,
      High_Drive_14_Ma_Dr,
      Ultra_High_Drive_20)
     with Size => 2;

   type Pin_Type is (Normal_Drive, High_Drive, High_Speed);

   type SFS_Register(Pin : Pin_Type := Normal_Drive) is record
      MODE     : MODE_ENUM;
      EPD      : EPD_ENUM;
      EPUN     : EPUN_ENUM;
      EZI      : EZI_ENUM;
      ZIF      : ZIF_ENUM;
      RESERVED : UInt22;

      case Pin is
         when Normal_Drive =>

            ND_EHS_RESERVED : Bit;
            ND_EHD_RESERVED : UInt2;

         when High_Drive =>

            EHD : EHD_ENUM;
            HD_EHS_RESERVED : Bit;

         when High_Speed =>
            EHS    : EHS_ENUM;
            HS_EHD_RESERVED : UInt2;

      end case;
   end record
     with Unchecked_Union, Size => 32, Volatile_Full_Access;

   for SFS_Register use record
      MODE            at 0 range 0 .. 2;
      EPD             at 0 range 3 .. 3;
      EPUN            at 0 range 4 .. 4;
      ND_EHS_RESERVED at 0 range 5 .. 5;
      HD_EHS_RESERVED at 0 range 5 .. 5;
      EHS             at 0 range 5 .. 5;
      EZI             at 0 range 6 .. 6;
      ZIF             at 0 range 7 .. 7;
      ND_EHD_RESERVED at 0 range 8 .. 9;
      EHD             at 0 range 8 .. 9;
      HS_EHD_RESERVED at 0 range 8 .. 9;
      RESERVED        at 0 range 10 .. 31;
   end record;

   type Normal_Drive_Pins is array (Integer range <>)
     of SFS_Register(Normal_Drive) with Volatile;

end VFA2;

Reply via email to