Because of some quite complex expressions with variable size that outsmart the 
unsharing mechanism.  Fixed by being smarter earlier.

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


2011-09-11  Eric Botcazou  <ebotca...@adacore.com>

        * gcc-interface/utils.c (maybe_unconstrained_array): In the reference
        to unconstrained array case, deal with each branch of a COND_EXPR.
        * gcc-interface/utils2.c (build_allocator): Deal with each branch of
        a COND_EXPR in the initializer, if present.


2011-09-11  Eric Botcazou  <ebotca...@adacore.com>

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


-- 
Eric Botcazou
-- { dg-do compile }
-- { dg-options "-gnat12" }

package body Cond_Expr2 is

  function F (X : integer) return String is
  begin
    return (if X > 0 then "positive" else "negative");
  end;

end Cond_Expr2;
package Cond_Expr2 is

  function F (X : integer) return String;

end Cond_Expr2;
Index: gcc-interface/utils.c
===================================================================
--- gcc-interface/utils.c	(revision 178757)
+++ gcc-interface/utils.c	(working copy)
@@ -4241,22 +4241,44 @@ tree
 maybe_unconstrained_array (tree exp)
 {
   enum tree_code code = TREE_CODE (exp);
-  tree new_exp;
 
   switch (TREE_CODE (TREE_TYPE (exp)))
     {
     case UNCONSTRAINED_ARRAY_TYPE:
       if (code == UNCONSTRAINED_ARRAY_REF)
 	{
-	  new_exp = TREE_OPERAND (exp, 0);
-	  new_exp
-	    = build_unary_op (INDIRECT_REF, NULL_TREE,
-			      build_component_ref (new_exp, NULL_TREE,
-						   TYPE_FIELDS
-						   (TREE_TYPE (new_exp)),
-						   false));
-	  TREE_READONLY (new_exp) = TREE_READONLY (exp);
-	  return new_exp;
+	  const bool read_only = TREE_READONLY (exp);
+	  exp = TREE_OPERAND (exp, 0);
+	  if (TREE_CODE (exp) == COND_EXPR)
+	    {
+	      tree op1
+		= build_unary_op (INDIRECT_REF, NULL_TREE,
+				  build_component_ref (TREE_OPERAND (exp, 1),
+						       NULL_TREE,
+						       TYPE_FIELDS
+						       (TREE_TYPE (exp)),
+						       false));
+	      tree op2
+		= build_unary_op (INDIRECT_REF, NULL_TREE,
+				  build_component_ref (TREE_OPERAND (exp, 2),
+						       NULL_TREE,
+						       TYPE_FIELDS
+						       (TREE_TYPE (exp)),
+						       false));
+
+	      exp = build3 (COND_EXPR,
+			    TREE_TYPE (TREE_TYPE (TYPE_FIELDS
+					          (TREE_TYPE (exp)))),
+			    TREE_OPERAND (exp, 0), op1, op2);
+	    }
+	  else
+	    exp = build_unary_op (INDIRECT_REF, NULL_TREE,
+				  build_component_ref (exp, NULL_TREE,
+						       TYPE_FIELDS
+						       (TREE_TYPE (exp)),
+						       false));
+	  TREE_READONLY (exp) = read_only;
+	  return exp;
 	}
 
       else if (code == NULL_EXPR)
@@ -4270,7 +4292,8 @@ maybe_unconstrained_array (tree exp)
 	 it contains a template.  */
       if (TYPE_PADDING_P (TREE_TYPE (exp)))
 	{
-	  new_exp = convert (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (exp))), exp);
+	  tree new_exp
+	    = convert (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (exp))), exp);
 	  if (TREE_CODE (TREE_TYPE (new_exp)) == RECORD_TYPE
 	      && TYPE_CONTAINS_TEMPLATE_P (TREE_TYPE (new_exp)))
 	    return
Index: gcc-interface/utils2.c
===================================================================
--- gcc-interface/utils2.c	(revision 178762)
+++ gcc-interface/utils2.c	(working copy)
@@ -2046,6 +2046,16 @@ build_allocator (tree type, tree init, t
   if (init && TREE_CODE (init) == NULL_EXPR)
     return build1 (NULL_EXPR, result_type, TREE_OPERAND (init, 0));
 
+  /* If the initializer, if present, is a COND_EXPR, deal with each branch.  */
+  else if (init && TREE_CODE (init) == COND_EXPR)
+    return build3 (COND_EXPR, result_type, TREE_OPERAND (init, 0),
+		   build_allocator (type, TREE_OPERAND (init, 1), result_type,
+				    gnat_proc, gnat_pool, gnat_node,
+				    ignore_init_type),
+		   build_allocator (type, TREE_OPERAND (init, 2), result_type,
+				    gnat_proc, gnat_pool, gnat_node,
+				    ignore_init_type));
+
   /* If RESULT_TYPE is a fat or thin pointer, set SIZE to be the sum of the
      sizes of the object and its template.  Allocate the whole thing and
      fill in the parts that are known.  */

Reply via email to