[multiple changes]
authorArnaud Charlet <charlet@gcc.gnu.org>
Tue, 15 Oct 2013 11:01:03 +0000 (13:01 +0200)
committerArnaud Charlet <charlet@gcc.gnu.org>
Tue, 15 Oct 2013 11:01:03 +0000 (13:01 +0200)
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

gcc/ada/ChangeLog
gcc/ada/exp_pakd.adb
gcc/ada/sem_attr.adb
gcc/ada/sem_ch7.adb
gcc/ada/sem_ch7.ads
gcc/ada/sem_prag.adb

index 382274eeb4b0d0f75f392def6b76ebceb8f7b162..41fd9869dcf4e5f08d0239aa890214e981b45af9 100644 (file)
@@ -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
index 45aafadefeec29c3d314cce53ce55d746d727088..7a27b7a58f8d58e856ef89bbdb245bd87d3318dd 100644 (file)
@@ -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-
index 493f544cf3a05520687d9520212edf74236eafaf..177c3de74fa7c732d198b8087ff84f28cdb48ae8 100644 (file)
@@ -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
index d15add3bf534844a23942a624fec0869aec30944..0239fa76d4b9de1f8a8dfc8c7b31f9498c0433d5 100644 (file)
@@ -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;
index 0445b2429492ec21429c90c1c92962f9b3751924..11e05cd7909c3f500b8f62e7c004563905e26690 100644 (file)
@@ -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
index 64d684d91e6492e1379ffd92ac6258bbc6ff7fb3..8fa7853dcd86540232ee16e2f3d716aace46ef17 100644 (file)
@@ -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