This change affects only back-end inlining and is two-fold:

1. It lifts in a 3rd place the limitation associated with
nested subprograms as well as with a couple of other constructs.
After it is applied, the only significant limitation left are
the nested packages.

2. It makes sure the errors associated with pragma Inline_Always
are issued whatever the optimization level, which is in keeping
with its semantics.

It makes it possible to inline/reject consistently at all
optimization levels subprograms marked with pragma Inline_Always,
for example:

package Q is
   procedure Test (I : Integer);
   pragma Inline_Always (Test);
end Q;
package body Q is
   procedure Test (I : Integer) is
      -- Uncomment to make it compile
      -- function F (J : Integer) return Integer;
      -- pragma Inline_Always (F);

      function F (J : Integer) return Integer is
      begin
         return I - J;
      end;

   begin
      if I /= F (I) then raise Program_Error; end if;
   end;
end Q;

Tested on x86_64-pc-linux-gnu, committed on trunk

2014-10-31  Eric Botcazou  <ebotca...@adacore.com>

        * inline.adb (Has_Excluded_Declaration): With back-end inlining,
        only return true for nested packages.
        (Cannot_Inline): Issue errors/warnings whatever the optimization level
        for back-end inlining and remove assertion.

Index: inline.adb
===================================================================
--- inline.adb  (revision 216960)
+++ inline.adb  (working copy)
@@ -1225,10 +1225,8 @@
             Error_Msg_NE (Msg & "p?", N, Subp);
          end if;
 
-         return;
+      --  New semantics relying on back end inlining
 
-      --  New semantics
-
       elsif Is_Serious then
 
          --  Remove last character (question mark) to make this into an error.
@@ -1242,10 +1240,8 @@
          Set_Is_Inlined_Always (Subp, False);
          Error_Msg_NE (Msg & "p?", N, Subp);
 
-      --  Do not issue errors/warnings when compiling with optimizations
+      else
 
-      elsif Optimization_Level = 0 then
-
          --  Do not emit warning if this is a predefined unit which is not
          --  the main unit. This behavior is currently provided for backward
          --  compatibility but it will be removed when we enforce the
@@ -1281,24 +1277,13 @@
 
             Error_Msg_NE (Msg (Msg'First .. Msg'Last - 1), N, Subp);
 
-         else pragma Assert (Front_End_Inlining);
+         else
             Set_Is_Inlined (Subp, False);
 
-            --  When inlining cannot take place we must issue an error.
-            --  For backward compatibility we still report a warning.
-
             if Ineffective_Inline_Warnings then
                Error_Msg_NE (Msg & "p?", N, Subp);
             end if;
          end if;
-
-      --  Compiling with optimizations enabled it is too early to report
-      --  problems since the backend may still perform inlining. In order
-      --  to report unhandled inlinings the program must be compiled with
-      --  -Winline and the error is reported by the backend.
-
-      else
-         null;
       end if;
    end Cannot_Inline;
 
@@ -3327,12 +3312,26 @@
 
       D := First (Decls);
       while Present (D) loop
-         if Nkind (D) = N_Subprogram_Body then
+         --  First declarations universally excluded
+
+         if Nkind (D) = N_Package_Declaration then
             Cannot_Inline
-              ("cannot inline & (nested subprogram)?",
+              ("cannot inline & (nested package declaration)?",
                D, Subp);
             return True;
 
+         elsif Nkind (D) = N_Package_Instantiation then
+            Cannot_Inline
+              ("cannot inline & (nested package instantiation)?",
+               D, Subp);
+            return True;
+         end if;
+
+         --  Then declarations excluded only for front end inlining
+
+         if Back_End_Inlining then
+            null;
+
          elsif Nkind (D) = N_Task_Type_Declaration
            or else Nkind (D) = N_Single_Task_Declaration
          then
@@ -3349,9 +3348,9 @@
                D, Subp);
             return True;
 
-         elsif Nkind (D) = N_Package_Declaration then
+         elsif Nkind (D) = N_Subprogram_Body then
             Cannot_Inline
-              ("cannot inline & (nested package declaration)?",
+              ("cannot inline & (nested subprogram)?",
                D, Subp);
             return True;
 
@@ -3368,12 +3367,6 @@
               ("cannot inline & (nested procedure instantiation)?",
                D, Subp);
             return True;
-
-         elsif Nkind (D) = N_Package_Instantiation then
-            Cannot_Inline
-              ("cannot inline & (nested package instantiation)?",
-               D, Subp);
-            return True;
          end if;
 
          Next (D);

Reply via email to