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]

Fix PR ada/27936


This is the Ada bootstrap failure on alpha-*-*, a regression on mainline and 
4.2 branch.

On the Alpha architecture, the compiler attempts to guarantee atomic access by
default to standalone objects of integral type.  This means that it will 
create padding record types whose purpose is to force sufficient alignment to 
achieve atomic access, if the object has not already the required alignment.
The compiler was considering that such objects wrapped in a padding record can
never be statically elaborated, thus causing artificial dynamic elaborations
for mere boolean variables.

Bootstrapped/regtested on alpha-dec-osf5.1b and i586-suse-linux, applied to 
mainline and 4.2 branch.


2006-11-17  Eric Botcazou  <ebotcazou@adacore.com>

	PR ada/27936
	* trans.c (add_decl_expr): Do not dynamically elaborate padded objects
	if the initializer takes into account the padding.


-- 
Eric Botcazou
Index: trans.c
===================================================================
RCS file: /gnat.dev/cvs/Dev/gnat/trans.c,v
retrieving revision 1.68.2.138.2.35
diff -u -p -r1.68.2.138.2.35 trans.c
--- trans.c	24 Oct 2006 00:05:01 -0000	1.68.2.138.2.35
+++ trans.c	26 Oct 2006 13:23:33 -0000
@@ -4539,7 +4539,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
@@ -4547,7 +4548,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;
 
   gnu_stmt = build1 (DECL_EXPR, void_type_node, gnu_decl);
@@ -4572,45 +4573,32 @@ add_decl_expr (tree gnu_decl, Entity_Id 
   else
     add_stmt_with_node (gnu_stmt, gnat_entity);
 
-  /* 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) = NULL_TREE;
-	  if (TREE_READONLY (gnu_decl))
-	    {
-	      TREE_READONLY (gnu_decl) = 0;
-	      DECL_READONLY_ONCE_ELAB (gnu_decl) = 1;
-	    }
-	  annotate_with_locus (gnu_assign_stmt,
-			       DECL_SOURCE_LOCATION (gnu_decl));
-	  add_stmt (gnu_assign_stmt);
+      DECL_INITIAL (gnu_decl) = NULL_TREE;
+      if (TREE_READONLY (gnu_decl))
+	{
+	  TREE_READONLY (gnu_decl) = 0;
+	  DECL_READONLY_ONCE_ELAB (gnu_decl) = 1;
 	}
+
+      add_stmt_with_node (gnu_stmt, gnat_entity);
     }
 }
 

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