From: Eric Botcazou <[email protected]>
The problem is that, for an inline subprogram declared in an instance, the
cross-unit inlining machinery does not have the body by the time it decides
to inline calls to the subprogram, because the instantiation of bodies is
deferred until the end of the compilation. So it cannot see whether this
body contains excluded declarations or statements by that time, typically
nested packages or instances thereof.
The fix is to check that Is_Inlined is still set on the subprogram before
passing it on to the back-end for cross-unit inlining. It also removes an
obsolete check that was done precisely there.
This also adjusts the description of the -gnatwp switch, which can be used
to get the reason why cross-inlining has failed, for example here:
g.ads:4:01: warning: in instantiation at generic_si.adb:60 [-gnatwp]
g.ads:4:01: warning: cannot inline "*" (nested package instantiation)
gcc/ada/ChangeLog:
PR ada/122574
* doc/gnat_ugn/building_executable_programs_with_gnat.rst (-gnatwp):
Replace reference to -gnatN with -gnatn and adjust accordingly.
* inline.adb: Remove clauses for Exp_Tss.
(Has_Initialized_Type): Delete.
(Add_Inlined_Subprogram): Test that the Is_Inlined flag is still set
on the subprogram.
* usage.adb (Usage): Adjust description of -gnatwp.
* gnat_ugn.texi: Regenerate.
Tested on x86_64-pc-linux-gnu, committed on master.
---
...building_executable_programs_with_gnat.rst | 14 +++----
gcc/ada/gnat_ugn.texi | 16 ++++----
gcc/ada/inline.adb | 41 ++-----------------
gcc/ada/usage.adb | 4 +-
4 files changed, 21 insertions(+), 54 deletions(-)
diff --git a/gcc/ada/doc/gnat_ugn/building_executable_programs_with_gnat.rst
b/gcc/ada/doc/gnat_ugn/building_executable_programs_with_gnat.rst
index 703607d2849..13654e185e0 100644
--- a/gcc/ada/doc/gnat_ugn/building_executable_programs_with_gnat.rst
+++ b/gcc/ada/doc/gnat_ugn/building_executable_programs_with_gnat.rst
@@ -3587,13 +3587,13 @@ of the pragma in the :title:`GNAT_Reference_manual`).
:switch:`-gnatwp`
*Activate warnings on ineffective pragma Inlines.*
- This switch activates warnings for failure of front end inlining
- (activated by :switch:`-gnatN`) to inline a particular call. There are
- many reasons for not being able to inline a call, including most
- commonly that the call is too complex to inline. The default is
- that such warnings are not given.
- Warnings on ineffective inlining by the gcc back end can be activated
- separately, using the gcc switch -Winline.
+ This switch activates warnings for failure of cross-unit inlining
+ (activated by :switch:`-gnatn`) to inline calls to a subprogram.
+ There are many reasons for not being able to inline these calls,
+ including most commonly that the subprogram body is too complex
+ to inline. The default is that such warnings are not given.
+ Warnings on ineffective inlining (within units) by the back end
+ can be activated separately, using the -Winline switch.
.. index:: -gnatwP (gcc)
diff --git a/gcc/ada/gnat_ugn.texi b/gcc/ada/gnat_ugn.texi
index 77db8789ca8..241ded65e8e 100644
--- a/gcc/ada/gnat_ugn.texi
+++ b/gcc/ada/gnat_ugn.texi
@@ -19,7 +19,7 @@
@copying
@quotation
-GNAT User's Guide for Native Platforms , Nov 18, 2025
+GNAT User's Guide for Native Platforms , Nov 27, 2025
AdaCore
@@ -11942,13 +11942,13 @@ the resulting assigned value is never read.
`Activate warnings on ineffective pragma Inlines.'
-This switch activates warnings for failure of front end inlining
-(activated by @code{-gnatN}) to inline a particular call. There are
-many reasons for not being able to inline a call, including most
-commonly that the call is too complex to inline. The default is
-that such warnings are not given.
-Warnings on ineffective inlining by the gcc back end can be activated
-separately, using the gcc switch -Winline.
+This switch activates warnings for failure of cross-unit inlining
+(activated by @code{-gnatn}) to inline calls to a subprogram.
+There are many reasons for not being able to inline these calls,
+including most commonly that the subprogram body is too complex
+to inline. The default is that such warnings are not given.
+Warnings on ineffective inlining (within units) by the back end
+can be activated separately, using the -Winline switch.
@end table
@geindex -gnatwP (gcc)
diff --git a/gcc/ada/inline.adb b/gcc/ada/inline.adb
index a966c28351f..0cb879a7133 100644
--- a/gcc/ada/inline.adb
+++ b/gcc/ada/inline.adb
@@ -34,7 +34,6 @@ with Elists; use Elists;
with Errout; use Errout;
with Exp_Ch6; use Exp_Ch6;
with Exp_Ch7; use Exp_Ch7;
-with Exp_Tss; use Exp_Tss;
with Exp_Util; use Exp_Util;
with Fname; use Fname;
with Fname.UF; use Fname.UF;
@@ -287,10 +286,6 @@ package body Inline is
-- Return the entity node for the unit containing E. Always return the spec
-- for a package.
- function Has_Initialized_Type (E : Entity_Id) return Boolean;
- -- If a candidate for inlining contains type declarations for types with
- -- nontrivial initialization procedures, they are not worth inlining.
-
function Has_Single_Return (N : Node_Id) return Boolean;
-- In general we cannot inline functions that return unconstrained type.
-- However, we can handle such functions if all return statements return
@@ -758,14 +753,15 @@ package body Inline is
-- an instance whose body will be analyzed anyway or the subprogram was
-- generated as a body by the compiler (for example an initialization
-- procedure) or its declaration was provided along with the body (for
- -- example an expression function) and it does not declare types with
- -- nontrivial initialization procedures.
+ -- example an expression function). Note that we need to test again the
+ -- Is_Inlined flag because Analyze_Subprogram_Body_Helper may have reset
+ -- it if the body contains excluded declarations or statements.
if (Is_Inlined (Pack)
or else Is_Generic_Instance (Pack)
or else Nkind (Decl) = N_Subprogram_Body
or else Present (Corresponding_Body (Decl)))
- and then not Has_Initialized_Type (E)
+ and then Is_Inlined (E)
then
Register_Backend_Inlined_Subprogram (E);
@@ -4528,35 +4524,6 @@ package body Inline is
return False;
end Has_Excluded_Statement;
- --------------------------
- -- Has_Initialized_Type --
- --------------------------
-
- function Has_Initialized_Type (E : Entity_Id) return Boolean is
- E_Body : constant Node_Id := Subprogram_Body (E);
- Decl : Node_Id;
-
- begin
- if No (E_Body) then -- imported subprogram
- return False;
-
- else
- Decl := First (Declarations (E_Body));
- while Present (Decl) loop
- if Nkind (Decl) = N_Full_Type_Declaration
- and then Comes_From_Source (Decl)
- and then Present (Init_Proc (Defining_Identifier (Decl)))
- then
- return True;
- end if;
-
- Next (Decl);
- end loop;
- end if;
-
- return False;
- end Has_Initialized_Type;
-
-----------------------
-- Has_Single_Return --
-----------------------
diff --git a/gcc/ada/usage.adb b/gcc/ada/usage.adb
index bf8417a92c8..868ecd85000 100644
--- a/gcc/ada/usage.adb
+++ b/gcc/ada/usage.adb
@@ -562,9 +562,9 @@ begin
Write_Line (" .O* turn off warnings for out parameters assigned " &
"but not read");
Write_Line (" p+ turn on warnings for ineffective pragma " &
- "Inline in frontend");
+ "Inline");
Write_Line (" P* turn off warnings for ineffective pragma " &
- "Inline in frontend");
+ "Inline");
Write_Line (" .p+ turn on warnings for suspicious parameter " &
"order");
Write_Line (" .P* turn off warnings for suspicious parameter " &
--
2.51.0