This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[4.1] Fix PR ada/30684


This should fix the bootstrap failure with GCC 4.1.x on Alpha.

Bootstrapped/regtested on i586-suse-linux and manually tested on Alpha/Tru64, 
applied to 4.1 branch.


2007-02-20  Eric Botcazou  <ebotcazou@adacore.com>

	PR ada/30684
	Backport from 4.2 branch:
	2006-11-17  Eric Botcazou  <ebotcazou@adacore.com>

	* ada-tree.h (DECL_READONLY_ONCE_ELAB): New macro.
	* decl.c (elaborate_expression_1): Test the DECL_READONLY_ONCE_ELAB
	flag in addition to TREE_READONLY to assert the constantness of
	variables for elaboration purposes.
	* trans.c (add_decl_expr): Do not dynamically elaborate padded objects
	if the initializer takes into account the padding.
	Set DECL_READONLY_ONCE_ELAB flag on variables originally TREE_READONLY
	but whose elaboration cannot be performed statically.


-- 
Eric Botcazou
Index: trans.c
===================================================================
--- trans.c	(revision 121990)
+++ trans.c	(working copy)
@@ -4315,7 +4315,8 @@ add_stmt_with_node (tree gnu_stmt, Node_
 void
 add_decl_expr (tree gnu_decl, Entity_Id gnat_entity)
 {
-  tree gnu_stmt;
+  tree type = TREE_TYPE (gnu_decl);
+  tree gnu_stmt, gnu_init, gnu_lhs;
 
   /* If this is a variable that Gigi is to ignore, we may have been given
      an ERROR_MARK.  So test for it.  We also might have been given a
@@ -4323,7 +4324,7 @@ add_decl_expr (tree gnu_decl, Entity_Id 
      ignore a TYPE_DECL for an UNCONSTRAINED_ARRAY_TYPE.  */
   if (!DECL_P (gnu_decl)
       || (TREE_CODE (gnu_decl) == TYPE_DECL
-	  && TREE_CODE (TREE_TYPE (gnu_decl)) == UNCONSTRAINED_ARRAY_TYPE))
+	  && TREE_CODE (type) == UNCONSTRAINED_ARRAY_TYPE))
     return;
 
   /* If we are global, we don't want to actually output the DECL_EXPR for
@@ -4345,41 +4346,32 @@ add_decl_expr (tree gnu_decl, Entity_Id 
 	}
     }
 
-  /* If this is a DECL_EXPR for a variable with DECL_INITIAL set,
-     there are two cases we need to handle here.  */
-  if (TREE_CODE (gnu_decl) == VAR_DECL && DECL_INITIAL (gnu_decl))
-    {
-      tree gnu_init = DECL_INITIAL (gnu_decl);
-      tree gnu_lhs = NULL_TREE;
-
-      /* If this is a DECL_EXPR for a variable with DECL_INITIAL set
-	 and decl has a padded type, convert it to the unpadded type so the
-	 assignment is done properly.  */
-      if (TREE_CODE (TREE_TYPE (gnu_decl)) == RECORD_TYPE
-	  && TYPE_IS_PADDING_P (TREE_TYPE (gnu_decl)))
-	gnu_lhs
-	  = convert (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (gnu_decl))), gnu_decl);
-
-      /* Otherwise, if this is going into memory and the initializer isn't
-	 valid for the assembler and loader.  Gimplification could do this,
-	 but would be run too late if -fno-unit-at-a-time.  */
-      else if (TREE_STATIC (gnu_decl)
-	       && !initializer_constant_valid_p (gnu_init,
-						 TREE_TYPE (gnu_decl)))
+  /* If this is a variable and an initializer is attached to it, it must be
+     valid for the context.  Similar to init_const in create_var_decl_1.  */ 
+  if (TREE_CODE (gnu_decl) == VAR_DECL
+      && (gnu_init = DECL_INITIAL (gnu_decl)) != NULL_TREE
+      && (TYPE_MAIN_VARIANT (type) != TYPE_MAIN_VARIANT (TREE_TYPE (gnu_init))
+	  || (TREE_STATIC (gnu_decl)
+	      && !initializer_constant_valid_p (gnu_init,
+						TREE_TYPE (gnu_init)))))
+    {
+      /* If GNU_DECL has a padded type, convert it to the unpadded
+	 type so the assignment is done properly.  */
+      if (TREE_CODE (type) == RECORD_TYPE && TYPE_IS_PADDING_P (type))
+	gnu_lhs = convert (TREE_TYPE (TYPE_FIELDS (type)), gnu_decl);
+      else
 	gnu_lhs = gnu_decl;
 
-      if (gnu_lhs)
-	{
-	  tree gnu_assign_stmt
-	    = build_binary_op (MODIFY_EXPR, NULL_TREE,
-			       gnu_lhs, DECL_INITIAL (gnu_decl));
+      gnu_stmt = build_binary_op (MODIFY_EXPR, NULL_TREE, gnu_lhs, gnu_init);
 
-	  DECL_INITIAL (gnu_decl) = 0;
+      DECL_INITIAL (gnu_decl) = NULL_TREE;
+      if (TREE_READONLY (gnu_decl))
+	{
 	  TREE_READONLY (gnu_decl) = 0;
-	  annotate_with_locus (gnu_assign_stmt,
-			       DECL_SOURCE_LOCATION (gnu_decl));
-	  add_stmt (gnu_assign_stmt);
+	  DECL_READONLY_ONCE_ELAB (gnu_decl) = 1;
 	}
+
+      add_stmt_with_node (gnu_stmt, gnat_entity);
     }
 }
 
Index: ada-tree.h
===================================================================
--- ada-tree.h	(revision 121990)
+++ ada-tree.h	(working copy)
@@ -235,6 +235,10 @@ struct lang_type GTY(()) {tree t; };
    discriminant.  */
 #define DECL_STUBBED_P(NODE) DECL_LANG_FLAG_0 (FUNCTION_DECL_CHECK (NODE))
 
+/* Nonzero in a VAR_DECL if it is guaranteed to be constant after having
+   been elaborated and TREE_READONLY is not set on it.  */
+#define DECL_READONLY_ONCE_ELAB(NODE) DECL_LANG_FLAG_0 (VAR_DECL_CHECK (NODE))
+
 /* Nonzero if this decl is always used by reference; i.e., an INDIRECT_REF
    is needed to access the object.  */
 #define DECL_BY_REF_P(NODE) DECL_LANG_FLAG_1 (NODE)
Index: decl.c
===================================================================
--- decl.c	(revision 121990)
+++ decl.c	(working copy)
@@ -4732,7 +4732,8 @@ elaborate_expression_1 (Node_Id gnat_exp
 
   expr_variable = (!CONSTANT_CLASS_P (gnu_expr)
 		   && !(TREE_CODE (gnu_inner_expr) == VAR_DECL
-			&& TREE_READONLY (gnu_inner_expr))
+			&& (TREE_READONLY (gnu_inner_expr)
+			    || DECL_READONLY_ONCE_ELAB (gnu_inner_expr)))
 		   && !CONTAINS_PLACEHOLDER_P (gnu_expr));
 
   /* If this is a static expression or contains a discriminant, we don't

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]