+2014-07-29 Vincent Celier <celier@adacore.com>
+
+ * gnat_ugn.texi: Document that configuration pragmas files are
+ added to the dependencies, unless they contain only pragmas
+ Source_File_Name_Project.
+
+2014-07-29 Robert Dewar <dewar@adacore.com>
+
+ * frontend.adb: Minor reformatting.
+
+2014-07-29 Robert Dewar <dewar@adacore.com>
+
+ * exp_ch6.adb (Add_Call_By_Copy_Code): Minor reformatting
+ (Expand_Actuals): Make sure predicate checks are properly applied
+ for the case of OUT or IN OUT parameters.
+ * sem_res.adb: Minor reformatting (Resolve_Actuals): Skip
+ predicate tests on arguments for Finalize
+ * sem_util.adb (No_Predicate_Test_On_Arguments): Returns True
+ if predicate tests on subprogram arguments should be skipped.
+ * sem_util.ads (No_Predicate_Test_On_Arguments): New function
+
+2014-07-29 Ed Schonberg <schonberg@adacore.com>
+
+ * sem_ch3.adb (Analyze_Object_Declaration): If there is an address
+ clause for the object and the expression is an aggregate, defer
+ resolution and expansion of the aggregate until the freeze point
+ of the entity.
+ * sem_aggr.adb (Resolve_Aggregate): An others_clause is legal if
+ the parent node is an N_Reference generated during expansion.
+
+2014-07-29 Vincent Celier <celier@adacore.com>
+
+ * prj.adb (Add_To_Buffer): Effectively double the size of the buffer.
+
2014-07-29 Robert Dewar <dewar@adacore.com>
* frontend.adb, inline.adb, sem_util.adb, sem_res.adb,
-- --
------------------------------------------------------------------------------
-with Aspects; use Aspects;
with Atree; use Atree;
with Checks; use Checks;
with Debug; use Debug;
-- For non-scalar objects that are possibly unaligned, add call by copy
-- code (copy in for IN and IN OUT, copy out for OUT and IN OUT).
--
+ -- For OUT and IN OUT parameters, add predicate checks after the call
+ -- based on the predicates of the actual type.
+ --
-- The parameter N is IN OUT because in some cases, the expansion code
-- rewrites the call as an expression actions with the call inside. In
-- this case N is reset to point to the inside call so that the caller
Init := Empty;
Indic :=
Make_Subtype_Indication (Loc,
- Subtype_Mark =>
- New_Occurrence_Of (F_Typ, Loc),
+ Subtype_Mark => New_Occurrence_Of (F_Typ, Loc),
Constraint =>
Make_Index_Or_Discriminant_Constraint (Loc,
Constraints => New_List (
Make_Range (Loc,
Low_Bound =>
Make_Attribute_Reference (Loc,
- Prefix => New_Occurrence_Of (Var, Loc),
+ Prefix => New_Occurrence_Of (Var, Loc),
Attribute_Name => Name_First),
High_Bound =>
Make_Attribute_Reference (Loc,
- Prefix => New_Occurrence_Of (Var, Loc),
+ Prefix => New_Occurrence_Of (Var, Loc),
Attribute_Name => Name_Last)))));
else
Add_Call_By_Copy_Code;
end if;
- -- RM 3.2.4 (23/3) : A predicate is checked on in-out and out
+ -- RM 3.2.4 (23/3): A predicate is checked on in-out and out
-- by-reference parameters on exit from the call. If the actual
-- is a derived type and the operation is inherited, the body
-- of the operation will not contain a call to the predicate
-- for subtype conversion on assignment, but we can generate the
-- required check now.
- -- Note that this is needed only if the subtype of the actual has
- -- an explicit predicate aspect, not if it inherits them from a
- -- base type or ancestor. The check is also superfluous if the
- -- subtype is elaborated before the body of the subprogram, but
- -- this is harder to verify, and there may be a redundant check.
-
-- Note also that Subp may be either a subprogram entity for
-- direct calls, or a type entity for indirect calls, which must
-- be handled separately because the name does not denote an
-- overloadable entity.
- if not Is_Init_Proc (Subp)
- and then (Has_Aspect (E_Actual, Aspect_Predicate)
- or else
- Has_Aspect (E_Actual, Aspect_Dynamic_Predicate)
- or else
- Has_Aspect (E_Actual, Aspect_Static_Predicate))
- and then Present (Predicate_Function (E_Actual))
- then
- Append_To (Post_Call,
- Make_Predicate_Check (E_Actual, Actual));
- end if;
+ declare
+ Aund : constant Entity_Id := Underlying_Type (E_Actual);
+ Atyp : Entity_Id;
+
+ begin
+ if No (Aund) then
+ Atyp := E_Actual;
+ else
+ Atyp := Aund;
+ end if;
+
+ if Has_Predicates (Atyp)
+ and then Present (Predicate_Function (Atyp))
+
+ -- Skip predicate checks for special cases
+
+ and then not No_Predicate_Test_On_Arguments (Subp)
+ then
+ Append_To (Post_Call,
+ Make_Predicate_Check (Atyp, Actual));
+ end if;
+ end;
-- Processing for IN parameters
Config_Pragmas : List_Id;
-- Gather configuration pragmas
- function Need_To_Be_In_The_Dependencies (Pragma_List : List_Id)
- return Boolean;
+ function Need_To_Be_In_The_Dependencies
+ (Pragma_List : List_Id) return Boolean;
-- Check if a configuration pragmas file that contains the Pragma_List
-- should be a dependency for the source being compiled. Returns
-- False if Pragma_List is Error_List or contains only pragmas
-- Need_To_Be_In_The_Dependencies --
------------------------------------
- function Need_To_Be_In_The_Dependencies (Pragma_List : List_Id)
- return Boolean
+ function Need_To_Be_In_The_Dependencies
+ (Pragma_List : List_Id) return Boolean
is
Prag : Node_Id;
Pname : Name_Id;
+
begin
if Pragma_List /= Error_List then
Prag := First (Pragma_List);
return False;
end Need_To_Be_In_The_Dependencies;
+-- Start of processing for Frontend
+
begin
-- Carry out package initializations. These are initializations which might
-- logically be performed at elaboration time, were it not for the fact
declare
Pragma_List : constant List_Id :=
- Par (Configuration_Pragmas => True);
+ Par (Configuration_Pragmas => True);
+
begin
if Need_To_Be_In_The_Dependencies (Pragma_List) then
Prepcomp.Add_Dependency (Source_Config_File);
this file is present, it is expected to contain one or more
configuration pragmas that will be applied to the current compilation.
However, if the switch @option{-gnatA} is used, @file{gnat.adc} is not
-considered.
+considered. When taken into account, @file{gnat.adc} is added to the
+dependencies, so that if @file{gnat.adc} is modified later, an invocation of
+@command{gnatmake} will recompile the source.
Configuration pragmas may be entered into the @file{gnat.adc} file
either by running @code{gnatchop} on a source file that consists only of
-configuration pragmas, or more conveniently by
-direct editing of the @file{gnat.adc} file, which is a standard format
-source file.
+configuration pragmas, or more conveniently by direct editing of the
+@file{gnat.adc} file, which is a standard format source file.
In addition to @file{gnat.adc}, additional files containing configuration
pragmas may be applied to the current compilation using the switch
-@option{-gnatec}@var{path}. @var{path} must designate an existing file that
+@option{-gnatec=}@var{path}. @var{path} must designate an existing file that
contains only configuration pragmas. These configuration pragmas are
in addition to those found in @file{gnat.adc} (provided @file{gnat.adc}
is present and switch @option{-gnatA} is not used).
-It is allowed to specify several switches @option{-gnatec}, all of which
+It is allowable to specify several switches @option{-gnatec=}, all of which
will be taken into account.
+Files containing configuration pragmas specified with switches
+@option{-gnatec=} are added to the dependencies, unless they contain
+only pragmas Source_File_Name_Project.
+
If you are using project file, a separate mechanism is provided using
project attributes, see @ref{Specifying Configuration Pragmas} for more
details.
while Last + S'Length > To'Last loop
declare
New_Buffer : constant String_Access :=
- new String (1 .. 2 * Last);
+ new String (1 .. 2 * To'Length);
begin
New_Buffer (1 .. Last) := To (1 .. Last);
-- formal parameter. Consequently we also need to test for
-- N_Procedure_Call_Statement or N_Function_Call.
+ -- The context may be an N_Reference node, created by expansion.
+ -- Legality of the others clause was established in the source,
+ -- so the context is legal.
+
Set_Etype (N, Aggr_Typ); -- May be overridden later on
if Pkind = N_Assignment_Statement
Pkind = N_Component_Declaration or else
Pkind = N_Parameter_Specification or else
Pkind = N_Qualified_Expression or else
+ Pkind = N_Reference or else
Pkind = N_Aggregate or else
Pkind = N_Extension_Aggregate or else
Pkind = N_Component_Association))
-- early usage within E is properly diagnosed.
Set_Etype (Id, T);
- Resolve (E, T);
+
+ -- If the expression is an aggregate we must look ahead to detect
+ -- the possible presence of an address clause, and defer resolution
+ -- and expansion of the aggregate to the freeze point of the entity.
+
+ if Comes_From_Source (N)
+ and then Expander_Active
+ and then Has_Following_Address_Clause (N)
+ and then Nkind (E) = N_Aggregate
+ then
+ Set_Etype (E, T);
+
+ else
+ Resolve (E, T);
+ end if;
-- No further action needed if E is a call to an inlined function
-- which returns an unconstrained type and it has been expanded into
return;
end if;
- -- Apply appropriate range checks for in, out, and in-out
- -- parameters. Out and in-out parameters also need a separate
- -- check, if there is a type conversion, to make sure the return
- -- value meets the constraints of the variable before the
- -- conversion.
-
- -- Gigi looks at the check flag and uses the appropriate types.
- -- For now since one flag is used there is an optimization which
- -- might not be done in the In Out case since Gigi does not do
- -- any analysis. More thought required about this ???
+ -- Apply appropriate constraint/predicate checks for IN [OUT] case
if Ekind_In (F, E_In_Parameter, E_In_Out_Parameter) then
- -- Apply predicate checks, unless this is a call to the
- -- predicate check function itself, which would cause an
- -- infinite recursion, or it is a call to an initialization
- -- procedure whose operand is of course an unfinished object.
+ -- Apply predicate tests except in certain special cases. Note
+ -- that it might be more consistent to apply these only when
+ -- expansion is active (in Exp_Ch6.Expand_Actuals), as we do
+ -- for the outbound predicate tests.
- if not (Ekind (Nam) = E_Function
- and then (Is_Predicate_Function (Nam)
- or else
- Is_Predicate_Function_M (Nam)))
- and then not Is_Init_Proc (Nam)
- then
+ if not No_Predicate_Test_On_Arguments (Nam) then
Apply_Predicate_Check (A, F_Typ);
end if;
-- Apply required constraint checks
+ -- Gigi looks at the check flag and uses the appropriate types.
+ -- For now since one flag is used there is an optimization
+ -- which might not be done in the IN OUT case since Gigi does
+ -- not do any analysis. More thought required about this ???
+
+ -- In fact is this comment obsolete??? doesn't the expander now
+ -- generate all these tests anyway???
+
if Is_Scalar_Type (Etype (A)) then
Apply_Scalar_Range_Check (A, F_Typ);
end if;
end if;
+ -- Checks for OUT parameters and IN OUT parameters
+
if Ekind_In (F, E_Out_Parameter, E_In_Out_Parameter) then
+
+ -- If there is a type conversion, to make sure the return value
+ -- meets the constraints of the variable before the conversion.
+
if Nkind (A) = N_Type_Conversion then
if Is_Scalar_Type (A_Typ) then
Apply_Scalar_Range_Check
(Expression (A), Etype (Expression (A)), A_Typ);
end if;
+ -- If no conversion apply scalar range checks and length checks
+ -- base on the subtype of the actual (NOT that of the formal).
+
else
if Is_Scalar_Type (F_Typ) then
Apply_Scalar_Range_Check (A, A_Typ, F_Typ);
Apply_Range_Check (A, A_Typ, F_Typ);
end if;
end if;
+
+ -- Note: we do not apply the predicate checks for the case of
+ -- OUT and IN OUT parameters. They are instead applied in the
+ -- Expand_Actuals routine in Exp_Ch6.
end if;
-- An actual associated with an access parameter is implicitly
Actual_Id := Next_Actual (Actual_Id);
end Next_Actual;
+ ------------------------------------
+ -- No_Predicate_Test_On_Arguments --
+ ------------------------------------
+
+ function No_Predicate_Test_On_Arguments (Subp : Entity_Id) return Boolean is
+ begin
+ -- Do not test predicates on call to generated default Finalize, since
+ -- we are not interested in whether something we are finalizing (and
+ -- typically destroying) satisfies its predicates.
+
+ if Chars (Subp) = Name_Finalize
+ and then not Comes_From_Source (Subp)
+ then
+ return True;
+
+ -- Do not test predicates on call to Init_Proc, since if needed the
+ -- predicate test will occur at some other point.
+
+ elsif Is_Init_Proc (Subp) then
+ return True;
+
+ -- Do not test predicates on call to predicate function, since this
+ -- would cause infinite recursion.
+
+ elsif Ekind (Subp) = E_Function
+ and then (Is_Predicate_Function (Subp)
+ or else
+ Is_Predicate_Function_M (Subp))
+ then
+ return True;
+
+ -- For now, no other cases
+
+ else
+ return False;
+ end if;
+ end No_Predicate_Test_On_Arguments;
+
---------------------
-- No_Scalar_Parts --
---------------------
-- Note that the result produced is always an expression, not a parameter
-- association node, even if named notation was used.
+ function No_Predicate_Test_On_Arguments (Subp : Entity_Id) return Boolean;
+ -- Subp is the entity for a subprogram call. This function returns True to
+ -- eliminate predicate tests on the input or output arguments in a call to
+ -- this subprogram. See body for exact cases currently covered.
+
function No_Scalar_Parts (T : Entity_Id) return Boolean;
-- Tests if type T can be determined at compile time to have no scalar
-- parts in the sense of the Valid_Scalars attribute. Returns True if