From: Eric Botcazou <[email protected]>
When the discriminated type is declared with default discriminants, it is
definite, so objects of the type can be declared without constraints, are
thus unconstrained, and are allocated with the maximum size by GNAT.
When these objects are passed as actuals of formal in out parameters, it
makes sense for the 'Size computed for them from within the subprogram to
also be the above "unconstrained" size instead of the "constrained" size
computed from the value of the discriminants present in them.
gcc/ada/ChangeLog:
* exp_attr.adb (Expand_Size_Attribute): If the attribute is applied
to a formal parameter allocated with an extra Constrained parameter,
use the value of the latter to choose between the "unconstrained" or
the "constrained" size of the formal parameter.
Tested on x86_64-pc-linux-gnu (before the recent bootstrap breakage), committed
on master.
---
gcc/ada/exp_attr.adb | 23 ++++++++++++++++++++++-
1 file changed, 22 insertions(+), 1 deletion(-)
diff --git a/gcc/ada/exp_attr.adb b/gcc/ada/exp_attr.adb
index 8816ec6ea8a..03cb02841fd 100644
--- a/gcc/ada/exp_attr.adb
+++ b/gcc/ada/exp_attr.adb
@@ -8960,7 +8960,7 @@ package body Exp_Attr is
then
Set_Actual_Designated_Subtype (Pref, Get_Actual_Subtype (Pref));
- -- If Size was applied to a slice of a bit-packed array, we rewrite
+ -- If Size is applied to a slice of a bit-packed array, we rewrite
-- it into the product of Length and Component_Size. We need to do so
-- because bit-packed arrays are represented internally as arrays of
-- System.Unsigned_Types.Packed_Byte for code generation purposes so
@@ -8976,6 +8976,27 @@ package body Exp_Attr is
Prefix => Duplicate_Subexpr (Pref, Name_Req => True),
Attribute_Name => Name_Component_Size)));
Analyze_And_Resolve (N, Typ);
+
+ -- If Size is applied to a formal parameter that has got a dynamic
+ -- indication of its constrained status, return the "constrained"
+ -- size if the status is True, that is to say the size based on the
+ -- constraints of the actual, and the "unconstrained" size if the
+ -- status is False, that is to say the Object_Size of the type.
+
+ elsif Is_Entity_Name (Pref)
+ and then Is_Formal (Entity (Pref))
+ and then Present (Extra_Constrained (Entity (Pref)))
+ then
+ Rewrite (N,
+ Make_If_Expression (Loc,
+ Expressions => New_List (
+ New_Occurrence_Of (Extra_Constrained (Entity (Pref)), Loc),
+ Relocate_Node (N),
+ Make_Attribute_Reference (Loc,
+ Prefix => New_Occurrence_Of (Etype (Pref), Loc),
+ Attribute_Name => Name_Object_Size))));
+ Set_Analyzed (Next (First (Expressions (N))));
+ Analyze_And_Resolve (N, Typ);
end if;
-- Apply the required checks last, after rewriting has taken place
--
2.51.0