]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
ada: Disable inlining of subprograms with Skip(_Flow_And)_Proof in GNATprove
authorYannick Moy <moy@adacore.com>
Fri, 21 Jul 2023 04:43:10 +0000 (06:43 +0200)
committerMarc Poulhiès <poulhies@adacore.com>
Tue, 1 Aug 2023 08:06:45 +0000 (10:06 +0200)
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.

gcc/ada/inline.adb

index edb90a9fe20bf84a6370af07addb14e49c99a99c..db8b4164e877eb919dce8a4d7c42c11898a1c64a 100644 (file)
@@ -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.