From: Yannick Moy <m...@adacore.com>

Subprograms with these Skip(_Flow_And)_Proof annotations should not be
inlined in GNATprove, as we want to skip part of the analysis for their
body.

gcc/ada/

        * inline.adb (Can_Be_Inlined_In_GNATprove_Mode): Check for
        Skip_Proof and Skip_Flow_And_Proof annotations for deciding
        whether a subprogram can be inlined.

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

---
 gcc/ada/inline.adb | 49 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 49 insertions(+)

diff --git a/gcc/ada/inline.adb b/gcc/ada/inline.adb
index edb90a9fe20..db8b4164e87 100644
--- a/gcc/ada/inline.adb
+++ b/gcc/ada/inline.adb
@@ -1503,6 +1503,10 @@ package body Inline is
       --  an unconstrained record type with per-object constraints on component
       --  types.
 
+      function Has_Skip_Proof_Annotation (Id : Entity_Id) return Boolean;
+      --  Returns True if subprogram Id has an annotation Skip_Proof or
+      --  Skip_Flow_And_Proof.
+
       function Has_Some_Contract (Id : Entity_Id) return Boolean;
       --  Return True if subprogram Id has any contract. The presence of
       --  Extensions_Visible or Volatile_Function is also considered as a
@@ -1701,6 +1705,45 @@ package body Inline is
          return False;
       end Has_Formal_With_Discriminant_Dependent_Fields;
 
+      -------------------------------
+      -- Has_Skip_Proof_Annotation --
+      -------------------------------
+
+      function Has_Skip_Proof_Annotation (Id : Entity_Id) return Boolean is
+         Decl : Node_Id := Unit_Declaration_Node (Id);
+
+      begin
+         Next (Decl);
+
+         while Present (Decl)
+           and then Nkind (Decl) = N_Pragma
+         loop
+            if Get_Pragma_Id (Decl) = Pragma_Annotate
+              and then List_Length (Pragma_Argument_Associations (Decl)) = 3
+            then
+               declare
+                  Arg1      : constant Node_Id :=
+                    First (Pragma_Argument_Associations (Decl));
+                  Arg2      : constant Node_Id := Next (Arg1);
+                  Arg1_Name : constant String :=
+                    Get_Name_String (Chars (Get_Pragma_Arg (Arg1)));
+                  Arg2_Name : constant String :=
+                    Get_Name_String (Chars (Get_Pragma_Arg (Arg2)));
+               begin
+                  if Arg1_Name = "gnatprove"
+                    and then Arg2_Name in "skip_proof" | "skip_flow_and_proof"
+                  then
+                     return True;
+                  end if;
+               end;
+            end if;
+
+            Next (Decl);
+         end loop;
+
+         return False;
+      end Has_Skip_Proof_Annotation;
+
       -----------------------
       -- Has_Some_Contract --
       -----------------------
@@ -1903,6 +1946,12 @@ package body Inline is
       elsif Maybe_Traversal_Function (Id) then
          return False;
 
+      --  Do not inline subprograms with the Skip_Proof or Skip_Flow_And_Proof
+      --  annotation, which should be handled separately.
+
+      elsif Has_Skip_Proof_Annotation (Id) then
+         return False;
+
       --  Otherwise, this is a subprogram declared inside the private part of a
       --  package, or inside a package body, or locally in a subprogram, and it
       --  does not have any contract. Inline it.
-- 
2.40.0

Reply via email to