Skip to content

Commit 8836210

Browse files
author
Eric Botcazou
committed
Ada: Fix incorrect legality check in instantiation of child generic unit
The problem arises when the generic unit has a formal access type parameter, because the manual resolution implemented in Find_Actual_Type does not pick the correct entity for the designated type. The fix replaces it with a bona fide resolution and cleans up the associated code in the callers. gcc/ada/ PR ada/18453 * sem_ch12.adb (Find_Actual_Type): Add Typ_Ref parameter and perform a standard resolution on it in the fallback case. Call Get_Instance_Of if the type is declared in a formal of the child unit. (Instantiate_Type.Validate_Access_Type_Instance): Adjust call to Find_Actual_Type. (Instantiate_Type.Validate_Array_Type_Instance): Likewise and streamline the check for matching component subtypes. gcc/testsuite/ * gnat.dg/specs/generic_inst9.ads: New test. * gnat.dg/specs/generic_inst9_pkg1.ads: New helper. * gnat.dg/specs/generic_inst9_pkg2.ads: Likewise. * gnat.dg/specs/generic_inst9_pkg2-g.ads: Likewise.
1 parent 4cad566 commit 8836210

File tree

5 files changed

+82
-70
lines changed

5 files changed

+82
-70
lines changed

gcc/ada/sem_ch12.adb

Lines changed: 46 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -642,8 +642,9 @@ package body Sem_Ch12 is
642642
-- of freeze nodes for instance bodies that may depend on other instances.
643643

644644
function Find_Actual_Type
645-
(Typ : Entity_Id;
646-
Gen_Type : Entity_Id) return Entity_Id;
645+
(Typ : Entity_Id;
646+
Gen_Type : Entity_Id;
647+
Typ_Ref : Node_Id) return Entity_Id;
647648
-- When validating the actual types of a child instance, check whether
648649
-- the formal is a formal type of the parent unit, and retrieve the current
649650
-- actual for it. Typ is the entity in the analyzed formal type declaration
@@ -653,7 +654,8 @@ package body Sem_Ch12 is
653654
-- be declared in a formal package of a parent. In both cases it is a
654655
-- generic actual type because it appears within a visible instance.
655656
-- Finally, it may be declared in a parent unit without being a formal
656-
-- of that unit, in which case it must be retrieved by visibility.
657+
-- of that unit, in which case it must be retrieved by visibility and
658+
-- Typ_Ref is the unanalyzed subtype mark in the instance to be used.
657659
-- Ambiguities may still arise if two homonyms are declared in two formal
658660
-- packages, and the prefix of the formal type may be needed to resolve
659661
-- the ambiguity in the instance ???
@@ -10465,10 +10467,10 @@ package body Sem_Ch12 is
1046510467

1046610468
function Find_Actual_Type
1046710469
(Typ : Entity_Id;
10468-
Gen_Type : Entity_Id) return Entity_Id
10470+
Gen_Type : Entity_Id;
10471+
Typ_Ref : Node_Id) return Entity_Id
1046910472
is
1047010473
Gen_Scope : constant Entity_Id := Scope (Gen_Type);
10471-
T : Entity_Id;
1047210474

1047310475
begin
1047410476
-- Special processing only applies to child units
@@ -10482,6 +10484,12 @@ package body Sem_Ch12 is
1048210484
elsif Scope (Typ) = Gen_Scope then
1048310485
return Get_Instance_Of (Typ);
1048410486

10487+
-- If designated or component type is declared in a formal of the child
10488+
-- unit, its instance is available.
10489+
10490+
elsif Scope (Scope (Typ)) = Gen_Scope then
10491+
return Get_Instance_Of (Typ);
10492+
1048510493
-- If the array or access type is not declared in the parent unit,
1048610494
-- no special processing needed.
1048710495

@@ -10493,18 +10501,8 @@ package body Sem_Ch12 is
1049310501
-- Otherwise, retrieve designated or component type by visibility
1049410502

1049510503
else
10496-
T := Current_Entity (Typ);
10497-
while Present (T) loop
10498-
if In_Open_Scopes (Scope (T)) then
10499-
return T;
10500-
elsif Is_Generic_Actual_Type (T) then
10501-
return T;
10502-
end if;
10503-
10504-
T := Homonym (T);
10505-
end loop;
10506-
10507-
return Typ;
10504+
Analyze (Typ_Ref);
10505+
return Entity (Typ_Ref);
1050810506
end if;
1050910507
end Find_Actual_Type;
1051010508

@@ -14596,7 +14594,8 @@ package body Sem_Ch12 is
1459614594

1459714595
procedure Validate_Access_Type_Instance is
1459814596
Desig_Type : constant Entity_Id :=
14599-
Find_Actual_Type (Designated_Type (A_Gen_T), A_Gen_T);
14597+
Find_Actual_Type
14598+
(Designated_Type (A_Gen_T), A_Gen_T, Subtype_Indication (Def));
1460014599
Desig_Act : Entity_Id;
1460114600

1460214601
begin
@@ -14685,31 +14684,15 @@ package body Sem_Ch12 is
1468514684
----------------------------------
1468614685

1468714686
procedure Validate_Array_Type_Instance is
14688-
I1 : Node_Id;
14689-
I2 : Node_Id;
14690-
T2 : Entity_Id;
14691-
14692-
function Formal_Dimensions return Nat;
14693-
-- Count number of dimensions in array type formal
14687+
Dims : constant List_Id
14688+
:= (if Nkind (Def) = N_Constrained_Array_Definition
14689+
then Discrete_Subtype_Definitions (Def)
14690+
else Subtype_Marks (Def));
1469414691

14695-
-----------------------
14696-
-- Formal_Dimensions --
14697-
-----------------------
14698-
14699-
function Formal_Dimensions return Nat is
14700-
Dims : List_Id;
14701-
14702-
begin
14703-
if Nkind (Def) = N_Constrained_Array_Definition then
14704-
Dims := Discrete_Subtype_Definitions (Def);
14705-
else
14706-
Dims := Subtype_Marks (Def);
14707-
end if;
14708-
14709-
return List_Length (Dims);
14710-
end Formal_Dimensions;
14711-
14712-
-- Start of processing for Validate_Array_Type_Instance
14692+
Dim : Node_Id;
14693+
I1 : Node_Id;
14694+
I2 : Node_Id;
14695+
T2 : Entity_Id;
1471314696

1471414697
begin
1471514698
if not Is_Array_Type (Act_T) then
@@ -14734,15 +14717,16 @@ package body Sem_Ch12 is
1473414717
end if;
1473514718
end if;
1473614719

14737-
if Formal_Dimensions /= Number_Dimensions (Act_T) then
14720+
if List_Length (Dims) /= Number_Dimensions (Act_T) then
1473814721
Error_Msg_NE
1473914722
("dimensions of actual do not match formal &", Actual, Gen_T);
1474014723
Abandon_Instantiation (Actual);
1474114724
end if;
1474214725

14743-
I1 := First_Index (A_Gen_T);
14744-
I2 := First_Index (Act_T);
14745-
for J in 1 .. Formal_Dimensions loop
14726+
Dim := First (Dims);
14727+
I1 := First_Index (A_Gen_T);
14728+
I2 := First_Index (Act_T);
14729+
for J in 1 .. List_Length (Dims) loop
1474614730

1474714731
-- If the indexes of the actual were given by a subtype_mark,
1474814732
-- the index was transformed into a range attribute. Retrieve
@@ -14765,42 +14749,34 @@ package body Sem_Ch12 is
1476514749
end if;
1476614750

1476714751
if not Subtypes_Match
14768-
(Find_Actual_Type (Etype (I1), A_Gen_T), T2)
14752+
(Find_Actual_Type
14753+
(Etype (I1),
14754+
A_Gen_T,
14755+
(if Nkind (Dim) = N_Subtype_Indication
14756+
then Subtype_Mark (Dim)
14757+
else Dim)),
14758+
T2)
1476914759
then
1477014760
Error_Msg_NE
1477114761
("index types of actual do not match those of formal &",
1477214762
Actual, Gen_T);
1477314763
Abandon_Instantiation (Actual);
1477414764
end if;
1477514765

14766+
Next (Dim);
1477614767
Next_Index (I1);
1477714768
Next_Index (I2);
1477814769
end loop;
1477914770

14780-
-- Check matching subtypes. Note that there are complex visibility
14781-
-- issues when the generic is a child unit and some aspect of the
14782-
-- generic type is declared in a parent unit of the generic. We do
14783-
-- the test to handle this special case only after a direct check
14784-
-- for static matching has failed. The case where both the component
14785-
-- type and the array type are separate formals, and the component
14786-
-- type is a private view may also require special checking in
14787-
-- Subtypes_Match. Finally, we assume that a child instance where
14788-
-- the component type comes from a formal of a parent instance is
14789-
-- correct because the generic was correct. A more precise check
14790-
-- seems too complex to install???
14791-
14792-
if Subtypes_Match
14793-
(Component_Type (A_Gen_T), Component_Type (Act_T))
14794-
or else
14795-
Subtypes_Match
14796-
(Find_Actual_Type (Component_Type (A_Gen_T), A_Gen_T),
14797-
Component_Type (Act_T))
14798-
or else
14799-
(not Inside_A_Generic
14800-
and then Is_Child_Unit (Scope (Component_Type (A_Gen_T))))
14771+
-- Check matching component subtypes
14772+
14773+
if not Subtypes_Match
14774+
(Find_Actual_Type
14775+
(Component_Type (A_Gen_T),
14776+
A_Gen_T,
14777+
Subtype_Indication (Component_Definition (Def))),
14778+
Component_Type (Act_T))
1480114779
then
14802-
null;
14803-
else
1480414780
Error_Msg_NE
1480514781
("component subtype of actual does not match that of formal &",
1480614782
Actual, Gen_T);
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
-- { dg-do compile }
2+
3+
with Generic_Inst9_Pkg1;
4+
with Generic_Inst9_Pkg2.G;
5+
6+
package Generic_Inst9 is
7+
8+
type T4 is null record;
9+
type T5 is null record;
10+
11+
subtype T3 is T5;
12+
13+
type T4_ptr is access T4;
14+
type T5_ptr is access T5;
15+
16+
package My_Pkg2 is new Generic_Inst9_Pkg2 (T2 => T4);
17+
package My_G4 is new My_Pkg2.G (T4_ptr); -- { dg-bogus "does not match|abandoned" }
18+
package My_G5 is new My_Pkg2.G (T5_ptr); -- { dg-error "does not match|abandoned" }
19+
20+
end Generic_Inst9;
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
generic
2+
type T1 is private;
3+
package Generic_Inst9_Pkg1 is
4+
subtype T3 is T1;
5+
end Generic_Inst9_Pkg1;
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
generic
2+
type T2 is access the_pak1.T3;
3+
package Generic_Inst9_Pkg2.G is
4+
end Generic_Inst9_Pkg2.G;
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
with Generic_Inst9_Pkg1;
2+
3+
generic
4+
type T2 is private;
5+
package Generic_Inst9_Pkg2 is
6+
package the_pak1 is new Generic_Inst9_Pkg1 (T1 => T2);
7+
end Generic_Inst9_Pkg2;

0 commit comments

Comments
 (0)