This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[4.1] Fix PR ada/30684
- From: Eric Botcazou <ebotcazou at adacore dot com>
- To: gcc-patches at gcc dot gnu dot org
- Cc: Laurent GUERBY <laurent at guerby dot net>, Serge Belyshev <belyshev at depni dot sinp dot msu dot ru>
- Date: Wed, 21 Feb 2007 00:57:07 +0100
- Subject: [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