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