The front-end cannot inline subprograms that contain certain declarations,
such as nested subprograms. If the the subprogram to inline includes a
subtype declaration with predicates, it cannot be inlined because the
analysis of the predicate will generate (nested) predicate functions.
Source:
---
package body Foo
with SPARK_Mode
is
pragma Warnings (Off, "analyzing unreferenced procedure *");
G_V : Natural := 123;
G_VC : constant Natural := G_V;
G_SC : constant Natural := 500;
procedure Test_05 (A, B : Natural;
O : out Boolean)
is
-- ok
subtype T is Natural range 0 .. A with Predicate => (3 <= T);
subtype U is Natural range 0 .. 10 with Predicate => (B <= U);
subtype V is Natural range 0 .. 10 with Predicate => (V in G_VC .. G_SC);
X : Natural := 10;
begin
O := X in T | U | V;
end Test_05;
end Foo;
--
package Foo
with SPARK_Mode
is
pragma Elaborate_Body;
end Foo;
--
Command:
gcc -c -gnatd.F foo.adb
Output:
foo.adb:15:07: info:
no contextual analysis of "Test_05"(subtype declaration with predicate)
Tested on x86_64-pc-linux-gnu, committed on trunk
2015-10-26 Ed Schonberg <[email protected]>
* inline.adb (Has_Excluded_Declaration): A subtype declaration
with a predicate aspect generates a subprogram, and therefore
prevents the inlining of the enclosing subprogram.
Index: inline.adb
===================================================================
--- inline.adb (revision 229313)
+++ inline.adb (working copy)
@@ -3513,6 +3513,37 @@
("cannot inline & (nested procedure instantiation)?",
D, Subp);
return True;
+
+ -- Subtype declarations with predicates will generate predicate
+ -- functions, i.e. nested subprogram bodies, so inlining is not
+ -- possible.
+
+ elsif Nkind (D) = N_Subtype_Declaration
+ and then Present (Aspect_Specifications (D))
+ then
+ declare
+ A : Node_Id;
+ A_Id : Aspect_Id;
+
+ begin
+ A := First (Aspect_Specifications (D));
+ while Present (A) loop
+ A_Id := Get_Aspect_Id (Chars (Identifier (A)));
+
+ if A_Id = Aspect_Predicate
+ or else A_Id = Aspect_Static_Predicate
+ or else A_Id = Aspect_Dynamic_Predicate
+ then
+ Cannot_Inline
+ ("cannot inline & "
+ & "(subtype declaration with predicate)?",
+ D, Subp);
+ return True;
+ end if;
+
+ Next (A);
+ end loop;
+ end;
end if;
Next (D);