The compiler rejects an element iterator (for .. of) over a container
that extends a predefined container with additional operations in the
private part, when these added operations overload existing
GNAT-specific private operations used to optimize such loops.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

        * exp_ch5.adb (Expand_Iterator_Loop_Over_Container): Check the
        signature of the private operation Get_Element_Access to prevent
        accidental use of a user-defined homonym subprogram.
diff --git a/gcc/ada/exp_ch5.adb b/gcc/ada/exp_ch5.adb
--- a/gcc/ada/exp_ch5.adb
+++ b/gcc/ada/exp_ch5.adb
@@ -4346,10 +4346,21 @@ package body Exp_Ch5 is
             Iter_Pack := Scope (Root_Type (Etype (Iter_Type)));
 
             --  Find declarations needed for "for ... of" optimization
+            --  These declarations come from GNAT sources or sources
+            --  derived from them. User code may include additional
+            --  overloadings with similar names, and we need to perforn
+            --  some reasonable resolution to find the needed primitives.
+            --  It is unclear whether this mechanism is fragile if a user
+            --  makes arbitrary changes to the private part of a package
+            --  that supports iterators.
 
             Ent := First_Entity (Pack);
             while Present (Ent) loop
-               if Chars (Ent) = Name_Get_Element_Access then
+               if Chars (Ent) = Name_Get_Element_Access
+                 and then Present (First_Formal (Ent))
+                 and then Chars (First_Formal (Ent)) = Name_Position
+                 and then No (Next_Formal (First_Formal (Ent)))
+               then
                   Fast_Element_Access_Op := Ent;
 
                elsif Chars (Ent) = Name_Step


Reply via email to