[Ada] fix bug in limited with

Arnaud Charlet charlet@adacore.com
Tue Apr 10 06:49:00 GMT 2007


Tested on i686-linux, committed on trunk

A limited_with clause can be analyzed multiple times: first when the
unit that contains it is analyzed, and then when this unit appears in the
context of some other unit that is being analyzed. In the latter case, the
non-limited view of the package may be currently available: this is the
case when compiling a body B that has a regular with_clause on a unit P,
when the spec for B has a limited_with_clause on the same P. In such cases,
we need to install the non-limited view of P and all its types.
However, when compiling a child unit, we may reanalyze the limited_with
clause in the parent, without the non-limited view of the package being
available. In such a case, the non-limited view of any type is still an
incomplete type, and only the limited view remains available.
The following must compile quietly:
--
package Employees is
   type Employee is tagged private;
private
   type Employee is tagged record
      Id : Natural := 0;
   end record;
end Employees;
--
limited with Employees;
package Visibility is
   subtype Employee is Employees.Employee;
end Visibility;
--
private package Visibility.Internal is
   type Secret is new Integer;
end Visibility.Internal;

In addition, when the prefix P of an expanded name P.X denotes the renaming of a
package, the entity of P is set to the original package, for visiblity
purposes. When checking on whether a with_clause is needed in a given
compilation unit context, this renaming must be taken into account, This
is significant because a very common with_clause in Ada programs is for
Text_IO, which is a renaming of Ada.Text_IO.
--
gnat.dg/renaming1.adb must compile quietly.


2007-04-06  Ed Schonberg  <schonberg@adacore.com>

	* sem_ch10.adb (Install_Limited_Context_Clauses.
	Expand_Limited_With_Clause): Use a new copy of selector name in the
	call to Make_With_Clause. This fixes the tree structure for ASIS
	purposes. Nothing is changed in the compiler behaviour.
	(Process_Body_Clauses): Handle properly use clauses whose prefix is
	a package renaming.
	(Install_Limited_With_Clauses): Do not install non-limited view when it
	is still incomplete.

-------------- next part --------------
Index: sem_ch10.adb
===================================================================
--- sem_ch10.adb	(revision 123291)
+++ sem_ch10.adb	(working copy)
@@ -305,6 +305,28 @@ package body Sem_Ch10 is
             Subt_Mark : Node_Id;
             Use_Item  : Node_Id;
 
+            function Same_Unit (N : Node_Id; P : Entity_Id) return Boolean;
+            --  In an expanded name in a use clause, if the prefix is a
+            --  renamed package, the entity is set to the original package
+            --  as a result, when checking whether the package appears in a
+            --  previous with_clause, the renaming has to be taken into
+            --  account, to prevent spurious or incorrect warnings. The
+            --  common case is the use of Text_IO.
+
+            ---------------
+            -- Same_Unit --
+            ---------------
+
+            function Same_Unit (N : Node_Id; P : Entity_Id) return Boolean is
+            begin
+               return Entity (N) = P
+                 or else
+                   (Present (Renamed_Object (P))
+                     and then Entity (N) = Renamed_Object (P));
+            end Same_Unit;
+
+         --  Start of processing for Process_Body_Clauses
+
          begin
             Used := False;
             Used_Type_Or_Elab := False;
@@ -338,7 +360,7 @@ package body Sem_Ch10 is
 
                            UE := Use_Item;
                            while Nkind (UE) = N_Expanded_Name loop
-                              if Entity (Prefix (UE)) = Nam_Ent then
+                              if Same_Unit (Prefix (UE), Nam_Ent) then
                                  Used := True;
                                  exit;
                               end if;
@@ -360,7 +382,7 @@ package body Sem_Ch10 is
                   while Present (Subt_Mark)
                     and then not Used_Type_Or_Elab
                   loop
-                     if Entity (Prefix (Subt_Mark)) = Nam_Ent then
+                     if Same_Unit (Prefix (Subt_Mark), Nam_Ent) then
                         Used_Type_Or_Elab := True;
                      end if;
 
@@ -3652,7 +3674,7 @@ package body Sem_Ch10 is
               Make_With_Clause (Loc,
                 Name => Make_Selected_Component (Loc,
                   Prefix        => New_Copy_Tree (Prefix (Nam)),
-                  Selector_Name => Selector_Name (Nam)));
+                  Selector_Name => New_Copy (Selector_Name (Nam))));
             Set_Parent (Withn, Parent (N));
          end if;
 
@@ -3767,21 +3789,31 @@ package body Sem_Ch10 is
                   Def_Id := Defining_Identifier (Decl);
                   Non_Lim_View := Non_Limited_View (Def_Id);
 
-                  --  Convert an incomplete subtype declaration into a
-                  --  corresponding non-limited view subtype declaration.
+                  if not Is_Incomplete_Type (Non_Lim_View) then
 
-                  Set_Subtype_Indication (Decl,
-                    New_Reference_To (Non_Lim_View, Sloc (Def_Id)));
-                  Set_Etype (Def_Id, Non_Lim_View);
-                  Set_Ekind (Def_Id, Subtype_Kind (Ekind (Non_Lim_View)));
-                  Set_Analyzed (Decl, False);
-
-                  --  Reanalyze the declaration, suppressing the call to
-                  --  Enter_Name to avoid duplicate names.
-
-                  Analyze_Subtype_Declaration
-                   (N    => Decl,
-                    Skip => True);
+                     --  Convert an incomplete subtype declaration into a
+                     --  corresponding non-limited view subtype declaration.
+                     --  This is usually the case when analyzing a body that
+                     --  has regular with-clauses, when the spec has limited
+                     --  ones.
+                     --  if the non-limited view is still incomplete, it is
+                     --  the dummy entry already created, and the declaration
+                     --  cannot be reanalyzed. This is the case when installing
+                     --  a parent unit that has limited with-clauses.
+
+                     Set_Subtype_Indication (Decl,
+                       New_Reference_To (Non_Lim_View, Sloc (Def_Id)));
+                     Set_Etype (Def_Id, Non_Lim_View);
+                     Set_Ekind (Def_Id, Subtype_Kind (Ekind (Non_Lim_View)));
+                     Set_Analyzed (Decl, False);
+
+                     --  Reanalyze the declaration, suppressing the call to
+                     --  Enter_Name to avoid duplicate names.
+
+                     Analyze_Subtype_Declaration
+                      (N    => Decl,
+                       Skip => True);
+                  end if;
                end if;
 
                Next (Decl);


More information about the Gcc-patches mailing list