From bf1e48d172ead219afc6471252f1a7c775999070 Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Wed, 2 Apr 2008 10:06:57 +0000 Subject: [PATCH] decl.c (gnat_to_gnu_entity): For a constant object whose type has self-referential size... * decl.c (gnat_to_gnu_entity) : 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 --- gcc/ada/ChangeLog | 7 ++++++ gcc/ada/decl.c | 29 ++++++++++++++++++---- gcc/testsuite/ChangeLog | 4 +++ .../gnat.dg/specs/discr_record_constant.ads | 22 ++++++++++++++++ 4 files changed, 57 insertions(+), 5 deletions(-) create mode 100644 gcc/testsuite/gnat.dg/specs/discr_record_constant.ads diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index c3e49b92727..f37efec39a9 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,10 @@ +2008-04-02 Eric Botcazou + + * decl.c (gnat_to_gnu_entity) : 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 PR ada/33688 diff --git a/gcc/ada/decl.c b/gcc/ada/decl.c index 6f92fac5428..ee9c1c58cde 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 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index c7b5920e9ad..873e2b76705 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2008-04-02 Eric Botcazou + + * gnat.dg/specs/discr_record_constant.ads: New test. + 2008-04-02 Richard Guenther * gcc.dg/tree-ssa/vrp38.c: New testcase. diff --git a/gcc/testsuite/gnat.dg/specs/discr_record_constant.ads b/gcc/testsuite/gnat.dg/specs/discr_record_constant.ads new file mode 100644 index 00000000000..f43b1386909 --- /dev/null +++ b/gcc/testsuite/gnat.dg/specs/discr_record_constant.ads @@ -0,0 +1,22 @@ +-- { dg-do compile } + +pragma Restrictions (No_Implicit_Heap_Allocations); + +package Discr_Record_Constant is + + type T (Big : Boolean := False) is record + case Big is + when True => + Content : Integer; + when False => + null; + end case; + end record; + + D : constant T := (True, 0); + + Var : T := D; -- OK, maximum size + Con : constant T := D; -- Violation of restriction + Ter : constant T := Con; -- Violation of restriction + +end Discr_Record_Constant; -- 2.11.4.GIT