+2018-05-31 Ed Schonberg <schonberg@adacore.com>
+
+ * checks.adb (Apply_Discriminant_Check): Do not apply discriminant
+ check to a call to a build-in-place function, given that the return
+ object is limited and cannot be copied.
+
2018-05-31 Olivier Hainque <hainque@adacore.com>
* libgnat/s-atopri.ads: Update comment on __atomic_compare_exchange
T_Typ := Typ;
end if;
+ -- If the expression is a function call that returns a limited object
+ -- it cannot be copied. It is not clear how to perform the proper
+ -- discriminant check in this case because the discriminant value must
+ -- be retrieved from the constructed object itself.
+
+ if Nkind (N) = N_Function_Call
+ and then Is_Limited_Type (Typ)
+ and then Is_Entity_Name (Name (N))
+ and then Returns_By_Ref (Entity (Name (N)))
+ then
+ return;
+ end if;
+
-- Only apply checks when generating code and discriminant checks are
-- not suppressed. In GNATprove mode, we do not apply the checks, but we
-- still analyze the expression to possibly issue errors on SPARK code
+2018-05-31 Ed Schonberg <schonberg@adacore.com>
+
+ * gnat.dg/limited1.adb, gnat.dg/limited1_inner.adb,
+ gnat.dg/limited1_inner.ads, gnat.dg/limited1_outer.adb,
+ gnat.dg/limited1_outer.ads: New testcase.
+
2018-05-31 Hristian Kirtchev <kirtchev@adacore.com>
* gnat.dg/tampering_check1.adb, gnat.dg/tampering_check1_ivectors.ads,
--- /dev/null
+-- { dg-do run }
+
+with Limited1_Outer; use Limited1_Outer;
+
+procedure Limited1 is
+ X : Outer_Type := Make_Outer;
+begin
+ null;
+end;
--- /dev/null
+package body Limited1_Inner is
+ overriding procedure Finalize (X : in out Limited_Type) is
+ begin
+ if X.Self /= X'Unchecked_Access then
+ raise Program_Error with "Copied!";
+ end if;
+ end;
+
+ function Make_Inner return Inner_Type is
+ begin
+ return Inner : Inner_Type (True) do
+ null;
+ end return;
+ end;
+end;
--- /dev/null
+with Ada.Finalization;
+package Limited1_Inner is
+ type Limited_Type is new Ada.Finalization.Limited_Controlled with record
+ Self : access Limited_Type := Limited_Type'Unchecked_Access;
+ end record;
+ overriding procedure Finalize (X : in out Limited_Type);
+
+ type Inner_Type (What : Boolean) is record
+ case What is
+ when False =>
+ null;
+ when True =>
+ L : Limited_Type;
+ end case;
+ end record;
+
+ function Make_Inner return Inner_Type;
+end;
--- /dev/null
+package body Limited1_Outer is
+ function Make_Outer return Outer_Type is
+ begin
+ return (What => True, Inner => Make_Inner);
+ end;
+end;
--- /dev/null
+with Limited1_Inner; use Limited1_Inner;
+
+package Limited1_Outer is
+ type Outer_Type (What : Boolean) is record
+ Inner : Inner_Type (What);
+ end record;
+
+ function Make_Outer return Outer_Type;
+end Limited1_Outer;