aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorArnaud Charlet <charlet@gcc.gnu.org>2014-01-20 16:50:09 +0100
committerArnaud Charlet <charlet@gcc.gnu.org>2014-01-20 16:50:09 +0100
commit9559eccf365a3bc6741ad2bad2916973fb41fbe6 (patch)
treee58a1094a1e0599789d195dc148d2c338c8c3879 /gcc
parent92e162285046e62d0662648edd11223d3fbad43d (diff)
downloadgcc-9559eccf365a3bc6741ad2bad2916973fb41fbe6.zip
gcc-9559eccf365a3bc6741ad2bad2916973fb41fbe6.tar.gz
gcc-9559eccf365a3bc6741ad2bad2916973fb41fbe6.tar.bz2
[multiple changes]
2014-01-20 Hristian Kirtchev <kirtchev@adacore.com> * sem_prag.adb (Check_Mode): Reimplement the routine. (Find_Mode): New routine. 2014-01-20 Robert Dewar <dewar@adacore.com> * sem_ch4.adb (Operator_Check): Handle additional Allow_Integer_Address cases. From-SVN: r206835
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ada/ChangeLog10
-rw-r--r--gcc/ada/sem_ch4.adb34
-rw-r--r--gcc/ada/sem_prag.adb193
3 files changed, 165 insertions, 72 deletions
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index 395cc96..05db4c0 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -1,3 +1,13 @@
+2014-01-20 Hristian Kirtchev <kirtchev@adacore.com>
+
+ * sem_prag.adb (Check_Mode): Reimplement the routine.
+ (Find_Mode): New routine.
+
+2014-01-20 Robert Dewar <dewar@adacore.com>
+
+ * sem_ch4.adb (Operator_Check): Handle additional
+ Allow_Integer_Address cases.
+
2014-01-20 Robert Dewar <dewar@adacore.com>
* gnat_rm.texi (Allow_Integer_Address): Remove note about not
diff --git a/gcc/ada/sem_ch4.adb b/gcc/ada/sem_ch4.adb
index bf4e317..c63d423 100644
--- a/gcc/ada/sem_ch4.adb
+++ b/gcc/ada/sem_ch4.adb
@@ -6331,7 +6331,8 @@ package body Sem_Ch4 is
-- binary operator case.
elsif Junk_Operand (R)
- or (Nkind (N) in N_Binary_Op and then Junk_Operand (L))
+ or -- really mean OR here and not OR ELSE, see above
+ (Nkind (N) in N_Binary_Op and then Junk_Operand (L))
then
return;
@@ -6390,11 +6391,42 @@ package body Sem_Ch4 is
Rewrite (L,
Unchecked_Convert_To (Etype (R), Relocate_Node (L)));
Analyze_Arithmetic_Op (N);
+ return;
else
Resolve (L, Etype (R));
end if;
+
return;
+
+ elsif Allow_Integer_Address
+ and then Is_Descendent_Of_Address (Etype (L))
+ and then Is_Descendent_Of_Address (Etype (R))
+ and then not Error_Posted (N)
+ then
+ declare
+ Addr_Type : constant Entity_Id := Etype (L);
+
+ begin
+ Rewrite (L,
+ Unchecked_Convert_To (
+ Standard_Integer, Relocate_Node (L)));
+ Rewrite (R,
+ Unchecked_Convert_To (
+ Standard_Integer, Relocate_Node (R)));
+ Analyze_Arithmetic_Op (N);
+
+ -- If this is an operand in an enclosing arithmetic
+ -- operation, Convert the result as an address so that
+ -- arithmetic folding of address can continue.
+
+ if Nkind (Parent (N)) in N_Op then
+ Rewrite (N,
+ Unchecked_Convert_To (Addr_Type, Relocate_Node (N)));
+ end if;
+
+ return;
+ end;
end if;
-- Comparisons on A'Access are common enough to deserve a
diff --git a/gcc/ada/sem_prag.adb b/gcc/ada/sem_prag.adb
index 7520856..3da7e00 100644
--- a/gcc/ada/sem_prag.adb
+++ b/gcc/ada/sem_prag.adb
@@ -953,98 +953,149 @@ package body Sem_Prag is
Is_Input : Boolean;
Self_Ref : Boolean)
is
- begin
- -- Input
+ procedure Find_Mode
+ (Is_Input : out Boolean;
+ Is_Output : out Boolean);
+ -- Find the mode of Item_Id. Flags Is_Input and Is_Output are set
+ -- depending on the mode.
- if Is_Input then
+ ---------------
+ -- Find_Mode --
+ ---------------
- -- IN and IN OUT parameters already have the proper mode to act
- -- as input. OUT parameters are valid inputs only when their type
- -- is unconstrained or tagged as their discriminants, array bouns
- -- or tags can be read. In general, states and variables are
- -- considered to have mode IN OUT unless they are classified by
- -- pragma [Refined_]Global. In that case, the item must appear in
- -- an input global list. OUT parameters of enclosing subprograms
- -- behave as read-write variables in which case do not emit an
- -- error.
-
- if (Ekind (Item_Id) = E_Out_Parameter
- and then Scope (Item_Id) = Spec_Id
- and then not Is_Unconstrained_Or_Tagged_Item (Item_Id))
- or else
- (Global_Seen and then not Appears_In (Subp_Inputs, Item_Id))
- then
- Error_Msg_NE
- ("item & must have mode IN or `IN OUT`", Item, Item_Id);
- end if;
+ procedure Find_Mode
+ (Is_Input : out Boolean;
+ Is_Output : out Boolean)
+ is
+ begin
+ Is_Input := False;
+ Is_Output := False;
- -- Self-referential output
+ -- Abstract state cases
- elsif Self_Ref then
+ if Ekind (Item_Id) = E_Abstract_State then
- -- In general, states and variables are considered to have mode
- -- IN OUT unless they are explicitly moded by pragma [Refined_]
- -- Global. If this is the case, then the item must appear in both
- -- an input and output global list.
+ -- When pragma Global is present, the mode of the state may be
+ -- further constrained by setting a more restrictive mode.
- if Ekind_In (Item_Id, E_Abstract_State, E_Variable) then
- if Global_Seen
- and then not
- (Appears_In (Subp_Inputs, Item_Id)
- and then
- Appears_In (Subp_Outputs, Item_Id))
+ if Global_Seen then
+ if Appears_In (Subp_Inputs, Item_Id) then
+ Is_Input := True;
+ end if;
+
+ if Appears_In (Subp_Outputs, Item_Id) then
+ Is_Output := True;
+ end if;
+
+ -- Otherwise the mode of the state is the one defined in pragma
+ -- Abstract_State. An In_Out state lacks both Input_Only and
+ -- Output_Only modes.
+
+ elsif not Is_Input_Only_State (Item_Id)
+ and then not Is_Output_Only_State (Item_Id)
then
- Error_Msg_NE
- ("item & must have mode `IN OUT`", Item, Item_Id);
+ Is_Input := True;
+ Is_Output := True;
+
+ elsif Is_Input_Only_State (Item_Id) then
+ Is_Input := True;
+
+ elsif Is_Output_Only_State (Item_Id) then
+ Is_Output := True;
end if;
- -- A self-referential OUT parameter of an unconstrained or tagged
- -- type acts as an input because the discriminants, array bounds
- -- or the tag may be read. Note that the presence of [Refined_]
- -- Global is not significant here because the item is a parameter.
- -- This rule applies only to the formals of the related subprogram
- -- as OUT parameters of enclosing subprograms behave as read-write
- -- variables and their types do not matter.
+ -- Parameter cases
- elsif Ekind (Item_Id) = E_Out_Parameter
- and then Scope (Item_Id) = Spec_Id
- and then Is_Unconstrained_Or_Tagged_Item (Item_Id)
- then
- null;
+ elsif Ekind (Item_Id) = E_In_Parameter then
+ Is_Input := True;
- -- The remaining cases are IN, IN OUT, and OUT parameters. To
- -- qualify as self-referential item, the parameter must be of
- -- mode IN OUT or be an IN OUT or OUT parameter of an enclosing
- -- subprogram.
+ elsif Ekind (Item_Id) = E_In_Out_Parameter then
+ Is_Input := True;
+ Is_Output := True;
- elsif Scope (Item_Id) = Spec_Id then
- if Ekind (Item_Id) /= E_In_Out_Parameter then
- Error_Msg_NE
- ("item & must have mode `IN OUT`", Item, Item_Id);
+ elsif Ekind (Item_Id) = E_Out_Parameter then
+ if Scope (Item_Id) = Spec_Id then
+
+ -- An OUT parameter of the related subprogram has mode IN
+ -- if its type is unconstrained or tagged because array
+ -- bounds, discriminants or tags can be read.
+
+ if Is_Unconstrained_Or_Tagged_Item (Item_Id) then
+ Is_Input := True;
+ end if;
+
+ Is_Output := True;
+
+ -- An OUT parameter of an enclosing subprogram behaves as a
+ -- read-write variable in which case the mode is IN OUT.
+
+ else
+ Is_Input := True;
+ Is_Output := True;
end if;
- -- Enclosing subprogram parameter
+ -- Variable cases
- elsif not Ekind_In (Item_Id, E_In_Out_Parameter,
- E_Out_Parameter)
- then
+ else pragma Assert (Ekind (Item_Id) = E_Variable);
+
+ -- When pragma Global is present, the mode of the variable may
+ -- be further constrained by setting a more restrictive mode.
+
+ if Global_Seen then
+
+ -- A variable has mode IN when its type is unconstrained or
+ -- tagged because array bounds, discriminants or tags can be
+ -- read.
+
+ if Appears_In (Subp_Inputs, Item_Id)
+ or else Is_Unconstrained_Or_Tagged_Item (Item_Id)
+ then
+ Is_Input := True;
+ end if;
+
+ if Appears_In (Subp_Outputs, Item_Id) then
+ Is_Output := True;
+ end if;
+
+ -- Otherwise the variable has a default IN OUT mode
+
+ else
+ Is_Input := True;
+ Is_Output := True;
+ end if;
+ end if;
+ end Find_Mode;
+
+ -- Local variables
+
+ Item_Is_Input : Boolean;
+ Item_Is_Output : Boolean;
+
+ -- Start of processing for Check_Mode
+
+ begin
+ Find_Mode (Item_Is_Input, Item_Is_Output);
+
+ -- Input item
+
+ if Is_Input then
+ if not Item_Is_Input then
Error_Msg_NE
- ("item & must have mode `IN OUT` or `OUT`", Item, Item_Id);
+ ("item & must have mode `IN` or `IN OUT`", Item, Item_Id);
end if;
- -- Output
+ -- Self-referential item
- -- IN OUT and OUT parameters already have the proper mode to act as
- -- output. In general, states and variables are considered to have
- -- mode IN OUT unless they are moded by pragma [Refined_]Global. In
- -- that case, the item must appear in an output global list.
+ elsif Self_Ref then
+ if not Item_Is_Input or else not Item_Is_Output then
+ Error_Msg_NE ("item & must have mode `IN OUT`", Item, Item_Id);
+ end if;
- elsif Ekind (Item_Id) = E_In_Parameter
- or else
- (Global_Seen and then not Appears_In (Subp_Outputs, Item_Id))
- then
+ -- Output item
+
+ elsif not Item_Is_Output then
Error_Msg_NE
- ("item & must have mode OUT or `IN OUT`", Item, Item_Id);
+ ("item & must have mode `OUT` or `IN OUT`", Item, Item_Id);
end if;
end Check_Mode;