This is a regression present on the mainline.  The compiler aborts on the 
element of an array whose index is an enumeration type with representation 
clause and whose component contains a small discriminated type with default 
discriminant, because of a spurious SAVE_EXPR created by gigi.

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


2016-02-17  Eric Botcazou  <ebotca...@adacore.com>

        * gcc-interface/utils2.c (gnat_protect_expr): Make a SAVE_EXPR only
        for fat pointer or scalar types.


2016-02-17  Eric Botcazou  <ebotca...@adacore.com>

        * gnat.dg/discr46.ad[sb]: New test.

-- 
Eric Botcazou
Index: gcc-interface/utils2.c
===================================================================
--- gcc-interface/utils2.c	(revision 233448)
+++ gcc-interface/utils2.c	(working copy)
@@ -2559,12 +2559,11 @@ gnat_protect_expr (tree exp)
     return build3 (code, type, gnat_protect_expr (TREE_OPERAND (exp, 0)),
 		   TREE_OPERAND (exp, 1), TREE_OPERAND (exp, 2));
 
-  /* If this is a fat pointer or something that can be placed in a register,
-     just make a SAVE_EXPR.  Likewise for a CALL_EXPR as large objects are
-     returned via invisible reference in most ABIs so the temporary will
-     directly be filled by the callee.  */
+  /* If this is a fat pointer or a scalar, just make a SAVE_EXPR.  Likewise
+     for a CALL_EXPR as large objects are returned via invisible reference
+     in most ABIs so the temporary will directly be filled by the callee.  */
   if (TYPE_IS_FAT_POINTER_P (type)
-      || TYPE_MODE (type) != BLKmode
+      || !AGGREGATE_TYPE_P (type)
       || code == CALL_EXPR)
     return save_expr (exp);
 
-- { dg-do compile }

package body Discr46 is

   function F (Id : Enum) return Integer is
      Node : Integer := 0;
   begin
      if A (Id).R.D = True then
         Node := A (Id).R.T;
      end if;
      return Node;
   end; 

end Discr46;
package Discr46 is

   type Enum is (One, Two, Three);
   for Enum use (One => 1, Two => 2, Three => 3);

   type Rec1 (D : Boolean := False) is record
      case D is
         when False => null;
         when True => T : Integer;
      end case;
   end record;

   type Rec2 is record
      R : Rec1;
      C : Character;
   end record;

   type Arr is array (Enum) of Rec2;

   A : Arr; 

   function F (Id : Enum) return Integer;  

end Discr46;

Reply via email to