diff mbox series

[COMMITTED] ada: Attach pre/post on access-to-subprogram to internal subprogram type

Message ID 20230529082946.2410945-1-poulhies@adacore.com
State New
Headers show
Series [COMMITTED] ada: Attach pre/post on access-to-subprogram to internal subprogram type | expand

Commit Message

Marc Poulhiès May 29, 2023, 8:29 a.m. UTC
From: Piotr Trojanek <trojanek@adacore.com>

Aspects Pre/Post that annotate access-to-subprogram type were attached
to the source entity (whose kind is either E_Access_Subprogram_Type or
E_Access_Protected_Subprogram_Type). However, it is more convenient to
attach them to the internal entity (whose kind is E_Subprogram_Type), so
that both Pre/Post aspects and First_Formal/Next_Formal chain are
attached to the same entity, just like for ordinary subprograms.

The drawback of having the Post aspect attached to an internal entity is
that name in prefixes of attribute Result no longer match the name of
entity where this Post aspect is attached. However, currently there is
no code that relies on this matching and, in general, there are fewer
routines that deal with attribute Result so they are easier to adapt
than the code that queries the Pre/Post aspects.

gcc/ada/

	* contracts.adb
	(Add_Pre_Post_Condition): Attach pre/post aspects to E_Subprogram_Type
	entity.
	(Analyze_Entry_Or_Subprogram_Contract): Adapt to use full type
	declaration for a contract attached to E_Subprogram_Type entity.
	* sem_prag.adb
	(Analyze_Pre_Post_Condition): Add pre/post aspects to the designed type.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/ada/contracts.adb | 12 ++++++++----
 gcc/ada/sem_prag.adb  |  6 +++++-
 2 files changed, 13 insertions(+), 5 deletions(-)
diff mbox series

Patch

diff --git a/gcc/ada/contracts.adb b/gcc/ada/contracts.adb
index 15b65ee4c06..7625abf9554 100644
--- a/gcc/ada/contracts.adb
+++ b/gcc/ada/contracts.adb
@@ -334,7 +334,7 @@  package body Contracts is
             if Is_OK_Classification then
                Add_Classification;
 
-            elsif Ekind (Id) in Access_Subprogram_Kind
+            elsif Ekind (Id) = E_Subprogram_Type
                 and then Prag_Nam in Name_Precondition
                                    | Name_Postcondition
             then
@@ -665,7 +665,10 @@  package body Contracts is
       Freeze_Id : Entity_Id := Empty)
    is
       Items     : constant Node_Id := Contract (Subp_Id);
-      Subp_Decl : constant Node_Id := Unit_Declaration_Node (Subp_Id);
+      Subp_Decl : constant Node_Id :=
+        (if Ekind (Subp_Id) = E_Subprogram_Type
+         then Associated_Node_For_Itype (Subp_Id)
+         else Unit_Declaration_Node (Subp_Id));
 
       Saved_SM  : constant SPARK_Mode_Type := SPARK_Mode;
       Saved_SMP : constant Node_Id         := SPARK_Mode_Pragma;
@@ -1593,8 +1596,9 @@  package body Contracts is
 
       --  Analyze Pre/Post on access-to-subprogram type
 
-      if Is_Access_Subprogram_Type (Type_Id) then
-         Analyze_Entry_Or_Subprogram_Contract (Type_Id);
+      if Ekind (Type_Id) in Access_Subprogram_Kind then
+         Analyze_Entry_Or_Subprogram_Contract
+           (Directly_Designated_Type (Type_Id));
       end if;
    end Analyze_Type_Contract;
 
diff --git a/gcc/ada/sem_prag.adb b/gcc/ada/sem_prag.adb
index 0d62b04cc37..0de410a2392 100644
--- a/gcc/ada/sem_prag.adb
+++ b/gcc/ada/sem_prag.adb
@@ -5265,7 +5265,11 @@  package body Sem_Prag is
          --  Chain the pragma on the contract for further processing by
          --  Analyze_Pre_Post_Condition_In_Decl_Part.
 
-         Add_Contract_Item (N, Subp_Id);
+         if Ekind (Subp_Id) in Access_Subprogram_Kind then
+            Add_Contract_Item (N, Directly_Designated_Type (Subp_Id));
+         else
+            Add_Contract_Item (N, Subp_Id);
+         end if;
 
          --  Fully analyze the pragma when it appears inside an entry or
          --  subprogram body because it cannot benefit from forward references.