diff options
author | Eric Botcazou <ebotcazou@adacore.com> | 2008-04-02 10:06:57 +0000 |
---|---|---|
committer | Eric Botcazou <ebotcazou@gcc.gnu.org> | 2008-04-02 10:06:57 +0000 |
commit | bf1e48d172ead219afc6471252f1a7c775999070 (patch) | |
tree | 0324cb22ae6b92906b1821b9193e435d537bf03a /gcc/ada | |
parent | 4846b4355c6f0253228e64ade49b8bf34227d693 (diff) | |
download | gcc-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/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/ada/decl.c | 29 |
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 |