exp_ch4.adb (Expand_N_Type_Conversion): Remove special processing for conversion...
authorGeert Bosch <bosch@adacore.com>
Fri, 6 Apr 2007 09:17:46 +0000 (11:17 +0200)
committerArnaud Charlet <charlet@gcc.gnu.org>
Fri, 6 Apr 2007 09:17:46 +0000 (11:17 +0200)
2007-04-06  Geert Bosch  <bosch@adacore.com>
    Ed Schonberg  <schonberg@adacore.com>
    Javier Miranda  <miranda@adacore.com>
    Bob Duff  <duff@adacore.com>

* exp_ch4.adb (Expand_N_Type_Conversion): Remove special processing
for conversion of a Float_Type'Truncation to integer.

* exp_attr.adb (Is_Inline_Floating_Point_Attribute): New function to
check if a node is an attribute that can be handled directly by the
back end.
(Expand_N_Attribute_Reference): Suppress expansion of floating-point
attributes that can be handled directly by the back end.
(Expand_N_Attribute_Reference, case 'Access and 'Unchecked_Access):
use new predicate Is_Access_Protected_Subprogram_Type.
(Expand_N_Attribute_Reference, case 'Write): The reference is legal for
and Unchecked_Union if it is generated as part of the default  Output
procedure for a type with default discriminants.
(Expand_N_Attribute_Reference): Avoid the expansion of dispatching calls
if we are compiling under restriction No_Dispatching_Calls.
(Constrained): Use Underlying_Type, in case the type is private without
discriminants, but the full type has discriminants.
(Expand_N_Attribute_Reference): Replace call to Get_Access_Level by
call to Build_Get_Access_Level.
(Expand_N_Attribute_Reference): The use of 'Address with class-wide
interface objects requires a call to the run-time subprogram that
returns the base address of the object.
(Valid_Conversion): Improve error message on illegal attempt to store
an anonymous access to subprogram value into a record component.

* sem_res.adb (Resolve_Equality_Op): Detect ambiguity for "X'Access =
null".
(Simplify_Type_Conversion): New procedure that performs simplification
of Int_Type (Float_Type'Truncation (X)).
(Resolve_Type_Conversion): Call above procedure after resolving operand
and before performing checks. This replaces the existing ineffective
code in Exp_Ch4.
(Set_String_Literal_Subtype): When creating the internal static lower
bound subtype for a string literal, use a newly created copy of the
subtree representing the lower bound.
(Resolve_Call): Exclude build-in-place function calls from transient
scope treatment. Update comments to describe this exception.
(Resolve_Equality_Op): In case of dispatching call check violation of
restriction No_Dispatching_Calls.
(Resolve_Call): If the call returns an array, the context imposes the
component type of the array, and the function has one non-defaulted
parameter, rewrite the call as the indexing of a call with a single
parameter, to handle an Ada 2005 syntactic ambiguity for calls written
in prefix form.
(Resolve_Actuals): If an actual is an allocator for an access parameter,
the master of the created object is the innermost enclosing statement.
(Remove_Conversions): For a binary operator, check if type of second
formal is numeric, to check if an abstract interpretation is present
in the case of exponentiation as well.

From-SVN: r123552

gcc/ada/exp_attr.adb
gcc/ada/exp_ch4.adb
gcc/ada/sem_res.adb

index 9d2bae12e74870fb8d74e9bb796a7de7183ea5f2..79096e9d6f79412cd976f21ff0015a6cbe786e08 100644 (file)
@@ -28,6 +28,7 @@ with Atree;    use Atree;
 with Checks;   use Checks;
 with Einfo;    use Einfo;
 with Elists;   use Elists;
+with Exp_Atag; use Exp_Atag;
 with Exp_Ch2;  use Exp_Ch2;
 with Exp_Ch9;  use Exp_Ch9;
 with Exp_Imgv; use Exp_Imgv;
@@ -160,6 +161,12 @@ package body Exp_Attr is
    --  Utility for array attributes, returns true on packed constrained
    --  arrays, and on access to same.
 
+   function Is_Inline_Floating_Point_Attribute (N : Node_Id) return Boolean;
+   --  Returns true iff the given node refers to an attribute call that
+   --  can be expanded directly by the back end and does not need front end
+   --  expansion. Typically used for rounding and truncation attributes that
+   --  appear directly inside a conversion to integer.
+
    ----------------------------------
    -- Compile_Stream_Body_In_Scope --
    ----------------------------------
@@ -497,7 +504,7 @@ package body Exp_Attr is
    -- Expand_Fpt_Attribute_RR --
    -----------------------------
 
-   --  The two arguments is converted to their root types to call the
+   --  The two arguments are converted to their root types to call the
    --  appropriate runtime function, with the actual call being built
    --  by Expand_Fpt_Attribute
 
@@ -665,7 +672,7 @@ package body Exp_Attr is
 
       when Attribute_Access =>
 
-         if Ekind (Btyp) = E_Access_Protected_Subprogram_Type then
+         if Is_Access_Protected_Subprogram_Type (Btyp) then
             Expand_Access_To_Protected_Op (N, Pref, Typ);
 
          elsif Ekind (Btyp) = E_General_Access_Type then
@@ -795,6 +802,23 @@ package body Exp_Attr is
 
                Analyze_And_Resolve (N, Addr);
             end;
+
+         --  Ada 2005 (AI-251): Class-wide interface objects are always
+         --  "displaced" to reference the tag associated with the interface
+         --  type. In order to obtain the real address of such objects we
+         --  generate a call to a run-time subprogram that returns the base
+         --  address of the object.
+
+         elsif Is_Class_Wide_Type (Etype (Pref))
+            and then Is_Interface (Etype (Pref))
+         then
+            Rewrite (N,
+              Make_Function_Call (Loc,
+                Name => New_Reference_To (RTE (RE_Base_Address), Loc),
+                Parameter_Associations => New_List (
+                  Relocate_Node (N))));
+            Analyze (N);
+            return;
          end if;
 
          --  Deal with packed array reference, other cases are handled by gigi
@@ -829,6 +853,15 @@ package body Exp_Attr is
          --  operation _Alignment applied to X.
 
          elsif Is_Class_Wide_Type (Ptyp) then
+
+            --  No need to do anything else compiling under restriction
+            --  No_Dispatching_Calls. During the semantic analysis we
+            --  already notified such violation.
+
+            if Restriction_Active (No_Dispatching_Calls) then
+               return;
+            end if;
+
             New_Node :=
               Make_Function_Call (Loc,
                 Name => New_Reference_To
@@ -1327,8 +1360,13 @@ package body Exp_Attr is
                --  not accurate (the procedure formal case), has been
                --  handled above.
 
+               --  We use the Underlying_Type here (and below) in case the
+               --  type is private without discriminants, but the full type
+               --  has discriminants. This case is illegal, but we generate it
+               --  internally for passing to the Extra_Constrained parameter.
+
                else
-                  Res := Is_Constrained (Etype (Ent));
+                  Res := Is_Constrained (Underlying_Type (Etype (Ent)));
                end if;
 
                Rewrite (N,
@@ -1350,7 +1388,7 @@ package body Exp_Attr is
                      (Nkind (Pref) = N_Explicit_Dereference
                         and then
                           not Has_Constrained_Partial_View (Base_Type (Typ)))
-                    or else Is_Constrained (Typ)),
+                    or else Is_Constrained (Underlying_Type (Typ))),
                 Loc));
          end if;
 
@@ -2013,6 +2051,14 @@ package body Exp_Attr is
 
             elsif Is_Class_Wide_Type (P_Type) then
 
+               --  No need to do anything else compiling under restriction
+               --  No_Dispatching_Calls. During the semantic analysis we
+               --  already notified such violation.
+
+               if Restriction_Active (No_Dispatching_Calls) then
+                  return;
+               end if;
+
                declare
                   Rtyp : constant Entity_Id := Root_Type (P_Type);
                   Dnn  : Entity_Id;
@@ -2430,10 +2476,13 @@ package body Exp_Attr is
 
       --  Transforms 'Machine_Rounding into a call to the floating-point
       --  attribute function Machine_Rounding in Fat_xxx (where xxx is the root
-      --  type).
+      --  type). Expansion is avoided for cases the back end can handle
+      --  directly.
 
       when Attribute_Machine_Rounding =>
-         Expand_Fpt_Attribute_R (N);
+         if not Is_Inline_Floating_Point_Attribute (N) then
+            Expand_Fpt_Attribute_R (N);
+         end if;
 
       ------------------
       -- Machine_Size --
@@ -2707,6 +2756,15 @@ package body Exp_Attr is
             --  to the appropriate primitive Output function (RM 13.13.2(31)).
 
             elsif Is_Class_Wide_Type (P_Type) then
+
+               --  No need to do anything else compiling under restriction
+               --  No_Dispatching_Calls. During the semantic analysis we
+               --  already notified such violation.
+
+               if Restriction_Active (No_Dispatching_Calls) then
+                  return;
+               end if;
+
                Tag_Write : declare
                   Strm : constant Node_Id := First (Exprs);
                   Item : constant Node_Id := Next (Strm);
@@ -2730,21 +2788,18 @@ package body Exp_Attr is
                          Condition =>
                            Make_Op_Ne (Loc,
                              Left_Opnd  =>
-                               Make_Function_Call (Loc,
-                                 Name =>
-                                   New_Reference_To
-                                     (RTE (RE_Get_Access_Level), Loc),
-                                 Parameter_Associations =>
-                                   New_List (Make_Attribute_Reference (Loc,
-                                               Prefix         =>
-                                                 Relocate_Node (
-                                                   Duplicate_Subexpr (Item,
-                                                     Name_Req => True)),
-                                               Attribute_Name =>
-                                                  Name_Tag))),
+                               Build_Get_Access_Level (Loc,
+                                 Make_Attribute_Reference (Loc,
+                                   Prefix         =>
+                                     Relocate_Node (
+                                       Duplicate_Subexpr (Item,
+                                         Name_Req => True)),
+                                   Attribute_Name => Name_Tag)),
+
                              Right_Opnd =>
-                               Make_Integer_Literal
-                                 (Loc, Type_Access_Level (P_Type))),
+                               Make_Integer_Literal (Loc,
+                                 Type_Access_Level (P_Type))),
+
                          Then_Statements =>
                            New_List (Make_Raise_Statement (Loc,
                                        New_Occurrence_Of (
@@ -2775,9 +2830,9 @@ package body Exp_Attr is
             elsif Is_Tagged_Type (U_Type) then
                Pname := Find_Prim_Op (U_Type, TSS_Stream_Output);
 
---              --  All other record type cases, including protected records.
---              --  The latter only arise for expander generated code for
---              --  handling shared passive partition access.
+            --  All other record type cases, including protected records.
+            --  The latter only arise for expander generated code for
+            --  handling shared passive partition access.
 
             else
                pragma Assert
@@ -3450,6 +3505,15 @@ package body Exp_Attr is
          --  X'Size into a call to the primitive operation _Size applied to X.
 
          elsif Is_Class_Wide_Type (Ptyp) then
+
+            --  No need to do anything else compiling under restriction
+            --  No_Dispatching_Calls. During the semantic analysis we
+            --  already notified such violation.
+
+            if Restriction_Active (No_Dispatching_Calls) then
+               return;
+            end if;
+
             New_Node :=
               Make_Function_Call (Loc,
                 Name => New_Reference_To
@@ -3912,10 +3976,13 @@ package body Exp_Attr is
       ----------------
 
       --  Transforms 'Truncation into a call to the floating-point attribute
-      --  function Truncation in Fat_xxx (where xxx is the root type)
+      --  function Truncation in Fat_xxx (where xxx is the root type).
+      --  Expansion is avoided for cases the back end can handle directly.
 
       when Attribute_Truncation =>
-         Expand_Fpt_Attribute_R (N);
+         if not Is_Inline_Floating_Point_Attribute (N) then
+            Expand_Fpt_Attribute_R (N);
+         end if;
 
       -----------------------
       -- Unbiased_Rounding --
@@ -3923,10 +3990,13 @@ package body Exp_Attr is
 
       --  Transforms 'Unbiased_Rounding into a call to the floating-point
       --  attribute function Unbiased_Rounding in Fat_xxx (where xxx is the
-      --  root type)
+      --  root type). Expansion is avoided for cases the back end can handle
+      --  directly.
 
       when Attribute_Unbiased_Rounding =>
-         Expand_Fpt_Attribute_R (N);
+         if not Is_Inline_Floating_Point_Attribute (N) then
+            Expand_Fpt_Attribute_R (N);
+         end if;
 
       ----------------------
       -- Unchecked_Access --
@@ -3999,7 +4069,7 @@ package body Exp_Attr is
 
       when Attribute_Unrestricted_Access =>
 
-         if Ekind (Btyp) = E_Access_Protected_Subprogram_Type then
+         if Is_Access_Protected_Subprogram_Type (Btyp) then
             Expand_Access_To_Protected_Op (N, Pref, Typ);
 
          --  Ada 2005 (AI-251): If the designated type is an interface, then
@@ -4184,7 +4254,7 @@ package body Exp_Attr is
                   --  to call the special routine Unaligned_Valid, which makes
                   --  the needed copy, being careful not to load the value into
                   --  any floating-point register. The argument in this case is
-                  --  obj'Address (see Unchecked_Valid routine in Fat_Gen).
+                  --  obj'Address (see Unaligned_Valid routine in Fat_Gen).
 
                   if Is_Possibly_Unaligned_Object (Pref) then
                      Set_Attribute_Name (N, Name_Unaligned_Valid);
@@ -4667,9 +4737,14 @@ package body Exp_Attr is
 
                --  Ada 2005 (AI-216): Program_Error is raised when executing
                --  the default implementation of the Write attribute of an
-               --  Unchecked_Union type.
+               --  Unchecked_Union type. However, if the 'Write reference is
+               --  within the generated Output stream procedure, Write outputs
+               --  the components, and the default values of the discriminant
+               --  are streamed by the Output procedure itself.
 
-               if Is_Unchecked_Union (Base_Type (U_Type)) then
+               if Is_Unchecked_Union (Base_Type (U_Type))
+                 and not Is_TSS (Current_Scope, TSS_Stream_Output)
+               then
                   Insert_Action (N,
                     Make_Raise_Program_Error (Loc,
                       Reason => PE_Unchecked_Union_Restriction));
@@ -5038,4 +5113,24 @@ package body Exp_Attr is
         and then Present (Packed_Array_Type (Arr));
    end Is_Constrained_Packed_Array;
 
+   ----------------------------------------
+   -- Is_Inline_Floating_Point_Attribute --
+   ----------------------------------------
+
+   function Is_Inline_Floating_Point_Attribute (N : Node_Id) return Boolean is
+      Id : constant Attribute_Id := Get_Attribute_Id (Attribute_Name (N));
+
+   begin
+      if Nkind (Parent (N)) /= N_Type_Conversion
+        or else not Is_Integer_Type (Etype (Parent (N)))
+      then
+         return False;
+      end if;
+
+      --  Should also support 'Machine_Rounding and 'Unbiased_Rounding, but
+      --  required back end support has not been implemented yet ???
+
+      return Id = Attribute_Truncation;
+   end Is_Inline_Floating_Point_Attribute;
+
 end Exp_Attr;
index a65809fb63801a58e08e6749120e035c8bd24af6..d508c348098e1481703242549b445701834689e6 100644 (file)
@@ -30,6 +30,7 @@ with Einfo;    use Einfo;
 with Elists;   use Elists;
 with Errout;   use Errout;
 with Exp_Aggr; use Exp_Aggr;
+with Exp_Atag; use Exp_Atag;
 with Exp_Ch3;  use Exp_Ch3;
 with Exp_Ch6;  use Exp_Ch6;
 with Exp_Ch7;  use Exp_Ch7;
@@ -46,6 +47,8 @@ with Inline;   use Inline;
 with Nlists;   use Nlists;
 with Nmake;    use Nmake;
 with Opt;      use Opt;
+with Restrict; use Restrict;
+with Rident;   use Rident;
 with Rtsfind;  use Rtsfind;
 with Sem;      use Sem;
 with Sem_Cat;  use Sem_Cat;
@@ -481,37 +484,47 @@ package body Exp_Ch4 is
          --  type, generate an accessibility check to verify that the level of
          --  the type of the created object is not deeper than the level of the
          --  access type. If the type of the qualified expression is class-
-         --  wide, then always generate the check. Otherwise, only generate the
-         --  check if the level of the qualified expression type is statically
-         --  deeper than the access type. Although the static accessibility
-         --  will generally have been performed as a legality check, it won't
-         --  have been done in cases where the allocator appears in generic
-         --  body, so a run-time check is needed in general.
+         --  wide, then always generate the check (except in the case where it
+         --  is known to be unnecessary, see comment below). Otherwise, only
+         --  generate the check if the level of the qualified expression type
+         --  is statically deeper than the access type. Although the static
+         --  accessibility will generally have been performed as a legality
+         --  check, it won't have been done in cases where the allocator
+         --  appears in generic body, so a run-time check is needed in general.
+         --  One special case is when the access type is declared in the same
+         --  scope as the class-wide allocator, in which case the check can
+         --  never fail, so it need not be generated. As an open issue, there
+         --  seem to be cases where the static level associated with the
+         --  class-wide object's underlying type is not sufficient to perform
+         --  the proper accessibility check, such as for allocators in nested
+         --  subprograms or accept statements initialized by class-wide formals
+         --  when the actual originates outside at a deeper static level. The
+         --  nested subprogram case might require passing accessibility levels
+         --  along with class-wide parameters, and the task case seems to be
+         --  an actual gap in the language rules that needs to be fixed by the
+         --  ARG. ???
 
          if Ada_Version >= Ada_05
            and then Is_Class_Wide_Type (DesigT)
            and then not Scope_Suppress (Accessibility_Check)
            and then
-             (Is_Class_Wide_Type (Etype (Exp))
-                or else
-              Type_Access_Level (Etype (Exp)) > Type_Access_Level (PtrT))
+             (Type_Access_Level (Etype (Exp)) > Type_Access_Level (PtrT)
+               or else
+                 (Is_Class_Wide_Type (Etype (Exp))
+                   and then Scope (PtrT) /= Current_Scope))
          then
             Insert_Action (N,
                Make_Raise_Program_Error (Loc,
                  Condition =>
                    Make_Op_Gt (Loc,
                      Left_Opnd  =>
-                       Make_Function_Call (Loc,
-                         Name =>
-                           New_Reference_To (RTE (RE_Get_Access_Level), Loc),
-                         Parameter_Associations =>
-                           New_List (Make_Attribute_Reference (Loc,
-                                       Prefix         =>
-                                          New_Reference_To (Temp, Loc),
-                                       Attribute_Name =>
-                                          Name_Tag))),
+                       Build_Get_Access_Level (Loc,
+                         Make_Attribute_Reference (Loc,
+                           Prefix => New_Reference_To (Temp, Loc),
+                           Attribute_Name => Name_Tag)),
                      Right_Opnd =>
-                       Make_Integer_Literal (Loc, Type_Access_Level (PtrT))),
+                       Make_Integer_Literal (Loc,
+                         Type_Access_Level (PtrT))),
                  Reason => PE_Accessibility_Check_Failed));
          end if;
 
@@ -2489,6 +2502,72 @@ package body Exp_Ch4 is
       Temp  : Entity_Id;
       Node  : Node_Id;
 
+      function Is_Local_Access_Discriminant (N : Node_Id) return Boolean;
+      --  If the allocator is for an access discriminant of a stack-allocated
+      --  object, the discriminant can be allocated locally as well, to ensure
+      --  that its lifetime does not exceed that of the enclosing object.
+      --  This is an optimization mandated / suggested by Ada 2005 AI-162.
+
+      ----------------------------------
+      -- Is_Local_Access_Discriminant --
+      ----------------------------------
+
+      function Is_Local_Access_Discriminant (N : Node_Id) return Boolean is
+         Decl : Node_Id;
+         Temp : Entity_Id;
+
+      begin
+         if Nkind (Parent (N)) = N_Index_Or_Discriminant_Constraint
+           and then not Is_Coextension (N)
+           and then not Is_Record_Type (Current_Scope)
+         then
+            Temp :=
+              Make_Defining_Identifier (Loc,
+                Chars => New_Internal_Name ('T'));
+
+            Decl :=
+              Make_Object_Declaration (Loc,
+                Defining_Identifier => Temp,
+                Aliased_Present     => True,
+                Object_Definition   => New_Occurrence_Of (Etyp, Loc));
+
+            if Nkind (Expression (N)) = N_Qualified_Expression then
+               Set_Expression (Decl, Expression (Expression (N)));
+            end if;
+
+            declare
+               Nod : Node_Id;
+
+            begin
+               Nod := Parent (N);
+               while Present (Nod) loop
+                  exit when
+                      Nkind (Nod) in N_Statement_Other_Than_Procedure_Call
+                    or else Nkind (Nod) = N_Procedure_Call_Statement
+                    or else Nkind (Nod) in N_Declaration;
+                  Nod := Parent (Nod);
+               end loop;
+
+               Insert_Before (Nod, Decl);
+               Analyze (Decl);
+            end;
+
+            Rewrite (N,
+              Make_Attribute_Reference (Loc,
+                Prefix => New_Occurrence_Of (Temp, Loc),
+                Attribute_Name => Name_Unrestricted_Access));
+
+            Analyze_And_Resolve (N, PtrT);
+
+            return True;
+
+         else
+            return False;
+         end if;
+      end Is_Local_Access_Discriminant;
+
+   --  Start of processing for Expand_N_Allocator
+
    begin
       --  RM E.2.3(22). We enforce that the expected type of an allocator
       --  shall not be a remote access-to-class-wide-limited-private type
@@ -2581,6 +2660,14 @@ package body Exp_Ch4 is
          return;
       end if;
 
+      --  Same if the allocator is an access discriminant for a local object:
+      --  instead of an allocator we create a local value and constrain the
+      --  the enclosing object with the corresponding access attribute.
+
+      if Is_Local_Access_Discriminant (N) then
+         return;
+      end if;
+
       --  Handle case of qualified expression (other than optimization above)
 
       if Nkind (Expression (N)) = N_Qualified_Expression then
@@ -2721,6 +2808,7 @@ package body Exp_Ch4 is
                      --  The designated type was an incomplete type, and the
                      --  access type did not get expanded. Salvage it now.
 
+                     pragma Assert (Present (Parent (Base_Type (PtrT))));
                      Expand_N_Full_Type_Declaration
                        (Parent (Base_Type (PtrT)));
                   end if;
@@ -2895,11 +2983,26 @@ package body Exp_Ch4 is
 
                if Controlled_Type (T) then
                   Flist := Get_Allocator_Final_List (N, Base_Type (T), PtrT);
-                  if Ekind (PtrT) = E_Anonymous_Access_Type then
+
+                  --  Anonymous access types created for access parameters
+                  --  are attached to an explicitly constructed controller,
+                  --  which ensures that they can be finalized properly, even
+                  --  if their deallocation might not happen. The list
+                  --  associated with the controller is doubly-linked. For
+                  --  other anonymous access types, the object may end up
+                  --  on the global final list which is singly-linked.
+                  --  Work needed for access discriminants in Ada 2005 ???
+
+                  if Ekind (PtrT) = E_Anonymous_Access_Type
+                      and then
+                        Nkind (Associated_Node_For_Itype (PtrT))
+                          not in N_Subprogram_Specification
+                  then
                      Attach_Level := Uint_1;
                   else
                      Attach_Level := Uint_2;
                   end if;
+
                   Insert_Actions (N,
                     Make_Init_Call (
                       Ref          => New_Copy_Tree (Arg1),
@@ -4571,6 +4674,14 @@ package body Exp_Ch4 is
 
          if Is_Tagged_Type (Typl) then
 
+            --  No need to do anything else compiling under restriction
+            --  No_Dispatching_Calls. During the semantic analysis we
+            --  already notified such violation.
+
+            if Restriction_Active (No_Dispatching_Calls) then
+               return;
+            end if;
+
             --  If this is derived from an untagged private type completed
             --  with a tagged type, it does not have a full view, so we
             --  use the primitive operations of the private type.
@@ -6420,6 +6531,18 @@ package body Exp_Ch4 is
         and then (not Is_Entity_Name (Pfx)
                    or else not Index_Checks_Suppressed (Entity (Pfx)))
         and then Nkind (Discrete_Range (N)) /= N_Subtype_Indication
+
+         --  Do not enable range check to nodes associated with the frontend
+         --  expansion of the dispatch table. We first check if Ada.Tags is
+         --  already loaded to avoid the addition of an undesired dependence
+         --  on such run-time unit.
+
+        and then not
+          (RTU_Loaded (Ada_Tags)
+            and then Nkind (Prefix (N)) = N_Selected_Component
+            and then Present (Entity (Selector_Name (Prefix (N))))
+            and then Entity (Selector_Name (Prefix (N))) =
+                                         RTE_Record_Component (RE_Prims_Ptr))
       then
          Enable_Range_Check (Discrete_Range (N));
       end if;
@@ -6431,7 +6554,7 @@ package body Exp_Ch4 is
       --       situation correctly in the assignment statement expansion).
 
       --    2. Prefix of indexed component (the slide is optimized away
-      --       in this case, see the start of Expand_N_Slice.
+      --       in this case, see the start of Expand_N_Slice.)
 
       --    3. Object renaming declaration, since we want the name of
       --       the slice, not the value.
@@ -6906,7 +7029,7 @@ package body Exp_Ch4 is
             return;
          end if;
 
-         --  Oherwise, proceed with processing tagged conversion
+         --  Otherwise, proceed with processing tagged conversion
 
          declare
             Actual_Operand_Type : Entity_Id;
@@ -7072,32 +7195,16 @@ package body Exp_Ch4 is
             or else
           (Is_Fixed_Point_Type (Target_Type) and then Conversion_OK (N)))
       then
-         --  Special processing required if the conversion is the expression
-         --  of a Truncation attribute reference. In this case we replace:
-
-         --     ityp (ftyp'Truncation (x))
-
-         --  by
-
-         --     ityp (x)
-
-         --  with the Float_Truncate flag set. This is clearly more efficient
-
-         if Nkind (Operand) = N_Attribute_Reference
-           and then Attribute_Name (Operand) = Name_Truncation
-         then
-            Rewrite (Operand,
-              Relocate_Node (First (Expressions (Operand))));
-            Set_Float_Truncate (N, True);
-         end if;
-
          --  One more check here, gcc is still not able to do conversions of
          --  this type with proper overflow checking, and so gigi is doing an
          --  approximation of what is required by doing floating-point compares
          --  with the end-point. But that can lose precision in some cases, and
          --  give a wrong result. Converting the operand to Universal_Real is
          --  helpful, but still does not catch all cases with 64-bit integers
-         --  on targets with only 64-bit floats ???
+         --  on targets with only 64-bit floats
+
+         --  The above comment seems obsoleted by Apply_Float_Conversion_Check
+         --  Can this code be removed ???
 
          if Do_Range_Check (Operand) then
             Rewrite (Operand,
@@ -8358,6 +8465,11 @@ package body Exp_Ch4 is
    --  is usually implemented by looking in the ancestor tables contained in
    --  the dispatch table pointed by Left_Expr.Tag for Typ'Tag
 
+   --  Ada 2005 (AI-251): If it is a class-wide interface type we use the RT
+   --  function IW_Membership which is usually implemented by looking in the
+   --  table of abstract interface types plus the ancestor table contained in
+   --  the dispatch table pointed by Left_Expr.Tag for Typ'Tag
+
    function Tagged_Membership (N : Node_Id) return Node_Id is
       Left  : constant Node_Id    := Left_Opnd  (N);
       Right : constant Node_Id    := Right_Opnd (N);
@@ -8383,11 +8495,44 @@ package body Exp_Ch4 is
 
       if Is_Class_Wide_Type (Right_Type) then
 
+         --  No need to issue a run-time check if we statically know that the
+         --  result of this membership test is always true. For example,
+         --  considering the following declarations:
+
+         --    type Iface is interface;
+         --    type T     is tagged null record;
+         --    type DT    is new T and Iface with null record;
+
+         --    Obj1 : T;
+         --    Obj2 : DT;
+
+         --  These membership tests are always true:
+
+         --    Obj1 in T'Class
+         --    Obj2 in T'Class;
+         --    Obj2 in Iface'Class;
+
+         --  We do not need to handle cases where the membership is illegal.
+         --  For example:
+
+         --    Obj1 in DT'Class;     --  Compile time error
+         --    Obj1 in Iface'Class;  --  Compile time error
+
+         if not Is_Class_Wide_Type (Left_Type)
+           and then (Is_Parent (Etype (Right_Type), Left_Type)
+                       or else (Is_Interface (Etype (Right_Type))
+                                 and then Interface_Present_In_Ancestor
+                                           (Typ   => Left_Type,
+                                            Iface => Etype (Right_Type))))
+         then
+            return New_Reference_To (Standard_True, Loc);
+         end if;
+
          --  Ada 2005 (AI-251): Class-wide applied to interfaces
 
          if Is_Interface (Etype (Class_Wide_Type (Right_Type)))
 
-            --   Give support to: "Iface_CW_Typ in Typ'Class"
+            --   Support to: "Iface_CW_Typ in Typ'Class"
 
            or else Is_Interface (Left_Type)
          then
@@ -8415,23 +8560,31 @@ package body Exp_Ch4 is
 
          else
             return
-              Make_Function_Call (Loc,
-                 Name => New_Occurrence_Of (RTE (RE_CW_Membership), Loc),
-                 Parameter_Associations => New_List (
-                   Obj_Tag,
+              Build_CW_Membership (Loc,
+                Obj_Tag_Node => Obj_Tag,
+                Typ_Tag_Node =>
                    New_Reference_To (
                      Node (First_Elmt
                             (Access_Disp_Table (Root_Type (Right_Type)))),
-                     Loc)));
+                     Loc));
          end if;
 
+      --  Right_Type is not a class-wide type
+
       else
-         return
-           Make_Op_Eq (Loc,
-             Left_Opnd  => Obj_Tag,
-             Right_Opnd =>
-               New_Reference_To
-                 (Node (First_Elmt (Access_Disp_Table (Right_Type))), Loc));
+         --  No need to check the tag of the object if Right_Typ is abstract
+
+         if Is_Abstract_Type (Right_Type) then
+            return New_Reference_To (Standard_False, Loc);
+
+         else
+            return
+              Make_Op_Eq (Loc,
+                Left_Opnd  => Obj_Tag,
+                Right_Opnd =>
+                  New_Reference_To
+                    (Node (First_Elmt (Access_Disp_Table (Right_Type))), Loc));
+         end if;
       end if;
    end Tagged_Membership;
 
index ee263fe4ce6d5cc7d399e683149dc3ca2d321453..8a0f531b9206b826b7875365a536c21676a33328 100644 (file)
@@ -32,6 +32,7 @@ with Einfo;    use Einfo;
 with Errout;   use Errout;
 with Expander; use Expander;
 with Exp_Disp; use Exp_Disp;
+with Exp_Ch6;  use Exp_Ch6;
 with Exp_Ch7;  use Exp_Ch7;
 with Exp_Tss;  use Exp_Tss;
 with Exp_Util; use Exp_Util;
@@ -66,7 +67,6 @@ with Sinfo;    use Sinfo;
 with Snames;   use Snames;
 with Stand;    use Stand;
 with Stringt;  use Stringt;
-with Targparm; use Targparm;
 with Tbuild;   use Tbuild;
 with Uintp;    use Uintp;
 with Urealp;   use Urealp;
@@ -215,6 +215,11 @@ package body Sem_Res is
    procedure Set_Slice_Subtype (N : Node_Id);
    --  Build subtype of array type, with the range specified by the slice
 
+   procedure Simplify_Type_Conversion (N : Node_Id);
+   --  Called after N has been resolved and evaluated, but before range checks
+   --  have been applied. Currently simplifies a combination of floating-point
+   --  to integer conversion and Truncation attribute.
+
    function Unique_Fixed_Point_Type (N : Node_Id) return Entity_Id;
    --  A universal_fixed expression in an universal context is unambiguous
    --  if there is only one applicable fixed point type. Determining whether
@@ -821,15 +826,9 @@ package body Sem_Res is
    --  Start of processing for Check_Initialization_Call
 
    begin
-      --  Nothing to do if functions do not use the secondary stack for
-      --  returns (i.e. they use a depressed stack pointer instead).
-
-      if Functions_Return_By_DSP_On_Target then
-         return;
+      --  Establish a transient scope if the type needs it
 
-      --  Otherwise establish a transient scope if the type needs it
-
-      elsif Uses_SS (Typ) then
+      if Uses_SS (Typ) then
          Establish_Transient_Scope (First_Actual (N), Sec_Stack => True);
       end if;
    end Check_Initialization_Call;
@@ -1835,24 +1834,29 @@ package body Sem_Res is
                               N, It.Nam);
                         end if;
 
-                        Error_Msg_N
-                          ("\\possible interpretation#!", N);
                         Ambiguous := True;
+
+                        if Nkind (Parent (Seen)) = N_Full_Type_Declaration then
+                           Error_Msg_N
+                             ("\\possible interpretation (inherited)#!", N);
+                        else
+                           Error_Msg_N ("\\possible interpretation#!", N);
+                        end if;
                      end if;
 
                      Error_Msg_Sloc := Sloc (It.Nam);
 
                      --  By default, the error message refers to the candidate
-                     --  interpretation. But if it is a  predefined operator,
-                     --  it is implicitly declared at the declaration of
-                     --  the type of the operand. Recover the sloc of that
-                     --  declaration for the error message.
+                     --  interpretation. But if it is a predefined operator, it
+                     --  is implicitly declared at the declaration of the type
+                     --  of the operand. Recover the sloc of that declaration
+                     --  for the error message.
 
                      if Nkind (N) in N_Op
                        and then Scope (It.Nam) = Standard_Standard
                        and then not Is_Overloaded (Right_Opnd (N))
-                       and then  Scope (Base_Type (Etype (Right_Opnd (N))))
-                            /= Standard_Standard
+                       and then Scope (Base_Type (Etype (Right_Opnd (N)))) /=
+                                                             Standard_Standard
                      then
                         Err_Type := First_Subtype (Etype (Right_Opnd (N)));
 
@@ -1865,8 +1869,8 @@ package body Sem_Res is
                      elsif Nkind (N) in N_Binary_Op
                        and then Scope (It.Nam) = Standard_Standard
                        and then not Is_Overloaded (Left_Opnd (N))
-                       and then Scope (Base_Type (Etype (Left_Opnd (N))))
-                            /= Standard_Standard
+                       and then Scope (Base_Type (Etype (Left_Opnd (N)))) /=
+                                                             Standard_Standard
                      then
                         Err_Type := First_Subtype (Etype (Left_Opnd (N)));
 
@@ -1888,7 +1892,6 @@ package body Sem_Res is
                         Err_Type := It.Nam;
                         Error_Msg_Sloc :=
                           Sloc (Associated_Node_For_Itype (Err_Type));
-
                      else
                         Err_Type := Empty;
                      end if;
@@ -1912,11 +1915,11 @@ package body Sem_Res is
                   end if;
                end if;
 
-               --  We have a matching interpretation, Expr_Type is the
-               --  type from this interpretation, and Seen is the entity.
+               --  We have a matching interpretation, Expr_Type is the type
+               --  from this interpretation, and Seen is the entity.
 
-               --  For an operator, just set the entity name. The type will
-               --  be set by the specific operator resolution routine.
+               --  For an operator, just set the entity name. The type will be
+               --  set by the specific operator resolution routine.
 
                if Nkind (N) in N_Op then
                   Set_Entity (N, Seen);
@@ -1926,9 +1929,9 @@ package body Sem_Res is
                   Set_Etype (N, Expr_Type);
 
                --  For an explicit dereference, attribute reference, range,
-               --  short-circuit form (which is not an operator node),
-               --  or a call with a name that is an explicit dereference,
-               --  there is nothing to be done at this point.
+               --  short-circuit form (which is not an operator node), or call
+               --  with a name that is an explicit dereference, there is
+               --  nothing to be done at this point.
 
                elsif     Nkind (N) = N_Explicit_Dereference
                  or else Nkind (N) = N_Attribute_Reference
@@ -1942,8 +1945,8 @@ package body Sem_Res is
                then
                   null;
 
-               --  For procedure or function calls, set the type of the
-               --  name, and also the entity pointer for the prefix
+               --  For procedure or function calls, set the type of the name,
+               --  and also the entity pointer for the prefix
 
                elsif (Nkind (N) = N_Procedure_Call_Statement
                        or else Nkind (N) = N_Function_Call)
@@ -1985,11 +1988,10 @@ package body Sem_Res is
       if not Found then
          if Typ /= Any_Type then
 
-            --  If type we are looking for is Void, then this is the
-            --  procedure call case, and the error is simply that what
-            --  we gave is not a procedure name (we think of procedure
-            --  calls as expressions with types internally, but the user
-            --  doesn't think of them this way!)
+            --  If type we are looking for is Void, then this is the procedure
+            --  call case, and the error is simply that what we gave is not a
+            --  procedure name (we think of procedure calls as expressions with
+            --  types internally, but the user doesn't think of them this way!)
 
             if Typ = Standard_Void_Type then
 
@@ -2003,8 +2005,8 @@ package body Sem_Res is
                     ("cannot use function & in a procedure call",
                      Name (N), Entity (Name (N)));
 
-               --  Otherwise give general message (not clear what cases
-               --  this covers, but no harm in providing for them!)
+               --  Otherwise give general message (not clear what cases this
+               --  covers, but no harm in providing for them!)
 
                else
                   Error_Msg_N ("expect procedure name in procedure call", N);
@@ -2014,11 +2016,11 @@ package body Sem_Res is
 
             --  Otherwise we do have a subexpression with the wrong type
 
-            --  Check for the case of an allocator which uses an access
-            --  type instead of the designated type. This is a common
-            --  error and we specialize the message, posting an error
-            --  on the operand of the allocator, complaining that we
-            --  expected the designated type of the allocator.
+            --  Check for the case of an allocator which uses an access type
+            --  instead of the designated type. This is a common error and we
+            --  specialize the message, posting an error on the operand of the
+            --  allocator, complaining that we expected the designated type of
+            --  the allocator.
 
             elsif Nkind (N) = N_Allocator
               and then Ekind (Typ) in Access_Kind
@@ -2028,8 +2030,8 @@ package body Sem_Res is
                Wrong_Type (Expression (N), Designated_Type (Typ));
                Found := True;
 
-            --  Check for view mismatch on Null in instances, for
-            --  which the view-swapping mechanism has no identifier.
+            --  Check for view mismatch on Null in instances, for which the
+            --  view-swapping mechanism has no identifier.
 
             elsif (In_Instance or else In_Inlined_Body)
               and then (Nkind (N) = N_Null)
@@ -2087,10 +2089,10 @@ package body Sem_Res is
                         Elmt := First (Component_Associations (Aggr));
                         while Present (Elmt) loop
 
-                           --  Nothing to check is this is a default-
-                           --  initialized component. The box will be
-                           --  be replaced by the appropriate call during
-                           --  late expansion.
+                           --  If this is a default-initialized component, then
+                           --  there is nothing to check. The box will be
+                           --  replaced by the appropriate call during late
+                           --  expansion.
 
                            if not Box_Present (Elmt) then
                               Check_Elmt (Expression (Elmt));
@@ -2293,15 +2295,15 @@ package body Sem_Res is
             when N_Identifier
                              => Resolve_Entity_Name              (N, Ctx_Type);
 
-            when N_Membership_Test
-                             => Resolve_Membership_Op            (N, Ctx_Type);
-
             when N_Indexed_Component
                              => Resolve_Indexed_Component        (N, Ctx_Type);
 
             when N_Integer_Literal
                              => Resolve_Integer_Literal          (N, Ctx_Type);
 
+            when N_Membership_Test
+                             => Resolve_Membership_Op            (N, Ctx_Type);
+
             when N_Null      => Resolve_Null                     (N, Ctx_Type);
 
             when N_Op_And | N_Op_Or | N_Op_Xor
@@ -2773,6 +2775,16 @@ package body Sem_Res is
                           Directly_Designated_Type (Etype (A)));
                         Set_Etype (A, New_Itype);
                      end if;
+
+                     --  Ada 2005, AI-162:If the actual is an allocator, the
+                     --  innermost enclosing statement is the master of the
+                     --  created object.
+
+                     if Is_Controlled (DDT)
+                       or else Has_Task (DDT)
+                     then
+                        Establish_Transient_Scope (A, False);
+                     end if;
                   end;
                end if;
 
@@ -2959,8 +2971,28 @@ package body Sem_Res is
             --  Check that subprograms don't have improper controlling
             --  arguments (RM 3.9.2 (9))
 
+            --  A primitive operation may have an access parameter of an
+            --  incomplete tagged type, but a dispatching call is illegal
+            --  if the type is still incomplete.
+
             if Is_Controlling_Formal (F) then
                Set_Is_Controlling_Actual (A);
+
+               if Ekind (Etype (F)) = E_Anonymous_Access_Type then
+                  declare
+                     Desig : constant Entity_Id := Designated_Type (Etype (F));
+                  begin
+                     if Ekind (Desig) = E_Incomplete_Type
+                       and then No (Full_View (Desig))
+                       and then No (Non_Limited_View (Desig))
+                     then
+                        Error_Msg_NE
+                          ("premature use of incomplete type& " &
+                           "in dispatching call", A, Desig);
+                     end if;
+                  end;
+               end if;
+
             elsif Nkind (A) = N_Explicit_Dereference then
                Validate_Remote_Access_To_Class_Wide_Type (A);
             end if;
@@ -3070,7 +3102,7 @@ package body Sem_Res is
          Set_Etype (N, Base_Type (Typ));
       end if;
 
-      if Is_Abstract (Typ) then
+      if Is_Abstract_Type (Typ) then
          Error_Msg_N ("type of allocator cannot be abstract",  N);
       end if;
 
@@ -3924,7 +3956,7 @@ package body Sem_Res is
       --  when the type of the component is an access to the array type. In
       --  this case the call is truly ambiguous.
 
-      elsif Needs_No_Actuals (Nam)
+      elsif (Needs_No_Actuals (Nam) or else Needs_One_Actual (Nam))
         and then
           ((Is_Array_Type (Etype (Nam))
                    and then Covers (Typ, Component_Type (Etype (Nam))))
@@ -3950,12 +3982,33 @@ package body Sem_Res is
                Set_Entity (Subp, Nam);
 
                if Component_Type (Ret_Type) /= Any_Type then
-                  Index_Node :=
-                    Make_Indexed_Component (Loc,
-                      Prefix =>
-                        Make_Function_Call (Loc,
-                          Name => New_Subp),
-                      Expressions => Parameter_Associations (N));
+                  if Needs_No_Actuals (Nam) then
+
+                     --  Indexed call to a parameterless function
+
+                     Index_Node :=
+                       Make_Indexed_Component (Loc,
+                         Prefix =>
+                           Make_Function_Call (Loc,
+                             Name => New_Subp),
+                         Expressions => Parameter_Associations (N));
+                  else
+                     --  An Ada 2005 prefixed call to a primitive operation
+                     --  whose first parameter is the prefix. This prefix was
+                     --  prepended to the parameter list, which is actually a
+                     --  list of indices. Remove the prefix in order to build
+                     --  the proper indexed component.
+
+                     Index_Node :=
+                        Make_Indexed_Component (Loc,
+                          Prefix =>
+                            Make_Function_Call (Loc,
+                               Name => New_Subp,
+                               Parameter_Associations =>
+                                 New_List
+                                   (Remove_Head (Parameter_Associations (N)))),
+                           Expressions => Parameter_Associations (N));
+                  end if;
 
                   --  Since we are correcting a node classification error made
                   --  by the parser, we call Replace rather than Rewrite.
@@ -4110,12 +4163,16 @@ package body Sem_Res is
 
       --  Create a transient scope if the resulting type requires it
 
-      --  There are 3 notable exceptions: in init procs, the transient scope
+      --  There are 4 notable exceptions: in init procs, the transient scope
       --  overhead is not needed and even incorrect due to the actual expansion
-      --  of adjust calls; the second case is enumeration literal pseudo calls,
-      --  the other case is intrinsic subprograms (Unchecked_Conversion and
+      --  of adjust calls; the second case is enumeration literal pseudo calls;
+      --  the third case is intrinsic subprograms (Unchecked_Conversion and
       --  source information functions) that do not use the secondary stack
-      --  even though the return type is unconstrained.
+      --  even though the return type is unconstrained; the fourth case is a
+      --  call to a build-in-place function, since such functions may allocate
+      --  their result directly in a target object, and cases where the result
+      --  does get allocated in the secondary stack are checked for within the
+      --  specialized Exp_Ch6 procedures for expanding build-in-place calls.
 
       --  If this is an initialization call for a type whose initialization
       --  uses the secondary stack, we also need to create a transient scope
@@ -4136,12 +4193,12 @@ package body Sem_Res is
       elsif Expander_Active
         and then Is_Type (Etype (Nam))
         and then Requires_Transient_Scope (Etype (Nam))
+        and then not Is_Build_In_Place_Function (Nam)
         and then Ekind (Nam) /= E_Enumeration_Literal
         and then not Within_Init_Proc
         and then not Is_Intrinsic_Subprogram (Nam)
       then
-         Establish_Transient_Scope
-           (N, Sec_Stack => not Functions_Return_By_DSP_On_Target);
+         Establish_Transient_Scope (N, Sec_Stack => True);
 
          --  If the call appears within the bounds of a loop, it will
          --  be rewritten and reanalyzed, nothing left to do here.
@@ -4213,7 +4270,8 @@ package body Sem_Res is
       then
          Check_Dispatching_Call (N);
 
-      elsif Is_Abstract (Nam)
+      elsif Ekind (Nam) /= E_Subprogram_Type
+        and then Is_Abstract_Subprogram (Nam)
         and then not In_Instance
       then
          Error_Msg_NE ("cannot call abstract subprogram &!", N, Nam);
@@ -4978,8 +5036,7 @@ package body Sem_Res is
       elsif Expander_Active
         and then Requires_Transient_Scope (Etype (Nam))
       then
-         Establish_Transient_Scope (N,
-           Sec_Stack => not Functions_Return_By_DSP_On_Target);
+         Establish_Transient_Scope (N, Sec_Stack => True);
       end if;
    end Resolve_Entry_Call;
 
@@ -5073,6 +5130,7 @@ package body Sem_Res is
 
          elsif T = Any_Access
            or else Ekind (T) = E_Allocator_Type
+           or else Ekind (T) = E_Access_Attribute_Type
          then
             T := Find_Unique_Access_Type;
 
@@ -5086,6 +5144,14 @@ package body Sem_Res is
          Resolve (L, T);
          Resolve (R, T);
 
+         --  If the unique type is a class-wide type then it will be expanded
+         --  into a dispatching call to the predefined primitive. Therefore we
+         --  check here for potential violation of such restriction.
+
+         if Is_Class_Wide_Type (T) then
+            Check_Restriction (No_Dispatching_Calls, N);
+         end if;
+
          if Warn_On_Redundant_Constructs
            and then Comes_From_Source (N)
            and then Is_Entity_Name (R)
@@ -5112,7 +5178,7 @@ package body Sem_Res is
          then
             Eval_Relational_Op (N);
          elsif Nkind (N) = N_Op_Ne
-           and then Is_Abstract (Entity (N))
+           and then Is_Abstract_Subprogram (Entity (N))
          then
             Error_Msg_NE ("cannot call abstract subprogram &!", N, Entity (N));
          end if;
@@ -5341,8 +5407,18 @@ package body Sem_Res is
          end loop;
       end if;
 
-      Warn_On_Suspicious_Index (Name, First (Expressions (N)));
-      Eval_Indexed_Component (N);
+      --  Do not generate the warning on suspicious index if we are analyzing
+      --  package Ada.Tags; otherwise we will report the warning with the
+      --  Prims_Ptr field of the dispatch table.
+
+      if Scope (Etype (Prefix (N))) = Standard_Standard
+        or else not
+          Is_RTU (Cunit_Entity (Get_Source_Unit (Etype (Prefix (N)))),
+                  Ada_Tags)
+      then
+         Warn_On_Suspicious_Index (Name, First (Expressions (N)));
+         Eval_Indexed_Component (N);
+      end if;
    end Resolve_Indexed_Component;
 
    -----------------------------
@@ -6498,7 +6574,20 @@ package body Sem_Res is
          Index := First_Index (Array_Type);
          Resolve (Drange, Base_Type (Etype (Index)));
 
-         if Nkind (Drange) = N_Range then
+         if Nkind (Drange) = N_Range
+
+            --  Do not apply the range check to nodes associated with the
+            --  frontend expansion of the dispatch table. We first check
+            --  if Ada.Tags is already loaded to void the addition of an
+            --  undesired dependence on such run-time unit.
+
+           and then not
+             (RTU_Loaded (Ada_Tags)
+              and then Nkind (Prefix (N)) = N_Selected_Component
+              and then Present (Entity (Selector_Name (Prefix (N))))
+              and then Entity (Selector_Name (Prefix (N)))
+                         = RTE_Record_Component (RE_Prims_Ptr))
+         then
             Apply_Range_Check (Drange, Etype (Index));
          end if;
       end if;
@@ -6881,6 +6970,15 @@ package body Sem_Res is
 
       Eval_Type_Conversion (N);
 
+      --  Even when evaluation is not possible, we may be able to simplify
+      --  the conversion or its expression. This needs to be done before
+      --  applying checks, since otherwise the checks may use the original
+      --  expression and defeat the simplifications. The is specifically
+      --  the case for elimination of the floating-point Truncation
+      --  attribute in float-to-int conversions.
+
+      Simplify_Type_Conversion (N);
+
       --  If after evaluation, we still have a type conversion, then we
       --  may need to apply checks required for a subtype conversion.
 
@@ -6929,8 +7027,13 @@ package body Sem_Res is
       end if;
 
       --  Ada 2005 (AI-251): Handle conversions to abstract interface types
+      --  No need to perform any interface conversion if the type of the
+      --  expression coincides with the target type.
 
-      if Ada_Version >= Ada_05 and then Expander_Active then
+      if Ada_Version >= Ada_05
+        and then Expander_Active
+        and then Opnd_Type /= Target_Type
+      then
          if Is_Access_Type (Target_Type) then
             Target_Type := Directly_Designated_Type (Target_Type);
          end if;
@@ -6994,18 +7097,7 @@ package body Sem_Res is
       Hi    : Uint;
 
    begin
-      --  Generate warning for expressions like -5 mod 3
-
-      if Warn_On_Questionable_Missing_Parens
-        and then Paren_Count (N) = 0
-        and then (Nkind (N) = N_Op_Minus or else Nkind (N) = N_Op_Plus)
-        and then Paren_Count (Right_Opnd (N)) = 0
-        and then Nkind (Right_Opnd (N)) in N_Multiplying_Operator
-        and then Comes_From_Source (N)
-      then
-         Error_Msg_N
-           ("?unary minus expression should be parenthesized here", N);
-      end if;
+      --  Deal with intrincis unary operators
 
       if Comes_From_Source (N)
         and then Ekind (Entity (N)) = E_Function
@@ -7016,8 +7108,11 @@ package body Sem_Res is
          return;
       end if;
 
+      --  Deal with universal cases
+
       if Etype (R) = Universal_Integer
-           or else Etype (R) = Universal_Real
+           or else
+         Etype (R) = Universal_Real
       then
          Check_For_Visible_Operator (N, B_Typ);
       end if;
@@ -7038,6 +7133,8 @@ package body Sem_Res is
          end if;
       end if;
 
+      --  Deal with reference generation
+
       Check_Unset_Reference (R);
       Generate_Operator_Reference (N, B_Typ);
       Eval_Unary_Op (N);
@@ -7051,6 +7148,135 @@ package body Sem_Res is
             Enable_Overflow_Check (N);
          end if;
       end if;
+
+      --  Generate warning for expressions like -5 mod 3 for integers. No
+      --  need to worry in the floating-point case, since parens do not affect
+      --  the result so there is no point in giving in a warning.
+
+      declare
+         Norig : constant Node_Id := Original_Node (N);
+         Rorig : Node_Id;
+         Val   : Uint;
+         HB    : Uint;
+         LB    : Uint;
+         Lval  : Uint;
+         Opnd  : Node_Id;
+
+      begin
+         if Warn_On_Questionable_Missing_Parens
+           and then Comes_From_Source (Norig)
+           and then Is_Integer_Type (Typ)
+           and then Nkind (Norig) = N_Op_Minus
+         then
+            Rorig := Original_Node (Right_Opnd (Norig));
+
+            --  We are looking for cases where the right operand is not
+            --  parenthesized, and is a bianry operator, multiply, divide, or
+            --  mod. These are the cases where the grouping can affect results.
+
+            if Paren_Count (Rorig) = 0
+              and then (Nkind (Rorig) = N_Op_Mod
+                          or else
+                        Nkind (Rorig) = N_Op_Multiply
+                          or else
+                        Nkind (Rorig) = N_Op_Divide)
+            then
+               --  For mod, we always give the warning, since the value is
+               --  affected by the parenthesization (e.g. (-5) mod 315 /=
+               --  (5 mod 315)). But for the other cases, the only concern is
+               --  overflow, e.g. for the case of 8 big signed (-(2 * 64)
+               --  overflows, but (-2) * 64 does not). So we try to give the
+               --  message only when overflow is possible.
+
+               if Nkind (Rorig) /= N_Op_Mod
+                 and then Compile_Time_Known_Value (R)
+               then
+                  Val := Expr_Value (R);
+
+                  if Compile_Time_Known_Value (Type_High_Bound (Typ)) then
+                     HB := Expr_Value (Type_High_Bound (Typ));
+                  else
+                     HB := Expr_Value (Type_High_Bound (Base_Type (Typ)));
+                  end if;
+
+                  if Compile_Time_Known_Value (Type_Low_Bound (Typ)) then
+                     LB := Expr_Value (Type_Low_Bound (Typ));
+                  else
+                     LB := Expr_Value (Type_Low_Bound (Base_Type (Typ)));
+                  end if;
+
+                  --  Note that the test below is deliberately excluding
+                  --  the largest negative number, since that is a potentially
+                  --  troublesome case (e.g. -2 * x, where the result is the
+                  --  largest negative integer has an overflow with 2 * x).
+
+                  if Val > LB and then Val <= HB then
+                     return;
+                  end if;
+               end if;
+
+               --  For the multiplication case, the only case we have to worry
+               --  about is when (-a)*b is exactly the largest negative number
+               --  so that -(a*b) can cause overflow. This can only happen if
+               --  a is a power of 2, and more generally if any operand is a
+               --  constant that is not a power of 2, then the parentheses
+               --  cannot affect whether overflow occurs. We only bother to
+               --  test the left most operand
+
+               --  Loop looking at left operands for one that has known value
+
+               Opnd := Rorig;
+               Opnd_Loop : while Nkind (Opnd) = N_Op_Multiply loop
+                  if Compile_Time_Known_Value (Left_Opnd (Opnd)) then
+                     Lval := UI_Abs (Expr_Value (Left_Opnd (Opnd)));
+
+                     --  Operand value of 0 or 1 skips warning
+
+                     if Lval <= 1 then
+                        return;
+
+                     --  Otherwise check power of 2, if power of 2, warn, if
+                     --  anything else, skip warning.
+
+                     else
+                        while Lval /= 2 loop
+                           if Lval mod 2 = 1 then
+                              return;
+                           else
+                              Lval := Lval / 2;
+                           end if;
+                        end loop;
+
+                        exit Opnd_Loop;
+                     end if;
+                  end if;
+
+                  --  Keep looking at left operands
+
+                  Opnd := Left_Opnd (Opnd);
+               end loop Opnd_Loop;
+
+               --  For rem or "/" we can only have a problematic situation
+               --  if the divisor has a value of minus one or one. Otherwise
+               --  overflow is impossible (divisor > 1) or we have a case of
+               --  division by zero in any case.
+
+               if (Nkind (Rorig) = N_Op_Divide
+                    or else
+                   Nkind (Rorig) = N_Op_Rem)
+                 and then Compile_Time_Known_Value (Right_Opnd (Rorig))
+                 and then UI_Abs (Expr_Value (Right_Opnd (Rorig))) /= 1
+               then
+                  return;
+               end if;
+
+               --  If we fall through warning should be issued
+
+               Error_Msg_N
+                 ("?unary minus expression should be parenthesized here", N);
+            end if;
+         end if;
+      end;
    end Resolve_Unary_Op;
 
    ----------------------------------
@@ -7318,7 +7544,7 @@ package body Sem_Res is
          begin
             Index_Subtype :=
               Create_Itype (Subtype_Kind (Ekind (Index_Type)), N);
-            Drange := Make_Range (Loc, Low_Bound, High_Bound);
+            Drange := Make_Range (Loc, New_Copy_Tree (Low_Bound), High_Bound);
             Set_Scalar_Range (Index_Subtype, Drange);
             Set_Parent (Drange, N);
             Analyze_And_Resolve (Drange, Index_Type);
@@ -7347,6 +7573,47 @@ package body Sem_Res is
       end if;
    end Set_String_Literal_Subtype;
 
+   ------------------------------
+   -- Simplify_Type_Conversion --
+   ------------------------------
+
+   procedure Simplify_Type_Conversion (N : Node_Id) is
+   begin
+      if Nkind (N) = N_Type_Conversion then
+         declare
+            Operand    : constant Node_Id   := Expression (N);
+            Target_Typ : constant Entity_Id := Etype (N);
+            Opnd_Typ   : constant Entity_Id := Etype (Operand);
+
+         begin
+            if Is_Floating_Point_Type (Opnd_Typ)
+              and then
+                (Is_Integer_Type (Target_Typ)
+                   or else (Is_Fixed_Point_Type (Target_Typ)
+                              and then Conversion_OK (N)))
+              and then Nkind (Operand) = N_Attribute_Reference
+              and then Attribute_Name (Operand) = Name_Truncation
+
+            --  Special processing required if the conversion is the expression
+            --  of a Truncation attribute reference. In this case we replace:
+
+            --     ityp (ftyp'Truncation (x))
+
+            --  by
+
+            --     ityp (x)
+
+            --  with the Float_Truncate flag set, which is more efficient
+
+            then
+               Rewrite (Operand,
+                 Relocate_Node (First (Expressions (Operand))));
+               Set_Float_Truncate (N, True);
+            end if;
+         end;
+      end if;
+   end Simplify_Type_Conversion;
+
    -----------------------------
    -- Unique_Fixed_Point_Type --
    -----------------------------
@@ -7643,10 +7910,10 @@ package body Sem_Res is
               Conversion_Check (False,
                 "downward conversion of tagged objects not allowed");
 
-         --  Ada 2005 (AI-251): The conversion of a tagged type to an
-         --  abstract interface type is always valid
+         --  Ada 2005 (AI-251): The conversion to/from interface types is
+         --  always valid
 
-         elsif Is_Interface (Target_Type) then
+         elsif Is_Interface (Target_Type) or else Is_Interface (Opnd_Type) then
             return True;
 
          elsif Is_Access_Type (Opnd_Type)
@@ -7988,15 +8255,38 @@ package body Sem_Res is
          end if;
 
          declare
-            Target : constant Entity_Id := Designated_Type (Target_Type);
-            Opnd   : constant Entity_Id := Designated_Type (Opnd_Type);
+            function Full_Designated_Type (T : Entity_Id) return Entity_Id;
+            --  Helper function to handle limited views
+
+            --------------------------
+            -- Full_Designated_Type --
+            --------------------------
+
+            function Full_Designated_Type (T : Entity_Id) return Entity_Id is
+               Desig : constant Entity_Id := Designated_Type (T);
+            begin
+               if From_With_Type (Desig)
+                 and then Is_Incomplete_Type (Desig)
+                 and then Present (Non_Limited_View (Desig))
+               then
+                  return Non_Limited_View (Desig);
+               else
+                  return Desig;
+               end if;
+            end Full_Designated_Type;
+
+            Target : constant Entity_Id := Full_Designated_Type (Target_Type);
+            Opnd   : constant Entity_Id := Full_Designated_Type (Opnd_Type);
+
+            Same_Base : constant Boolean :=
+                          Base_Type (Target) = Base_Type (Opnd);
 
          begin
             if Is_Tagged_Type (Target) then
                return Valid_Tagged_Conversion (Target, Opnd);
 
             else
-               if Base_Type (Target) /= Base_Type (Opnd) then
+               if not Same_Base then
                   Error_Msg_NE
                     ("target designated type not compatible with }",
                      N, Base_Type (Opnd));
@@ -8031,10 +8321,27 @@ package body Sem_Res is
                or else
              Ekind (Target_Type) = E_Anonymous_Access_Subprogram_Type)
         and then No (Corresponding_Remote_Type (Opnd_Type))
-        and then Conversion_Check
-                   (Ekind (Base_Type (Opnd_Type)) = E_Access_Subprogram_Type,
-                    "illegal operand for access subprogram conversion")
       then
+         if
+           Ekind (Base_Type (Opnd_Type)) = E_Anonymous_Access_Subprogram_Type
+         then
+            Error_Msg_N
+              ("illegal attempt to store anonymous access to subprogram",
+               Operand);
+            Error_Msg_N
+              ("\value has deeper accessibility than any master " &
+               "('R'M 3.10.2 (13))",
+               Operand);
+
+            if Is_Entity_Name (Operand)
+              and then Ekind (Entity (Operand)) = E_In_Parameter
+            then
+               Error_Msg_NE
+                 ("\use named access type for& instead of access parameter",
+                  Operand, Entity (Operand));
+            end if;
+         end if;
+
          --  Check that the designated types are subtype conformant
 
          Check_Subtype_Conformant (New_Id  => Designated_Type (Target_Type),