If a subprogram to be inlined has a by-reference parameter, the value of the
actual must be captured in a renaming declaration to avoid an improper copy.
This was done for limited types and tagged types but not for types with by-
reference components.

The following must execute quietly:

with D2; use D2;
with Text_Io; use Text_Io;
procedure Always_Test is
  generic
    with procedure Action (By_Ref : By_Ref_T);
  procedure Scan_G;

  procedure Scan_G is
  begin
    Action (Data.By_Ref);
  end Scan_G;

  procedure Scan_Inline_Always is new Scan_G (Action_Inline_Always);

  procedure Scan is new Scan_G (Action);
begin

  Data := (12, (34,  (Me_tagged => 46)), 78);

  Scan;
  Scan_Inline_Always;
end Always_Test;
---
package D2 is
  type Tagged_T is tagged record Me_Tagged : Positive; end record;
  type By_Ref_T is
    record
      Me : Positive;
      Make_By_Ref : Tagged_T;
    end record;

  type Container_T is
    record
      Me_Bef : Positive;
      By_Ref : By_Ref_T;
      Me_After : Positive;
    end record;

  Data : Container_T;

  procedure Action_Inline_Always (By_Ref : By_Ref_T);
  pragma Inline_Always (Action_Inline_Always);

  procedure Action (By_Ref : By_Ref_T);
end D2;
---
with Text_Io; use Text_Io;
with System; use System;
package body D2 is
  procedure Common_Action (From : String;
                           Addr : System.Address) is
  begin
    if Addr = Data.By_Ref'Address then
      null;
    else
      Put_Line ("FAILED");
    end if;
  end Common_Action;

  procedure Action_Inline_Always (By_Ref : By_Ref_T) is
  begin
    Common_Action ("Action_Inline_Always", By_Ref'Address);
  end Action_Inline_Always;

  procedure Action (By_Ref : By_Ref_T) is
  begin
    Common_Action ("Action", By_Ref'Address);
  end Action;
end D2;

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

2011-09-01  Ed Schonberg  <schonb...@adacore.com>

        * exp_ch6.adb (Expand_Inlined_Call): If an actual is a by_reference
        type, declare a renaming for it, not an object declaration.

Index: exp_ch6.adb
===================================================================
--- exp_ch6.adb (revision 178403)
+++ exp_ch6.adb (working copy)
@@ -4188,6 +4188,7 @@
             if Ekind (F) = E_In_Parameter
               and then not Is_Limited_Type (Etype (A))
               and then not Is_Tagged_Type  (Etype (A))
+              and then not Is_By_Reference_Type (Etype (A))
               and then
                (not Is_Array_Type (Etype (A))
                  or else not Is_Object_Reference (A)

Reply via email to