[Ada] Errors on globals in expressions of predicate aspects in generic bodies

Message ID 20211109094550.GA830134@adacore.com
State Committed
Commit 64cb8ebef32c44ab7cab6021942df0b3d08a5fe5
Headers
Series [Ada] Errors on globals in expressions of predicate aspects in generic bodies |

Commit Message

Pierre-Marie de Rodat Nov. 9, 2021, 9:45 a.m. UTC
  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.
  

Patch

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