This patch fixes a visibility hole in the instantiation of child units. Before this patch, a declaration in the private part of a non-generic common ancestor was made visible by an instantiation of a child unit in another descendant of that ancestor.
Compiling p-c.ads must be rejected with: p-c.ads:8:19: "Private_Integer" is not visible p-c.ads:8:19: non-visible (private) declaration at p.ads:5 --- package P is private Private_Integer : Integer := 1; end P; --- generic package P.G is end P.G; --- with P.G; package P.C is package NG is new P.G; -- This instantiation causes the visibility problem. Y : Integer := Private_Integer; -- ERROR: Private_Integer not visible here end P.C; Tested on x86_64-pc-linux-gnu, committed on trunk 2013-10-10 Ed Schonberg <schonb...@adacore.com> * sem_ch7.adb (Install_Parent_Private_Declarations): When instantiating a child unit, do not install private declaration of a non-generic ancestor of the generic that is also an ancestor of the current unit: its private part will be installed when private part of ancestor itself is analyzed.
Index: sem_ch7.adb =================================================================== --- sem_ch7.adb (revision 203342) +++ sem_ch7.adb (working copy) @@ -1167,17 +1167,31 @@ -- then finish off by looping through the nongeneric parents -- and installing their private declarations. + -- If one of the non-generic parents is itself on the scope + -- stack, do not install its private declarations: they are + -- installed in due time when the private part of that parent + -- is analyzed. + else while Present (Inst_Par) and then Inst_Par /= Standard_Standard and then (not In_Open_Scopes (Inst_Par) or else not In_Private_Part (Inst_Par)) loop - Install_Private_Declarations (Inst_Par); - Set_Use (Private_Declarations - (Specification - (Unit_Declaration_Node (Inst_Par)))); - Inst_Par := Scope (Inst_Par); + if Nkind (Inst_Node) = N_Formal_Package_Declaration + or else + not Is_Ancestor_Package + (Inst_Par, Cunit_Entity (Current_Sem_Unit)) + then + Install_Private_Declarations (Inst_Par); + Set_Use (Private_Declarations + (Specification + (Unit_Declaration_Node (Inst_Par)))); + Inst_Par := Scope (Inst_Par); + + else + exit; + end if; end loop; exit;