[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