diff mbox series

[COMMITTED,05/13] ada: Fix analysis of Extensions_Visible

Message ID 20240702132130.523603-5-poulhies@adacore.com
State New
Headers show
Series [COMMITTED,01/13] ada: Document that -gnatdJ is unused | expand

Commit Message

Marc Poulhiès July 2, 2024, 1:21 p.m. UTC
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(-)
diff mbox series

Patch

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 --
    -----------------