OSDN Git Service

2011-12-05 Bob Duff <duff@adacore.com>
[pf3gnuchains/gcc-fork.git] / gcc / ada / sem_ch4.adb
index 4ba25d0..197b575 100644 (file)
@@ -6,7 +6,7 @@
 --                                                                          --
 --                                 B o d y                                  --
 --                                                                          --
---          Copyright (C) 1992-2010, Free Software Foundation, Inc.         --
+--          Copyright (C) 1992-2011, 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- --
@@ -23,6 +23,7 @@
 --                                                                          --
 ------------------------------------------------------------------------------
 
+with Aspects;  use Aspects;
 with Atree;    use Atree;
 with Debug;    use Debug;
 with Einfo;    use Einfo;
@@ -46,6 +47,7 @@ with Sem_Aux;  use Sem_Aux;
 with Sem_Case; use Sem_Case;
 with Sem_Cat;  use Sem_Cat;
 with Sem_Ch3;  use Sem_Ch3;
+with Sem_Ch5;  use Sem_Ch5;
 with Sem_Ch6;  use Sem_Ch6;
 with Sem_Ch8;  use Sem_Ch8;
 with Sem_Disp; use Sem_Disp;
@@ -99,7 +101,7 @@ package body Sem_Ch4 is
    --  the operand of the operator node.
 
    procedure Ambiguous_Operands (N : Node_Id);
-   --  for equality, membership, and comparison operators with overloaded
+   --  For equality, membership, and comparison operators with overloaded
    --  arguments, list possible interpretations.
 
    procedure Analyze_One_Call
@@ -247,6 +249,12 @@ package body Sem_Ch4 is
    --  Ada 2005: implementation of AI-310. An abstract non-dispatching
    --  operation is not a candidate interpretation.
 
+   function Try_Container_Indexing
+     (N      : Node_Id;
+      Prefix : Node_Id;
+      Expr   : Node_Id) return Boolean;
+   --  AI05-0139: Generalized indexing to support iterators over containers
+
    function Try_Indexed_Call
      (N          : Node_Id;
       Nam        : Entity_Id;
@@ -268,11 +276,17 @@ package body Sem_Ch4 is
    --  subprogram, and the call F (X) interpreted as F.all (X). In this case
    --  the call may be overloaded with both interpretations.
 
-   function Try_Object_Operation (N : Node_Id) return Boolean;
+   function Try_Object_Operation
+     (N            : Node_Id;
+      CW_Test_Only : Boolean := False) return Boolean;
    --  Ada 2005 (AI-252): Support the object.operation notation. If node N
    --  is a call in this notation, it is transformed into a normal subprogram
    --  call where the prefix is a parameter, and True is returned. If node
-   --  N is not of this form, it is unchanged, and False is returned.
+   --  N is not of this form, it is unchanged, and False is returned. if
+   --  CW_Test_Only is true then N is an N_Selected_Component node which
+   --  is part of a call to an entry or procedure of a tagged concurrent
+   --  type and this routine is invoked to search for class-wide subprograms
+   --  conflicting with the target entity.
 
    procedure wpo (T : Entity_Id);
    pragma Warnings (Off, wpo);
@@ -300,7 +314,24 @@ package body Sem_Ch4 is
                Nam := Opnd;
             elsif Nkind (Opnd) = N_Function_Call then
                Nam := Name (Opnd);
-            else
+            elsif Ada_Version >= Ada_2012 then
+               declare
+                  It : Interp;
+                  I  : Interp_Index;
+
+               begin
+                  Get_First_Interp (Opnd, I, It);
+                  while Present (It.Nam) loop
+                     if Has_Implicit_Dereference (It.Typ) then
+                        Error_Msg_N
+                          ("can be interpreted as implicit dereference", Opnd);
+                        return;
+                     end if;
+
+                     Get_Next_Interp (I, It);
+                  end loop;
+               end;
+
                return;
             end if;
 
@@ -364,22 +395,94 @@ package body Sem_Ch4 is
       E        : Node_Id             := Expression (N);
       Acc_Type : Entity_Id;
       Type_Id  : Entity_Id;
+      P        : Node_Id;
+      C        : Node_Id;
 
    begin
+      Check_SPARK_Restriction ("allocator is not allowed", N);
+
+      --  Deal with allocator restrictions
+
       --  In accordance with H.4(7), the No_Allocators restriction only applies
-      --  to user-written allocators.
+      --  to user-written allocators. The same consideration applies to the
+      --  No_Allocators_Before_Elaboration restriction.
 
       if Comes_From_Source (N) then
          Check_Restriction (No_Allocators, N);
+
+         --  Processing for No_Allocators_After_Elaboration, loop to look at
+         --  enclosing context, checking task case and main subprogram case.
+
+         C := N;
+         P := Parent (C);
+         while Present (P) loop
+
+            --  In both cases we need a handled sequence of statements, where
+            --  the occurrence of the allocator is within the statements.
+
+            if Nkind (P) = N_Handled_Sequence_Of_Statements
+              and then Is_List_Member (C)
+              and then List_Containing (C) = Statements (P)
+            then
+               --  Check for allocator within task body, this is a definite
+               --  violation of No_Allocators_After_Elaboration we can detect.
+
+               if Nkind (Original_Node (Parent (P))) = N_Task_Body then
+                  Check_Restriction (No_Allocators_After_Elaboration, N);
+                  exit;
+               end if;
+
+               --  The other case is appearance in a subprogram body. This may
+               --  be a violation if this is a library level subprogram, and it
+               --  turns out to be used as the main program, but only the
+               --  binder knows that, so just record the occurrence.
+
+               if Nkind (Original_Node (Parent (P))) = N_Subprogram_Body
+                 and then Nkind (Parent (Parent (P))) = N_Compilation_Unit
+               then
+                  Set_Has_Allocator (Current_Sem_Unit);
+               end if;
+            end if;
+
+            C := P;
+            P := Parent (C);
+         end loop;
       end if;
 
+      --  Ada 2012 (AI05-0111-3): Analyze the subpool_specification, if
+      --  any. The expected type for the name is any type. A non-overloading
+      --  rule then requires it to be of a type descended from
+      --  System.Storage_Pools.Subpools.Subpool_Handle.
+
+      --  This isn't exactly what the AI says, but it seems to be the right
+      --  rule. The AI should be fixed.???
+
+      declare
+         Subpool : constant Node_Id := Subpool_Handle_Name (N);
+
+      begin
+         if Present (Subpool) then
+            Analyze (Subpool);
+
+            if Is_Overloaded (Subpool) then
+               Error_Msg_N ("ambiguous subpool handle", Subpool);
+            end if;
+
+            --  Check that Etype (Subpool) is descended from Subpool_Handle
+
+            Resolve (Subpool);
+         end if;
+      end;
+
+      --  Analyze the qualified expression or subtype indication
+
       if Nkind (E) = N_Qualified_Expression then
          Acc_Type := Create_Itype (E_Allocator_Type, N);
          Set_Etype (Acc_Type, Acc_Type);
          Find_Type (Subtype_Mark (E));
 
          --  Analyze the qualified expression, and apply the name resolution
-         --  rule given in  4.7 (3).
+         --  rule given in  4.7(3).
 
          Analyze (E);
          Type_Id := Etype (E);
@@ -387,8 +490,14 @@ package body Sem_Ch4 is
 
          Resolve (Expression (E), Type_Id);
 
+         --  Allocators generated by the build-in-place expansion mechanism
+         --  are explicitly marked as coming from source but do not need to be
+         --  checked for limited initialization. To exclude this case, ensure
+         --  that the parent of the allocator is a source node.
+
          if Is_Limited_Type (Type_Id)
            and then Comes_From_Source (N)
+           and then Comes_From_Source (Parent (N))
            and then not In_Instance_Body
          then
             if not OK_For_Limited_Init (Type_Id, Expression (E)) then
@@ -466,11 +575,13 @@ package body Sem_Ch4 is
                --  partial view, it cannot receive a discriminant constraint,
                --  and the allocated object is unconstrained.
 
-               elsif Ada_Version >= Ada_05
-                 and then Has_Constrained_Partial_View (Base_Typ)
+               elsif Ada_Version >= Ada_2005
+                 and then Effectively_Has_Constrained_Partial_View
+                            (Typ  => Base_Typ,
+                             Scop => Current_Scope)
                then
                   Error_Msg_N
-                    ("constraint no allowed when type " &
+                    ("constraint not allowed when type " &
                       "has a constrained partial view", Constraint (E));
                end if;
 
@@ -507,15 +618,25 @@ package body Sem_Ch4 is
             --  be a null object, and we can insert an unconditional raise
             --  before the allocator.
 
+            --  Ada 2012 (AI-104): A not null indication here is altogether
+            --  illegal.
+
             if Can_Never_Be_Null (Type_Id) then
                declare
                   Not_Null_Check : constant Node_Id :=
                                      Make_Raise_Constraint_Error (Sloc (E),
                                        Reason => CE_Null_Not_Allowed);
+
                begin
-                  if Expander_Active then
+                  if Ada_Version >= Ada_2012 then
+                     Error_Msg_N
+                       ("an uninitialized allocator cannot have"
+                         & " a null exclusion", N);
+
+                  elsif Expander_Active then
                      Insert_Action (N, Not_Null_Check);
                      Analyze (Not_Null_Check);
+
                   else
                      Error_Msg_N ("null value not allowed here?", E);
                   end if;
@@ -542,7 +663,7 @@ package body Sem_Ch4 is
                   Error_Msg_N
                     ("initialization required in class-wide allocation", N);
                else
-                  if Ada_Version < Ada_05
+                  if Ada_Version < Ada_2005
                     and then Is_Limited_Type (Type_Id)
                   then
                      Error_Msg_N ("unconstrained allocation not allowed", N);
@@ -593,13 +714,16 @@ package body Sem_Ch4 is
          Check_Restriction (No_Tasking, N);
          Check_Restriction (Max_Tasks, N);
          Check_Restriction (No_Task_Allocators, N);
+      end if;
 
-         --  Check that an allocator with task parts isn't for a nested access
-         --  type when restriction No_Task_Hierarchy applies.
+      --  AI05-0013-1: No_Nested_Finalization forbids allocators if the access
+      --  type is nested, and the designated type needs finalization. The rule
+      --  is conservative in that class-wide types need finalization.
 
-         if not Is_Library_Level_Entity (Acc_Type) then
-            Check_Restriction (No_Task_Hierarchy, N);
-         end if;
+      if Needs_Finalization (Designated_Type (Acc_Type))
+        and then not Is_Library_Level_Entity (Acc_Type)
+      then
+         Check_Restriction (No_Nested_Finalization, N);
       end if;
 
       --  Check that an allocator of a nested access type doesn't create a
@@ -730,6 +854,10 @@ package body Sem_Ch4 is
       --  Flag indicates whether an interpretation of the prefix is a
       --  parameterless call that returns an access_to_subprogram.
 
+      procedure Check_Mixed_Parameter_And_Named_Associations;
+      --  Check that parameter and named associations are not mixed. This is
+      --  a restriction in SPARK mode.
+
       function Name_Denotes_Function return Boolean;
       --  If the type of the name is an access to subprogram, this may be the
       --  type of a name, or the return type of the function being called. If
@@ -740,6 +868,35 @@ package body Sem_Ch4 is
       procedure No_Interpretation;
       --  Output error message when no valid interpretation exists
 
+      --------------------------------------------------
+      -- Check_Mixed_Parameter_And_Named_Associations --
+      --------------------------------------------------
+
+      procedure Check_Mixed_Parameter_And_Named_Associations is
+         Actual     : Node_Id;
+         Named_Seen : Boolean;
+
+      begin
+         Named_Seen := False;
+
+         Actual := First (Actuals);
+         while Present (Actual) loop
+            case Nkind (Actual) is
+               when N_Parameter_Association =>
+                  if Named_Seen then
+                     Check_SPARK_Restriction
+                       ("named association cannot follow positional one",
+                        Actual);
+                     exit;
+                  end if;
+               when others =>
+                  Named_Seen := True;
+            end case;
+
+            Next (Actual);
+         end loop;
+      end Check_Mixed_Parameter_And_Named_Associations;
+
       ---------------------------
       -- Name_Denotes_Function --
       ---------------------------
@@ -797,6 +954,10 @@ package body Sem_Ch4 is
    --  Start of processing for Analyze_Call
 
    begin
+      if Restriction_Check_Required (SPARK) then
+         Check_Mixed_Parameter_And_Named_Associations;
+      end if;
+
       --  Initialize the type of the result of the call to the error type,
       --  which will be reset if the type is successfully resolved.
 
@@ -891,8 +1052,8 @@ package body Sem_Ch4 is
 
          --  If this is an indirect call, the return type of the access_to
          --  subprogram may be an incomplete type. At the point of the call,
-         --  use the full type if available, and at the same time update
-         --  the return type of the access_to_subprogram.
+         --  use the full type if available, and at the same time update the
+         --  return type of the access_to_subprogram.
 
          if Success
            and then Nkind (Nam) = N_Explicit_Dereference
@@ -920,12 +1081,12 @@ package body Sem_Ch4 is
 
             --  Name may be call that returns an access to subprogram, or more
             --  generally an overloaded expression one of whose interpretations
-            --  yields an access to subprogram. If the name is an entity, we
-            --  do not dereference, because the node is a call that returns
-            --  the access type: note difference between f(x), where the call
-            --  may return an access subprogram type, and f(x)(y), where the
-            --  type returned by the call to f is implicitly dereferenced to
-            --  analyze the outer call.
+            --  yields an access to subprogram. If the name is an entity, we do
+            --  not dereference, because the node is a call that returns the
+            --  access type: note difference between f(x), where the call may
+            --  return an access subprogram type, and f(x)(y), where the type
+            --  returned by the call to f is implicitly dereferenced to analyze
+            --  the outer call.
 
             if Is_Access_Type (Nam_Ent) then
                Nam_Ent := Designated_Type (Nam_Ent);
@@ -1081,7 +1242,6 @@ package body Sem_Ch4 is
       Exp_Type  : Entity_Id;
       Exp_Btype : Entity_Id;
 
-      Last_Choice    : Nat;
       Dont_Care      : Boolean;
       Others_Present : Boolean;
 
@@ -1098,8 +1258,6 @@ package body Sem_Ch4 is
            Process_Associated_Node   => No_OP);
       use Case_Choices_Processing;
 
-      Case_Table : Choice_Table_Type (1 .. Number_Of_Choices (N));
-
       -----------------------------
       -- Non_Static_Choice_Error --
       -----------------------------
@@ -1142,8 +1300,8 @@ package body Sem_Ch4 is
             Get_First_Interp (FirstX, I, It);
             while Present (It.Nam) loop
 
-               --  For each intepretation of the first expression, we only
-               --  add the intepretation if every other expression in the
+               --  For each interpretation of the first expression, we only
+               --  add the interpretation if every other expression in the
                --  case expression alternatives has a compatible type.
 
                Alt := Next (First (Alternatives (N)));
@@ -1196,8 +1354,7 @@ package body Sem_Ch4 is
 
       --  Call instantiated Analyze_Choices which does the rest of the work
 
-      Analyze_Choices
-        (N, Exp_Type, Case_Table, Last_Choice, Dont_Care, Others_Present);
+      Analyze_Choices (N, Exp_Type, Dont_Care, Others_Present);
 
       if Exp_Type = Universal_Integer and then not Others_Present then
          Error_Msg_N
@@ -1415,6 +1572,8 @@ package body Sem_Ch4 is
          return;
       end if;
 
+      Check_SPARK_Restriction ("conditional expression is not allowed", N);
+
       Else_Expr := Next (Then_Expr);
 
       if Comes_From_Source (N) then
@@ -1442,20 +1601,30 @@ package body Sem_Ch4 is
 
          begin
             Set_Etype (N, Any_Type);
+
+            --  Shouldn't the following statement be down in the ELSE of the
+            --  following loop? ???
+
             Get_First_Interp (Then_Expr, I, It);
-            while Present (It.Nam) loop
 
-               --  For each possible intepretation of the Then Expression,
-               --  add it only if the else expression has a compatible type.
+            --  if no Else_Expression the conditional must be boolean
 
-               --  Is this right if Else_Expr is empty?
+            if No (Else_Expr) then
+               Set_Etype (N, Standard_Boolean);
 
-               if Has_Compatible_Type (Else_Expr, It.Typ) then
-                  Add_One_Interp (N, It.Typ, It.Typ);
-               end if;
+            --  Else_Expression Present. For each possible intepretation of
+            --  the Then_Expression, add it only if the Else_Expression has
+            --  a compatible type.
 
-               Get_Next_Interp (I, It);
-            end loop;
+            else
+               while Present (It.Nam) loop
+                  if Has_Compatible_Type (Else_Expr, It.Typ) then
+                     Add_One_Interp (N, It.Typ, It.Typ);
+                  end if;
+
+                  Get_Next_Interp (I, It);
+               end loop;
+            end if;
          end;
       end if;
    end Analyze_Conditional_Expression;
@@ -1603,6 +1772,20 @@ package body Sem_Ch4 is
    --  Start of processing for Analyze_Explicit_Dereference
 
    begin
+      --  If source node, check SPARK restriction. We guard this with the
+      --  source node check, because ???
+
+      if Comes_From_Source (N) then
+         Check_SPARK_Restriction ("explicit dereference is not allowed", N);
+      end if;
+
+      --  In formal verification mode, keep track of all reads and writes
+      --  through explicit dereferences.
+
+      if Alfa_Mode then
+         Alfa.Generate_Dereference (N);
+      end if;
+
       Analyze (P);
       Set_Etype (N, Any_Type);
 
@@ -1917,6 +2100,9 @@ package body Sem_Ch4 is
             then
                return;
 
+            elsif Try_Container_Indexing (N, P, Exp) then
+               return;
+
             elsif Array_Type = Any_Type then
                Set_Etype (N, Any_Type);
 
@@ -1970,6 +2156,7 @@ package body Sem_Ch4 is
             end loop;
 
             Set_Etype (N, Component_Type (Array_Type));
+            Check_Implicit_Dereference (N, Etype (N));
 
             if Present (Index) then
                Error_Msg_N
@@ -2066,10 +2253,18 @@ package body Sem_Ch4 is
                end loop;
 
                if Found and then No (Index) and then No (Exp) then
-                  Add_One_Interp (N,
-                     Etype (Component_Type (Typ)),
-                     Etype (Component_Type (Typ)));
+                  declare
+                     CT : constant Entity_Id :=
+                            Base_Type (Component_Type (Typ));
+                  begin
+                     Add_One_Interp (N, CT, CT);
+                     Check_Implicit_Dereference (N, CT);
+                  end;
                end if;
+
+            elsif Try_Container_Indexing (N, P, First (Exprs)) then
+               return;
+
             end if;
 
             Get_Next_Interp (I, It);
@@ -2103,9 +2298,7 @@ package body Sem_Ch4 is
 
       P_T := Base_Type (Etype (P));
 
-      if Is_Entity_Name (P)
-        or else Nkind (P) = N_Operator_Symbol
-      then
+      if Is_Entity_Name (P) and then Present (Entity (P)) then
          U_N := Entity (P);
 
          if Is_Type (U_N) then
@@ -2226,8 +2419,9 @@ package body Sem_Ch4 is
    ---------------------------
 
    procedure Analyze_Membership_Op (N : Node_Id) is
-      L     : constant Node_Id := Left_Opnd (N);
-      R     : constant Node_Id := Right_Opnd (N);
+      Loc   : constant Source_Ptr := Sloc (N);
+      L     : constant Node_Id    := Left_Opnd (N);
+      R     : constant Node_Id    := Right_Opnd (N);
 
       Index : Interp_Index;
       It    : Interp;
@@ -2366,7 +2560,7 @@ package body Sem_Ch4 is
       Analyze_Expression (L);
 
       if No (R)
-        and then Ada_Version >= Ada_12
+        and then Ada_Version >= Ada_2012
       then
          Analyze_Set_Membership;
          return;
@@ -2389,14 +2583,42 @@ package body Sem_Ch4 is
             end loop;
          end if;
 
-      --  If not a range, it can only be a subtype mark, or else there
-      --  is a more basic error, to be diagnosed in Find_Type.
+      --  If not a range, it can be a subtype mark, or else it is a degenerate
+      --  membership test with a singleton value, i.e. a test for equality,
+      --  if the types are compatible.
 
       else
-         Find_Type (R);
+         Analyze (R);
 
-         if Is_Entity_Name (R) then
+         if Is_Entity_Name (R)
+           and then Is_Type (Entity (R))
+         then
+            Find_Type (R);
             Check_Fully_Declared (Entity (R), R);
+
+         elsif Ada_Version >= Ada_2012
+           and then Has_Compatible_Type (R, Etype (L))
+         then
+            if Nkind (N) = N_In then
+               Rewrite (N,
+                 Make_Op_Eq (Loc,
+                   Left_Opnd  => L,
+                   Right_Opnd => R));
+            else
+               Rewrite (N,
+                 Make_Op_Ne (Loc,
+                   Left_Opnd  => L,
+                   Right_Opnd => R));
+            end if;
+
+            Analyze (N);
+            return;
+
+         else
+            --  In all versions of the language, if we reach this point there
+            --  is a previous error that will be diagnosed below.
+
+            Find_Type (R);
          end if;
       end if;
 
@@ -2457,6 +2679,8 @@ package body Sem_Ch4 is
 
    procedure Analyze_Null (N : Node_Id) is
    begin
+      Check_SPARK_Restriction ("null is not allowed", N);
+
       Set_Etype (N, Any_Access);
    end Analyze_Null;
 
@@ -2517,6 +2741,7 @@ package body Sem_Ch4 is
       procedure Indicate_Name_And_Type is
       begin
          Add_One_Interp (N, Nam, Etype (Nam));
+         Check_Implicit_Dereference (N, Etype (Nam));
          Success := True;
 
          --  If the prefix of the call is a name, indicate the entity
@@ -2526,9 +2751,7 @@ package body Sem_Ch4 is
          --  being called is noted on the selector.
 
          if not Is_Type (Nam) then
-            if Is_Entity_Name (Name (N))
-              or else Nkind (Name (N)) = N_Operator_Symbol
-            then
+            if Is_Entity_Name (Name (N)) then
                Set_Entity (Name (N), Nam);
 
             elsif Nkind (Name (N)) = N_Selected_Component then
@@ -2747,9 +2970,9 @@ package body Sem_Ch4 is
          Actual := First_Actual (N);
          Formal := First_Formal (Nam);
 
-         --  If we are analyzing a call rewritten from object notation,
-         --  skip first actual, which may be rewritten later as an
-         --  explicit dereference.
+         --  If we are analyzing a call rewritten from object notation, skip
+         --  first actual, which may be rewritten later as an explicit
+         --  dereference.
 
          if Must_Skip then
             Next_Actual (Actual);
@@ -2825,6 +3048,11 @@ package body Sem_Ch4 is
                      if All_Errors_Mode then
                         Error_Msg_Sloc := Sloc (Nam);
 
+                        if Etype (Formal) = Any_Type then
+                           Error_Msg_N
+                             ("there is no legal actual parameter", Actual);
+                        end if;
+
                         if Is_Overloadable (Nam)
                           and then Present (Alias (Nam))
                           and then not Comes_From_Source (Nam)
@@ -2888,63 +3116,61 @@ package body Sem_Ch4 is
 
          if Present (Next_Actual (Act2)) then
             return;
+         end if;
 
-         elsif     Op_Name = Name_Op_Add
-           or else Op_Name = Name_Op_Subtract
-           or else Op_Name = Name_Op_Multiply
-           or else Op_Name = Name_Op_Divide
-           or else Op_Name = Name_Op_Mod
-           or else Op_Name = Name_Op_Rem
-           or else Op_Name = Name_Op_Expon
-         then
-            Find_Arithmetic_Types (Act1, Act2, Op_Id, N);
+         --  Otherwise action depends on operator
 
-         elsif     Op_Name =  Name_Op_And
-           or else Op_Name = Name_Op_Or
-           or else Op_Name = Name_Op_Xor
-         then
-            Find_Boolean_Types (Act1, Act2, Op_Id, N);
+         case Op_Name is
+            when Name_Op_Add      |
+                 Name_Op_Subtract |
+                 Name_Op_Multiply |
+                 Name_Op_Divide   |
+                 Name_Op_Mod      |
+                 Name_Op_Rem      |
+                 Name_Op_Expon    =>
+               Find_Arithmetic_Types (Act1, Act2, Op_Id, N);
 
-         elsif     Op_Name = Name_Op_Lt
-           or else Op_Name = Name_Op_Le
-           or else Op_Name = Name_Op_Gt
-           or else Op_Name = Name_Op_Ge
-         then
-            Find_Comparison_Types (Act1, Act2, Op_Id,  N);
+            when Name_Op_And      |
+                 Name_Op_Or       |
+                 Name_Op_Xor      =>
+               Find_Boolean_Types (Act1, Act2, Op_Id, N);
 
-         elsif     Op_Name = Name_Op_Eq
-           or else Op_Name = Name_Op_Ne
-         then
-            Find_Equality_Types (Act1, Act2, Op_Id,  N);
+            when Name_Op_Lt       |
+                 Name_Op_Le       |
+                 Name_Op_Gt       |
+                 Name_Op_Ge       =>
+               Find_Comparison_Types (Act1, Act2, Op_Id,  N);
 
-         elsif     Op_Name = Name_Op_Concat then
-            Find_Concatenation_Types (Act1, Act2, Op_Id, N);
+            when Name_Op_Eq       |
+                 Name_Op_Ne       =>
+               Find_Equality_Types (Act1, Act2, Op_Id,  N);
 
-         --  Is this else null correct, or should it be an abort???
+            when Name_Op_Concat   =>
+               Find_Concatenation_Types (Act1, Act2, Op_Id, N);
 
-         else
-            null;
-         end if;
+            --  Is this when others, or should it be an abort???
+
+            when others           =>
+               null;
+         end case;
 
       --  Unary operator case
 
       else
-         if Op_Name = Name_Op_Subtract or else
-            Op_Name = Name_Op_Add      or else
-            Op_Name = Name_Op_Abs
-         then
-            Find_Unary_Types (Act1, Op_Id, N);
+         case Op_Name is
+            when Name_Op_Subtract |
+                 Name_Op_Add      |
+                 Name_Op_Abs      =>
+               Find_Unary_Types (Act1, Op_Id, N);
 
-         elsif
-            Op_Name = Name_Op_Not
-         then
-            Find_Negation_Types (Act1, Op_Id, N);
+            when Name_Op_Not      =>
+               Find_Negation_Types (Act1, Op_Id, N);
 
-         --  Is this else null correct, or should it be an abort???
+            --  Is this when others correct, or should it be an abort???
 
-         else
-            null;
-         end if;
+            when others           =>
+               null;
+         end case;
       end if;
    end Analyze_Operator_Call;
 
@@ -2972,7 +3198,10 @@ package body Sem_Ch4 is
             T := It.Typ;
          end if;
 
-         if Is_Record_Type (T) then
+         --  Locate the component. For a private prefix the selector can denote
+         --  a discriminant.
+
+         if Is_Record_Type (T) or else Is_Private_Type (T) then
 
             --  If the prefix is a class-wide type, the visible components are
             --  those of the base type.
@@ -3000,6 +3229,7 @@ package body Sem_Ch4 is
                      Set_Entity (Sel, Comp);
                      Set_Etype (Sel, Etype (Comp));
                      Add_One_Interp (N, Etype (Comp), Etype (Comp));
+                     Check_Implicit_Dereference (N, Etype (Comp));
 
                      --  This also specifies a candidate to resolve the name.
                      --  Further overloading will be resolved from context.
@@ -3125,6 +3355,66 @@ package body Sem_Ch4 is
       Set_Etype  (N, T);
    end Analyze_Qualified_Expression;
 
+   -----------------------------------
+   -- Analyze_Quantified_Expression --
+   -----------------------------------
+
+   procedure Analyze_Quantified_Expression (N : Node_Id) is
+      Loc : constant Source_Ptr := Sloc (N);
+      Ent : constant Entity_Id :=
+              New_Internal_Entity
+                (E_Loop, Current_Scope, Sloc (N), 'L');
+
+      Iterator : Node_Id;
+
+   begin
+      Set_Etype  (Ent,  Standard_Void_Type);
+      Set_Scope  (Ent, Current_Scope);
+      Set_Parent (Ent, N);
+
+      Check_SPARK_Restriction ("quantified expression is not allowed", N);
+
+      --  If expansion is enabled (and not in Alfa mode), the condition is
+      --  analyzed after rewritten as a loop. So we only need to set the type.
+
+      if Operating_Mode /= Check_Semantics
+        and then not Alfa_Mode
+      then
+         Set_Etype (N, Standard_Boolean);
+         return;
+      end if;
+
+      if Present (Loop_Parameter_Specification (N)) then
+         Iterator :=
+           Make_Iteration_Scheme (Loc,
+             Loop_Parameter_Specification =>
+               Loop_Parameter_Specification (N));
+      else
+         Iterator :=
+           Make_Iteration_Scheme (Loc,
+              Iterator_Specification =>
+                Iterator_Specification (N));
+      end if;
+
+      Push_Scope (Ent);
+      Set_Parent (Iterator, N);
+      Analyze_Iteration_Scheme (Iterator);
+
+      --  The loop specification may have been converted into an iterator
+      --  specification during its analysis. Update the quantified node
+      --  accordingly.
+
+      if Present (Iterator_Specification (Iterator)) then
+         Set_Iterator_Specification
+           (N, Iterator_Specification (Iterator));
+         Set_Loop_Parameter_Specification (N, Empty);
+      end if;
+
+      Analyze (Condition (N));
+      End_Scope;
+      Set_Etype (N, Standard_Boolean);
+   end Analyze_Quantified_Expression;
+
    -------------------
    -- Analyze_Range --
    -------------------
@@ -3144,8 +3434,8 @@ package body Sem_Ch4 is
       --  of the high bound.
 
       procedure Check_Universal_Expression (N : Node_Id);
-      --  In Ada83, reject bounds of a universal range that are not
-      --  literals or entity names.
+      --  In Ada 83, reject bounds of a universal range that are not literals
+      --  or entity names.
 
       -----------------------
       -- Check_Common_Type --
@@ -3324,6 +3614,14 @@ package body Sem_Ch4 is
       Is_Single_Concurrent_Object : Boolean;
       --  Set True if the prefix is a single task or a single protected object
 
+      procedure Find_Component_In_Instance (Rec : Entity_Id);
+      --  In an instance, a component of a private extension may not be visible
+      --  while it was visible in the generic. Search candidate scope for a
+      --  component with the proper identifier. This is only done if all other
+      --  searches have failed. When the match is found (it always will be),
+      --  the Etype of both N and Sel are set from this component, and the
+      --  entity of Sel is set to reference this component.
+
       function Has_Mode_Conformant_Spec (Comp : Entity_Id) return Boolean;
       --  It is known that the parent of N denotes a subprogram call. Comp
       --  is an overloadable component of the concurrent type of the prefix.
@@ -3331,6 +3629,31 @@ package body Sem_Ch4 is
       --  conformant. If the parent node is not analyzed yet it may be an
       --  indexed component rather than a function call.
 
+      --------------------------------
+      -- Find_Component_In_Instance --
+      --------------------------------
+
+      procedure Find_Component_In_Instance (Rec : Entity_Id) is
+         Comp : Entity_Id;
+
+      begin
+         Comp := First_Component (Rec);
+         while Present (Comp) loop
+            if Chars (Comp) = Chars (Sel) then
+               Set_Entity_With_Style_Check (Sel, Comp);
+               Set_Etype (Sel, Etype (Comp));
+               Set_Etype (N,   Etype (Comp));
+               return;
+            end if;
+
+            Next_Component (Comp);
+         end loop;
+
+         --  This must succeed because code was legal in the generic
+
+         raise Program_Error;
+      end Find_Component_In_Instance;
+
       ------------------------------
       -- Has_Mode_Conformant_Spec --
       ------------------------------
@@ -3511,6 +3834,7 @@ package body Sem_Ch4 is
       --  be done transitively, so note the new original discriminant.
 
       if Nkind (Sel) = N_Identifier
+        and then In_Instance
         and then Present (Original_Discriminant (Sel))
       then
          Comp := Find_Corresponding_Discriminant (Sel, Prefix_Type);
@@ -3523,6 +3847,7 @@ package body Sem_Ch4 is
            New_Occurrence_Of (Comp, Sloc (N)));
          Set_Original_Discriminant (Selector_Name (N), Comp);
          Set_Etype (N, Etype (Comp));
+         Check_Implicit_Dereference (N, Etype (Comp));
 
          if Is_Access_Type (Etype (Name)) then
             Insert_Explicit_Dereference (Name);
@@ -3659,6 +3984,7 @@ package body Sem_Ch4 is
                   Set_Etype (N, Etype (Comp));
                end if;
 
+               Check_Implicit_Dereference (N, Etype (N));
                return;
             end if;
 
@@ -3667,7 +3993,7 @@ package body Sem_Ch4 is
             --  which can appear in expanded code in a tag check.
 
             if Ekind (Type_To_Use) = E_Record_Type_With_Private
-              and then  Chars (Selector_Name (N)) /= Name_uTag
+              and then Chars (Selector_Name (N)) /= Name_uTag
             then
                exit when Comp = Last_Entity (Type_To_Use);
             end if;
@@ -3683,7 +4009,7 @@ package body Sem_Ch4 is
          --  Ada 2005 (AI05-0030): In the case of dispatching requeue, the
          --  selected component should resolve to a name.
 
-         if Ada_Version >= Ada_05
+         if Ada_Version >= Ada_2005
            and then Is_Tagged_Type (Prefix_Type)
            and then not Is_Concurrent_Type (Prefix_Type)
          then
@@ -3724,6 +4050,7 @@ package body Sem_Ch4 is
 
                   Set_Etype (Sel, Etype (Comp));
                   Set_Etype (N,   Etype (Comp));
+                  Check_Implicit_Dereference (N, Etype (N));
 
                   if Is_Generic_Type (Prefix_Type)
                     or else Is_Generic_Type (Root_Type (Prefix_Type))
@@ -3734,7 +4061,7 @@ package body Sem_Ch4 is
                --  Before declaring an error, check whether this is tagged
                --  private type and a call to a primitive operation.
 
-               elsif Ada_Version >= Ada_05
+               elsif Ada_Version >= Ada_2005
                  and then Is_Tagged_Type (Prefix_Type)
                  and then Try_Object_Operation (N)
                then
@@ -3798,6 +4125,11 @@ package body Sem_Ch4 is
                   Set_Entity_With_Style_Check (Sel, Comp);
                   Generate_Reference (Comp, Sel);
 
+                  --  The selector is not overloadable, so we have a candidate
+                  --  interpretation.
+
+                  Has_Candidate := True;
+
                else
                   goto Next_Comp;
                end if;
@@ -3830,7 +4162,7 @@ package body Sem_Ch4 is
          --  visible entities are plausible interpretations, check whether
          --  there is some other primitive operation with that name.
 
-         if Ada_Version >= Ada_05
+         if Ada_Version >= Ada_2005
            and then Is_Tagged_Type (Prefix_Type)
          then
             if (Etype (N) = Any_Type
@@ -3855,9 +4187,30 @@ package body Sem_Ch4 is
             then
                return;
             end if;
+
+            --  Ada 2012 (AI05-0090-1): If we found a candidate of a call to an
+            --  entry or procedure of a tagged concurrent type we must check
+            --  if there are class-wide subprograms covering the primitive. If
+            --  true then Try_Object_Operation reports the error.
+
+            if Has_Candidate
+              and then Is_Concurrent_Type (Prefix_Type)
+              and then Nkind (Parent (N)) = N_Procedure_Call_Statement
+
+               --  Duplicate the call. This is required to avoid problems with
+               --  the tree transformations performed by Try_Object_Operation.
+
+              and then
+                Try_Object_Operation
+                  (N            => Sinfo.Name (New_Copy_Tree (Parent (N))),
+                   CW_Test_Only => True)
+            then
+               return;
+            end if;
          end if;
 
          if Etype (N) = Any_Type and then Is_Protected_Type (Prefix_Type) then
+
             --  Case of a prefix of a protected type: selector might denote
             --  an invisible private component.
 
@@ -3910,33 +4263,31 @@ package body Sem_Ch4 is
             Analyze_Selected_Component (N);
             return;
 
+         --  Similarly, if this is the actual for a formal derived type, the
+         --  component inherited from the generic parent may not be visible
+         --  in the actual, but the selected component is legal.
+
          elsif Ekind (Prefix_Type) = E_Record_Subtype_With_Private
            and then Is_Generic_Actual_Type (Prefix_Type)
            and then Present (Full_View (Prefix_Type))
          then
-            --  Similarly, if this the actual for a formal derived type, the
-            --  component inherited from the generic parent may not be visible
-            --  in the actual, but the selected component is legal.
 
-            declare
-               Comp : Entity_Id;
+            Find_Component_In_Instance
+              (Generic_Parent_Type (Parent (Prefix_Type)));
+            return;
 
-            begin
-               Comp :=
-                 First_Component (Generic_Parent_Type (Parent (Prefix_Type)));
-               while Present (Comp) loop
-                  if Chars (Comp) = Chars (Sel) then
-                     Set_Entity_With_Style_Check (Sel, Comp);
-                     Set_Etype (Sel, Etype (Comp));
-                     Set_Etype (N,   Etype (Comp));
-                     return;
-                  end if;
+         --  Finally, the formal and the actual may be private extensions,
+         --  but the generic is declared in a child unit of the parent, and
+         --  an additional step is needed to retrieve the proper scope.
 
-                  Next_Component (Comp);
-               end loop;
+         elsif In_Instance
+           and then Present (Parent_Subtype (Etype (Base_Type (Prefix_Type))))
+         then
+            Find_Component_In_Instance
+              (Parent_Subtype (Etype (Base_Type (Prefix_Type))));
+            return;
 
-               pragma Assert (Etype (N) /= Any_Type);
-            end;
+         --  Component not found, specialize error message when appropriate
 
          else
             if Ekind (Prefix_Type) = E_Record_Subtype then
@@ -3976,6 +4327,34 @@ package body Sem_Ch4 is
             Error_Msg_Node_2 := First_Subtype (Prefix_Type);
             Error_Msg_NE ("no selector& for}", N, Sel);
 
+            --  Add information in the case of an incomplete prefix
+
+            if Is_Incomplete_Type (Type_To_Use) then
+               declare
+                  Inc : constant Entity_Id := First_Subtype (Type_To_Use);
+
+               begin
+                  if From_With_Type (Scope (Type_To_Use)) then
+                     Error_Msg_NE
+                       ("\limited view of& has no components", N, Inc);
+
+                  else
+                     Error_Msg_NE
+                       ("\premature usage of incomplete type&", N, Inc);
+
+                     if Nkind (Parent (Inc)) =
+                                          N_Incomplete_Type_Declaration
+                     then
+                        --  Record location of premature use in entity so that
+                        --  a continuation message is generated when the
+                        --  completion is seen.
+
+                        Set_Premature_Use (Parent (Inc), N);
+                     end if;
+                  end if;
+               end;
+            end if;
+
             Check_Misspelled_Selector (Type_To_Use, Sel);
          end if;
 
@@ -4085,6 +4464,10 @@ package body Sem_Ch4 is
    --  Start of processing for Analyze_Slice
 
    begin
+      if Comes_From_Source (N) then
+         Check_SPARK_Restriction ("slice is not allowed", N);
+      end if;
+
       Analyze (P);
       Analyze (D);
 
@@ -4659,7 +5042,7 @@ package body Sem_Ch4 is
       pragma Warnings (Off, Boolean);
 
    begin
-      if Ada_Version >= Ada_05 then
+      if Ada_Version >= Ada_2005 then
          Actual := First_Actual (N);
          while Present (Actual) loop
 
@@ -5146,7 +5529,7 @@ package body Sem_Ch4 is
             null;
 
          else
-            --  Save candidate type for subsquent error message, if any
+            --  Save candidate type for subsequent error message, if any
 
             if not Is_Limited_Type (T1) then
                Candidate_Type := T1;
@@ -5158,16 +5541,22 @@ package body Sem_Ch4 is
          --  Ada 2005 (AI-230): Keep restriction imposed by Ada 83 and 95:
          --  Do not allow anonymous access types in equality operators.
 
-         if Ada_Version < Ada_05
+         if Ada_Version < Ada_2005
            and then Ekind (T1) = E_Anonymous_Access_Type
          then
             return;
          end if;
 
          if T1 /= Standard_Void_Type
-           and then not Is_Limited_Type (T1)
-           and then not Is_Limited_Composite (T1)
            and then Has_Compatible_Type (R, T1)
+           and then
+             ((not Is_Limited_Type (T1)
+                and then not Is_Limited_Composite (T1))
+
+               or else
+                 (Is_Array_Type (T1)
+                   and then not Is_Limited_Type (Component_Type (T1))
+                   and then Available_Full_View_Of_Component (T1)))
          then
             if Found
               and then Base_Type (T1) /= Base_Type (T_F)
@@ -5514,7 +5903,6 @@ package body Sem_Ch4 is
                          or else Is_Array_Type (Etype (L))
                          or else Is_Array_Type (Etype (R)))
             then
-
                if Nkind (N) = N_Op_Concat then
                   if Etype (L) /= Any_Composite
                     and then Is_Array_Type (Etype (L))
@@ -5531,8 +5919,20 @@ package body Sem_Ch4 is
                Error_Msg_NE -- CODEFIX
                  ("operator for} is not directly visible!",
                   N, First_Subtype (Candidate_Type));
-               Error_Msg_N -- CODEFIX
-                 ("use clause would make operation legal!",  N);
+
+               declare
+                  U : constant Node_Id :=
+                        Cunit (Get_Source_Unit (Candidate_Type));
+               begin
+                  if Unit_Is_Visible (U) then
+                     Error_Msg_N -- CODEFIX
+                       ("use clause would make operation legal!",  N);
+                  else
+                     Error_Msg_NE  --  CODEFIX
+                       ("add with_clause and use_clause for&!",
+                          N, Defining_Entity (Unit (U)));
+                  end if;
+               end;
                return;
 
             --  If either operand is a junk operand (e.g. package name), then
@@ -5833,12 +6233,12 @@ package body Sem_Ch4 is
                   Remove_Interp (I);
                   exit;
 
-               --  In Ada 2005, this operation does not participate in Overload
+               --  In Ada 2005, this operation does not participate in overload
                --  resolution. If the operation is defined in a predefined
                --  unit, it is one of the operations declared abstract in some
                --  variants of System, and it must be removed as well.
 
-               elsif Ada_Version >= Ada_05
+               elsif Ada_Version >= Ada_2005
                  or else Is_Predefined_File_Name
                            (Unit_File_Name (Get_Source_Unit (It.Nam)))
                then
@@ -5998,7 +6398,7 @@ package body Sem_Ch4 is
             --  predefined operators when addresses are involved since this
             --  case is handled separately.
 
-            elsif Ada_Version >= Ada_05
+            elsif Ada_Version >= Ada_2005
               and then not Address_Kludge
             then
                while Present (It.Nam) loop
@@ -6015,6 +6415,127 @@ package body Sem_Ch4 is
       end if;
    end Remove_Abstract_Operations;
 
+   ----------------------------
+   -- Try_Container_Indexing --
+   ----------------------------
+
+   function Try_Container_Indexing
+     (N      : Node_Id;
+      Prefix : Node_Id;
+      Expr   : Node_Id) return Boolean
+   is
+      Loc       : constant Source_Ptr := Sloc (N);
+      Disc      : Entity_Id;
+      Func      : Entity_Id;
+      Func_Name : Node_Id;
+      Indexing  : Node_Id;
+
+   begin
+
+      --  Check whether type has a specified indexing aspect
+
+      Func_Name := Empty;
+
+      if Is_Variable (Prefix) then
+         Func_Name := Find_Aspect (Etype (Prefix), Aspect_Variable_Indexing);
+      end if;
+
+      if No (Func_Name) then
+         Func_Name := Find_Aspect (Etype (Prefix), Aspect_Constant_Indexing);
+      end if;
+
+      --  If aspect does not exist the expression is illegal. Error is
+      --  diagnosed in caller.
+
+      if No (Func_Name) then
+
+         --  The prefix itself may be an indexing of a container
+         --  rewrite as such and re-analyze.
+
+         if Has_Implicit_Dereference (Etype (Prefix)) then
+            Build_Explicit_Dereference
+              (Prefix, First_Discriminant (Etype (Prefix)));
+            return Try_Container_Indexing (N, Prefix, Expr);
+
+         else
+            return False;
+         end if;
+      end if;
+
+      if not Is_Overloaded (Func_Name) then
+         Func := Entity (Func_Name);
+         Indexing := Make_Function_Call (Loc,
+           Name => New_Occurrence_Of (Func, Loc),
+           Parameter_Associations =>
+             New_List (Relocate_Node (Prefix), Relocate_Node (Expr)));
+         Rewrite (N, Indexing);
+         Analyze (N);
+
+         --  The return type of the indexing function is a reference type, so
+         --  add the dereference as a possible interpretation.
+
+         Disc := First_Discriminant (Etype (Func));
+         while Present (Disc) loop
+            if Has_Implicit_Dereference (Disc) then
+               Add_One_Interp (N, Disc, Designated_Type (Etype (Disc)));
+               exit;
+            end if;
+
+            Next_Discriminant (Disc);
+         end loop;
+
+      else
+         Indexing := Make_Function_Call (Loc,
+           Name => Make_Identifier (Loc, Chars (Func_Name)),
+           Parameter_Associations =>
+             New_List (Relocate_Node (Prefix), Relocate_Node (Expr)));
+
+         Rewrite (N, Indexing);
+
+         declare
+            I  : Interp_Index;
+            It : Interp;
+            Success : Boolean;
+
+         begin
+            Get_First_Interp (Func_Name, I, It);
+            Set_Etype (N, Any_Type);
+            while Present (It.Nam) loop
+               Analyze_One_Call (N, It.Nam, False, Success);
+               if Success then
+                  Set_Etype (Name (N), It.Typ);
+                  Set_Entity (Name (N), It.Nam);
+
+                  --  Add implicit dereference interpretation
+
+                  Disc := First_Discriminant (Etype (It.Nam));
+                  while Present (Disc) loop
+                     if Has_Implicit_Dereference (Disc) then
+                        Add_One_Interp
+                          (N, Disc, Designated_Type (Etype (Disc)));
+                        exit;
+                     end if;
+
+                     Next_Discriminant (Disc);
+                  end loop;
+
+                  exit;
+               end if;
+               Get_Next_Interp (I, It);
+            end loop;
+         end;
+      end if;
+
+      if Etype (N) = Any_Type then
+         Error_Msg_NE ("container cannot be indexed with&", N, Etype (Expr));
+         Rewrite (N, New_Occurrence_Of (Any_Id, Loc));
+      else
+         Analyze (N);
+      end if;
+
+      return True;
+   end Try_Container_Indexing;
+
    -----------------------
    -- Try_Indirect_Call --
    -----------------------
@@ -6101,14 +6622,25 @@ package body Sem_Ch4 is
            and then Is_Type (Entity (Actual))
            and then No (Next (Actual))
          then
-            Rewrite (N,
-              Make_Slice (Loc,
-                Prefix => Make_Function_Call (Loc,
-                  Name => Relocate_Node (Name (N))),
-                Discrete_Range =>
-                  New_Occurrence_Of (Entity (Actual), Sloc (Actual))));
+            --  A single actual that is a type name indicates a slice if the
+            --  type is discrete, and an error otherwise.
+
+            if Is_Discrete_Type (Entity (Actual)) then
+               Rewrite (N,
+                 Make_Slice (Loc,
+                   Prefix =>
+                     Make_Function_Call (Loc,
+                       Name => Relocate_Node (Name (N))),
+                   Discrete_Range =>
+                     New_Occurrence_Of (Entity (Actual), Sloc (Actual))));
+
+               Analyze (N);
+
+            else
+               Error_Msg_N ("invalid use of type in expression", Actual);
+               Set_Etype (N, Any_Type);
+            end if;
 
-            Analyze (N);
             return True;
 
          elsif not Has_Compatible_Type (Actual, Etype (Index)) then
@@ -6141,7 +6673,9 @@ package body Sem_Ch4 is
    -- Try_Object_Operation --
    --------------------------
 
-   function Try_Object_Operation (N : Node_Id) return Boolean is
+   function Try_Object_Operation
+     (N : Node_Id; CW_Test_Only : Boolean := False) return Boolean
+   is
       K              : constant Node_Kind  := Nkind (Parent (N));
       Is_Subprg_Call : constant Boolean    := Nkind_In
                                                (K, N_Procedure_Call_Statement,
@@ -6170,7 +6704,7 @@ package body Sem_Ch4 is
          Call    : Node_Id;
          Subp    : Entity_Id) return Entity_Id;
       --  If the subprogram is a valid interpretation, record it, and add
-      --  to the list of interpretations of Subprog.
+      --  to the list of interpretations of Subprog. Otherwise return Empty.
 
       procedure Complete_Object_Operation
         (Call_Node       : Node_Id;
@@ -6253,8 +6787,8 @@ package body Sem_Ch4 is
 
          if Present (Arr_Type) then
 
-            --  Verify that the actuals (excluding the object)
-            --  match the types of the indices.
+            --  Verify that the actuals (excluding the object) match the types
+            --  of the indexes.
 
             declare
                Actual : Node_Id;
@@ -6316,7 +6850,8 @@ package body Sem_Ch4 is
          First_Actual := First (Parameter_Associations (Call_Node));
 
          --  For cross-reference purposes, treat the new node as being in
-         --  the source if the original one is.
+         --  the source if the original one is. Set entity and type, even
+         --  though they may be overwritten during resolution if overloaded.
 
          Set_Comes_From_Source (Subprog, Comes_From_Source (N));
          Set_Comes_From_Source (Call_Node, Comes_From_Source (N));
@@ -6325,6 +6860,7 @@ package body Sem_Ch4 is
            and then not Inside_A_Generic
          then
             Set_Entity (Selector_Name (N), Entity (Subprog));
+            Set_Etype  (Selector_Name (N), Etype (Entity (Subprog)));
          end if;
 
          --  If need be, rewrite first actual as an explicit dereference
@@ -6430,14 +6966,17 @@ package body Sem_Ch4 is
       ----------------------
 
       procedure Report_Ambiguity (Op : Entity_Id) is
-         Access_Formal : constant Boolean :=
-                           Is_Access_Type (Etype (First_Formal (Op)));
          Access_Actual : constant Boolean :=
                            Is_Access_Type (Etype (Prefix (N)));
+         Access_Formal : Boolean := False;
 
       begin
          Error_Msg_Sloc := Sloc (Op);
 
+         if Present (First_Formal (Op)) then
+            Access_Formal := Is_Access_Type (Etype (First_Formal (Op)));
+         end if;
+
          if Access_Formal and then not Access_Actual then
             if Nkind (Parent (Op)) = N_Full_Type_Declaration then
                Error_Msg_N
@@ -6607,13 +7146,13 @@ package body Sem_Ch4 is
 
             Hom := Current_Entity (Subprog);
 
-            --  Find operation whose first parameter is of the class-wide
-            --  type, a subtype thereof, or an anonymous access to same.
+            --  Find a non-hidden operation whose first parameter is of the
+            --  class-wide type, a subtype thereof, or an anonymous access
+            --  to same.
 
             while Present (Hom) loop
-               if (Ekind (Hom) = E_Procedure
-                     or else
-                   Ekind (Hom) = E_Function)
+               if Ekind_In (Hom, E_Procedure, E_Function)
+                 and then not Is_Hidden (Hom)
                  and then Scope (Hom) = Scope (Anc_Type)
                  and then Present (First_Formal (Hom))
                  and then
@@ -6628,6 +7167,24 @@ package body Sem_Ch4 is
                               (Designated_Type (Etype (First_Formal (Hom)))) =
                                                                    Cls_Type))
                then
+                  --  If the context is a procedure call, ignore functions
+                  --  in the name of the call.
+
+                  if Ekind (Hom) = E_Function
+                    and then Nkind (Parent (N)) = N_Procedure_Call_Statement
+                    and then N = Name (Parent (N))
+                  then
+                     goto Next_Hom;
+
+                  --  If the context is a function call, ignore procedures
+                  --  in the name of the call.
+
+                  elsif Ekind (Hom) = E_Procedure
+                    and then Nkind (Parent (N)) /= N_Procedure_Call_Statement
+                  then
+                     goto Next_Hom;
+                  end if;
+
                   Set_Etype (Call_Node, Any_Type);
                   Set_Is_Overloaded (Call_Node, False);
                   Success := False;
@@ -6669,7 +7226,8 @@ package body Sem_Ch4 is
                   end if;
                end if;
 
-               Hom := Homonym (Hom);
+               <<Next_Hom>>
+                  Hom := Homonym (Hom);
             end loop;
          end Traverse_Homonyms;
 
@@ -6718,6 +7276,13 @@ package body Sem_Ch4 is
       --  Start of processing for Try_Class_Wide_Operation
 
       begin
+         --  If we are searching only for conflicting class-wide subprograms
+         --  then initialize directly Matching_Op with the target entity.
+
+         if CW_Test_Only then
+            Matching_Op := Entity (Selector_Name (N));
+         end if;
+
          --  Loop through ancestor types (including interfaces), traversing
          --  the homonym chain of the subprogram, trying out those homonyms
          --  whose first formal has the class-wide type of the ancestor, or
@@ -6792,16 +7357,41 @@ package body Sem_Ch4 is
             return;
          end if;
 
-         if Try_Primitive_Operation
-              (Call_Node       => New_Call_Node,
-               Node_To_Replace => Node_To_Replace)
-           or else
-             Try_Class_Wide_Operation
-               (Call_Node       => New_Call_Node,
-                Node_To_Replace => Node_To_Replace)
-         then
-            null;
-         end if;
+         declare
+            Dup_Call_Node : constant Node_Id := New_Copy (New_Call_Node);
+            CW_Result     : Boolean;
+            Prim_Result   : Boolean;
+            pragma Unreferenced (CW_Result);
+
+         begin
+            if not CW_Test_Only then
+               Prim_Result :=
+                  Try_Primitive_Operation
+                   (Call_Node       => New_Call_Node,
+                    Node_To_Replace => Node_To_Replace);
+            end if;
+
+            --  Check if there is a class-wide subprogram covering the
+            --  primitive. This check must be done even if a candidate
+            --  was found in order to report ambiguous calls.
+
+            if not (Prim_Result) then
+               CW_Result :=
+                 Try_Class_Wide_Operation
+                   (Call_Node       => New_Call_Node,
+                    Node_To_Replace => Node_To_Replace);
+
+            --  If we found a primitive we search for class-wide subprograms
+            --  using a duplicate of the call node (done to avoid missing its
+            --  decoration if there is no ambiguity).
+
+            else
+               CW_Result :=
+                 Try_Class_Wide_Operation
+                   (Call_Node       => Dup_Call_Node,
+                    Node_To_Replace => Node_To_Replace);
+            end if;
+         end;
       end Try_One_Prefix_Interpretation;
 
       -----------------------------
@@ -6990,7 +7580,8 @@ package body Sem_Ch4 is
 
               or else
                 (Ekind (Typ) = E_Anonymous_Access_Type
-                  and then Designated_Type (Typ) = Base_Type (Corr_Type));
+                  and then
+                    Base_Type (Designated_Type (Typ)) = Base_Type (Corr_Type));
          end Valid_First_Argument_Of;
 
       --  Start of processing for Try_Primitive_Operation
@@ -7152,10 +7743,18 @@ package body Sem_Ch4 is
       end if;
 
       if Etype (New_Call_Node) /= Any_Type then
-         Complete_Object_Operation
-           (Call_Node       => New_Call_Node,
-            Node_To_Replace => Node_To_Replace);
-         return True;
+
+         --  No need to complete the tree transformations if we are only
+         --  searching for conflicting class-wide subprograms
+
+         if CW_Test_Only then
+            return False;
+         else
+            Complete_Object_Operation
+              (Call_Node       => New_Call_Node,
+               Node_To_Replace => Node_To_Replace);
+            return True;
+         end if;
 
       elsif Present (Candidate) then