This patch fixes an omission in the code that resolves actuals in a call. Previous to this patch, and actual in a call that is an overloaded function call, one of whose interpretations returns an unconstrained limited type may be resolved incorrectly. The command
gnatmake -q -gnat05 main main Must yield Create for Type_A --- with Lib; use Lib; procedure Main is A : Type_A (2); begin Set (A, Create (2)); end Main; --- private with Ada.Finalization; package Lib is type Type_B (Value : Integer) is tagged limited private; function Create (Value : Integer) return Type_B; type Type_A (Value : Integer) is tagged limited private; function Create (Value : Integer) return Type_A; procedure Set (Left : in out Type_A; Right : Type_A); private use Ada.Finalization; type Type_B (Value : Integer) is new Limited_Controlled with null record; type Natural_A is access Natural; type Type_A (Value : Integer) is new Limited_Controlled with record Refcount : Natural_A; end record; overriding procedure Initialize (Object : in out Type_A); procedure Adjust (Object : in out Type_A); overriding procedure Finalize (Object : in out Type_A); end Lib; --- with Ada.Text_IO; with System.Storage_Elements; with Unchecked_Deallocation; package body Lib is use Ada.Text_IO; procedure Free is new Unchecked_Deallocation (Natural, Natural_A); overriding procedure Initialize (Object : in out Type_A) is begin Object.Refcount := new Natural'(1); end Initialize; procedure Adjust (Object : in out Type_A) is begin raise Program_Error with "Never override Adjust for Limited type."; end Adjust; overriding procedure Finalize (Object : in out Type_A) is Refcount : Natural_A := Object.Refcount; begin Object.Refcount := null; -- Finalize must be idempotent if Refcount = null then null; else Refcount.all := Refcount.all - 1; if Refcount.all = 0 then Free (Refcount); end if; end if; end Finalize; procedure Set (Left : in out Type_A; Right : Type_A) is begin if Left.Value /= Right.Value then Put_Line ("Left.Value, Right.Value : " & Left.Value'Img & ", " & Right.Value'Img); raise Constraint_Error with "Set : Discriminant Values don't match"; end if; Left.Finalize; Left.Refcount := Right.Refcount; Left.Refcount.all := Left.Refcount.all + 1; end Set; function Create (Value : Integer) return Type_A is begin return R : Type_A (Value) do Put_Line ("Create for Type_A"); end return; end Create; function Create (Value : Integer) return Type_B is begin return R : Type_B (Value) do Put_Line ("Create for Type_B"); end return; end Create; end Lib; Tested on x86_64-pc-linux-gnu, committed on trunk 2011-09-02 Ed Schonberg <schonb...@adacore.com> * sem_res.adb (Resolve_Actuals): add missing call to Resolve for an actual that is a function call returning an unconstrained limited controlled type.
Index: sem_res.adb =================================================================== --- sem_res.adb (revision 178381) +++ sem_res.adb (working copy) @@ -3446,6 +3446,7 @@ and then (Is_Controlled (Etype (F)) or else Has_Task (Etype (F))) then Establish_Transient_Scope (A, False); + Resolve (A, Etype (F)); -- A small optimization: if one of the actuals is a concatenation -- create a block around a procedure call to recover stack space.