https://gcc.gnu.org/g:cdbd7946acc884901c06ec40162e47923d941f12

commit r16-2412-gcdbd7946acc884901c06ec40162e47923d941f12
Author: Gary Dismukes <dismu...@adacore.com>
Date:   Mon Jul 7 20:59:18 2025 +0000

    ada: Additional condition for Capacity discriminant on bounded container 
aggregates
    
    This change test an additional condition as part of the criteria used
    for deciding whether to generate a call to a container type's Length
    function (for passing to the Empty function) when determining the
    size of the object to allocate for a bounded container aggregate
    with a "for of" iterator.
    
    An update is also made to function Empty in 
Ada.Containers.Bounded_Hash_Maps,
    adding a default to the formal Capacity, to make it consistent with other
    bounded containers (and to make it conformant with the Ada RM).
    
    gcc/ada/ChangeLog:
    
            * libgnat/a-cbhama.ads (Empty): Add missing default to Capacity 
formal.
            * libgnat/a-cbhama.adb (Empty): Add missing default to Capacity 
formal.
            * exp_aggr.adb (Build_Size_Expr): Test for presence of Capacity
            discriminant as additional criterion for generating the call to
            the Length function. Update comments.

Diff:
---
 gcc/ada/exp_aggr.adb         | 42 +++++++++++++++++++++++++++---------------
 gcc/ada/libgnat/a-cbhama.adb |  2 +-
 gcc/ada/libgnat/a-cbhama.ads |  2 +-
 3 files changed, 29 insertions(+), 17 deletions(-)

diff --git a/gcc/ada/exp_aggr.adb b/gcc/ada/exp_aggr.adb
index 987db2a5d813..9458bdea6633 100644
--- a/gcc/ada/exp_aggr.adb
+++ b/gcc/ada/exp_aggr.adb
@@ -6874,6 +6874,7 @@ package body Exp_Aggr is
                  and then not Is_Class_Wide_Type (It_Subt)
                then
                   declare
+                     Aggr_Base    : constant Entity_Id := Base_Type (Typ);
                      It_Base      : constant Entity_Id := Base_Type (It_Subt);
                      Empty_Formal : constant Entity_Id :=
                                       First_Formal (Entity (Empty_Subp));
@@ -6886,16 +6887,27 @@ package body Exp_Aggr is
                      --  generally have a Length function. User-defined
                      --  containers don't necessarily have such a function,
                      --  or it may be named differently, or it may have
-                     --  the wrong semantics. The base subtype is tested,
-                     --  since its Sloc will refer to the original container
-                     --  generic in the predefined library, even though it's
-                     --  declared in a package instantiation within the current
-                     --  library unit. Also, this is only done when Empty_Subp
-                     --  has a formal parameter (usually named Capacity), and
-                     --  not in the case of a parameterless Empty function.
-
-                     if In_Predefined_Unit (It_Base)
-                       and then Present (Empty_Formal)
+                     --  the wrong semantics. The base subtypes are tested,
+                     --  since their Sloc will refer to the original container
+                     --  generics in the predefined library, even though the
+                     --  types are declared in a package instantiation in some
+                     --  other unit. Also, this is only done when Empty_Subp
+                     --  has a formal parameter (generally named Capacity),
+                     --  and not in the case of a parameterless Empty function.
+                     --  Finally, we test for the container aggregate's type
+                     --  having a first discriminant with the name Capacity,
+                     --  since determining capacity via Length is only sensible
+                     --  for container types with that discriminant (bounded
+                     --  containers).
+
+                     if Present (Empty_Formal)
+                       and then In_Predefined_Unit (It_Base)
+                       and then In_Predefined_Unit (Aggr_Base)
+                       and then Has_Discriminants (Aggr_Base)
+                       and then
+                         Get_Name_String
+                           (Chars (First_Discriminant (Aggr_Base)))
+                           = "capacity"
                      then
                         --  Look for the container type's Length function in
                         --  the package where it's defined.
@@ -6907,11 +6919,11 @@ package body Exp_Aggr is
                         Pop_Scope;
 
                         --  If we found a Length function that has a single
-                        --  parameter of the container type, then expand a call
-                        --  to that, passing the container object named in the
-                        --  iterator_specification, and return that call, which
-                        --  will be used as the "size" of the current aggregate
-                        --  element association.
+                        --  parameter of the iterator object's container type,
+                        --  then expand a call to that, passing the object,
+                        --  and return that call, which will be used as the
+                        --  "size" of the current element association of the
+                        --  bounded container aggregate.
 
                         if Present (Length_Subp)
                           and then Ekind (Length_Subp) = E_Function
diff --git a/gcc/ada/libgnat/a-cbhama.adb b/gcc/ada/libgnat/a-cbhama.adb
index ee6584dc3b10..b2d796446fdd 100644
--- a/gcc/ada/libgnat/a-cbhama.adb
+++ b/gcc/ada/libgnat/a-cbhama.adb
@@ -368,7 +368,7 @@ is
    -- Empty --
    -----------
 
-   function Empty (Capacity : Count_Type) return Map is
+   function Empty (Capacity : Count_Type := 10) return Map is
    begin
       return Result : Map (Capacity, 0) do
          null;
diff --git a/gcc/ada/libgnat/a-cbhama.ads b/gcc/ada/libgnat/a-cbhama.ads
index 6ffc8157e85f..c741b404da4d 100644
--- a/gcc/ada/libgnat/a-cbhama.ads
+++ b/gcc/ada/libgnat/a-cbhama.ads
@@ -71,7 +71,7 @@ is
    --  Map objects declared without an initialization expression are
    --  initialized to the value Empty_Map.
 
-   function Empty (Capacity : Count_Type) return Map;
+   function Empty (Capacity : Count_Type := 10) return Map;
 
    No_Element : constant Cursor;
    --  Cursor objects declared without an initialization expression are

Reply via email to