[Ada] Fix internal error on component of class-wide parameter in instance body

Message ID 20200619082834.GA31388@adacore.com
State New
Headers show
Series
  • [Ada] Fix internal error on component of class-wide parameter in instance body
Related show

Commit Message

Pierre-Marie de Rodat June 19, 2020, 8:28 a.m.
This fixes a Program_Error raised by Analyze_Selected_Component because
it didn't manage to find the proper selector for a selected component
applied to a parameter of class-wide type in an instance body.

The problem is that the tagged type is derived in the private part of
the generic spec from a private tagged type declared in a parent unit,
but this second tagged type is never referenced in the generic body,
so the mechanism implemented to restore the proper views in instances
does not work in this case.

Analyze_Selected_Component already has a specific countermeasure for
tagged types in instance bodies so this extends its usage to this case.

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

2020-06-19  Eric Botcazou  <ebotcazou@adacore.com>

gcc/ada/

	* sem_ch4.adb (Analyze_Selected_Component): In an instance body,
	also invoke Find_Component_In_Instance on the parent subtype of
	a derived tagged type immediately visible.  Remove obsolete case.

Patch

--- gcc/ada/sem_ch4.adb
+++ gcc/ada/sem_ch4.adb
@@ -5268,25 +5268,21 @@  package body Sem_Ch4 is
                   end loop;
 
                --  Another special case: the type is an extension of a private
-               --  type T, is an actual in an instance, and we are in the body
-               --  of the instance, so the generic body had a full view of the
-               --  type declaration for T or of some ancestor that defines the
-               --  component in question.
+               --  type T, either is an actual in an instance or is immediately
+               --  visible, and we are in the body of the instance, which means
+               --  the generic body had a full view of the type declaration for
+               --  T or some ancestor that defines the component in question.
+               --  This happens because Is_Visible_Component returned False on
+               --  this component, as T or the ancestor is still private since
+               --  the Has_Private_View mechanism is bypassed because T or the
+               --  ancestor is not directly referenced in the generic body.
 
                elsif Is_Derived_Type (Type_To_Use)
-                 and then Used_As_Generic_Actual (Type_To_Use)
+                 and then (Used_As_Generic_Actual (Type_To_Use)
+                            or else Is_Immediately_Visible (Type_To_Use))
                  and then In_Instance_Body
                then
                   Find_Component_In_Instance (Parent_Subtype (Type_To_Use));
-
-               --  In ASIS mode the generic parent type may be absent. Examine
-               --  the parent type directly for a component that may have been
-               --  visible in a parent generic unit.
-               --  ??? Revisit now that ASIS mode is gone
-
-               elsif Is_Derived_Type (Prefix_Type) then
-                  Par := Etype (Prefix_Type);
-                  Find_Component_In_Instance (Par);
                end if;
             end;