+2018-09-26 Ed Schonberg <schonberg@adacore.com>
+
+ * contracts.adb (Expand_Subprogram_Contract,
+ Process_Preconditions_For): Apply Freeze_Expr_Types to the
+ expression for a precondition of an expression function that is
+ a completion, when the completion appears in the private part
+ and the declaration it completes is in the visible part of the
+ same package.
+ * freeze.adb (Freeze_Expr_Types): Do not establish the scope of
+ the operation if it is already installed, as will be the case
+ when called to analyze the contract oc the subprogram (which
+ happens when generating code inside the subprogram body).
+
2018-09-26 Maroua Maalej <maalej@adacore.com>
* sem_spark.adb (Check_Param_In, Setup_Parameter_Or_Global):
with Exp_Tss; use Exp_Tss;
with Exp_Util; use Exp_Util;
with Freeze; use Freeze;
+with Lib; use Lib;
with Namet; use Namet;
with Nlists; use Nlists;
with Nmake; use Nmake;
if Skip_Assert_Exprs then
null;
- -- Otherwise analyze the pre/postconditions. Their expressions
+ -- Otherwise analyze the pre/postconditions.
+ -- If these come from an aspect specification, their expressions
-- might include references to types that are not frozen yet, in the
-- case where the body is a rewritten expression function that is a
-- completion, so freeze all types within before constructing the
procedure Process_Preconditions_For (Subp_Id : Entity_Id) is
Items : constant Node_Id := Contract (Subp_Id);
+ Bod : constant Node_Id := Unit_Declaration_Node (Body_Id);
Decl : Node_Id;
+ Freeze_T : Boolean;
Prag : Node_Id;
Subp_Decl : Node_Id;
begin
- -- Process the contract
+ -- Process the contract. If the body is an expression function
+ -- that is a completion, freeze types within, because this may
+ -- not have been done yet, when the subprogram declaration and
+ -- its completion by an expression function appear in distinct
+ -- declarative lists of the same unit (visible and private).
+
+ Freeze_T := Was_Expression_Function (Bod)
+ and then Sloc (Body_Id) /= Sloc (Subp_Id)
+ and then In_Same_Source_Unit (Body_Id, Subp_Id)
+ and then List_Containing (Bod) /=
+ List_Containing (Unit_Declaration_Node (Subp_Id))
+ and then not In_Instance;
if Present (Items) then
Prag := Pre_Post_Conditions (Items);
if Pragma_Name (Prag) = Name_Precondition
and then Is_Checked (Prag)
then
+ if Freeze_T
+ and then Present (Corresponding_Aspect (Prag))
+ then
+ Freeze_Expr_Types (Subp_Id, Standard_Boolean,
+ Expression (Corresponding_Aspect (Prag)), Bod);
+ end if;
+
Prepend_To_Decls_Or_Save (Prag);
end if;
-- minimum decoration needed to locate referenced unfrozen types
-- without adding any decoration to the function expression.
- Push_Scope (Def_Id);
- Install_Formals (Def_Id);
+ -- This routine is also applied to expressions in the contract for
+ -- the subprogram. If that happens when expanding the code for
+ -- pre/postconditions during expansion of the subprogram body, the
+ -- subprogram is already installed.
- Preanalyze_Spec_Expression (Dup_Expr, Typ);
- End_Scope;
+ if Def_Id /= Current_Scope then
+ Push_Scope (Def_Id);
+ Install_Formals (Def_Id);
+
+ Preanalyze_Spec_Expression (Dup_Expr, Typ);
+ End_Scope;
+ else
+ Preanalyze_Spec_Expression (Dup_Expr, Typ);
+ end if;
-- Restore certain attributes of Def_Id since the preanalysis may
-- have introduced itypes to this scope, thus modifying attributes