diff mbox

[Ada] Improper visibility with child instance that is siblling of current unit

Message ID 20131010110332.GA14984@adacore.com
State New
Headers show

Commit Message

Arnaud Charlet Oct. 10, 2013, 11:03 a.m. UTC
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  <schonberg@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.
diff mbox

Patch

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;