+2017-04-25 Ed Schonberg <schonberg@adacore.com>
+
+ * sem_util.adb, sem_util.ads (From_Nested_Package): New predicate
+ to determine whether a type is declared in a local package that
+ has not yet been frozen.
+ * freeze.adb (Freeze_Before): Use new predicate to determine
+ whether a local package must be installed on the scope stack
+ in order to evaluate in the proper scope actions generated by
+ aspect specifications, such as Predicate
+ * sem_ch13.adb: Simplify code in Analyze_Aspects_At_Freeze_Point
+ using new predicate.
+
2017-04-25 Hristian Kirtchev <kirtchev@adacore.com>
* sem_warn.adb (Warn_On_Constant_Valid_Condition): Do not consider
-- --
-- B o d y --
-- --
--- Copyright (C) 1992-2016, Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2017, Free Software Foundation, Inc. --
-- --
-- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
Freeze_Nodes : constant List_Id :=
Freeze_Entity (T, N, Do_Freeze_Profile);
+ Pack : constant Entity_Id := Scope (T);
begin
if Ekind (T) = E_Function then
end if;
if Is_Non_Empty_List (Freeze_Nodes) then
- Insert_Actions (N, Freeze_Nodes);
+
+ -- If the entity is a type declared in an inner package, it may be
+ -- frozen by an outer declaration before the package itself is
+ -- frozen. Install the package scope to analyze the freeze nodes,
+ -- which may include generated subprograms such as predicate
+ -- functions, etc.
+
+ if Is_Type (T) and then From_Nested_Package (T) then
+ Push_Scope (Pack);
+ Install_Visible_Declarations (Pack);
+ Install_Private_Declarations (Pack);
+ Insert_Actions (N, Freeze_Nodes);
+ End_Package_Scope (Pack);
+
+ else
+ Insert_Actions (N, Freeze_Nodes);
+ end if;
end if;
end Freeze_Before;
-- itself is frozen the type will have been frozen as well.
if not Scope_Within_Or_Same (Current_Scope, Scope (E)) then
- if Is_Type (E)
- and then Ekind (Scope (E)) = E_Package
- and then not Is_Frozen (Scope (E))
- then
+ if Is_Type (E) and then From_Nested_Package (E) then
declare
Pack : constant Entity_Id := Scope (E);
end if;
End_Package_Scope (Pack);
+ return;
end;
else
return Res (Res'First .. Res_Index - 1);
end Fix_Msg;
+ -------------------------
+ -- From_Nested_Package --
+ -------------------------
+
+ function From_Nested_Package (T : Entity_Id) return Boolean is
+ Pack : constant Entity_Id := Scope (T);
+ begin
+ return Ekind (Pack) = E_Package
+ and then not Is_Frozen (Pack)
+ and then not Scope_Within_Or_Same (Current_Scope, Pack)
+ and then In_Open_Scopes (Scope (Pack));
+ end From_Nested_Package;
+
-----------------------
-- Gather_Components --
-----------------------
-- --
-- S p e c --
-- --
--- Copyright (C) 1992-2016, Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2017, Free Software Foundation, Inc. --
-- --
-- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
-- - "task" when Id is a single task object, task type or task body
-- All other non-matching words remain as is
+ function From_Nested_Package (T : Entity_Id) return Boolean;
+ -- A type declared in a nested package may be frozen by a declaration
+ -- appearing after the package but before the package is frozen. If the
+ -- type has aspects that generate subprograms, these may contain references
+ -- to entities local to the nested package. In that case the package must
+ -- be installed on the scope stack to prevent spurious visibility errors.
+
procedure Gather_Components
(Typ : Entity_Id;
Comp_List : Node_Id;