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 <schonb...@adacore.com> * 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);