]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
ada: Change 'Size of formal unconstrained discriminated in out parameters
authorEric Botcazou <ebotcazou@adacore.com>
Wed, 10 Dec 2025 20:40:27 +0000 (21:40 +0100)
committerMarc Poulhiès <dkm@gcc.gnu.org>
Fri, 9 Jan 2026 10:57:16 +0000 (11:57 +0100)
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.

gcc/ada/exp_attr.adb

index 8816ec6ea8a2095f5fd4ee33980fcd9f633946b9..03cb02841fdfed0054f91000634f7c2e917c4de3 100644 (file)
@@ -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