OSDN Git Service

2010-10-05 Ed Schonberg <schonberg@adacore.com>
[pf3gnuchains/gcc-fork.git] / gcc / ada / freeze.adb
index 406db64..bda6e79 100644 (file)
@@ -6,7 +6,7 @@
 --                                                                          --
 --                                 B o d y                                  --
 --                                                                          --
---          Copyright (C) 1992-2009, Free Software Foundation, Inc.         --
+--          Copyright (C) 1992-2010, 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- --
@@ -36,6 +36,7 @@ with Exp_Pakd; use Exp_Pakd;
 with Exp_Util; use Exp_Util;
 with Exp_Tss;  use Exp_Tss;
 with Layout;   use Layout;
+with Lib;      use Lib;
 with Namet;    use Namet;
 with Nlists;   use Nlists;
 with Nmake;    use Nmake;
@@ -203,12 +204,64 @@ package body Freeze is
       New_S : Entity_Id;
       After : in out Node_Id)
    is
-      Body_Node : constant Node_Id := Build_Renamed_Body (Decl, New_S);
+      Body_Decl    : constant Node_Id := Unit_Declaration_Node (New_S);
+      Ent          : constant Entity_Id := Defining_Entity (Decl);
+      Body_Node    : Node_Id;
+      Renamed_Subp : Entity_Id;
+
    begin
-      Insert_After (After, Body_Node);
-      Mark_Rewrite_Insertion (Body_Node);
-      Analyze (Body_Node);
-      After := Body_Node;
+      --  If the renamed subprogram is intrinsic, there is no need for a
+      --  wrapper body: we set the alias that will be called and expanded which
+      --  completes the declaration. This transformation is only legal if the
+      --  renamed entity has already been elaborated.
+
+      --  Note that it is legal for a renaming_as_body to rename an intrinsic
+      --  subprogram, as long as the renaming occurs before the new entity
+      --  is frozen. See RM 8.5.4 (5).
+
+      if Nkind (Body_Decl) = N_Subprogram_Renaming_Declaration
+        and then Is_Entity_Name (Name (Body_Decl))
+      then
+         Renamed_Subp := Entity (Name (Body_Decl));
+      else
+         Renamed_Subp := Empty;
+      end if;
+
+      if Present (Renamed_Subp)
+        and then Is_Intrinsic_Subprogram (Renamed_Subp)
+        and then
+          (not In_Same_Source_Unit (Renamed_Subp, Ent)
+            or else Sloc (Renamed_Subp) < Sloc (Ent))
+
+        --  We can make the renaming entity intrisic if the renamed function
+        --  has an interface name, or if it is one of the shift/rotate
+        --  operations known to the compiler.
+
+        and then (Present (Interface_Name (Renamed_Subp))
+                   or else Chars (Renamed_Subp) = Name_Rotate_Left
+                   or else Chars (Renamed_Subp) = Name_Rotate_Right
+                   or else Chars (Renamed_Subp) = Name_Shift_Left
+                   or else Chars (Renamed_Subp) = Name_Shift_Right
+                   or else Chars (Renamed_Subp) = Name_Shift_Right_Arithmetic)
+      then
+         Set_Interface_Name (Ent, Interface_Name (Renamed_Subp));
+
+         if Present (Alias (Renamed_Subp)) then
+            Set_Alias (Ent, Alias (Renamed_Subp));
+         else
+            Set_Alias (Ent, Renamed_Subp);
+         end if;
+
+         Set_Is_Intrinsic_Subprogram (Ent);
+         Set_Has_Completion (Ent);
+
+      else
+         Body_Node := Build_Renamed_Body (Decl, New_S);
+         Insert_After (After, Body_Node);
+         Mark_Rewrite_Insertion (Body_Node);
+         Analyze (Body_Node);
+         After := Body_Node;
+      end if;
    end Build_And_Analyze_Renamed_Body;
 
    ------------------------
@@ -220,12 +273,12 @@ package body Freeze is
       New_S : Entity_Id) return Node_Id
    is
       Loc : constant Source_Ptr := Sloc (New_S);
-      --  We use for the source location of the renamed body, the location
-      --  of the spec entity. It might seem more natural to use the location
-      --  of the renaming declaration itself, but that would be wrong, since
-      --  then the body we create would look as though it was created far
-      --  too late, and this could cause problems with elaboration order
-      --  analysis, particularly in connection with instantiations.
+      --  We use for the source location of the renamed body, the location of
+      --  the spec entity. It might seem more natural to use the location of
+      --  the renaming declaration itself, but that would be wrong, since then
+      --  the body we create would look as though it was created far too late,
+      --  and this could cause problems with elaboration order analysis,
+      --  particularly in connection with instantiations.
 
       N          : constant Node_Id := Unit_Declaration_Node (New_S);
       Nam        : constant Node_Id := Name (N);
@@ -301,18 +354,16 @@ package body Freeze is
             Call_Name := New_Copy (Name (N));
          end if;
 
-         --  The original name may have been overloaded, but
-         --  is fully resolved now.
+         --  Original name may have been overloaded, but is fully resolved now
 
          Set_Is_Overloaded (Call_Name, False);
       end if;
 
       --  For simple renamings, subsequent calls can be expanded directly as
-      --  called to the renamed entity. The body must be generated in any case
-      --  for calls they may appear elsewhere.
+      --  calls to the renamed entity. The body must be generated in any case
+      --  for calls that may appear elsewhere.
 
-      if (Ekind (Old_S) = E_Function
-           or else Ekind (Old_S) = E_Procedure)
+      if Ekind_In (Old_S, E_Function, E_Procedure)
         and then Nkind (Decl) = N_Subprogram_Declaration
       then
          Set_Body_To_Inline (Decl, Old_S);
@@ -331,7 +382,6 @@ package body Freeze is
             Form_Type : constant Entity_Id := Etype (First_Formal (Old_S));
 
          begin
-
             --  The controlling formal may be an access parameter, or the
             --  actual may be an access value, so adjust accordingly.
 
@@ -380,10 +430,8 @@ package body Freeze is
       if Present (Formal) then
          O_Formal := First_Formal (Old_S);
          Param_Spec := First (Parameter_Specifications (Spec));
-
          while Present (Formal) loop
             if Is_Entry (Old_S) then
-
                if Nkind (Parameter_Type (Param_Spec)) /=
                                                     N_Access_Definition
                then
@@ -446,7 +494,6 @@ package body Freeze is
         Make_Defining_Identifier (Loc, Chars => Chars (New_S)));
 
       Param_Spec := First (Parameter_Specifications (Spec));
-
       while Present (Param_Spec) loop
          Set_Defining_Identifier (Param_Spec,
            Make_Defining_Identifier (Loc,
@@ -497,49 +544,7 @@ package body Freeze is
       if Present (Addr) then
          Expr := Expression (Addr);
 
-         --  If we have no initialization of any kind, then we don't need to
-         --  place any restrictions on the address clause, because the object
-         --  will be elaborated after the address clause is evaluated. This
-         --  happens if the declaration has no initial expression, or the type
-         --  has no implicit initialization, or the object is imported.
-
-         --  The same holds for all initialized scalar types and all access
-         --  types. Packed bit arrays of size up to 64 are represented using a
-         --  modular type with an initialization (to zero) and can be processed
-         --  like other initialized scalar types.
-
-         --  If the type is controlled, code to attach the object to a
-         --  finalization chain is generated at the point of declaration,
-         --  and therefore the elaboration of the object cannot be delayed:
-         --  the address expression must be a constant.
-
-         if (No (Expression (Decl))
-              and then not Needs_Finalization (Typ)
-              and then
-                (not Has_Non_Null_Base_Init_Proc (Typ)
-                  or else Is_Imported (E)))
-
-           or else
-             (Present (Expression (Decl))
-               and then Is_Scalar_Type (Typ))
-
-           or else
-             Is_Access_Type (Typ)
-
-           or else
-             (Is_Bit_Packed_Array (Typ)
-               and then
-                 Is_Modular_Integer_Type (Packed_Array_Type (Typ)))
-         then
-            null;
-
-         --  Otherwise, we require the address clause to be constant because
-         --  the call to the initialization procedure (or the attach code) has
-         --  to happen at the point of the declaration.
-         --  Actually the IP call has been moved to the freeze actions
-         --  anyway, so maybe we can relax this restriction???
-
-         else
+         if Needs_Constant_Address (Decl, Typ) then
             Check_Constant_Address_Clause (Expr, E);
 
             --  Has_Delayed_Freeze was set on E when the address clause was
@@ -551,7 +556,36 @@ package body Freeze is
             end if;
          end if;
 
-         if not Error_Posted (Expr)
+         --  If Rep_Clauses are to be ignored, remove address clause from
+         --  list attached to entity, because it may be illegal for gigi,
+         --  for example by breaking order of elaboration..
+
+         if Ignore_Rep_Clauses then
+            declare
+               Rep : Node_Id;
+
+            begin
+               Rep := First_Rep_Item (E);
+
+               if Rep = Addr then
+                  Set_First_Rep_Item (E, Next_Rep_Item (Addr));
+
+               else
+                  while Present (Rep)
+                    and then Next_Rep_Item (Rep) /= Addr
+                  loop
+                     Rep := Next_Rep_Item (Rep);
+                  end loop;
+               end if;
+
+               if Present (Rep) then
+                  Set_Next_Rep_Item (Rep, Next_Rep_Item (Addr));
+               end if;
+            end;
+
+            Rewrite (Addr, Make_Null_Statement (Sloc (E)));
+
+         elsif not Error_Posted (Expr)
            and then not Needs_Finalization (Typ)
          then
             Warn_Overlay (Expr, Typ, Name (Addr));
@@ -568,7 +602,7 @@ package body Freeze is
       procedure Set_Small_Size (T : Entity_Id; S : Uint);
       --  Sets the compile time known size (32 bits or less) in the Esize
       --  field, of T checking for a size clause that was given which attempts
-      --  to give a smaller size.
+      --  to give a smaller size, and also checking for an alignment clause.
 
       function Size_Known (T : Entity_Id) return Boolean;
       --  Recursive function that does all the work
@@ -589,11 +623,20 @@ package body Freeze is
          if S > 32 then
             return;
 
+         --  Don't bother if alignment clause with a value other than 1 is
+         --  present, because size may be padded up to meet back end alignment
+         --  requirements, and only the back end knows the rules!
+
+         elsif Known_Alignment (T) and then Alignment (T) /= 1 then
+            return;
+
+         --  Check for bad size clause given
+
          elsif Has_Size_Clause (T) then
             if RM_Size (T) < S then
                Error_Msg_Uint_1 := S;
                Error_Msg_NE
-                 ("size for & too small, minimum allowed is ^",
+                 ("size for& too small, minimum allowed is ^",
                   Size_Clause (T), T);
 
             elsif Unknown_Esize (T) then
@@ -780,7 +823,7 @@ package body Freeze is
                  and then Present (Parent (T))
                  and then Nkind (Parent (T)) = N_Full_Type_Declaration
                  and then Nkind (Type_Definition (Parent (T))) =
-                            N_Record_Definition
+                                               N_Record_Definition
                  and then not Null_Present (Type_Definition (Parent (T)))
                  and then Present (Variant_Part
                             (Component_List (Type_Definition (Parent (T)))))
@@ -792,8 +835,7 @@ package body Freeze is
 
                   if not Is_Constrained (T)
                     and then
-                      No (Discriminant_Default_Value
-                           (First_Discriminant (T)))
+                      No (Discriminant_Default_Value (First_Discriminant (T)))
                     and then Unknown_Esize (T)
                   then
                      return False;
@@ -890,12 +932,12 @@ package body Freeze is
 
                      if Is_Elementary_Type (Ctyp)
                        or else (Is_Array_Type (Ctyp)
-                                and then Present (Packed_Array_Type (Ctyp))
-                                and then Is_Modular_Integer_Type
-                                           (Packed_Array_Type (Ctyp)))
+                                 and then Present (Packed_Array_Type (Ctyp))
+                                 and then Is_Modular_Integer_Type
+                                            (Packed_Array_Type (Ctyp)))
                      then
-                        --  If RM_Size is known and static, then we can
-                        --  keep accumulating the packed size.
+                        --  If RM_Size is known and static, then we can keep
+                        --  accumulating the packed size.
 
                         if Known_Static_RM_Size (Ctyp) then
 
@@ -1047,7 +1089,9 @@ package body Freeze is
 
       --  Do not attempt to analyze case where range was in error
 
-      if Error_Posted (Scalar_Range (E)) then
+      if No (Scalar_Range (E))
+        or else Error_Posted (Scalar_Range (E))
+      then
          return;
       end if;
 
@@ -1111,36 +1155,47 @@ package body Freeze is
       end loop;
    end Check_Unsigned_Type;
 
-   -----------------------------
-   -- Expand_Atomic_Aggregate --
-   -----------------------------
+   -------------------------
+   -- Is_Atomic_Aggregate --
+   -------------------------
 
-   procedure Expand_Atomic_Aggregate (E : Entity_Id; Typ : Entity_Id) is
+   function  Is_Atomic_Aggregate
+     (E   : Entity_Id;
+      Typ : Entity_Id) return Boolean
+   is
       Loc   : constant Source_Ptr := Sloc (E);
       New_N : Node_Id;
+      Par   : Node_Id;
       Temp  : Entity_Id;
 
    begin
-      if (Nkind (Parent (E)) = N_Object_Declaration
-            or else Nkind (Parent (E)) = N_Assignment_Statement)
-        and then Comes_From_Source (Parent (E))
-      then
-         Temp :=
-           Make_Defining_Identifier (Loc,
-             New_Internal_Name ('T'));
+      Par := Parent (E);
+
+      --  Array may be qualified, so find outer context
 
+      if Nkind (Par) = N_Qualified_Expression then
+         Par := Parent (Par);
+      end if;
+
+      if Nkind_In (Par, N_Object_Declaration, N_Assignment_Statement)
+        and then Comes_From_Source (Par)
+      then
+         Temp := Make_Temporary (Loc, 'T', E);
          New_N :=
            Make_Object_Declaration (Loc,
              Defining_Identifier => Temp,
              Object_Definition   => New_Occurrence_Of (Typ, Loc),
              Expression          => Relocate_Node (E));
-         Insert_Before (Parent (E), New_N);
+         Insert_Before (Par, New_N);
          Analyze (New_N);
 
-         Set_Expression (Parent (E), New_Occurrence_Of (Temp, Loc));
+         Set_Expression (Par, New_Occurrence_Of (Temp, Loc));
+         return True;
 
+      else
+         return False;
       end if;
-   end Expand_Atomic_Aggregate;
+   end Is_Atomic_Aggregate;
 
    ----------------
    -- Freeze_All --
@@ -1168,10 +1223,7 @@ package body Freeze is
       -- Freeze_All_Ent --
       --------------------
 
-      procedure Freeze_All_Ent
-        (From  : Entity_Id;
-         After : in out Node_Id)
-      is
+      procedure Freeze_All_Ent (From : Entity_Id; After : in out Node_Id) is
          E     : Entity_Id;
          Flist : List_Id;
          Lastn : Node_Id;
@@ -1254,7 +1306,6 @@ package body Freeze is
 
                begin
                   Prim  := First_Elmt (Prim_List);
-
                   while Present (Prim) loop
                      Subp := Node (Prim);
 
@@ -1289,11 +1340,11 @@ package body Freeze is
                   Bod : constant Node_Id := Next (After);
 
                begin
-                  if (Nkind (Bod) = N_Subprogram_Body
-                        or else Nkind (Bod) = N_Entry_Body
-                        or else Nkind (Bod) = N_Package_Body
-                        or else Nkind (Bod) = N_Protected_Body
-                        or else Nkind (Bod) = N_Task_Body
+                  if (Nkind_In (Bod, N_Subprogram_Body,
+                                     N_Entry_Body,
+                                     N_Package_Body,
+                                     N_Protected_Body,
+                                     N_Task_Body)
                         or else Nkind (Bod) in N_Body_Stub)
                      and then
                        List_Containing (After) = List_Containing (Parent (E))
@@ -1320,6 +1371,9 @@ package body Freeze is
       --  point at which such functions are constructed (after all types that
       --  might be used in such expressions have been frozen).
 
+      --  For subprograms that are renaming_as_body, we create the wrapper
+      --  bodies as needed.
+
       --  We also add finalization chains to access types whose designated
       --  types are controlled. This is normally done when freezing the type,
       --  but this misses recursive type definitions where the later members
@@ -1360,11 +1414,10 @@ package body Freeze is
          then
             declare
                Ent : Entity_Id;
+
             begin
                Ent := First_Entity (E);
-
                while Present (Ent) loop
-
                   if Is_Entry (Ent)
                     and then not Default_Expressions_Processed (Ent)
                   then
@@ -1441,6 +1494,11 @@ package body Freeze is
       --  which is the current instance type can only be applied when the type
       --  is limited.
 
+      procedure Check_Suspicious_Modulus (Utype : Entity_Id);
+      --  Give warning for modulus of 8, 16, 32, or 64 given as an explicit
+      --  integer literal without an explicit corresponding size clause. The
+      --  caller has checked that Utype is a modular integer type.
+
       function After_Last_Declaration return Boolean;
       --  If Loc is a freeze_entity that appears after the last declaration
       --  in the scope, inhibit error messages on late completion.
@@ -1454,7 +1512,7 @@ package body Freeze is
       ----------------------------
 
       function After_Last_Declaration return Boolean is
-         Spec  : constant Node_Id := Parent (Current_Scope);
+         Spec : constant Node_Id := Parent (Current_Scope);
       begin
          if Nkind (Spec) = N_Package_Specification then
             if Present (Private_Declarations (Spec)) then
@@ -1519,9 +1577,7 @@ package body Freeze is
          --  either a tagged type, or a limited record.
 
          if Is_Limited_Type (Rec_Type)
-           and then
-             (Ada_Version < Ada_05
-               or else Is_Tagged_Type (Rec_Type))
+           and then (Ada_Version < Ada_05 or else Is_Tagged_Type (Rec_Type))
          then
             return;
 
@@ -1535,6 +1591,76 @@ package body Freeze is
          end if;
       end Check_Current_Instance;
 
+      ------------------------------
+      -- Check_Suspicious_Modulus --
+      ------------------------------
+
+      procedure Check_Suspicious_Modulus (Utype : Entity_Id) is
+         Decl : constant Node_Id := Declaration_Node (Underlying_Type (Utype));
+
+      begin
+         if Nkind (Decl) = N_Full_Type_Declaration then
+            declare
+               Tdef : constant Node_Id := Type_Definition (Decl);
+            begin
+               if Nkind (Tdef) = N_Modular_Type_Definition then
+                  declare
+                     Modulus : constant Node_Id :=
+                                 Original_Node (Expression (Tdef));
+                  begin
+                     if Nkind (Modulus) = N_Integer_Literal then
+                        declare
+                           Modv : constant Uint := Intval (Modulus);
+                           Sizv : constant Uint := RM_Size (Utype);
+
+                        begin
+                           --  First case, modulus and size are the same. This
+                           --  happens if you have something like mod 32, with
+                           --  an explicit size of 32, this is for sure a case
+                           --  where the warning is given, since it is seems
+                           --  very unlikely that someone would want e.g. a
+                           --  five bit type stored in 32 bits. It is much
+                           --  more likely they wanted a 32-bit type.
+
+                           if Modv = Sizv then
+                              null;
+
+                           --  Second case, the modulus is 32 or 64 and no
+                           --  size clause is present. This is a less clear
+                           --  case for giving the warning, but in the case
+                           --  of 32/64 (5-bit or 6-bit types) these seem rare
+                           --  enough that it is a likely error (and in any
+                           --  case using 2**5 or 2**6 in these cases seems
+                           --  clearer. We don't include 8 or 16 here, simply
+                           --  because in practice 3-bit and 4-bit types are
+                           --  more common and too many false positives if
+                           --  we warn in these cases.
+
+                           elsif not Has_Size_Clause (Utype)
+                             and then (Modv = Uint_32 or else Modv = Uint_64)
+                           then
+                              null;
+
+                           --  No warning needed
+
+                           else
+                              return;
+                           end if;
+
+                           --  If we fall through, give warning
+
+                           Error_Msg_Uint_1 := Modv;
+                           Error_Msg_N
+                             ("?2 '*'*^' may have been intended here",
+                              Modulus);
+                        end;
+                     end if;
+                  end;
+               end if;
+            end;
+         end if;
+      end Check_Suspicious_Modulus;
+
       ------------------------
       -- Freeze_Record_Type --
       ------------------------
@@ -1680,7 +1806,7 @@ package body Freeze is
          Prev := Empty;
          while Present (Comp) loop
 
-            --  First handle the (real) component case
+            --  First handle the component case
 
             if Ekind (Comp) = E_Component
               or else Ekind (Comp) = E_Discriminant
@@ -1751,129 +1877,12 @@ package body Freeze is
                            Component_Name (Component_Clause (Comp)));
                      end if;
                   end if;
-
-                  --  If component clause is present, then deal with the non-
-                  --  default bit order case for Ada 95 mode. The required
-                  --  processing for Ada 2005 mode is handled separately after
-                  --  processing all components.
-
-                  --  We only do this processing for the base type, and in
-                  --  fact that's important, since otherwise if there are
-                  --  record subtypes, we could reverse the bits once for
-                  --  each subtype, which would be incorrect.
-
-                  if Present (CC)
-                    and then Reverse_Bit_Order (Rec)
-                    and then Ekind (E) = E_Record_Type
-                    and then Ada_Version <= Ada_95
-                  then
-                     declare
-                        CFB : constant Uint    := Component_Bit_Offset (Comp);
-                        CSZ : constant Uint    := Esize (Comp);
-                        CLC : constant Node_Id := Component_Clause (Comp);
-                        Pos : constant Node_Id := Position (CLC);
-                        FB  : constant Node_Id := First_Bit (CLC);
-
-                        Storage_Unit_Offset : constant Uint :=
-                                                CFB / System_Storage_Unit;
-
-                        Start_Bit : constant Uint :=
-                                      CFB mod System_Storage_Unit;
-
-                     begin
-                        --  Cases where field goes over storage unit boundary
-
-                        if Start_Bit + CSZ > System_Storage_Unit then
-
-                           --  Allow multi-byte field but generate warning
-
-                           if Start_Bit mod System_Storage_Unit = 0
-                             and then CSZ mod System_Storage_Unit = 0
-                           then
-                              Error_Msg_N
-                                ("multi-byte field specified with non-standard"
-                                 & " Bit_Order?", CLC);
-
-                              if Bytes_Big_Endian then
-                                 Error_Msg_N
-                                   ("bytes are not reversed "
-                                    & "(component is big-endian)?", CLC);
-                              else
-                                 Error_Msg_N
-                                   ("bytes are not reversed "
-                                    & "(component is little-endian)?", CLC);
-                              end if;
-
-                           --  Do not allow non-contiguous field
-
-                           else
-                              Error_Msg_N
-                                ("attempt to specify non-contiguous field "
-                                 & "not permitted", CLC);
-                              Error_Msg_N
-                                ("\caused by non-standard Bit_Order "
-                                 & "specified", CLC);
-                              Error_Msg_N
-                                ("\consider possibility of using "
-                                 & "Ada 2005 mode here", CLC);
-                           end if;
-
-                        --  Case where field fits in one storage unit
-
-                        else
-                           --  Give warning if suspicious component clause
-
-                           if Intval (FB) >= System_Storage_Unit
-                             and then Warn_On_Reverse_Bit_Order
-                           then
-                              Error_Msg_N
-                                ("?Bit_Order clause does not affect " &
-                                 "byte ordering", Pos);
-                              Error_Msg_Uint_1 :=
-                                Intval (Pos) + Intval (FB) /
-                                  System_Storage_Unit;
-                              Error_Msg_N
-                                ("?position normalized to ^ before bit " &
-                                 "order interpreted", Pos);
-                           end if;
-
-                           --  Here is where we fix up the Component_Bit_Offset
-                           --  value to account for the reverse bit order.
-                           --  Some examples of what needs to be done are:
-
-                           --    First_Bit .. Last_Bit     Component_Bit_Offset
-                           --      old          new          old       new
-
-                           --     0 .. 0       7 .. 7         0         7
-                           --     0 .. 1       6 .. 7         0         6
-                           --     0 .. 2       5 .. 7         0         5
-                           --     0 .. 7       0 .. 7         0         4
-
-                           --     1 .. 1       6 .. 6         1         6
-                           --     1 .. 4       3 .. 6         1         3
-                           --     4 .. 7       0 .. 3         4         0
-
-                           --  The general rule is that the first bit is
-                           --  is obtained by subtracting the old ending bit
-                           --  from storage_unit - 1.
-
-                           Set_Component_Bit_Offset
-                             (Comp,
-                              (Storage_Unit_Offset * System_Storage_Unit) +
-                                (System_Storage_Unit - 1) -
-                                  (Start_Bit + CSZ - 1));
-
-                           Set_Normalized_First_Bit
-                             (Comp,
-                                Component_Bit_Offset (Comp) mod
-                                  System_Storage_Unit);
-                        end if;
-                     end;
-                  end if;
                end;
             end if;
 
-            --  Gather data for possible Implicit_Packing later
+            --  Gather data for possible Implicit_Packing later. Note that at
+            --  this stage we might be dealing with a real component, or with
+            --  an implicit subtype declaration.
 
             if not Is_Scalar_Type (Etype (Comp)) then
                All_Scalar_Components := False;
@@ -1886,12 +1895,12 @@ package body Freeze is
 
             --  If the component is an Itype with Delayed_Freeze and is either
             --  a record or array subtype and its base type has not yet been
-            --  frozen, we must remove this from the entity list of this
-            --  record and put it on the entity list of the scope of its base
-            --  type. Note that we know that this is not the type of a
-            --  component since we cleared Has_Delayed_Freeze for it in the
-            --  previous loop. Thus this must be the Designated_Type of an
-            --  access type, which is the type of a component.
+            --  frozen, we must remove this from the entity list of this record
+            --  and put it on the entity list of the scope of its base type.
+            --  Note that we know that this is not the type of a component
+            --  since we cleared Has_Delayed_Freeze for it in the previous
+            --  loop. Thus this must be the Designated_Type of an access type,
+            --  which is the type of a component.
 
             if Is_Itype (Comp)
               and then Is_Type (Scope (Comp))
@@ -2022,25 +2031,35 @@ package body Freeze is
             Next_Entity (Comp);
          end loop;
 
-         --  Deal with pragma Bit_Order
+         --  Deal with pragma Bit_Order setting non-standard bit order
 
          if Reverse_Bit_Order (Rec) and then Base_Type (Rec) = Rec then
             if not Placed_Component then
                ADC :=
                  Get_Attribute_Definition_Clause (Rec, Attribute_Bit_Order);
-               Error_Msg_N
-                 ("?Bit_Order specification has no effect", ADC);
+               Error_Msg_N ("?Bit_Order specification has no effect", ADC);
                Error_Msg_N
                  ("\?since no component clauses were specified", ADC);
 
-            --  Here is where we do Ada 2005 processing for bit order (the Ada
-            --  95 case was already taken care of above).
+            --  Here is where we do the processing for reversed bit order
 
-            elsif Ada_Version >= Ada_05 then
+            else
                Adjust_Record_For_Reverse_Bit_Order (Rec);
             end if;
          end if;
 
+         --  Complete error checking on record representation clause (e.g.
+         --  overlap of components). This is called after adjusting the
+         --  record for reverse bit order.
+
+         declare
+            RRC : constant Node_Id := Get_Record_Representation_Clause (Rec);
+         begin
+            if Present (RRC) then
+               Check_Record_Representation_Clause (RRC);
+            end if;
+         end;
+
          --  Set OK_To_Reorder_Components depending on debug flags
 
          if Rec = Base_Type (Rec)
@@ -2076,7 +2095,7 @@ package body Freeze is
             --  Give warning if redundant constructs warnings on
 
             if Warn_On_Redundant_Constructs then
-               Error_Msg_N
+               Error_Msg_N -- CODEFIX
                  ("?pragma Pack has no effect, no unplaced components",
                   Get_Rep_Pragma (Rec, Name_Pack));
             end if;
@@ -2098,14 +2117,21 @@ package body Freeze is
 
             Comp := First_Component (Rec);
             while Present (Comp) loop
-               if Has_Controlled_Component (Etype (Comp))
-                 or else (Chars (Comp) /= Name_uParent
-                           and then Is_Controlled (Etype (Comp)))
-                 or else (Is_Protected_Type (Etype (Comp))
-                           and then Present
-                             (Corresponding_Record_Type (Etype (Comp)))
-                           and then Has_Controlled_Component
-                             (Corresponding_Record_Type (Etype (Comp))))
+
+               --  Do not set Has_Controlled_Component on a class-wide
+               --  equivalent type. See Make_CW_Equivalent_Type.
+
+               if not Is_Class_Wide_Equivalent_Type (Rec)
+                 and then (Has_Controlled_Component (Etype (Comp))
+                            or else (Chars (Comp) /= Name_uParent
+                                      and then Is_Controlled (Etype (Comp)))
+                            or else (Is_Protected_Type (Etype (Comp))
+                                      and then Present
+                                        (Corresponding_Record_Type
+                                          (Etype (Comp)))
+                                      and then Has_Controlled_Component
+                                        (Corresponding_Record_Type
+                                          (Etype (Comp)))))
                then
                   Set_Has_Controlled_Component (Rec);
                   exit;
@@ -2193,15 +2219,39 @@ package body Freeze is
             end;
          end if;
 
-         --  See if Implicit_Packing would work
+         --  See if Size is too small as is (and implicit packing might help)
 
          if not Is_Packed (Rec)
+
+           --  No implicit packing if even one component is explicitly placed
+
            and then not Placed_Component
+
+           --  Must have size clause and all scalar components
+
            and then Has_Size_Clause (Rec)
            and then All_Scalar_Components
+
+           --  Do not try implicit packing on records with discriminants, too
+           --  complicated, especially in the variant record case.
+
            and then not Has_Discriminants (Rec)
+
+           --  We can implicitly pack if the specified size of the record is
+           --  less than the sum of the object sizes (no point in packing if
+           --  this is not the case).
+
            and then Esize (Rec) < Scalar_Component_Total_Esize
+
+           --  And the total RM size cannot be greater than the specified size
+           --  since otherwise packing will not get us where we have to be!
+
            and then Esize (Rec) >= Scalar_Component_Total_RM_Size
+
+           --  Never do implicit packing in CodePeer mode since we don't do
+           --  any packing ever in this mode (why not???)
+
+           and then not CodePeer_Mode
          then
             --  If implicit packing enabled, do it
 
@@ -2214,9 +2264,9 @@ package body Freeze is
                declare
                   Sz : constant Node_Id := Size_Clause (Rec);
                begin
-                  Error_Msg_NE --  CODEFIX
+                  Error_Msg_NE -- CODEFIX
                     ("size given for& too small", Sz, Rec);
-                  Error_Msg_N --  CODEFIX
+                  Error_Msg_N -- CODEFIX
                     ("\use explicit pragma Pack "
                      & "or use pragma Implicit_Packing", Sz);
                end;
@@ -2273,6 +2323,7 @@ package body Freeze is
             S : Entity_Id := Current_Scope;
 
          begin
+
             while Present (S) loop
                if Is_Overloadable (S) then
                   if Comes_From_Source (S)
@@ -2332,11 +2383,16 @@ package body Freeze is
          --  If entity is exported or imported and does not have an external
          --  name, now is the time to provide the appropriate default name.
          --  Skip this if the entity is stubbed, since we don't need a name
-         --  for any stubbed routine.
+         --  for any stubbed routine. For the case on intrinsics, if no
+         --  external name is specified, then calls will be handled in
+         --  Exp_Intr.Expand_Intrinsic_Call, and no name is needed. If an
+         --  external name is provided, then Expand_Intrinsic_Call leaves
+         --  calls in place for expansion by GIGI.
 
          if (Is_Imported (E) or else Is_Exported (E))
            and then No (Interface_Name (E))
            and then Convention (E) /= Convention_Stubbed
+           and then Convention (E) /= Convention_Intrinsic
          then
             Set_Encoded_Interface_Name
               (E, Get_Default_External_Name (E));
@@ -2351,15 +2407,17 @@ package body Freeze is
            and then Nkind (Parent (E)) = N_Object_Declaration
            and then Present (Expression (Parent (E)))
            and then Nkind (Expression (Parent (E))) = N_Aggregate
+           and then
+             Is_Atomic_Aggregate (Expression (Parent (E)), Etype (E))
          then
-            Expand_Atomic_Aggregate (Expression (Parent (E)), Etype (E));
+            null;
          end if;
 
          --  For a subprogram, freeze all parameter types and also the return
          --  type (RM 13.14(14)). However skip this for internal subprograms.
          --  This is also the point where any extra formal parameters are
-         --  created since we now know whether the subprogram will use
-         --  foreign convention.
+         --  created since we now know whether the subprogram will use a
+         --  foreign convention.
 
          if Is_Subprogram (E) then
             if not Is_Internal (E) then
@@ -2385,12 +2443,10 @@ package body Freeze is
                         --  If the type of a formal is incomplete, subprogram
                         --  is being frozen prematurely. Within an instance
                         --  (but not within a wrapper package) this is an
-                        --  an artifact of our need to regard the end of an
+                        --  artifact of our need to regard the end of an
                         --  instantiation as a freeze point. Otherwise it is
                         --  a definite error.
 
-                        --  and then not Is_Wrapper_Package (Current_Scope) ???
-
                         if In_Instance then
                            Set_Is_Frozen (E, False);
                            return No_List;
@@ -2419,6 +2475,8 @@ package body Freeze is
                        and then not Has_Warnings_Off (F_Type)
                        and then not Has_Warnings_Off (Formal)
                      then
+                        --  Qualify mention of formals with subprogram name
+
                         Error_Msg_Qual_Level := 1;
 
                         --  Check suspicious use of fat C pointer
@@ -2427,8 +2485,8 @@ package body Freeze is
                           and then Esize (F_Type) > Ttypes.System_Address_Size
                         then
                            Error_Msg_N
-                             ("?type of & does not correspond "
-                              & "to C pointer!", Formal);
+                             ("?type of & does not correspond to C pointer!",
+                              Formal);
 
                         --  Check suspicious return of boolean
 
@@ -2436,10 +2494,12 @@ package body Freeze is
                           and then Convention (F_Type) = Convention_Ada
                           and then not Has_Warnings_Off (F_Type)
                           and then not Has_Size_Clause (F_Type)
+                          and then VM_Target = No_VM
                         then
+                           Error_Msg_N ("& is an 8-bit Ada Boolean?", Formal);
                            Error_Msg_N
-                             ("?& is an 8-bit Ada Boolean, "
-                              & "use char in C!", Formal);
+                             ("\use appropriate corresponding type in C "
+                              & "(e.g. char)?", Formal);
 
                         --  Check suspicious tagged type
 
@@ -2451,7 +2511,7 @@ package body Freeze is
                           and then Convention (E) = Convention_C
                         then
                            Error_Msg_N
-                             ("?& is a tagged type which does not "
+                             ("?& involves a tagged type which does not "
                               & "correspond to any C type!", Formal);
 
                         --  Check wrong convention subprogram pointer
@@ -2468,6 +2528,8 @@ package body Freeze is
                               Formal, F_Type);
                         end if;
 
+                        --  Turn off name qualification after message output
+
                         Error_Msg_Qual_Level := 0;
                      end if;
 
@@ -2479,6 +2541,11 @@ package body Freeze is
                        and then Is_Array_Type (F_Type)
                        and then not Is_Constrained (F_Type)
                        and then Warn_On_Export_Import
+
+                       --  Exclude VM case, since both .NET and JVM can handle
+                       --  unconstrained arrays without a problem.
+
+                       and then VM_Target = No_VM
                      then
                         Error_Msg_Qual_Level := 1;
 
@@ -2560,13 +2627,22 @@ package body Freeze is
 
                         elsif Root_Type (R_Type) = Standard_Boolean
                           and then Convention (R_Type) = Convention_Ada
+                          and then VM_Target = No_VM
                           and then not Has_Warnings_Off (E)
                           and then not Has_Warnings_Off (R_Type)
                           and then not Has_Size_Clause (R_Type)
                         then
-                           Error_Msg_N
-                             ("?return type of & is an 8-bit "
-                              & "Ada Boolean, use char in C!", E);
+                           declare
+                              N : constant Node_Id :=
+                                    Result_Definition (Declaration_Node (E));
+                           begin
+                              Error_Msg_NE
+                                ("return type of & is an 8-bit Ada Boolean?",
+                                 N, E);
+                              Error_Msg_NE
+                                ("\use appropriate corresponding type in C "
+                                 & "(e.g. char)?", N, E);
+                           end;
 
                         --  Check suspicious return tagged type
 
@@ -2600,11 +2676,30 @@ package body Freeze is
                         end if;
                      end if;
 
-                     if Is_Array_Type (R_Type)
+                     --  Give warning for suspicous return of a result of an
+                     --  unconstrained array type in a foreign convention
+                     --  function.
+
+                     if Has_Foreign_Convention (E)
+
+                       --  We are looking for a return of unconstrained array
+
+                       and then Is_Array_Type (R_Type)
                        and then not Is_Constrained (R_Type)
+
+                       --  Exclude imported routines, the warning does not
+                       --  belong on the import, but on the routine definition.
+
                        and then not Is_Imported (E)
+
+                       --  Exclude VM case, since both .NET and JVM can handle
+                       --  return of unconstrained arrays without a problem.
+
                        and then VM_Target = No_VM
-                       and then Has_Foreign_Convention (E)
+
+                       --  Check that general warning is enabled, and that it
+                       --  is not suppressed for this particular case.
+
                        and then Warn_On_Export_Import
                        and then not Has_Warnings_Off (E)
                        and then not Has_Warnings_Off (R_Type)
@@ -2651,6 +2746,29 @@ package body Freeze is
 
             if Nkind (Declaration_Node (E)) = N_Object_Declaration then
 
+               --  Abstract type allowed only for C++ imported variables or
+               --  constants.
+
+               --  Note: we inhibit this check for objects that do not come
+               --  from source because there is at least one case (the
+               --  expansion of x'class'input where x is abstract) where we
+               --  legitimately generate an abstract object.
+
+               if Is_Abstract_Type (Etype (E))
+                 and then Comes_From_Source (Parent (E))
+                 and then not (Is_Imported (E)
+                                 and then Is_CPP_Class (Etype (E)))
+               then
+                  Error_Msg_N ("type of object cannot be abstract",
+                               Object_Definition (Parent (E)));
+
+                  if Is_CPP_Class (Etype (E)) then
+                     Error_Msg_NE
+                       ("\} may need a cpp_constructor",
+                       Object_Definition (Parent (E)), Etype (E));
+                  end if;
+               end if;
+
                --  For object created by object declaration, perform required
                --  categorization (preelaborate and pure) checks. Defer these
                --  checks to freeze time since pragma Import inhibits default
@@ -2879,6 +2997,7 @@ package body Freeze is
                     and then not Is_Limited_Composite (E)
                     and then not Is_Packed (Root_Type (E))
                     and then not Has_Component_Size_Clause (Root_Type (E))
+                    and then not CodePeer_Mode
                   then
                      Get_Index_Bounds (First_Index (E), Lo, Hi);
 
@@ -2902,7 +3021,10 @@ package body Freeze is
                         --  was a pragma Pack (resulting in the component size
                         --  being the same as the RM_Size). Furthermore, the
                         --  component type size must be an odd size (not a
-                        --  multiple of storage unit)
+                        --  multiple of storage unit). If the component RM size
+                        --  is an exact number of storage units that is a power
+                        --  of two, the array is not packed and has a standard
+                        --  representation.
 
                         begin
                            if RM_Size (E) = Len * Rsiz
@@ -2922,10 +3044,23 @@ package body Freeze is
                               else
                                  Error_Msg_NE
                                    ("size given for& too small", SZ, E);
-                                 Error_Msg_N
+                                 Error_Msg_N -- CODEFIX
                                    ("\use explicit pragma Pack "
                                     & "or use pragma Implicit_Packing", SZ);
                               end if;
+
+                           elsif RM_Size (E) = Len * Rsiz
+                             and then Implicit_Packing
+                             and then
+                               (Rsiz / System_Storage_Unit = 1
+                                 or else Rsiz / System_Storage_Unit = 2
+                                 or else Rsiz / System_Storage_Unit = 4)
+                           then
+
+                              --  Not a packed array, but indicate the desired
+                              --  component size, for the back-end.
+
+                              Set_Component_Size (Btyp, Rsiz);
                            end if;
                         end;
                      end if;
@@ -3166,9 +3301,7 @@ package body Freeze is
 
                --  For bit-packed arrays, check the size
 
-               if Is_Bit_Packed_Array (E)
-                 and then Known_RM_Size (E)
-               then
+               if Is_Bit_Packed_Array (E) and then Known_RM_Size (E) then
                   declare
                      SizC : constant Node_Id := Size_Clause (E);
 
@@ -3287,10 +3420,7 @@ package body Freeze is
             end if;
 
             --  The equivalent type associated with a class-wide subtype needs
-            --  to be frozen to ensure that its layout is done. Class-wide
-            --  subtypes are currently only frozen on targets requiring
-            --  front-end layout (see New_Class_Wide_Subtype and
-            --  Make_CW_Equivalent_Type in exp_util.adb).
+            --  to be frozen to ensure that its layout is done.
 
             if Ekind (E) = E_Class_Wide_Subtype
               and then Present (Equivalent_Type (E))
@@ -3564,6 +3694,12 @@ package body Freeze is
          elsif Is_Integer_Type (E) then
             Adjust_Esize_For_Alignment (E);
 
+            if Is_Modular_Integer_Type (E)
+              and then Warn_On_Suspicious_Modulus_Value
+            then
+               Check_Suspicious_Modulus (E);
+            end if;
+
          elsif Is_Access_Type (E) then
 
             --  Check restriction for standard storage pool
@@ -3971,6 +4107,13 @@ package body Freeze is
       --  designated type is a private type without full view, the expression
       --  cannot contain an allocator, so the type is not frozen.
 
+      --  For a function, we freeze the entity when the subprogram declaration
+      --  is frozen, but a function call may appear in an initialization proc.
+      --  before the declaration is frozen. We need to generate the extra
+      --  formals, if any, to ensure that the expansion of the call includes
+      --  the proper actuals. This only applies to Ada subprograms, not to
+      --  imported ones.
+
       Desig_Typ := Empty;
 
       case Nkind (N) is
@@ -3992,6 +4135,15 @@ package body Freeze is
                Desig_Typ := Designated_Type (Etype (Prefix (N)));
             end if;
 
+         when N_Identifier =>
+            if Present (Nam)
+              and then Ekind (Nam) = E_Function
+              and then Nkind (Parent (N)) = N_Function_Call
+              and then Convention (Nam) = Convention_Ada
+            then
+               Create_Extra_Formals (Nam);
+            end if;
+
          when others =>
             null;
       end case;
@@ -4012,7 +4164,7 @@ package body Freeze is
          return;
       end if;
 
-      --  Loop for looking at the right place to insert the freeze nodes
+      --  Loop for looking at the right place to insert the freeze nodes,
       --  exiting from the loop when it is appropriate to insert the freeze
       --  node before the current node P.
 
@@ -4194,6 +4346,8 @@ package body Freeze is
                  N_Entry_Call_Alternative     |
                  N_Triggering_Alternative     |
                  N_Abortable_Part             |
+                 N_And_Then                   |
+                 N_Or_Else                    |
                  N_Freeze_Entity              =>
 
                exit when Is_List_Member (P);
@@ -4282,8 +4436,8 @@ package body Freeze is
                   Scope_Stack.Table (Pos).Pending_Freeze_Actions :=
                       Freeze_Nodes;
                else
-                  Append_List (Freeze_Nodes, Scope_Stack.Table
-                                   (Pos).Pending_Freeze_Actions);
+                  Append_List (Freeze_Nodes,
+                    Scope_Stack.Table (Pos).Pending_Freeze_Actions);
                end if;
             end if;
          end;
@@ -4944,13 +5098,20 @@ package body Freeze is
    exception
       when Cannot_Be_Static =>
 
-         --  If the object that cannot be static is imported or exported,
-         --  then we give an error message saying that this object cannot
-         --  be imported or exported.
+         --  If the object that cannot be static is imported or exported, then
+         --  issue an error message saying that this object cannot be imported
+         --  or exported. If it has an address clause it is an overlay in the
+         --  current partition and the static requirement is not relevant.
+         --  Do not issue any error message when ignoring rep clauses.
 
-         if Is_Imported (E) then
-            Error_Msg_N
-              ("& cannot be imported (local type is not constant)", E);
+         if Ignore_Rep_Clauses then
+            null;
+
+         elsif Is_Imported (E) then
+            if No (Address_Clause (E)) then
+               Error_Msg_N
+                 ("& cannot be imported (local type is not constant)", E);
+            end if;
 
          --  Otherwise must be exported, something is wrong if compiler
          --  is marking something as statically allocated which cannot be).
@@ -5043,10 +5204,24 @@ package body Freeze is
             elsif Is_Generic_Type (Etype (E)) then
                null;
 
+            --  Display warning if returning unconstrained array
+
             elsif Is_Array_Type (Retype)
               and then not Is_Constrained (Retype)
+
+              --  Exclude cases where descriptor mechanism is set, since the
+              --  VMS descriptor mechanisms allow such unconstrained returns.
+
               and then Mechanism (E) not in Descriptor_Codes
+
+              --  Check appropriate warning is enabled (should we check for
+              --  Warnings (Off) on specific entities here, probably so???)
+
               and then Warn_On_Export_Import
+
+               --  Exclude the VM case, since return of unconstrained arrays
+               --  is properly handled in both the JVM and .NET cases.
+
               and then VM_Target = No_VM
             then
                Error_Msg_N
@@ -5076,9 +5251,9 @@ package body Freeze is
          end if;
       end if;
 
-      --  For VMS, descriptor mechanisms for parameters are allowed only
-      --  for imported/exported subprograms.  Moreover, the NCA descriptor
-      --  is not allowed for parameters of exported subprograms.
+      --  For VMS, descriptor mechanisms for parameters are allowed only for
+      --  imported/exported subprograms. Moreover, the NCA descriptor is not
+      --  allowed for parameters of exported subprograms.
 
       if OpenVMS_On_Target then
          if Is_Exported (E) then
@@ -5170,6 +5345,26 @@ package body Freeze is
             return True;
          end;
 
+      --  For the designated type of an access to subprogram, all types in
+      --  the profile must be fully defined.
+
+      elsif Ekind (T) = E_Subprogram_Type then
+         declare
+            F : Entity_Id;
+
+         begin
+            F := First_Formal (T);
+            while Present (F) loop
+               if not Is_Fully_Defined (Etype (F)) then
+                  return False;
+               end if;
+
+               Next_Formal (F);
+            end loop;
+
+            return Is_Fully_Defined (Etype (T));
+         end;
+
       else
          return not Is_Private_Type (T)
            or else Present (Full_View (Base_Type (T)));
@@ -5280,8 +5475,7 @@ package body Freeze is
             --  involve secondary stack expansion.
 
             else
-               Dnam :=
-                 Make_Defining_Identifier (Loc, New_Internal_Name ('D'));
+               Dnam := Make_Temporary (Loc, 'D');
 
                Dbody :=
                  Make_Subprogram_Body (Loc,
@@ -5416,16 +5610,18 @@ package body Freeze is
 
       --  We only give the warning for non-imported entities of a type for
       --  which a non-null base init proc is defined, or for objects of access
-      --  types with implicit null initialization, or when Initialize_Scalars
+      --  types with implicit null initialization, or when Normalize_Scalars
       --  applies and the type is scalar or a string type (the latter being
       --  tested for because predefined String types are initialized by inline
-      --  code rather than by an init_proc).
+      --  code rather than by an init_proc). Note that we do not give the
+      --  warning for Initialize_Scalars, since we suppressed initialization
+      --  in this case.
 
       if Present (Expr)
         and then not Is_Imported (Ent)
         and then (Has_Non_Null_Base_Init_Proc (Typ)
                     or else Is_Access_Type (Typ)
-                    or else (Init_Or_Norm_Scalars
+                    or else (Normalize_Scalars
                               and then (Is_Scalar_Type (Typ)
                                          or else Is_String_Type (Typ))))
       then