This is a regression present on the mainline and 6 branch: the compiler ICEs 
in the gimplifier on a double renaming with a chain of access types because 
there is a orphaned PLACEHOLDER_EXPR.

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


2016-11-13  Eric Botcazou  <ebotca...@adacore.com>

        * gcc-interface/utils2.c (gnat_protect_expr): Also protect only the
        address if the expression is the component of a dereference.
        Do not use a reference type for the final temporary reference.


2016-11-13  Eric Botcazou  <ebotca...@adacore.com>

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

-- 
Eric Botcazou
Index: gcc-interface/utils2.c
===================================================================
--- gcc-interface/utils2.c	(revision 242334)
+++ gcc-interface/utils2.c	(working copy)
@@ -2586,6 +2586,12 @@ gnat_protect_expr (tree exp)
       return t;
     }
 
+  /* Likewise if we're indirectly referencing part of something.  */
+  if (code == COMPONENT_REF
+      && TREE_CODE (TREE_OPERAND (exp, 0)) == INDIRECT_REF)
+    return build3 (code, type, gnat_protect_expr (TREE_OPERAND (exp, 0)),
+		   TREE_OPERAND (exp, 1), NULL_TREE);
+
   /* If this is a COMPONENT_REF of a fat pointer, save the entire fat pointer.
      This may be more efficient, but will also allow us to more easily find
      the match for the PLACEHOLDER_EXPR.  */
@@ -2605,9 +2611,7 @@ gnat_protect_expr (tree exp)
   /* Otherwise reference, protect the address and dereference.  */
   return
     build_unary_op (INDIRECT_REF, type,
-		    save_expr (build_unary_op (ADDR_EXPR,
-					       build_reference_type (type),
-					       exp)));
+		    save_expr (build_unary_op (ADDR_EXPR, NULL_TREE, exp)));
 }
 
 /* This is equivalent to stabilize_reference_1 in tree.c but we take an extra
-- { dg-do compile }

package body Renaming11 is

   function F (Arg: Ptr3) return Integer is
      V : Ptr1 renames Arg.all.all;
      I : Integer renames V.A(1);
   begin
      return I;
   end;

end Renaming11;
package Renaming11 is

   subtype Index_Type is Integer range 1..10;

   type Arr is array (Index_Type range <>) of Integer;

   type Rec (Min : Index_Type; Max : Index_Type) is record
      A : Arr (Min .. Max);
   end record;

   type Ptr1 is access Rec;

   type Ptr2 is access Ptr1;

   type Ptr3 is access Ptr2;

   function F (Arg : Ptr3) return Integer;

end Renaming11;

Reply via email to