aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@adacore.com>2008-04-02 10:06:57 +0000
committerEric Botcazou <ebotcazou@gcc.gnu.org>2008-04-02 10:06:57 +0000
commitbf1e48d172ead219afc6471252f1a7c775999070 (patch)
tree0324cb22ae6b92906b1821b9193e435d537bf03a /gcc/ada
parent4846b4355c6f0253228e64ade49b8bf34227d693 (diff)
downloadgcc-bf1e48d172ead219afc6471252f1a7c775999070.zip
gcc-bf1e48d172ead219afc6471252f1a7c775999070.tar.gz
gcc-bf1e48d172ead219afc6471252f1a7c775999070.tar.bz2
decl.c (gnat_to_gnu_entity): For a constant object whose type has self-referential size...
* decl.c (gnat_to_gnu_entity) <object>: For a constant object whose type has self-referential size, get the size from the initializing expression directly if it is also a constant whose nominal type has self-referential size. From-SVN: r133831
Diffstat (limited to 'gcc/ada')
-rw-r--r--gcc/ada/ChangeLog7
-rw-r--r--gcc/ada/decl.c29
2 files changed, 31 insertions, 5 deletions
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index c3e49b9..f37efec 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -1,3 +1,10 @@
+2008-04-02 Eric Botcazou <ebotcazou@adacore.com>
+
+ * decl.c (gnat_to_gnu_entity) <object>: For a constant object whose
+ type has self-referential size, get the size from the initializing
+ expression directly if it is also a constant whose nominal type
+ has self-referential size.
+
2008-04-01 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
PR ada/33688
diff --git a/gcc/ada/decl.c b/gcc/ada/decl.c
index 6f92fac..ee9c1c5 100644
--- a/gcc/ada/decl.c
+++ b/gcc/ada/decl.c
@@ -607,15 +607,34 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
initializing expression, in which case we can get the size from
that. Note that the resulting size may still be a variable, so
this may end up with an indirect allocation. */
-
if (No (Renamed_Object (gnat_entity))
&& CONTAINS_PLACEHOLDER_P (TYPE_SIZE (gnu_type)))
{
if (gnu_expr && kind == E_Constant)
- gnu_size
- = SUBSTITUTE_PLACEHOLDER_IN_EXPR
- (TYPE_SIZE (TREE_TYPE (gnu_expr)), gnu_expr);
-
+ {
+ tree size = TYPE_SIZE (TREE_TYPE (gnu_expr));
+ if (CONTAINS_PLACEHOLDER_P (size))
+ {
+ /* If the initializing expression is itself a constant,
+ despite having a nominal type with self-referential
+ size, we can get the size directly from it. */
+ if (TREE_CODE (gnu_expr) == COMPONENT_REF
+ && TREE_CODE (TREE_TYPE (TREE_OPERAND (gnu_expr, 0)))
+ == RECORD_TYPE
+ && TYPE_IS_PADDING_P
+ (TREE_TYPE (TREE_OPERAND (gnu_expr, 0)))
+ && TREE_CODE (TREE_OPERAND (gnu_expr, 0)) == VAR_DECL
+ && (TREE_READONLY (TREE_OPERAND (gnu_expr, 0))
+ || DECL_READONLY_ONCE_ELAB
+ (TREE_OPERAND (gnu_expr, 0))))
+ gnu_size = DECL_SIZE (TREE_OPERAND (gnu_expr, 0));
+ else
+ gnu_size
+ = SUBSTITUTE_PLACEHOLDER_IN_EXPR (size, gnu_expr);
+ }
+ else
+ gnu_size = size;
+ }
/* We may have no GNU_EXPR because No_Initialization is
set even though there's an Expression. */
else if (kind == E_Constant