This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Fix PR ada/27936
- From: Eric Botcazou <ebotcazou at adacore dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Fri, 17 Nov 2006 16:15:07 +0100
- Subject: 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);
}
}