Patchwork [Ada] Build-in place calls with inherited operations of untagged types

login
register
mail settings
Submitter Arnaud Charlet
Date June 17, 2010, 1:39 p.m.
Message ID <20100617133956.GA14591@adacore.com>
Download mbox | patch
Permalink /patch/56048/
State New
Headers show

Comments

Arnaud Charlet - June 17, 2010, 1:39 p.m.
When a call invokes an inherited operation, the parent function is placed
on the tree after expansion. If the call is for a build-in-place function,
subsequent expansion builds an access type to designate the constructed
object. The designated type of this access type is the type imposed by the
context, rather than that of the function, which may be the parent operation.
The following must compile quietly in Ada05:

procedure Limited_Problem is

   package Isolated is

      type Limited_Type is limited record
         Value : Integer:= -12345;
      end record;

      function Create return Limited_Type;

   end Isolated;

   package body Isolated is

      function Create return Limited_Type is
      begin
         return (others => <>);
      end Create;

   end Isolated;

   type Limited_Type_2 is new Isolated.Limited_Type;

   X : Limited_Type_2 := Create;

begin
   null;
end Limited_Problem;

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

2010-06-17  Ed Schonberg  <schonberg@adacore.com>

	* exp_ch6.adb (Make_Build_In_Place_Call_In_Object_Declaration): The
	designated type of the generated pointer is the type of the original
	expression, not that of the function call itself, because the return
	type may be an untagged  derived type and the function may be an
	inherited operation.

Patch

Index: exp_ch6.adb
===================================================================
--- exp_ch6.adb	(revision 160914)
+++ exp_ch6.adb	(working copy)
@@ -5095,7 +5095,7 @@  package body Exp_Ch6 is
          Rewrite (Allocator, New_Allocator);
 
          --  Create a new access object and initialize it to the result of the
-         --  new uninitialized allocator. Do not use Allocator as the
+         --  new uninitialized allocator. Note: we do not use Allocator as the
          --  Related_Node of Return_Obj_Access in call to Make_Temporary below
          --  as this would create a sort of infinite "recursion".
 
@@ -5660,7 +5660,10 @@  package body Exp_Ch6 is
       Add_Access_Actual_To_Build_In_Place_Call
         (Func_Call, Function_Id, Caller_Object, Is_Access => Pass_Caller_Acc);
 
-      --  Create an access type designating the function's result subtype
+      --  Create an access type designating the function's result subtype. We
+      --  use the type of the original expression because it may be a call to
+      --  an inherited operation, which the expansion has replaced with the
+      --  parent operation that yields the parent type.
 
       Ref_Type := Make_Temporary (Loc, 'A');
 
@@ -5671,7 +5674,7 @@  package body Exp_Ch6 is
             Make_Access_To_Object_Definition (Loc,
               All_Present => True,
               Subtype_Indication =>
-                New_Reference_To (Result_Subt, Loc)));
+                New_Reference_To (Etype (Function_Call), Loc)));
 
       --  The access type and its accompanying object must be inserted after
       --  the object declaration in the constrained case, so that the function