@@ -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;
@@ -448,6 +448,7 @@ package Einfo.Utils is
-- Effective_Reads
-- Effective_Writes
-- Exceptional_Cases
+ -- Extensions_Visible
-- Global
-- Initial_Condition
-- Initializes
@@ -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 --
-----------------
From: Yannick Moy <moy@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(-)