From: Yannick Moy <m...@adacore.com> Pragma/aspect Extensions_Visible should be analyzed before any pre/post contracts on a subprogram, as the legality of conversions of formal parameters to classwide type depends on the value of Extensions_Visible. Now fixed.
gcc/ada/ * contracts.adb (Analyze_Pragmas_In_Declarations): Analyze pragmas in two iterations over the list of declarations in order to analyze some pragmas before others. * einfo-utils.ads (Get_Pragma): Fix comment. * sem_prag.ads (Pragma_Significant_To_Subprograms): Fix. (Pragma_Significant_To_Subprograms_Analyzed_First): Add new global array to identify these pragmas which should be analyzed first, which concerns only Extensions_Visible for now. Tested on x86_64-pc-linux-gnu, committed on master. --- gcc/ada/contracts.adb | 46 ++++++++++++++++++++++++----------------- gcc/ada/einfo-utils.ads | 1 + gcc/ada/sem_prag.ads | 10 +++++++++ 3 files changed, 38 insertions(+), 19 deletions(-) diff --git a/gcc/ada/contracts.adb b/gcc/ada/contracts.adb index 9fc9e05db68..a93bf622aa1 100644 --- a/gcc/ada/contracts.adb +++ b/gcc/ada/contracts.adb @@ -546,33 +546,41 @@ package body Contracts is begin -- Move through the body's declarations analyzing all pragmas which - -- appear at the top of the declarations. + -- appear at the top of the declarations. Go over the list twice, so + -- that pragmas which should be analyzed first are analyzed in the + -- first pass. - Curr_Decl := First (Declarations (Unit_Declaration_Node (Body_Id))); - while Present (Curr_Decl) loop + for Pragmas_Analyzed_First in reverse False .. True loop - if Nkind (Curr_Decl) = N_Pragma then + Curr_Decl := First (Declarations (Unit_Declaration_Node (Body_Id))); + while Present (Curr_Decl) loop - if Pragma_Significant_To_Subprograms - (Get_Pragma_Id (Curr_Decl)) - then - Analyze (Curr_Decl); - end if; + if Nkind (Curr_Decl) = N_Pragma then - -- Skip the renamings of discriminants and protection fields + if Pragma_Significant_To_Subprograms + (Get_Pragma_Id (Curr_Decl)) + and then Pragmas_Analyzed_First = + Pragma_Significant_To_Subprograms_Analyzed_First + (Get_Pragma_Id (Curr_Decl)) + then + Analyze (Curr_Decl); + end if; - elsif Is_Prologue_Renaming (Curr_Decl) then - null; + -- Skip the renamings of discriminants and protection fields - -- We have reached something which is not a pragma so we can be sure - -- there are no more contracts or pragmas which need to be taken into - -- account. + elsif Is_Prologue_Renaming (Curr_Decl) then + null; - else - exit; - end if; + -- We have reached something which is not a pragma so we can be + -- sure there are no more contracts or pragmas which need to be + -- taken into account. + + else + exit; + end if; - Next (Curr_Decl); + Next (Curr_Decl); + end loop; end loop; end Analyze_Pragmas_In_Declarations; diff --git a/gcc/ada/einfo-utils.ads b/gcc/ada/einfo-utils.ads index 01953c35bc3..8207576fb89 100644 --- a/gcc/ada/einfo-utils.ads +++ b/gcc/ada/einfo-utils.ads @@ -448,6 +448,7 @@ package Einfo.Utils is -- Effective_Reads -- Effective_Writes -- Exceptional_Cases + -- Extensions_Visible -- Global -- Initial_Condition -- Initializes diff --git a/gcc/ada/sem_prag.ads b/gcc/ada/sem_prag.ads index 59220ea890c..557e0454870 100644 --- a/gcc/ada/sem_prag.ads +++ b/gcc/ada/sem_prag.ads @@ -216,6 +216,7 @@ package Sem_Prag is Pragma_Contract_Cases => True, Pragma_Depends => True, Pragma_Exceptional_Cases => True, + Pragma_Extensions_Visible => True, Pragma_Ghost => True, Pragma_Global => True, Pragma_Inline => True, @@ -238,6 +239,15 @@ package Sem_Prag is Pragma_Volatile_Function => True, others => False); + -- The following table lists all pragmas which are relevant to the analysis + -- of subprogram bodies and should be analyzed first, because the analysis + -- of other pragmas relevant to subprogram bodies depend on them. + + Pragma_Significant_To_Subprograms_Analyzed_First : + constant array (Pragma_Id) of Boolean := + (Pragma_Extensions_Visible => True, + others => False); + ----------------- -- Subprograms -- ----------------- -- 2.45.2