https://gcc.gnu.org/g:4638dd827a8ce4741aae1e3ed774253efe43ab1c
commit r17-733-g4638dd827a8ce4741aae1e3ed774253efe43ab1c Author: Gary Dismukes <[email protected]> Date: Wed Jan 7 20:23:55 2026 +0000 ada: Visibility bug in instance of generic with precondition on formal subprogram The compiler may issue an error saying that a global entity referenced in the precondition of a formal subprogram is not visible when the containing generic is instantiated at a place where the entity is not directly visible. This was due to the formal subprogram's contract not having been analyzed in the generic template. As a result, the nodes with global references were not properly captured (by Save_Global_References). An additional problem was exposed, which was that references within contract aspect specifications of generic formals to other formals of the same generic were not being properly analyzed/resolved, due to copying the aspect specifications of the already-analyzed copy of the generic formal when building subprogram wrappers for the contracts. This could lead to blowups in the back end due to references to the original formals occurring in the expansion of the instantiation. This is addressed by copying the aspect specifications of the unanalyzed formals rather than those that were analyzed in the copy of the generic template. gcc/ada/ChangeLog: * contracts.adb (Analyze_Contracts): Add cases for formal subprogram Nkinds so that Analyze_Entry_Or_Subprogram_Contract will be called for them. * sem_attr.adb (Analyze_Attribute_Old_Result): Account for the cases of formal subprogram Nkinds, allowing Old attributes for those. * sem_ch12.adb (Build_Subprogram_Wrappers): Add a formal for passing the unanalyzed generic formal, and use it for copying any aspect specifications of the generic formal rather than copying the analyzed generic formal's aspects. (Analyze_One_Association): Pass Assoc.Un_Formal as an additional actual in the call to Build_Subprogram_Wrappers. Diff: --- gcc/ada/contracts.adb | 2 ++ gcc/ada/sem_attr.adb | 2 ++ gcc/ada/sem_ch12.adb | 24 +++++++++++++++++++----- 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/gcc/ada/contracts.adb b/gcc/ada/contracts.adb index 81a04facfc97..bde66171cbc0 100644 --- a/gcc/ada/contracts.adb +++ b/gcc/ada/contracts.adb @@ -452,6 +452,8 @@ package body Contracts is if Nkind (Decl) in N_Abstract_Subprogram_Declaration | N_Entry_Declaration + | N_Formal_Abstract_Subprogram_Declaration + | N_Formal_Concrete_Subprogram_Declaration | N_Generic_Subprogram_Declaration | N_Subprogram_Declaration then diff --git a/gcc/ada/sem_attr.adb b/gcc/ada/sem_attr.adb index e4fc782fcd92..691667226925 100644 --- a/gcc/ada/sem_attr.adb +++ b/gcc/ada/sem_attr.adb @@ -1518,6 +1518,8 @@ package body Sem_Attr is if Nkind (Subp_Decl) not in N_Abstract_Subprogram_Declaration | N_Entry_Declaration | N_Expression_Function + | N_Formal_Abstract_Subprogram_Declaration + | N_Formal_Concrete_Subprogram_Declaration | N_Full_Type_Declaration | N_Generic_Subprogram_Declaration | N_Subprogram_Body diff --git a/gcc/ada/sem_ch12.adb b/gcc/ada/sem_ch12.adb index c0835cb39581..5d8c8c3ca346 100644 --- a/gcc/ada/sem_ch12.adb +++ b/gcc/ada/sem_ch12.adb @@ -524,7 +524,10 @@ package body Sem_Ch12 is -- pre/postconditon checks added. procedure Build_Subprogram_Wrappers - (Match, Analyzed_Formal : Node_Id; Renamings : List_Id); + (Match : Node_Id; + Analyzed_Formal : Node_Id; + Unanalyzed_Formal : Node_Id; + Renamings : List_Id); -- Ada 2022: AI12-0272 introduces pre/postconditions for formal -- subprograms. The implementation of making the formal into a renaming -- of the actual does not work, given that subprogram renaming cannot @@ -534,6 +537,10 @@ package body Sem_Ch12 is -- The wrapper declaration and body are appended to Renamings. -- ???But renaming declarations CAN have aspects specs, -- and that was true from the start (see AI05-0183-1). + -- + -- The procedure also copies the aspect specifications from the unanalyzed + -- formal subprogram to the wrapper subprogram for later analysis in the + -- context of the instantiation. procedure Check_Abbreviated_Instance (N : Node_Id; @@ -2753,7 +2760,10 @@ package body Sem_Ch12 is and then (Expander_Active or GNATprove_Mode) then Build_Subprogram_Wrappers - (Match, Assoc.An_Formal, Result_Renamings); + (Match => Match, + Analyzed_Formal => Assoc.An_Formal, + Unanalyzed_Formal => Assoc.Un_Formal, + Renamings => Result_Renamings); end if; -- An instantiation is a freeze point for the actuals, @@ -7535,7 +7545,10 @@ package body Sem_Ch12 is ------------------------------- procedure Build_Subprogram_Wrappers - (Match, Analyzed_Formal : Node_Id; Renamings : List_Id) + (Match : Node_Id; + Analyzed_Formal : Node_Id; + Unanalyzed_Formal : Node_Id; + Renamings : List_Id) is function Adjust_Aspect_Sloc (N : Node_Id) return Traverse_Result; -- Adjust Sloc so that errors will be reported on the instance rather @@ -7593,10 +7606,11 @@ package body Sem_Ch12 is Decl_Node := Build_Subprogram_Decl_Wrapper (Formal); - -- Transfer aspect specifications from formal subprogram to wrapper + -- Transfer aspect specifications from the unanalyzed formal subprogram + -- to the wrapper for later analysis. Set_Aspect_Specifications (Decl_Node, - New_Copy_List_Tree (Aspect_Specifications (Analyzed_Formal))); + New_Copy_List_Tree (Aspect_Specifications (Unanalyzed_Formal))); Aspect_Spec := First (Aspect_Specifications (Decl_Node)); while Present (Aspect_Spec) loop
