summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorcharlet <charlet@138bc75d-0d04-0410-961f-82ee72b054a4>2014-02-19 10:25:53 +0000
committercharlet <charlet@138bc75d-0d04-0410-961f-82ee72b054a4>2014-02-19 10:25:53 +0000
commit389062c95789bc6f7cec1b5d92b7bd233377003d (patch)
tree81beccc9022d393327bfc13b482c3b472b676ace /gcc
parent4563499dfd676ff1ff23a4184253ae2bc8ea5399 (diff)
downloadgcc-389062c95789bc6f7cec1b5d92b7bd233377003d.tar.gz
2014-02-19 Robert Dewar <dewar@adacore.com>
* exp_attr.adb (Expand_Min_Max_Attribute): New procedure (Expand_N_Attribute_Reference): Use this procedure for Min and Max. * exp_ch4.adb (Expand_N_Expression_With_Actions): Remove object declarations from list of actions. * output.ads, output.adb (Delete_Last_Char): New procedure. * sinfo.ads: Document handling of Mod and expression with actions in Modify_Tree_For_C mode. 2014-02-19 Ed Schonberg <schonberg@adacore.com> * par-ch9.adb (P_Task): Add a null statement to produce a well-formed task body when due to a previous syntax error the statement list is empty. 2014-02-19 Hristian Kirtchev <kirtchev@adacore.com> * sem_prag.adb (Check_Dependency_Clause): Account for the case where a state with a non-null refinement matches a null output list. Comment reformatting. (Inputs_Match): Copy a solitary input to avoid an assertion failure when trying to match the same input in multiple clauses. 2014-02-19 Gary Dismukes <dismukes@adacore.com> * sem_attr.adb: Minor typo fix. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@207880 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ada/ChangeLog28
-rw-r--r--gcc/ada/exp_attr.adb182
-rw-r--r--gcc/ada/exp_ch4.adb63
-rw-r--r--gcc/ada/output.adb11
-rw-r--r--gcc/ada/output.ads4
-rw-r--r--gcc/ada/par-ch9.adb11
-rw-r--r--gcc/ada/sem_attr.adb2
-rw-r--r--gcc/ada/sem_prag.adb49
-rw-r--r--gcc/ada/sinfo.ads18
9 files changed, 282 insertions, 86 deletions
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index a7937443ddc..d456c84c913 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -1,3 +1,31 @@
+2014-02-19 Robert Dewar <dewar@adacore.com>
+
+ * exp_attr.adb (Expand_Min_Max_Attribute): New procedure
+ (Expand_N_Attribute_Reference): Use this procedure for Min and Max.
+ * exp_ch4.adb (Expand_N_Expression_With_Actions): Remove object
+ declarations from list of actions.
+ * output.ads, output.adb (Delete_Last_Char): New procedure.
+ * sinfo.ads: Document handling of Mod and expression with actions
+ in Modify_Tree_For_C mode.
+
+2014-02-19 Ed Schonberg <schonberg@adacore.com>
+
+ * par-ch9.adb (P_Task): Add a null statement to produce a
+ well-formed task body when due to a previous syntax error the
+ statement list is empty.
+
+2014-02-19 Hristian Kirtchev <kirtchev@adacore.com>
+
+ * sem_prag.adb (Check_Dependency_Clause): Account
+ for the case where a state with a non-null refinement matches a
+ null output list. Comment reformatting.
+ (Inputs_Match): Copy a solitary input to avoid an assertion failure
+ when trying to match the same input in multiple clauses.
+
+2014-02-19 Gary Dismukes <dismukes@adacore.com>
+
+ * sem_attr.adb: Minor typo fix.
+
2014-02-18 Robert Dewar <dewar@adacore.com>
* cstand.adb (Build_Signed_Integer_Type): Minor change of formal
diff --git a/gcc/ada/exp_attr.adb b/gcc/ada/exp_attr.adb
index 7a55d8b6c67..503a1ae3a21 100644
--- a/gcc/ada/exp_attr.adb
+++ b/gcc/ada/exp_attr.adb
@@ -140,6 +140,10 @@ package body Exp_Attr is
-- Handle the expansion of attribute 'Loop_Entry. As a result, the related
-- loop may be converted into a conditional block. See body for details.
+ procedure Expand_Min_Max_Attribute (N : Node_Id);
+ -- Handle the expansion of attributes 'Max and 'Min, including expanding
+ -- then out if we are in Modify_Tree_For_C mode.
+
procedure Expand_Pred_Succ_Attribute (N : Node_Id);
-- Handles expansion of Pred or Succ attributes for case of non-real
-- operand with overflow checking required.
@@ -1035,6 +1039,116 @@ package body Exp_Attr is
end if;
end Expand_Loop_Entry_Attribute;
+ ------------------------------
+ -- Expand_Min_Max_Attribute --
+ ------------------------------
+
+ procedure Expand_Min_Max_Attribute (N : Node_Id) is
+ begin
+ -- Min and Max are handled by the back end (except that static cases
+ -- have already been evaluated during semantic processing, although the
+ -- back end should not count on this). The one bit of special processing
+ -- required in the normal case is that these two attributes typically
+ -- generate conditionals in the code, so check the relevant restriction.
+
+ Check_Restriction (No_Implicit_Conditionals, N);
+
+ -- In Modify_Tree_For_C mode, we rewrite as an if expression
+
+ if Modify_Tree_For_C then
+ declare
+ Loc : constant Source_Ptr := Sloc (N);
+ Typ : constant Entity_Id := Etype (N);
+ Expr : constant Node_Id := First (Expressions (N));
+ Left : constant Node_Id := Relocate_Node (Expr);
+ Right : constant Node_Id := Relocate_Node (Next (Expr));
+ Ltyp : constant Entity_Id := Etype (Left);
+ Rtyp : constant Entity_Id := Etype (Right);
+
+ function Make_Compare (Left, Right : Node_Id) return Node_Id;
+ -- Returns Left >= Right for Max, Left <= Right for Min
+
+ ------------------
+ -- Make_Compare --
+ ------------------
+
+ function Make_Compare (Left, Right : Node_Id) return Node_Id is
+ begin
+ if Attribute_Name (N) = Name_Max then
+ return
+ Make_Op_Ge (Loc,
+ Left_Opnd => Left,
+ Right_Opnd => Right);
+ else
+ return
+ Make_Op_Le (Loc,
+ Left_Opnd => Left,
+ Right_Opnd => Right);
+ end if;
+ end Make_Compare;
+
+ -- Start of processing for Min_Max
+
+ begin
+ -- If both Left and Right are simple entity names, then we can
+ -- just use Duplicate_Expr to duplicate the references and return
+
+ -- (if Left >=|<= Right then Left else Right)
+
+ if Is_Entity_Name (Left) and then Is_Entity_Name (Right) then
+ Rewrite (N,
+ Make_If_Expression (Loc,
+ Expressions => New_List (
+ Make_Compare (Left, Right),
+ Duplicate_Subexpr_No_Checks (Left),
+ Duplicate_Subexpr_No_Checks (Right))));
+
+ -- Otherwise we wrap things in an expression with actions. You
+ -- might think we could just use the approach above, but there
+ -- are problems, in particular with escaped discriminants. In
+ -- this case we generate:
+
+ -- do
+ -- T1 : constant typ := Left;
+ -- T2 : constant typ := Right;
+ -- in
+ -- (if T1 >=|<= T2 then T1 else T2)
+ -- end;
+
+ else
+ declare
+ T1 : constant Entity_Id := Make_Temporary (Loc, 'T', Left);
+ T2 : constant Entity_Id := Make_Temporary (Loc, 'T', Left);
+
+ begin
+ Rewrite (N,
+ Make_Expression_With_Actions (Loc,
+ Actions => New_List (
+ Make_Object_Declaration (Loc,
+ Defining_Identifier => T1,
+ Object_Definition => New_Occurrence_Of (Ltyp, Loc),
+ Expression => Left),
+ Make_Object_Declaration (Loc,
+ Defining_Identifier => T2,
+ Object_Definition => New_Occurrence_Of (Rtyp, Loc),
+ Expression => Right)),
+
+ Expression =>
+ Make_If_Expression (Loc,
+ Expressions => New_List (
+ Make_Compare
+ (New_Occurrence_Of (T1, Loc),
+ New_Occurrence_Of (T2, Loc)),
+ New_Occurrence_Of (T1, Loc),
+ New_Occurrence_Of (T2, Loc)))));
+ end;
+ end if;
+
+ Analyze_And_Resolve (N, Typ);
+ end;
+ end if;
+ end Expand_Min_Max_Attribute;
+
----------------------------------
-- Expand_N_Attribute_Reference --
----------------------------------
@@ -3621,38 +3735,7 @@ package body Exp_Attr is
---------
when Attribute_Max =>
-
- -- Max is handled by the back end (except that static cases have
- -- already been evaluated during semantic processing, but anyway
- -- the back end should not count on this). The one bit of special
- -- processing required in the normal case is that this attribute
- -- typically generates conditionals in the code, so we must check
- -- the relevant restriction.
-
- Check_Restriction (No_Implicit_Conditionals, N);
-
- -- In Modify_Tree_For_C mode, we rewrite as an if expression
-
- if Modify_Tree_For_C then
- declare
- Loc : constant Source_Ptr := Sloc (N);
- Typ : constant Entity_Id := Etype (N);
- Expr : constant Node_Id := First (Expressions (N));
- Left : constant Node_Id := Relocate_Node (Expr);
- Right : constant Node_Id := Relocate_Node (Next (Expr));
-
- begin
- Rewrite (N,
- Make_If_Expression (Loc,
- Expressions => New_List (
- Make_Op_Ge (Loc,
- Left_Opnd => Left,
- Right_Opnd => Right),
- Duplicate_Subexpr_No_Checks (Left),
- Duplicate_Subexpr_No_Checks (Right))));
- Analyze_And_Resolve (N, Typ);
- end;
- end if;
+ Expand_Min_Max_Attribute (N);
----------------------------------
-- Max_Size_In_Storage_Elements --
@@ -3733,7 +3816,7 @@ package body Exp_Attr is
when Attribute_Mechanism_Code =>
- -- We must replace the prefix in the renamed case
+ -- We must replace the prefix i the renamed case
if Is_Entity_Name (Pref)
and then Present (Alias (Entity (Pref)))
@@ -3746,38 +3829,7 @@ package body Exp_Attr is
---------
when Attribute_Min =>
-
- -- Min is handled by the back end (except that static cases have
- -- already been evaluated during semantic processing, but anyway
- -- the back end should not count on this). The one bit of special
- -- processing required in the normal case is that this attribute
- -- typically generates conditionals in the code, so we must check
- -- the relevant restriction.
-
- Check_Restriction (No_Implicit_Conditionals, N);
-
- -- In Modify_Tree_For_C mode, we rewrite as an if expression
-
- if Modify_Tree_For_C then
- declare
- Loc : constant Source_Ptr := Sloc (N);
- Typ : constant Entity_Id := Etype (N);
- Expr : constant Node_Id := First (Expressions (N));
- Left : constant Node_Id := Relocate_Node (Expr);
- Right : constant Node_Id := Relocate_Node (Next (Expr));
-
- begin
- Rewrite (N,
- Make_If_Expression (Loc,
- Expressions => New_List (
- Make_Op_Le (Loc,
- Left_Opnd => Left,
- Right_Opnd => Right),
- Duplicate_Subexpr_No_Checks (Left),
- Duplicate_Subexpr_No_Checks (Right))));
- Analyze_And_Resolve (N, Typ);
- end;
- end if;
+ Expand_Min_Max_Attribute (N);
---------
-- Mod --
diff --git a/gcc/ada/exp_ch4.adb b/gcc/ada/exp_ch4.adb
index d5bd8048fdc..43dc9916ed6 100644
--- a/gcc/ada/exp_ch4.adb
+++ b/gcc/ada/exp_ch4.adb
@@ -5105,12 +5105,64 @@ package body Exp_Ch4 is
-- Local variables
+ Loc : Source_Ptr;
Act : Node_Id;
+ Def : Entity_Id;
+ Exp : Node_Id;
+ Nxt : Node_Id;
-- Start of processing for Expand_N_Expression_With_Actions
begin
+ -- Process the actions as described above
+
Act := First (Actions (N));
+ while Present (Act) loop
+ Process_Single_Action (Act);
+ Next (Act);
+ end loop;
+
+ -- In Modify_Tree_For_C, we have trouble in C with object declarations
+ -- in the actions list (expressions are fine). So if we have an object
+ -- declaration, insert it higher in the tree, if necessary replacing it
+ -- with an assignment to capture initialization.
+
+ if Modify_Tree_For_C then
+ Act := First (Actions (N));
+ while Present (Act) loop
+ if Nkind (Act) = N_Object_Declaration then
+ Def := Defining_Identifier (Act);
+ Exp := Expression (Act);
+ Set_Constant_Present (Act, False);
+ Set_Expression (Act, Empty);
+ Insert_Action (N, Relocate_Node (Act));
+
+ Loc := Sloc (Act);
+
+ -- Expression present, rewrite as assignment, get next action
+
+ if Present (Exp) then
+ Rewrite (Act,
+ Make_Assignment_Statement (Loc,
+ Name => New_Occurrence_Of (Def, Loc),
+ Expression => Exp));
+ Next (Act);
+
+ -- No expression, remove action and move to next
+
+ else
+ Nxt := Next (Act);
+ Remove (Act);
+ Act := Nxt;
+ end if;
+
+ -- Not an object declaration, move to next action
+
+ else
+ Next (Act);
+ end if;
+ end loop;
+ end if;
-- Deal with case where there are no actions. In this case we simply
-- rewrite the node with its expression since we don't need the actions
@@ -5121,17 +5173,8 @@ package body Exp_Ch4 is
-- tree in cases like this. This raises a whole lot of issues of whether
-- we have problems elsewhere, which will be addressed in the future???
- if No (Act) then
+ if Is_Empty_List (Actions (N)) then
Rewrite (N, Relocate_Node (Expression (N)));
-
- -- Otherwise process the actions as described above
-
- else
- loop
- Process_Single_Action (Act);
- Next (Act);
- exit when No (Act);
- end loop;
end if;
end Expand_N_Expression_With_Actions;
diff --git a/gcc/ada/output.adb b/gcc/ada/output.adb
index 901c922fd91..0a739370ae0 100644
--- a/gcc/ada/output.adb
+++ b/gcc/ada/output.adb
@@ -75,6 +75,17 @@ package body Output is
return Pos (Next_Col);
end Column;
+ ----------------------
+ -- Delete_Last_Char --
+ ----------------------
+
+ procedure Delete_Last_Char is
+ begin
+ if Next_Col /= 1 then
+ Next_Col := Next_Col - 1;
+ end if;
+ end Delete_Last_Char;
+
------------------
-- Flush_Buffer --
------------------
diff --git a/gcc/ada/output.ads b/gcc/ada/output.ads
index 715a26a285e..e4137c2add6 100644
--- a/gcc/ada/output.ads
+++ b/gcc/ada/output.ads
@@ -141,6 +141,10 @@ package Output is
-- Returns last character written on the current line, or null if the
-- current line is (so far) empty.
+ procedure Delete_Last_Char;
+ -- Deletes last character written on the current line, no effect if the
+ -- current line is (so far) empty.
+
function Column return Pos;
pragma Inline (Column);
-- Returns the number of the column about to be written (e.g. a value of 1
diff --git a/gcc/ada/par-ch9.adb b/gcc/ada/par-ch9.adb
index 7e4a9ee4e39..da7d76d573a 100644
--- a/gcc/ada/par-ch9.adb
+++ b/gcc/ada/par-ch9.adb
@@ -144,6 +144,17 @@ package body Ch9 is
end if;
Parse_Decls_Begin_End (Task_Node);
+
+ -- The statement list of a task body needs to include at least a
+ -- null statement, so if a parsing error produces an empty list,
+ -- patch it now.
+
+ if
+ No (First (Statements (Handled_Statement_Sequence (Task_Node))))
+ then
+ Set_Statements (Handled_Statement_Sequence (Task_Node),
+ New_List (Make_Null_Statement (Token_Ptr)));
+ end if;
end if;
return Task_Node;
diff --git a/gcc/ada/sem_attr.adb b/gcc/ada/sem_attr.adb
index ed4a677e181..6bebed6a89d 100644
--- a/gcc/ada/sem_attr.adb
+++ b/gcc/ada/sem_attr.adb
@@ -4418,7 +4418,7 @@ package body Sem_Attr is
-- Entities mentioned within the prefix of attribute 'Old must
-- be global to the related postcondition. If this is not the
- -- case, then the scope of the local entity is be nested within
+ -- case, then the scope of the local entity is nested within
-- that of the subprogram.
elsif Nkind (Nod) = N_Identifier
diff --git a/gcc/ada/sem_prag.adb b/gcc/ada/sem_prag.adb
index 1f46ae2222b..42c70764eb7 100644
--- a/gcc/ada/sem_prag.adb
+++ b/gcc/ada/sem_prag.adb
@@ -21434,15 +21434,37 @@ package body Sem_Prag is
elsif Has_Non_Null_Refinement (Dep_Id) then
Has_Refined_State := True;
- if Is_Entity_Name (Ref_Output) then
- Ref_Id := Entity_Of (Ref_Output);
+ -- Account for the case where a state with a non-null
+ -- refinement matches a null output list:
+
+ -- Refined_State => (State_1 => (C1, C2),
+ -- State_2 => (C3, C4))
+ -- Depends => (State_1 => State_2)
+ -- Refined_Depends => (null => C3)
+
+ if Nkind (Ref_Output) = N_Null
+ and then Inputs_Match
+ (Dep_Clause => Dep_Clause,
+ Ref_Clause => Ref_Clause,
+ Post_Errors => False)
+ then
+ Has_Constituent := True;
- -- The output of the refinement clause is a valid
- -- constituent of the state. Remove the clause from
- -- the pool of candidates if both input lists match.
- -- Note that the search continues because one clause
- -- may have been normalized into multiple clauses as
- -- per the example above.
+ -- Note that the search continues after the clause is
+ -- removed from the pool of candidates because it may
+ -- have been normalized into multiple simple clauses.
+
+ Remove (Ref_Clause);
+
+ -- Otherwise the output of the refinement clause must be
+ -- a valid constituent of the state:
+
+ -- Refined_State => (State => (C1, C2))
+ -- Depends => (State => <input>)
+ -- Refined_Depends => (C1 => <input>)
+
+ elsif Is_Entity_Name (Ref_Output) then
+ Ref_Id := Entity_Of (Ref_Output);
if Ekind_In (Ref_Id, E_Abstract_State, E_Variable)
and then Present (Encapsulating_State (Ref_Id))
@@ -21453,6 +21475,12 @@ package body Sem_Prag is
Post_Errors => False)
then
Has_Constituent := True;
+
+ -- Note that the search continues after the clause
+ -- is removed from the pool of candidates because
+ -- it may have been normalized into multiple simple
+ -- clauses.
+
Remove (Ref_Clause);
end if;
end if;
@@ -21819,12 +21847,13 @@ package body Sem_Prag is
begin
-- Construct a list of all refinement inputs. Note that the input
-- list is copied because the algorithm modifies its contents and
- -- this should not be visible in Refined_Depends.
+ -- this should not be visible in Refined_Depends. The same applies
+ -- for a solitary input.
if Nkind (Inputs) = N_Aggregate then
Ref_Inputs := New_Copy_List (Expressions (Inputs));
else
- Ref_Inputs := New_List (Inputs);
+ Ref_Inputs := New_List (New_Copy (Inputs));
end if;
-- Depending on whether the original dependency clause mentions
diff --git a/gcc/ada/sinfo.ads b/gcc/ada/sinfo.ads
index d3c3608ebbe..4feed599c5d 100644
--- a/gcc/ada/sinfo.ads
+++ b/gcc/ada/sinfo.ads
@@ -642,6 +642,13 @@ package Sinfo is
-- Min and Max attributes are expanded into equivalent if expressions,
-- dealing properly with side effect issues.
+ -- Mod for signed integer types is expanded into equivalent expressions
+ -- using Rem (which is % in C) and other C-available operators.
+
+ -- The Actions list of an Expression_With_Actions node has any object
+ -- declarations removed, so that it is composed only of expressions
+ -- (so that DO X,... Y IN Z can be represented as (X, .. Y, Z) in C).
+
------------------------------------
-- Description of Semantic Fields --
------------------------------------
@@ -4127,6 +4134,11 @@ package Sinfo is
-- and we are running in ELIMINATED mode, the operator node will be
-- changed to be a call to the appropriate routine in System.Bignums.
+ -- Note: In Modify_Tree_For_C mode, we do not generate an N_Op_Mod node
+ -- for signed integer types (since there is no equivalent operator in
+ -- C). Instead we rewrite such an operation in terms of REM (which is
+ -- % in C) and other C-available operators.
+
------------------------------------
-- 4.5.7 Conditional Expressions --
------------------------------------
@@ -7406,6 +7418,12 @@ package Sinfo is
-- not a proper expression), and in the long term all cases of this
-- idiom should instead use a new node kind N_Compound_Statement.
+ -- Note: In Modify_Tree_For_C, we eliminate declarations from the list
+ -- of actions, inserting them at the outer level. If we move an object
+ -- declaration with an initialization expression in this manner, then
+ -- the action is replaced by an appropriate assignment, otherwise it is
+ -- removed from the list of actions.
+
--------------------
-- Free Statement --
--------------------