When a predicate aspect is given on a declaration inside of a generic
body and the expression of the aspect references entities declared
outside of the generic, errors about those entities not being defined
can be issued in instantiations of the generic. This happens because the
expression of the Predicate pragma created for the aspect is not
analyzed before the global references are captured by
Save_Global_References. The pragma expression is now analyzed when the
declaration is frozen in the generic.
Tested on x86_64-pc-linux-gnu, committed on trunk
gcc/ada/
* sem_ch13.adb (Freeze_Entity_Checks): Analyze the expression of
a pragma Predicate associated with an aspect at the freeze point
of the type, to ensure that references to globals get saved when
the aspect occurs within a generic body. Also, add
Aspect_Static_Predicate to the choices of the membership test of
the enclosing guard.
diff --git a/gcc/ada/sem_ch13.adb b/gcc/ada/sem_ch13.adb
--- a/gcc/ada/sem_ch13.adb
+++ b/gcc/ada/sem_ch13.adb
@@ -13162,6 +13162,7 @@ package body Sem_Ch13 is
if Get_Aspect_Id (Ritem) in Aspect_CPU
| Aspect_Dynamic_Predicate
| Aspect_Predicate
+ | Aspect_Static_Predicate
| Aspect_Priority
then
-- Retrieve the visibility to components and discriminants
@@ -13169,6 +13170,34 @@ package body Sem_Ch13 is
Push_Type (E);
Check_Aspect_At_Freeze_Point (Ritem);
+
+ -- In the case of predicate aspects, there will be
+ -- a corresponding Predicate pragma associated with
+ -- the aspect, and the expression of the pragma also
+ -- needs to be analyzed at this point, to ensure that
+ -- Save_Global_References will capture global refs in
+ -- expressions that occur in generic bodies, for proper
+ -- later resolution of the pragma in instantiations.
+
+ if Is_Type (E)
+ and then Inside_A_Generic
+ and then Has_Predicates (E)
+ and then Present (Aspect_Rep_Item (Ritem))
+ then
+ declare
+ Pragma_Args : constant List_Id :=
+ Pragma_Argument_Associations
+ (Aspect_Rep_Item (Ritem));
+ Pragma_Expr : constant Node_Id :=
+ Expression (Next (First (Pragma_Args)));
+ begin
+ if Present (Pragma_Expr) then
+ Analyze_And_Resolve
+ (Pragma_Expr, Standard_Boolean);
+ end if;
+ end;
+ end if;
+
Pop_Type (E);
else