diff mbox series

[Ada] Spurious error on iterator over container with modified private part

Message ID 20201130141711.GA117778@adacore.com
State New
Headers show
Series [Ada] Spurious error on iterator over container with modified private part | expand

Commit Message

Pierre-Marie de Rodat Nov. 30, 2020, 2:17 p.m. UTC
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


	* 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 mbox series


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