+2013-04-23 Hristian Kirtchev <kirtchev@adacore.com>
+
+ * sem_prag.adb (Analyze_Dependency_Clause): Update all calls to
+ Analyze_Input_Output.
+ (Analyze_Input_List): Update all calls to Analyze_Input_Output.
+ (Analyze_Input_Output): Add formal parameter Self_Ref along with
+ comment on its usage. Update all calls to Analyze_Input_Output.
+ (Analyze_Pragma): Add new local variable Self_Ref to capture
+ the presence of a self-referential dependency clause. Update
+ all calls to Analyze_Input_Output.
+ (Check_Mode): Add formal parameter Self_Ref along with comment on its
+ usage. Verify the legality of a self-referential output.
+
+2013-04-23 Ed Schonberg <schonberg@adacore.com>
+
+ * exp_ch6.adb: Add predicate checks on by-copy parameter.
+
+2013-04-23 Vincent Celier <celier@adacore.com>
+
+ * a-envvar.adb, a-envvar.ads (Value): New.
+
2013-04-22 Yannick Moy <moy@adacore.com>
* exp_prag.adb (Expand_Pragma_Loop_Variant): Rewrite pragma as
-- --
------------------------------------------------------------------------------
+with Aspects; use Aspects;
with Atree; use Atree;
with Checks; use Checks;
with Debug; use Debug;
-- function, so it must be done explicitly after the call. Ditto
-- if the actual is an entity of a predicated subtype.
- if Is_By_Reference_Type (E_Formal)
- and then Has_Predicates (E_Actual)
+ -- The rule refers to by-reference types, but a check is needed
+ -- for by-copy types as well. That check is subsumed by the rule
+ -- 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.
+
+ if (Present (Find_Aspect (E_Actual, Aspect_Predicate))
+ or else Present
+ (Find_Aspect (E_Actual, Aspect_Dynamic_Predicate))
+ or else Present
+ (Find_Aspect (E_Actual, Aspect_Static_Predicate)))
and then not Is_Init_Proc (Subp)
then
if Is_Derived_Type (E_Actual)
procedure Check_Mode
(Item : Node_Id;
Item_Id : Entity_Id;
- Is_Input : Boolean);
+ Is_Input : Boolean;
+ Self_Ref : Boolean);
-- Ensure that an item has a proper "in", "in out" or "out" mode
-- depending on its function. If this is not the case, emit an
- -- error.
+ -- error. Item and Item_Id denote the attributes of an item. Flag
+ -- Is_Input should be set when item comes from an input list.
+ -- Flag Self_Ref should be set when the item is an output and the
+ -- dependency clause has operator "+".
procedure Check_Usage
(Subp_List : Elist_Id;
procedure Analyze_Input_Output
(Item : Node_Id;
Is_Input : Boolean;
+ Self_Ref : Boolean;
Top_Level : Boolean;
Seen : in out Elist_Id;
Null_Seen : in out Boolean);
-- Verify the legality of a single input or output item. Flag
-- Is_Input should be set whenever Item is an input, False when
- -- it denotes an output. Flag Top_Level should be set whenever
- -- Item appears immediately within an input or output list.
- -- Seen is a collection of all abstract states, variables and
- -- formals processed so far. Flag Null_Seen denotes whether a
- -- null input or output has been encountered.
+ -- it denotes an output. Flag Self_Ref should be set when the
+ -- item is an output and the dependency clause has a "+". Flag
+ -- Top_Level should be set whenever Item appears immediately
+ -- within an input or output list. Seen is a collection of all
+ -- abstract states, variables and formals processed so far.
+ -- Flag Null_Seen denotes whether a null input or output has
+ -- been encountered.
------------------------
-- Analyze_Input_List --
Analyze_Input_Output
(Item => Input,
Is_Input => True,
+ Self_Ref => False,
Top_Level => False,
Seen => Inputs_Seen,
Null_Seen => Null_Input_Seen);
Analyze_Input_Output
(Item => Inputs,
Is_Input => True,
+ Self_Ref => False,
Top_Level => False,
Seen => Inputs_Seen,
Null_Seen => Null_Input_Seen);
procedure Analyze_Input_Output
(Item : Node_Id;
Is_Input : Boolean;
+ Self_Ref : Boolean;
Top_Level : Boolean;
Seen : in out Elist_Id;
Null_Seen : in out Boolean)
Analyze_Input_Output
(Item => Grouped,
Is_Input => Is_Input,
+ Self_Ref => Self_Ref,
Top_Level => False,
Seen => Seen,
Null_Seen => Null_Seen);
-- Ensure that the item is of the correct mode
-- depending on its function.
- Check_Mode (Item, Item_Id, Is_Input);
+ Check_Mode (Item, Item_Id, Is_Input, Self_Ref);
-- Detect multiple uses of the same state, variable
-- or formal parameter. If this is not the case,
-- Local variables
- Inputs : Node_Id;
- Output : Node_Id;
+ Inputs : Node_Id;
+ Output : Node_Id;
+ Self_Ref : Boolean;
-- Start of processing for Analyze_Dependency_Clause
begin
+ Inputs := Expression (Clause);
+ Self_Ref := False;
+
+ -- An input list with a self-dependency appears as operator "+"
+ -- where the actuals inputs are the right operand.
+
+ if Nkind (Inputs) = N_Op_Plus then
+ Inputs := Right_Opnd (Inputs);
+ Self_Ref := True;
+ end if;
+
-- Process the output_list of a dependency_clause
Output := First (Choices (Clause));
Analyze_Input_Output
(Item => Output,
Is_Input => False,
+ Self_Ref => Self_Ref,
Top_Level => True,
Seen => Outputs_Seen,
Null_Seen => Null_Output_Seen);
-- Process the input_list of a dependency_clause
- Inputs := Expression (Clause);
-
- -- An input list with a self-dependency appears as operator "+"
- -- where the actuals inputs are the right operand.
-
- if Nkind (Inputs) = N_Op_Plus then
- Inputs := Right_Opnd (Inputs);
- end if;
-
Analyze_Input_List (Inputs);
end Analyze_Dependency_Clause;
procedure Check_Mode
(Item : Node_Id;
Item_Id : Entity_Id;
- Is_Input : Boolean)
+ Is_Input : Boolean;
+ Self_Ref : Boolean)
is
begin
+ -- Input
+
if Is_Input then
if Ekind (Item_Id) = E_Out_Parameter
or else (Global_Seen
("item & must have mode in or in out", Item, Item_Id);
end if;
- -- Output
+ -- Self-referential output
- else
- if Ekind (Item_Id) = E_In_Parameter
- or else
- (Global_Seen
- and then not Appears_In (Subp_Outputs, Item_Id))
- then
+ elsif Self_Ref then
+
+ -- A self-referential state or variable must appear in both
+ -- input and output lists of a subprogram.
+
+ if Ekind_In (Item_Id, E_Abstract_State, E_Variable) then
+ if Global_Seen
+ and then not Appears_In (Subp_Inputs, Item_Id)
+ then
+ Error_Msg_NE
+ ("item & must have mode in out", Item, Item_Id);
+ end if;
+
+ -- Self-referential parameter
+
+ elsif Ekind (Item_Id) /= E_In_Out_Parameter then
Error_Msg_NE
- ("item & must have mode out or in out", Item, Item_Id);
+ ("item & must have mode in out", Item, Item_Id);
end if;
+
+ -- Regular output
+
+ elsif Ekind (Item_Id) = E_In_Parameter
+ or else
+ (Global_Seen
+ and then not Appears_In (Subp_Outputs, Item_Id))
+ then
+ Error_Msg_NE
+ ("item & must have mode out or in out", Item, Item_Id);
end if;
end Check_Mode;