aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada
diff options
context:
space:
mode:
authorArnaud Charlet <charlet@gcc.gnu.org>2013-10-15 13:01:03 +0200
committerArnaud Charlet <charlet@gcc.gnu.org>2013-10-15 13:01:03 +0200
commit7569f6972e44e6c1f00ca5e64d940a90e0bc3e24 (patch)
tree11edc23b1f016bf36a7150ae2c7dd7a51d437f58 /gcc/ada
parentecbda48438f5bbdc95104785e61d81855f05db1b (diff)
downloadgcc-7569f6972e44e6c1f00ca5e64d940a90e0bc3e24.zip
gcc-7569f6972e44e6c1f00ca5e64d940a90e0bc3e24.tar.gz
gcc-7569f6972e44e6c1f00ca5e64d940a90e0bc3e24.tar.bz2
[multiple changes]
2013-10-15 Thomas Quinot <quinot@adacore.com> * exp_pakd.adb (Expand_Packed_Element_Set, Expand_Packed_Element_Reference): Adjust for the case of packed arrays of reverse-storage-order types. 2013-10-15 Robert Dewar <dewar@adacore.com> * sem_prag.adb: Minor reformatting. 2013-10-15 Ed Schonberg <schonberg@adacore.com> * sem_attr.adb (Analyze_Attribute_Specification, case To_Address): If the expression is an identifier, do not modify its type; it will be converted when necessary, and the type of the expression must remain consistent with that of the entity for back-end consistency. 2013-10-15 Robert Dewar <dewar@adacore.com> * sem_ch7.adb (Unit_Requires_Body): Add flag Ignore_Abstract_State (Analyze_Package_Specification): Enforce rule requiring Elaborate_Body if a non-null abstract state is specified for a library-level package. * sem_ch7.ads (Unit_Requires_Body): Add flag Ignore_Abstract_State. From-SVN: r203598
Diffstat (limited to 'gcc/ada')
-rw-r--r--gcc/ada/ChangeLog26
-rw-r--r--gcc/ada/exp_pakd.adb114
-rw-r--r--gcc/ada/sem_attr.adb9
-rw-r--r--gcc/ada/sem_ch7.adb47
-rw-r--r--gcc/ada/sem_ch7.ads14
-rw-r--r--gcc/ada/sem_prag.adb2
6 files changed, 184 insertions, 28 deletions
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index 382274e..41fd986 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -1,3 +1,29 @@
+2013-10-15 Thomas Quinot <quinot@adacore.com>
+
+ * exp_pakd.adb (Expand_Packed_Element_Set,
+ Expand_Packed_Element_Reference): Adjust for the case of packed
+ arrays of reverse-storage-order types.
+
+2013-10-15 Robert Dewar <dewar@adacore.com>
+
+ * sem_prag.adb: Minor reformatting.
+
+2013-10-15 Ed Schonberg <schonberg@adacore.com>
+
+ * sem_attr.adb (Analyze_Attribute_Specification, case
+ To_Address): If the expression is an identifier, do not modify
+ its type; it will be converted when necessary, and the type of
+ the expression must remain consistent with that of the entity
+ for back-end consistency.
+
+2013-10-15 Robert Dewar <dewar@adacore.com>
+
+ * sem_ch7.adb (Unit_Requires_Body): Add flag
+ Ignore_Abstract_State (Analyze_Package_Specification): Enforce
+ rule requiring Elaborate_Body if a non-null abstract state is
+ specified for a library-level package.
+ * sem_ch7.ads (Unit_Requires_Body): Add flag Ignore_Abstract_State.
+
2013-10-15 Hristian Kirtchev <kirtchev@adacore.com>
* sem_prag.adb (Analyze_Constituent): When
diff --git a/gcc/ada/exp_pakd.adb b/gcc/ada/exp_pakd.adb
index 45aafad..7a27b7a 100644
--- a/gcc/ada/exp_pakd.adb
+++ b/gcc/ada/exp_pakd.adb
@@ -543,39 +543,78 @@ package body Exp_Pakd is
-- array type on the fly). Such actions are inserted into the tree
-- directly using Insert_Action.
- function Byte_Swap (N : Node_Id) return Node_Id;
+ function Byte_Swap
+ (N : Node_Id;
+ Left_Justify : Boolean := False;
+ Right_Justify : Boolean := False) return Node_Id;
-- Wrap N in a call to a byte swapping function, with appropriate type
- -- conversions.
+ -- conversions. If Left_Justify is set True, the value is left justified
+ -- before swapping. If Right_Justify is set True, the value is right
+ -- justified after swapping. The Etype of the returned node is an
+ -- integer type of an appropriate power-of-2 size.
---------------
-- Byte_Swap --
---------------
- function Byte_Swap (N : Node_Id) return Node_Id is
+ function Byte_Swap
+ (N : Node_Id;
+ Left_Justify : Boolean := False;
+ Right_Justify : Boolean := False) return Node_Id
+ is
Loc : constant Source_Ptr := Sloc (N);
T : constant Entity_Id := Etype (N);
+ T_Size : constant Uint := RM_Size (T);
+
Swap_RE : RE_Id;
Swap_F : Entity_Id;
+ Swap_T : Entity_Id;
+ -- Swapping function
+
+ Arg : Node_Id;
+ Swapped : Node_Id;
+ Shift : Uint;
begin
- pragma Assert (Esize (T) > 8);
+ pragma Assert (T_Size > 8);
- if Esize (T) <= 16 then
+ if T_Size <= 16 then
Swap_RE := RE_Bswap_16;
- elsif Esize (T) <= 32 then
+
+ elsif T_Size <= 32 then
Swap_RE := RE_Bswap_32;
- else pragma Assert (Esize (T) <= 64);
+
+ else pragma Assert (T_Size <= 64);
Swap_RE := RE_Bswap_64;
end if;
Swap_F := RTE (Swap_RE);
+ Swap_T := Etype (Swap_F);
+ Shift := Esize (Swap_T) - T_Size;
+
+ Arg := RJ_Unchecked_Convert_To (Swap_T, N);
+
+ if Left_Justify and then Shift > Uint_0 then
+ Arg :=
+ Make_Op_Shift_Left (Loc,
+ Left_Opnd => Arg,
+ Right_Opnd => Make_Integer_Literal (Loc, Shift));
+ end if;
+
+ Swapped :=
+ Make_Function_Call (Loc,
+ Name => New_Occurrence_Of (Swap_F, Loc),
+ Parameter_Associations => New_List (Arg));
+
+ if Right_Justify and then Shift > Uint_0 then
+ Swapped :=
+ Make_Op_Shift_Right (Loc,
+ Left_Opnd => Swapped,
+ Right_Opnd => Make_Integer_Literal (Loc, Shift));
+ end if;
- return
- Unchecked_Convert_To (T,
- Make_Function_Call (Loc,
- Name => New_Occurrence_Of (Swap_F, Loc),
- Parameter_Associations =>
- New_List (Unchecked_Convert_To (Etype (Swap_F), N))));
+ Set_Etype (Swapped, Swap_T);
+ return Swapped;
end Byte_Swap;
------------------------------
@@ -1537,7 +1576,9 @@ package body Exp_Pakd is
and then not In_Reverse_Storage_Order_Object (Obj)
then
Require_Byte_Swapping := True;
- New_Rhs := Byte_Swap (New_Rhs);
+ New_Rhs := Byte_Swap (New_Rhs,
+ Left_Justify => Bytes_Big_Endian,
+ Right_Justify => not Bytes_Big_Endian);
end if;
end;
@@ -1610,7 +1651,6 @@ package body Exp_Pakd is
-- not a left justified conversion.
Rhs := RJ_Unchecked_Convert_To (Etype (Obj), Rhs);
-
end Fixup_Rhs;
begin
@@ -1660,18 +1700,24 @@ package body Exp_Pakd is
if Nkind (New_Rhs) = N_Op_And then
Set_Paren_Count (New_Rhs, 1);
+ Set_Etype (New_Rhs, Etype (Left_Opnd (New_Rhs)));
end if;
New_Rhs :=
Make_Op_Or (Loc,
Left_Opnd => New_Rhs,
- Right_Opnd => Or_Rhs);
+ Right_Opnd => Unchecked_Convert_To
+ (Etype (New_Rhs), Or_Rhs));
end;
end if;
if Require_Byte_Swapping then
Set_Etype (New_Rhs, Etype (Obj));
- New_Rhs := Byte_Swap (New_Rhs);
+ New_Rhs :=
+ Unchecked_Convert_To (Etype (Obj),
+ Byte_Swap (New_Rhs,
+ Left_Justify => not Bytes_Big_Endian,
+ Right_Justify => Bytes_Big_Endian));
end if;
-- Now do the rewrite
@@ -1991,6 +2037,11 @@ package body Exp_Pakd is
Lit : Node_Id;
Arg : Node_Id;
+ Byte_Swapped : Boolean;
+ -- Set true if bytes were swapped for the purpose of extracting the
+ -- element, in which case we must swap back if the component type is
+ -- a composite type with reverse scalar storage order.
+
begin
-- If the node is an actual in a call, the prefix has not been fully
-- expanded, to account for the additional expansion for in-out actuals
@@ -2057,7 +2108,13 @@ package body Exp_Pakd is
and then Esize (Atyp) > 8
and then not In_Reverse_Storage_Order_Object (Obj)
then
- Obj := Byte_Swap (Obj);
+ Obj := Byte_Swap (Obj,
+ Left_Justify => Bytes_Big_Endian,
+ Right_Justify => not Bytes_Big_Endian);
+ Byte_Swapped := True;
+
+ else
+ Byte_Swapped := False;
end if;
-- We generate a shift right to position the field, followed by a
@@ -2075,6 +2132,15 @@ package body Exp_Pakd is
Left_Opnd => Make_Shift_Right (Obj, Shift),
Right_Opnd => Lit);
+ -- Swap back if necessary
+
+ Set_Etype (Arg, Ctyp);
+ if Byte_Swapped and then Reverse_Storage_Order (Ctyp) then
+ Arg := Byte_Swap (Arg,
+ Left_Justify => not Bytes_Big_Endian,
+ Right_Justify => False);
+ end if;
+
-- We needed to analyze this before we do the unchecked convert
-- below, but we need it temporarily attached to the tree for
-- this analysis (hence the temporary Set_Parent call).
@@ -2597,6 +2663,18 @@ package body Exp_Pakd is
Source_Siz := UI_To_Int (RM_Size (Source_Typ));
Target_Siz := UI_To_Int (RM_Size (Target_Typ));
+ -- For a little-endian target type stored byte-swapped on a
+ -- big-endian machine, do not mask to Target_Siz bits.
+
+ if Bytes_Big_Endian
+ and then (Is_Record_Type (Target_Typ)
+ or else
+ Is_Array_Type (Target_Typ))
+ and then Reverse_Storage_Order (Target_Typ)
+ then
+ Source_Siz := Target_Siz;
+ end if;
+
-- First step, if the source type is not a discrete type, then we first
-- convert to a modular type of the source length, since otherwise, on
-- a big-endian machine, we get left-justification. We do it for little-
diff --git a/gcc/ada/sem_attr.adb b/gcc/ada/sem_attr.adb
index 493f544..177c3de 100644
--- a/gcc/ada/sem_attr.adb
+++ b/gcc/ada/sem_attr.adb
@@ -5627,9 +5627,16 @@ package body Sem_Attr is
Error_Attr ("address value out of range for % attribute", E1);
end if;
+ -- In most cases the expression is a numeric literal or some other
+ -- address expression, but if it is a declared constant it may be
+ -- of a compatible type that must be left on the node.
+
+ if Is_Entity_Name (E1) then
+ null;
+
-- Set type to universal integer if negative
- if Val < 0 then
+ elsif Val < 0 then
Set_Etype (E1, Universal_Integer);
-- Otherwise set type to Unsigned_64 to accomodate max values
diff --git a/gcc/ada/sem_ch7.adb b/gcc/ada/sem_ch7.adb
index d15add3..0239fa7 100644
--- a/gcc/ada/sem_ch7.adb
+++ b/gcc/ada/sem_ch7.adb
@@ -1483,7 +1483,38 @@ package body Sem_Ch7 is
Clear_Constants (Id, First_Private_Entity (Id));
end if;
+ -- Issue an error in SPARK mode if a package specification contains
+ -- more than one tagged type or type extension.
+
Check_One_Tagged_Type_Or_Extension_At_Most;
+
+ -- Issue an error if a package that is a library unit does not require a
+ -- body, and we have a non-null abstract state (SPARK LRM 7.1.5(4)).
+
+ if not Unit_Requires_Body (Id, Ignore_Abstract_State => True)
+ and then Present (Abstract_States (Id))
+
+ -- We use Scope_Depth of 1 to identify library units, which seems a
+ -- bit ugly, but there doesn't seem to be an easier way.
+
+ and then Scope_Depth (Id) = 1
+
+ -- A null abstract state always appears as the sole element of the
+ -- state list.
+
+ and then not Is_Null_State (Node (First_Elmt (Abstract_States (Id))))
+ then
+ declare
+ P : constant Node_Id := Get_Pragma (Id, Pragma_Abstract_State);
+ begin
+ Error_Msg_NE
+ ("package & specifies a non-null abstract state", P, Id);
+ Error_Msg_N
+ ("\but package does not otherwise require a body", P);
+ Error_Msg_N
+ ("\pragma Elaborate_Body is required in this case", P);
+ end;
+ end if;
end Analyze_Package_Specification;
--------------------------------------
@@ -2588,7 +2619,10 @@ package body Sem_Ch7 is
-- Unit_Requires_Body --
------------------------
- function Unit_Requires_Body (P : Entity_Id) return Boolean is
+ function Unit_Requires_Body
+ (P : Entity_Id;
+ Ignore_Abstract_State : Boolean := False) return Boolean
+ is
E : Entity_Id;
begin
@@ -2627,12 +2661,17 @@ package body Sem_Ch7 is
end;
-- A [generic] package that introduces at least one non-null abstract
- -- state requires completion. A null abstract state always appears as
- -- the sole element of the state list.
+ -- state requires completion. However, there is a separate rule that
+ -- requires that such a package have a reason other than this for a
+ -- body being required (if necessary a pragma Elaborate_Body must be
+ -- provided). If Ignore_Abstract_State is True, we don't do this check
+ -- (so we can use Unit_Requires_Body to check for some other reason).
elsif Ekind_In (P, E_Generic_Package, E_Package)
+ and then not Ignore_Abstract_State
and then Present (Abstract_States (P))
- and then not Is_Null_State (Node (First_Elmt (Abstract_States (P))))
+ and then
+ not Is_Null_State (Node (First_Elmt (Abstract_States (P))))
then
return True;
end if;
diff --git a/gcc/ada/sem_ch7.ads b/gcc/ada/sem_ch7.ads
index 0445b24..11e05cd 100644
--- a/gcc/ada/sem_ch7.ads
+++ b/gcc/ada/sem_ch7.ads
@@ -6,7 +6,7 @@
-- --
-- S p e c --
-- --
--- Copyright (C) 1992-2008, Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2013, Free Software Foundation, Inc. --
-- --
-- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
@@ -52,9 +52,15 @@ package Sem_Ch7 is
-- but is deferred until the compilation of the private part of the
-- child for public child packages.
- function Unit_Requires_Body (P : Entity_Id) return Boolean;
- -- Check if a unit requires a body. A specification requires a body
- -- if it contains declarations that require completion in a body.
+ function Unit_Requires_Body
+ (P : Entity_Id;
+ Ignore_Abstract_State : Boolean := False) return Boolean;
+ -- Check if a unit requires a body. A specification requires a body if it
+ -- contains declarations that require completion in a body. If the flag
+ -- Ignore_Abstract_State is set True, then the test for a non-null abstract
+ -- state (which normally requires a body) is not carried out. This allows
+ -- the use of this routine to tell if there is some other reason that a
+ -- body is required (as is required for analyzing Abstract_State).
procedure May_Need_Implicit_Body (E : Entity_Id);
-- If a package declaration contains tasks or RACWs and does not require
diff --git a/gcc/ada/sem_prag.adb b/gcc/ada/sem_prag.adb
index 64d684d..8fa7853 100644
--- a/gcc/ada/sem_prag.adb
+++ b/gcc/ada/sem_prag.adb
@@ -4960,7 +4960,7 @@ package body Sem_Prag is
Pragma_Misplaced;
elsif (Nkind (Parent_Node) = N_Generic_Package_Declaration
- or else Nkind (Parent_Node) =
+ or else Nkind (Parent_Node) =
N_Generic_Subprogram_Declaration)
and then Plist = Generic_Formal_Declarations (Parent_Node)
then