aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada/sem_ch4.adb
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/ada/sem_ch4.adb')
-rw-r--r--gcc/ada/sem_ch4.adb1048
1 files changed, 633 insertions, 415 deletions
diff --git a/gcc/ada/sem_ch4.adb b/gcc/ada/sem_ch4.adb
index 5910112..c92fb06 100644
--- a/gcc/ada/sem_ch4.adb
+++ b/gcc/ada/sem_ch4.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 1992-2019, Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2020, 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- --
@@ -171,6 +171,7 @@ package body Sem_Ch4 is
-- being called. The caller will have verified that the object is legal
-- for the call. If the remaining parameters match, the first parameter
-- will rewritten as a dereference if needed, prior to completing analysis.
+
procedure Check_Misspelled_Selector
(Prefix : Entity_Id;
Sel : Node_Id);
@@ -276,20 +277,6 @@ package body Sem_Ch4 is
-- type is not directly visible. The routine uses this type to emit a more
-- informative message.
- function Process_Implicit_Dereference_Prefix
- (E : Entity_Id;
- P : Node_Id) return Entity_Id;
- -- Called when P is the prefix of an implicit dereference, denoting an
- -- object E. The function returns the designated type of the prefix, taking
- -- into account that the designated type of an anonymous access type may be
- -- a limited view, when the nonlimited view is visible.
- --
- -- If in semantics only mode (-gnatc or generic), the function also records
- -- that the prefix is a reference to E, if any. Normally, such a reference
- -- is generated only when the implicit dereference is expanded into an
- -- explicit one, but for consistency we must generate the reference when
- -- expansion is disabled as well.
-
procedure Remove_Abstract_Operations (N : Node_Id);
-- Ada 2005: implementation of AI-310. An abstract non-dispatching
-- operation is not a candidate interpretation.
@@ -299,6 +286,7 @@ package body Sem_Ch4 is
Prefix : Node_Id;
Exprs : List_Id) return Boolean;
-- AI05-0139: Generalized indexing to support iterators over containers
+ -- ??? Need to provide a more detailed spec of what this function does
function Try_Indexed_Call
(N : Node_Id;
@@ -392,7 +380,7 @@ package body Sem_Ch4 is
if Nkind (N) in N_Membership_Test then
Error_Msg_N ("ambiguous operands for membership", N);
- elsif Nkind_In (N, N_Op_Eq, N_Op_Ne) then
+ elsif Nkind (N) in N_Op_Eq | N_Op_Ne then
Error_Msg_N ("ambiguous operands for equality", N);
else
@@ -469,8 +457,6 @@ package body Sem_Ch4 is
Onode : Node_Id;
begin
- Check_SPARK_05_Restriction ("allocator is not allowed", N);
-
-- Deal with allocator restrictions
-- In accordance with H.4(7), the No_Allocators restriction only applies
@@ -680,7 +666,7 @@ package body Sem_Ch4 is
-- that outside of spec expressions, otherwise the declaration
-- cannot be inserted and analyzed. In such a case, GNATprove
-- later rejects the allocator as it is not used here in
- -- a non-interfering context (SPARK 4.8(2) and 7.1.3(12)).
+ -- a non-interfering context (SPARK 4.8(2) and 7.1.3(10)).
if Expander_Active
or else (GNATprove_Mode and then not In_Spec_Expression)
@@ -935,16 +921,8 @@ package body Sem_Ch4 is
if Present (Op_Id) then
if Ekind (Op_Id) = E_Operator then
-
- if Nkind_In (N, N_Op_Divide, N_Op_Mod, N_Op_Multiply, N_Op_Rem)
- and then Treat_Fixed_As_Integer (N)
- then
- null;
- else
- Set_Etype (N, Any_Type);
- Find_Arithmetic_Types (L, R, Op_Id, N);
- end if;
-
+ Set_Etype (N, Any_Type);
+ Find_Arithmetic_Types (L, R, Op_Id, N);
else
Set_Etype (N, Any_Type);
Add_One_Interp (N, Op_Id, Etype (Op_Id));
@@ -1005,10 +983,6 @@ 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.
-
procedure Check_Writable_Actuals (N : Node_Id);
-- If the call has out or in-out parameters then mark its outermost
-- enclosing construct as a node on which the writable actuals check
@@ -1024,36 +998,6 @@ 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_05_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;
-
----------------------------
-- Check_Writable_Actuals --
----------------------------
@@ -1119,8 +1063,8 @@ package body Sem_Ch4 is
-- performing the writable actuals check.
if Has_Arbitrary_Evaluation_Order (Nkind (P))
- and then not Nkind_In (P, N_Assignment_Statement,
- N_Object_Declaration)
+ and then Nkind (P) not in
+ N_Assignment_Statement | N_Object_Declaration
then
Outermost := P;
end if;
@@ -1129,8 +1073,8 @@ package body Sem_Ch4 is
exit when Stop_Subtree_Climbing (Nkind (P))
or else (Nkind (P) = N_Range
- and then not
- Nkind_In (Parent (P), N_In, N_Not_In));
+ and then
+ Nkind (Parent (P)) not in N_In | N_Not_In);
P := Parent (P);
end loop;
@@ -1180,8 +1124,7 @@ package body Sem_Ch4 is
-- Check for tasking cases where only an entry call will do
elsif not L
- and then Nkind_In (K, N_Entry_Call_Alternative,
- N_Triggering_Alternative)
+ and then K in N_Entry_Call_Alternative | N_Triggering_Alternative
then
Error_Msg_N ("entry name expected", Nam);
@@ -1195,10 +1138,6 @@ package body Sem_Ch4 is
-- Start of processing for Analyze_Call
begin
- if Restriction_Check_Required (SPARK_05) 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.
@@ -1224,8 +1163,7 @@ package body Sem_Ch4 is
-- type is an array, F (X) cannot be interpreted as an indirect call
-- through the result of the call to F.
- elsif Is_Access_Type (Etype (Nam))
- and then Ekind (Designated_Type (Etype (Nam))) = E_Subprogram_Type
+ elsif Is_Access_Subprogram_Type (Base_Type (Etype (Nam)))
and then
(not Name_Denotes_Function
or else Nkind (N) = N_Procedure_Call_Statement
@@ -1246,10 +1184,10 @@ package body Sem_Ch4 is
elsif Nkind (Nam) = N_Selected_Component then
Nam_Ent := Entity (Selector_Name (Nam));
- if not Ekind_In (Nam_Ent, E_Entry,
- E_Entry_Family,
- E_Function,
- E_Procedure)
+ if Ekind (Nam_Ent) not in E_Entry
+ | E_Entry_Family
+ | E_Function
+ | E_Procedure
then
Error_Msg_N ("name in call is not a callable entity", Nam);
Set_Etype (N, Any_Type);
@@ -1424,7 +1362,7 @@ package body Sem_Ch4 is
Set_Etype (Nam, It.Typ);
end if;
- elsif Nkind_In (Name (N), N_Function_Call, N_Selected_Component)
+ elsif Nkind (Name (N)) in N_Function_Call | N_Selected_Component
then
Remove_Interp (X);
end if;
@@ -2100,13 +2038,6 @@ 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_05_Restriction ("explicit dereference is not allowed", N);
- end if;
-
-- In formal verification mode, keep track of all reads and writes
-- through explicit dereferences.
@@ -2286,17 +2217,91 @@ package body Sem_Ch4 is
-------------------------------------
procedure Analyze_Expression_With_Actions (N : Node_Id) is
+
+ procedure Check_Action_OK (A : Node_Id);
+ -- Check that the action is something that is allows as a declare_item
+ -- of a declare_expression, except the checks are suppressed for
+ -- generated code.
+
+ procedure Check_Action_OK (A : Node_Id) is
+ begin
+ if not Comes_From_Source (N) or else not Comes_From_Source (A) then
+ return; -- Allow anything in generated code
+ end if;
+
+ case Nkind (A) is
+ when N_Object_Declaration =>
+ if Nkind (Object_Definition (A)) = N_Access_Definition then
+ Error_Msg_N
+ ("anonymous access type not allowed in declare_expression",
+ Object_Definition (A));
+ end if;
+
+ if Aliased_Present (A) then
+ Error_Msg_N ("aliased not allowed in declare_expression", A);
+ end if;
+
+ if Constant_Present (A)
+ and then not Is_Limited_Type (Etype (Defining_Identifier (A)))
+ then
+ return; -- nonlimited constants are OK
+ end if;
+
+ when N_Object_Renaming_Declaration =>
+ if Present (Access_Definition (A)) then
+ Error_Msg_N
+ ("anonymous access type not allowed in declare_expression",
+ Access_Definition (A));
+ end if;
+
+ if not Is_Limited_Type (Etype (Defining_Identifier (A))) then
+ return; -- ???For now; the RM rule is a bit more complicated
+ end if;
+
+ when others =>
+ null; -- Nothing else allowed, not even pragmas
+ end case;
+
+ Error_Msg_N ("object renaming or constant declaration expected", A);
+ end Check_Action_OK;
+
A : Node_Id;
+ EWA_Scop : Entity_Id;
+
+ -- Start of processing for Analyze_Expression_With_Actions
begin
+ -- Create a scope, which is needed to provide proper visibility of the
+ -- declare_items.
+
+ EWA_Scop := New_Internal_Entity (E_Block, Current_Scope, Sloc (N), 'B');
+ Set_Etype (EWA_Scop, Standard_Void_Type);
+ Set_Scope (EWA_Scop, Current_Scope);
+ Set_Parent (EWA_Scop, N);
+ Push_Scope (EWA_Scop);
+
+ -- If this Expression_With_Actions node comes from source, then it
+ -- represents a declare_expression; increment the counter to take note
+ -- of that.
+
+ if Comes_From_Source (N) then
+ In_Declare_Expr := In_Declare_Expr + 1;
+ end if;
+
A := First (Actions (N));
while Present (A) loop
Analyze (A);
+ Check_Action_OK (A);
Next (A);
end loop;
Analyze_Expression (Expression (N));
Set_Etype (N, Etype (Expression (N)));
+ End_Scope;
+
+ if Comes_From_Source (N) then
+ In_Declare_Expr := In_Declare_Expr - 1;
+ end if;
end Analyze_Expression_With_Actions;
---------------------------
@@ -2326,10 +2331,6 @@ package body Sem_Ch4 is
Else_Expr := Next (Then_Expr);
if Comes_From_Source (N) then
- Check_SPARK_05_Restriction ("if expression is not allowed", N);
- end if;
-
- if Comes_From_Source (N) then
Check_Compiler_Unit ("if expression", N);
end if;
@@ -2411,7 +2412,10 @@ package body Sem_Ch4 is
procedure Process_Function_Call;
-- Prefix in indexed component form is an overloadable entity, so the
- -- node is a function call. Reformat it as such.
+ -- node is very likely a function call; reformat it as such. The only
+ -- exception is a call to a parameterless function that returns an
+ -- array type, or an access type thereof, in which case this will be
+ -- undone later by Resolve_Call or Resolve_Entry_Call.
procedure Process_Indexed_Component;
-- Prefix in indexed component form is actually an indexed component.
@@ -2522,7 +2526,7 @@ package body Sem_Ch4 is
if Is_Access_Type (Array_Type) then
Error_Msg_NW
(Warn_On_Dereference, "?d?implicit dereference", N);
- Array_Type := Process_Implicit_Dereference_Prefix (Pent, P);
+ Array_Type := Implicitly_Designated_Type (Array_Type);
end if;
if Is_Array_Type (Array_Type) then
@@ -2829,18 +2833,6 @@ package body Sem_Ch4 is
and then Is_Overloadable (Entity (Selector_Name (P)))
then
Process_Function_Call;
-
- -- In ASIS mode within a generic, a prefixed call is analyzed and
- -- partially rewritten but the original indexed component has not
- -- yet been rewritten as a call. Perform the replacement now.
-
- elsif Nkind (P) = N_Selected_Component
- and then Nkind (Parent (P)) = N_Function_Call
- and then ASIS_Mode
- then
- Rewrite (N, Parent (P));
- Analyze (N);
-
else
-- Indexed component, slice, or a call to a member of a family
-- entry, which will be converted to an entry call later.
@@ -3047,6 +3039,8 @@ package body Sem_Ch4 is
end if;
end Analyze_Set_Membership;
+ Op : Node_Id;
+
-- Start of processing for Analyze_Membership_Op
begin
@@ -3093,17 +3087,20 @@ package body Sem_Ch4 is
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));
+ Op := Make_Op_Eq (Loc, Left_Opnd => L, Right_Opnd => R);
else
- Rewrite (N,
- Make_Op_Ne (Loc,
- Left_Opnd => L,
- Right_Opnd => R));
+ Op := Make_Op_Ne (Loc, Left_Opnd => L, Right_Opnd => R);
+ end if;
+
+ if Is_Record_Or_Limited_Type (Etype (L)) then
+
+ -- We reset the Entity in order to use the primitive equality
+ -- of the type, as per RM 4.5.2 (28.1/4).
+
+ Set_Entity (Op, Empty);
end if;
+ Rewrite (N, Op);
Analyze (N);
return;
@@ -3202,8 +3199,6 @@ package body Sem_Ch4 is
procedure Analyze_Null (N : Node_Id) is
begin
- Check_SPARK_05_Restriction ("null is not allowed", N);
-
Set_Etype (N, Any_Access);
end Analyze_Null;
@@ -3282,7 +3277,7 @@ package body Sem_Ch4 is
-- When the type Address is a visible integer type, and the DEC
-- system extension is visible, the predefined operator may be
-- hidden as well, by one of the address operations in auxdec.
- -- Finally, The abstract operations on address do not hide the
+ -- Finally, the abstract operations on address do not hide the
-- predefined operator (this is the purpose of making them abstract).
-----------------------------------
@@ -3294,20 +3289,30 @@ package body Sem_Ch4 is
T2 : Entity_Id) return Boolean
is
function Common_Type (T : Entity_Id) return Entity_Id;
- -- Find non-private full view if any, without going to ancestor type
- -- (as opposed to Underlying_Type).
+ -- Find non-private underlying full view if any, without going to
+ -- ancestor type (as opposed to Underlying_Type).
-----------------
-- Common_Type --
-----------------
function Common_Type (T : Entity_Id) return Entity_Id is
+ CT : Entity_Id;
+
begin
- if Is_Private_Type (T) and then Present (Full_View (T)) then
- return Base_Type (Full_View (T));
- else
- return Base_Type (T);
+ CT := T;
+
+ if Is_Private_Type (CT) and then Present (Full_View (CT)) then
+ CT := Full_View (CT);
+ end if;
+
+ if Is_Private_Type (CT)
+ and then Present (Underlying_Full_View (CT))
+ then
+ CT := Underlying_Full_View (CT);
end if;
+
+ return Base_Type (CT);
end Common_Type;
-- Start of processing for Compatible_Types_In_Predicate
@@ -3770,22 +3775,23 @@ package body Sem_Ch4 is
-- To avoid breaking privacy, Is_Hidden gets set elsewhere on such
-- primitives, but we still need to verify that Nam is indeed a
- -- controlled subprogram. So, we do that here and issue the
- -- appropriate error.
+ -- non-visible controlled subprogram. So, we do that here and issue
+ -- the appropriate error.
if Is_Hidden (Nam)
and then not In_Instance
and then not Comes_From_Source (Nam)
and then Comes_From_Source (N)
- -- Verify Nam is a controlled primitive
+ -- Verify Nam is a non-visible controlled primitive
- and then Nam_In (Chars (Nam), Name_Adjust,
- Name_Finalize,
- Name_Initialize)
+ and then Chars (Nam) in Name_Adjust
+ | Name_Finalize
+ | Name_Initialize
and then Ekind (Nam) = E_Procedure
and then Is_Controlled (Etype (First_Form))
and then No (Next_Formal (First_Form))
+ and then not Is_Visibly_Controlled (Etype (First_Form))
then
Error_Msg_Node_2 := Etype (First_Form);
Error_Msg_NE ("call to non-visible controlled primitive & on type"
@@ -3921,15 +3927,13 @@ package body Sem_Ch4 is
and then Is_Visible_Component (Comp, Sel)
then
- -- AI05-105: if the context is an object renaming with
+ -- AI05-105: if the context is an object renaming with
-- an anonymous access type, the expected type of the
-- object must be anonymous. This is a name resolution rule.
if Nkind (Parent (N)) /= N_Object_Renaming_Declaration
or else No (Access_Definition (Parent (N)))
- or else Ekind (Etype (Comp)) = E_Anonymous_Access_Type
- or else
- Ekind (Etype (Comp)) = E_Anonymous_Access_Subprogram_Type
+ or else Is_Anonymous_Access_Type (Etype (Comp))
then
Set_Entity (Sel, Comp);
Set_Etype (Sel, Etype (Comp));
@@ -3971,18 +3975,6 @@ package body Sem_Ch4 is
Set_Etype (Sel, Etype (Comp));
Set_Etype (N, Etype (Comp));
Set_Etype (Nam, It.Typ);
-
- -- For access type case, introduce explicit dereference for
- -- more uniform treatment of entry calls. Do this only once
- -- if several interpretations yield an access type.
-
- if Is_Access_Type (Etype (Nam))
- and then Nkind (Nam) /= N_Explicit_Dereference
- then
- Insert_Explicit_Dereference (Nam);
- Error_Msg_NW
- (Warn_On_Dereference, "?d?implicit dereference", N);
- end if;
end if;
Next_Entity (Comp);
@@ -4021,14 +4013,15 @@ package body Sem_Ch4 is
Find_Type (Mark);
T := Entity (Mark);
- if Nkind_In (Enclosing_Declaration (N), N_Formal_Type_Declaration,
- N_Full_Type_Declaration,
- N_Incomplete_Type_Declaration,
- N_Protected_Type_Declaration,
- N_Private_Extension_Declaration,
- N_Private_Type_Declaration,
- N_Subtype_Declaration,
- N_Task_Type_Declaration)
+ if Nkind (Enclosing_Declaration (N)) in
+ N_Formal_Type_Declaration |
+ N_Full_Type_Declaration |
+ N_Incomplete_Type_Declaration |
+ N_Protected_Type_Declaration |
+ N_Private_Extension_Declaration |
+ N_Private_Type_Declaration |
+ N_Subtype_Declaration |
+ N_Task_Type_Declaration
and then T = Defining_Identifier (Enclosing_Declaration (N))
then
Error_Msg_N ("current instance not allowed", Mark);
@@ -4151,8 +4144,6 @@ package body Sem_Ch4 is
-- Start of processing for Analyze_Quantified_Expression
begin
- Check_SPARK_05_Restriction ("quantified expression is not allowed", N);
-
-- Create a scope to emulate the loop-like behavior of the quantified
-- expression. The scope is needed to provide proper visibility of the
-- loop variable.
@@ -4197,6 +4188,7 @@ package body Sem_Ch4 is
-- reflect the right kind. This is needed for proper ASIS
-- navigation. If expansion is enabled, the transformation is
-- performed when the expression is rewritten as a loop.
+ -- Is this still needed???
Set_Iterator_Specification (N,
New_Copy_Tree (Iterator_Specification (Parent (Loop_Par))));
@@ -4453,7 +4445,6 @@ package body Sem_Ch4 is
In_Scope : Boolean;
Is_Private_Op : Boolean;
Parent_N : Node_Id;
- Pent : Entity_Id := Empty;
Prefix_Type : Entity_Id;
Type_To_Use : Entity_Id;
@@ -4482,7 +4473,15 @@ package body Sem_Ch4 is
-- indexed component rather than a function call.
function Has_Dereference (Nod : Node_Id) return Boolean;
- -- Check whether prefix includes a dereference at any level.
+ -- Check whether prefix includes a dereference, explicit or implicit,
+ -- at any recursive level.
+
+ function Try_By_Protected_Procedure_Prefixed_View return Boolean;
+ -- Return True if N is an access attribute whose prefix is a prefixed
+ -- class-wide (synchronized or protected) interface view for which some
+ -- interpretation is a procedure with synchronization kind By_Protected
+ -- _Procedure, and collect all its interpretations (since it may be an
+ -- overloaded interface primitive); otherwise return False.
--------------------------------
-- Find_Component_In_Instance --
@@ -4594,14 +4593,10 @@ package body Sem_Ch4 is
if Nkind (Nod) = N_Explicit_Dereference then
return True;
- -- When expansion is disabled an explicit dereference may not have
- -- been inserted, but if this is an access type the indirection makes
- -- the call safe.
-
elsif Is_Access_Type (Etype (Nod)) then
return True;
- elsif Nkind_In (Nod, N_Indexed_Component, N_Selected_Component) then
+ elsif Nkind (Nod) in N_Indexed_Component | N_Selected_Component then
return Has_Dereference (Prefix (Nod));
else
@@ -4609,6 +4604,65 @@ package body Sem_Ch4 is
end if;
end Has_Dereference;
+ ----------------------------------------------
+ -- Try_By_Protected_Procedure_Prefixed_View --
+ ----------------------------------------------
+
+ function Try_By_Protected_Procedure_Prefixed_View return Boolean is
+ Candidate : Node_Id := Empty;
+ Elmt : Elmt_Id;
+ Prim : Node_Id;
+
+ begin
+ if Nkind (Parent (N)) = N_Attribute_Reference
+ and then Attribute_Name (Parent (N)) in
+ Name_Access
+ | Name_Unchecked_Access
+ | Name_Unrestricted_Access
+ and then Is_Class_Wide_Type (Prefix_Type)
+ and then (Is_Synchronized_Interface (Prefix_Type)
+ or else Is_Protected_Interface (Prefix_Type))
+ then
+ -- If we have not found yet any interpretation then mark this
+ -- one as the first interpretation (cf. Add_One_Interp).
+
+ if No (Etype (Sel)) then
+ Set_Etype (Sel, Any_Type);
+ end if;
+
+ Elmt := First_Elmt (Primitive_Operations (Etype (Prefix_Type)));
+ while Present (Elmt) loop
+ Prim := Node (Elmt);
+
+ if Chars (Prim) = Chars (Sel)
+ and then Is_By_Protected_Procedure (Prim)
+ then
+ Candidate := New_Copy (Prim);
+
+ -- Skip the controlling formal; required to check type
+ -- conformance of the target access to protected type
+ -- (see Conforming_Types).
+
+ Set_First_Entity (Candidate,
+ Next_Entity (First_Entity (Prim)));
+
+ Add_One_Interp (Sel, Candidate, Etype (Prim));
+ Set_Etype (N, Etype (Prim));
+ end if;
+
+ Next_Elmt (Elmt);
+ end loop;
+ end if;
+
+ -- Propagate overloaded attribute
+
+ if Present (Candidate) and then Is_Overloaded (Sel) then
+ Set_Is_Overloaded (N);
+ end if;
+
+ return Present (Candidate);
+ end Try_By_Protected_Procedure_Prefixed_View;
+
-- Start of processing for Analyze_Selected_Component
begin
@@ -4650,16 +4704,7 @@ package body Sem_Ch4 is
else
Error_Msg_NW (Warn_On_Dereference, "?d?implicit dereference", N);
-
- if Is_Entity_Name (Name) then
- Pent := Entity (Name);
- elsif Nkind (Name) = N_Selected_Component
- and then Is_Entity_Name (Selector_Name (Name))
- then
- Pent := Entity (Selector_Name (Name));
- end if;
-
- Prefix_Type := Process_Implicit_Dereference_Prefix (Pent, Name);
+ Prefix_Type := Implicitly_Designated_Type (Prefix_Type);
end if;
-- If we have an explicit dereference of a remote access-to-class-wide
@@ -4747,11 +4792,6 @@ package body Sem_Ch4 is
Set_Etype (N, Etype (Comp));
Check_Implicit_Dereference (N, Etype (Comp));
- if Is_Access_Type (Etype (Name)) then
- Insert_Explicit_Dereference (Name);
- Error_Msg_NW (Warn_On_Dereference, "?d?implicit dereference", N);
- end if;
-
elsif Is_Record_Type (Prefix_Type) then
-- Find component with given name. In an instance, if the node is
@@ -4833,10 +4873,10 @@ package body Sem_Ch4 is
or else
(Nkind (Parent_N) = N_Attribute_Reference
and then
- Nam_In (Attribute_Name (Parent_N), Name_First,
- Name_Last,
- Name_Length,
- Name_Range)))
+ Attribute_Name (Parent_N) in Name_First
+ | Name_Last
+ | Name_Length
+ | Name_Range))
then
Set_Etype (N, Etype (Comp));
@@ -4918,6 +4958,9 @@ package body Sem_Ch4 is
return;
end if;
+ elsif Try_By_Protected_Procedure_Prefixed_View then
+ return;
+
elsif Try_Object_Operation (N) then
return;
end if;
@@ -5014,9 +5057,9 @@ package body Sem_Ch4 is
-- a visible entity is found.
if Is_Tagged_Type (Prefix_Type)
- and then Nkind_In (Parent (N), N_Function_Call,
- N_Indexed_Component,
- N_Procedure_Call_Statement)
+ and then Nkind (Parent (N)) in N_Function_Call
+ | N_Indexed_Component
+ | N_Procedure_Call_Statement
and then Has_Mode_Conformant_Spec (Comp)
then
Has_Candidate := True;
@@ -5025,7 +5068,7 @@ package body Sem_Ch4 is
-- Note: a selected component may not denote a component of a
-- protected type (4.1.3(7)).
- elsif Ekind_In (Comp, E_Discriminant, E_Entry_Family)
+ elsif Ekind (Comp) in E_Discriminant | E_Entry_Family
or else (In_Scope
and then not Is_Protected_Type (Prefix_Type)
and then Is_Entity_Name (Name))
@@ -5052,15 +5095,6 @@ package body Sem_Ch4 is
if Ekind (Comp) = E_Discriminant then
Set_Original_Discriminant (Sel, Comp);
end if;
-
- -- For access type case, introduce explicit dereference for
- -- more uniform treatment of entry calls.
-
- if Is_Access_Type (Etype (Name)) then
- Insert_Explicit_Dereference (Name);
- Error_Msg_NW
- (Warn_On_Dereference, "?d?implicit dereference", N);
- end if;
end if;
<<Next_Comp>>
@@ -5112,7 +5146,7 @@ package body Sem_Ch4 is
then
if Is_Task_Type (Prefix_Type)
and then Present (Entity (Sel))
- and then Ekind_In (Entity (Sel), E_Entry, E_Entry_Family)
+ and then Is_Entry (Entity (Sel))
then
null;
@@ -5302,24 +5336,21 @@ package body Sem_Ch4 is
end loop;
-- Another special case: the type is an extension of a private
- -- type T, is an actual in an instance, and we are in the body
- -- of the instance, so the generic body had a full view of the
- -- type declaration for T or of some ancestor that defines the
- -- component in question.
+ -- type T, either is an actual in an instance or is immediately
+ -- visible, and we are in the body of the instance, which means
+ -- the generic body had a full view of the type declaration for
+ -- T or some ancestor that defines the component in question.
+ -- This happens because Is_Visible_Component returned False on
+ -- this component, as T or the ancestor is still private since
+ -- the Has_Private_View mechanism is bypassed because T or the
+ -- ancestor is not directly referenced in the generic body.
elsif Is_Derived_Type (Type_To_Use)
- and then Used_As_Generic_Actual (Type_To_Use)
+ and then (Used_As_Generic_Actual (Type_To_Use)
+ or else Is_Immediately_Visible (Type_To_Use))
and then In_Instance_Body
then
Find_Component_In_Instance (Parent_Subtype (Type_To_Use));
-
- -- In ASIS mode the generic parent type may be absent. Examine
- -- the parent type directly for a component that may have been
- -- visible in a parent generic unit.
-
- elsif Is_Derived_Type (Prefix_Type) then
- Par := Etype (Prefix_Type);
- Find_Component_In_Instance (Par);
end if;
end;
@@ -5517,10 +5548,6 @@ package body Sem_Ch4 is
-- Start of processing for Analyze_Slice
begin
- if Comes_From_Source (N) then
- Check_SPARK_05_Restriction ("slice is not allowed", N);
- end if;
-
Analyze (P);
Analyze (D);
@@ -5532,8 +5559,8 @@ package body Sem_Ch4 is
Set_Etype (N, Any_Type);
if Is_Access_Type (Array_Type) then
- Array_Type := Designated_Type (Array_Type);
Error_Msg_NW (Warn_On_Dereference, "?d?implicit dereference", N);
+ Array_Type := Implicitly_Designated_Type (Array_Type);
end if;
if not Is_Array_Type (Array_Type) then
@@ -5630,9 +5657,9 @@ package body Sem_Ch4 is
end if;
elsif Nkind (Expr) = N_Attribute_Reference
- and then Nam_In (Attribute_Name (Expr), Name_Access,
- Name_Unchecked_Access,
- Name_Unrestricted_Access)
+ and then Attribute_Name (Expr) in Name_Access
+ | Name_Unchecked_Access
+ | Name_Unrestricted_Access
then
Error_Msg_N ("argument of conversion cannot be access", N);
Error_Msg_N ("\use qualified expression instead", N);
@@ -5721,54 +5748,47 @@ package body Sem_Ch4 is
procedure Analyze_User_Defined_Binary_Op
(N : Node_Id;
- Op_Id : Entity_Id)
- is
+ Op_Id : Entity_Id) is
begin
- -- Only do analysis if the operator Comes_From_Source, since otherwise
- -- the operator was generated by the expander, and all such operators
- -- always refer to the operators in package Standard.
-
- if Comes_From_Source (N) then
- declare
- F1 : constant Entity_Id := First_Formal (Op_Id);
- F2 : constant Entity_Id := Next_Formal (F1);
-
- begin
- -- Verify that Op_Id is a visible binary function. Note that since
- -- we know Op_Id is overloaded, potentially use visible means use
- -- visible for sure (RM 9.4(11)).
+ declare
+ F1 : constant Entity_Id := First_Formal (Op_Id);
+ F2 : constant Entity_Id := Next_Formal (F1);
- if Ekind (Op_Id) = E_Function
- and then Present (F2)
- and then (Is_Immediately_Visible (Op_Id)
- or else Is_Potentially_Use_Visible (Op_Id))
- and then Has_Compatible_Type (Left_Opnd (N), Etype (F1))
- and then Has_Compatible_Type (Right_Opnd (N), Etype (F2))
- then
- Add_One_Interp (N, Op_Id, Etype (Op_Id));
+ begin
+ -- Verify that Op_Id is a visible binary function. Note that since
+ -- we know Op_Id is overloaded, potentially use visible means use
+ -- visible for sure (RM 9.4(11)).
+
+ if Ekind (Op_Id) = E_Function
+ and then Present (F2)
+ and then (Is_Immediately_Visible (Op_Id)
+ or else Is_Potentially_Use_Visible (Op_Id))
+ and then Has_Compatible_Type (Left_Opnd (N), Etype (F1))
+ and then Has_Compatible_Type (Right_Opnd (N), Etype (F2))
+ then
+ Add_One_Interp (N, Op_Id, Etype (Op_Id));
- -- If the left operand is overloaded, indicate that the current
- -- type is a viable candidate. This is redundant in most cases,
- -- but for equality and comparison operators where the context
- -- does not impose a type on the operands, setting the proper
- -- type is necessary to avoid subsequent ambiguities during
- -- resolution, when both user-defined and predefined operators
- -- may be candidates.
+ -- If the left operand is overloaded, indicate that the current
+ -- type is a viable candidate. This is redundant in most cases,
+ -- but for equality and comparison operators where the context
+ -- does not impose a type on the operands, setting the proper
+ -- type is necessary to avoid subsequent ambiguities during
+ -- resolution, when both user-defined and predefined operators
+ -- may be candidates.
- if Is_Overloaded (Left_Opnd (N)) then
- Set_Etype (Left_Opnd (N), Etype (F1));
- end if;
+ if Is_Overloaded (Left_Opnd (N)) then
+ Set_Etype (Left_Opnd (N), Etype (F1));
+ end if;
- if Debug_Flag_E then
- Write_Str ("user defined operator ");
- Write_Name (Chars (Op_Id));
- Write_Str (" on node ");
- Write_Int (Int (N));
- Write_Eol;
- end if;
+ if Debug_Flag_E then
+ Write_Str ("user defined operator ");
+ Write_Name (Chars (Op_Id));
+ Write_Str (" on node ");
+ Write_Int (Int (N));
+ Write_Eol;
end if;
- end;
- end if;
+ end if;
+ end;
end Analyze_User_Defined_Binary_Op;
-----------------------------------
@@ -5901,7 +5921,7 @@ package body Sem_Ch4 is
-- Start of processing for Check_Arithmetic_Pair
begin
- if Nam_In (Op_Name, Name_Op_Add, Name_Op_Subtract) then
+ if Op_Name in Name_Op_Add | Name_Op_Subtract then
if Is_Numeric_Type (T1)
and then Is_Numeric_Type (T2)
and then (Covers (T1 => T1, T2 => T2)
@@ -5911,29 +5931,19 @@ package body Sem_Ch4 is
Add_One_Interp (N, Op_Id, Specific_Type (T1, T2));
end if;
- elsif Nam_In (Op_Name, Name_Op_Multiply, Name_Op_Divide) then
+ elsif Op_Name in Name_Op_Multiply | Name_Op_Divide then
if Is_Fixed_Point_Type (T1)
and then (Is_Fixed_Point_Type (T2) or else T2 = Universal_Real)
then
- -- If Treat_Fixed_As_Integer is set then the Etype is already set
- -- and no further processing is required (this is the case of an
- -- operator constructed by Exp_Fixd for a fixed point operation)
- -- Otherwise add one interpretation with universal fixed result
- -- If the operator is given in functional notation, it comes
- -- from source and Fixed_As_Integer cannot apply.
-
- if (Nkind (N) not in N_Op
- or else not Treat_Fixed_As_Integer (N))
- and then
- (not Has_Fixed_Op (T1, Op_Id)
- or else Nkind (Parent (N)) = N_Type_Conversion)
+ -- Add one interpretation with universal fixed result
+
+ if not Has_Fixed_Op (T1, Op_Id)
+ or else Nkind (Parent (N)) = N_Type_Conversion
then
Add_One_Interp (N, Op_Id, Universal_Fixed);
end if;
elsif Is_Fixed_Point_Type (T2)
- and then (Nkind (N) not in N_Op
- or else not Treat_Fixed_As_Integer (N))
and then T1 = Universal_Real
and then
(not Has_Fixed_Op (T1, Op_Id)
@@ -5985,10 +5995,6 @@ package body Sem_Ch4 is
elsif Op_Name = Name_Op_Mod or else Op_Name = Name_Op_Rem then
- -- Note: The fixed-point operands case with Treat_Fixed_As_Integer
- -- set does not require any special processing, since the Etype is
- -- already set (case of operation constructed by Exp_Fixed).
-
if Is_Integer_Type (T1)
and then (Covers (T1 => T1, T2 => T2)
or else
@@ -6051,7 +6057,7 @@ package body Sem_Ch4 is
return;
end if;
- Comp := First_Entity (Prefix);
+ Comp := First_Entity (Prefix);
while Nr_Of_Suggestions <= Max_Suggestions and then Present (Comp) loop
if Is_Visible_Component (Comp, Sel) then
if Is_Bad_Spelling_Of (Chars (Comp), Chars (Sel)) then
@@ -6065,7 +6071,7 @@ package body Sem_Ch4 is
end if;
end if;
- Comp := Next_Entity (Comp);
+ Next_Entity (Comp);
end loop;
-- Report at most two suggestions
@@ -6223,7 +6229,7 @@ package body Sem_Ch4 is
else
while Present (It.Nam) loop
- if Ekind_In (It.Nam, E_Function, E_Operator) then
+ if Ekind (It.Nam) in E_Function | E_Operator then
return;
else
Get_Next_Interp (X, It);
@@ -6598,12 +6604,44 @@ package body Sem_Ch4 is
Op_Id : Entity_Id;
N : Node_Id)
is
- Index : Interp_Index;
- It : Interp;
- Found : Boolean := False;
- I_F : Interp_Index;
- T_F : Entity_Id;
- Scop : Entity_Id := Empty;
+ Index : Interp_Index := 0;
+ It : Interp;
+ Found : Boolean := False;
+ Is_Universal_Access : Boolean := False;
+ I_F : Interp_Index;
+ T_F : Entity_Id;
+ Scop : Entity_Id := Empty;
+
+ procedure Check_Access_Attribute (N : Node_Id);
+ -- For any object, '[Unchecked_]Access of such object can never be
+ -- passed as a parameter of a call to the Universal_Access equality
+ -- operator.
+ -- This is because the expected type for Obj'Access in a call to
+ -- the Standard."=" operator whose formals are of type
+ -- Universal_Access is Universal_Integer, and Universal_Access
+ -- doesn't have a designated type. For more detail see RM 6.4.1(3)
+ -- and 3.10.2.
+ -- This procedure assumes that the context is a universal_access.
+
+ function Check_Access_Object_Types
+ (N : Node_Id; Typ : Entity_Id) return Boolean;
+ -- Check for RM 4.5.2 (9.6/2): When both are of access-to-object types,
+ -- the designated types shall be the same or one shall cover the other,
+ -- and if the designated types are elementary or array types, then the
+ -- designated subtypes shall statically match.
+ -- If N is not overloaded, then its unique type must be compatible as
+ -- per above. Otherwise iterate through the interpretations of N looking
+ -- for a compatible one.
+
+ procedure Check_Compatible_Profiles (N : Node_Id; Typ : Entity_Id);
+ -- Check for RM 4.5.2(9.7/2): When both are of access-to-subprogram
+ -- types, the designated profiles shall be subtype conformant.
+
+ function References_Anonymous_Access_Type
+ (N : Node_Id; Typ : Entity_Id) return Boolean;
+ -- Return True either if N is not overloaded and its Etype is an
+ -- anonymous access type or if one of the interpretations of N refers
+ -- to an anonymous access type compatible with Typ.
procedure Try_One_Interp (T1 : Entity_Id);
-- The context of the equality operator plays no role in resolving the
@@ -6612,12 +6650,198 @@ package body Sem_Ch4 is
-- and an error can be emitted now, after trying to disambiguate, i.e.
-- applying preference rules.
+ ----------------------------
+ -- Check_Access_Attribute --
+ ----------------------------
+
+ procedure Check_Access_Attribute (N : Node_Id) is
+ begin
+ if Nkind (N) = N_Attribute_Reference
+ and then Attribute_Name (N) in Name_Access | Name_Unchecked_Access
+ then
+ Error_Msg_N
+ ("access attribute cannot be used as actual for "
+ & "universal_access equality", N);
+ end if;
+ end Check_Access_Attribute;
+
+ -------------------------------
+ -- Check_Access_Object_Types --
+ -------------------------------
+
+ function Check_Access_Object_Types
+ (N : Node_Id; Typ : Entity_Id) return Boolean
+ is
+ function Check_Designated_Types (DT1, DT2 : Entity_Id) return Boolean;
+ -- Check RM 4.5.2 (9.6/2) on the given designated types.
+
+ ----------------------------
+ -- Check_Designated_Types --
+ ----------------------------
+
+ function Check_Designated_Types
+ (DT1, DT2 : Entity_Id) return Boolean is
+ begin
+ -- If the designated types are elementary or array types, then
+ -- the designated subtypes shall statically match.
+
+ if Is_Elementary_Type (DT1) or else Is_Array_Type (DT1) then
+ if Base_Type (DT1) /= Base_Type (DT2) then
+ return False;
+ else
+ return Subtypes_Statically_Match (DT1, DT2);
+ end if;
+
+ -- Otherwise, the designated types shall be the same or one
+ -- shall cover the other.
+
+ else
+ return DT1 = DT2
+ or else Covers (DT1, DT2)
+ or else Covers (DT2, DT1);
+ end if;
+ end Check_Designated_Types;
+
+ -- Start of processing for Check_Access_Object_Types
+
+ begin
+ -- Return immediately with no checks if Typ is not an
+ -- access-to-object type.
+
+ if not Is_Access_Object_Type (Typ) then
+ return True;
+
+ -- Any_Type is compatible with all types in this context, and is used
+ -- in particular for the designated type of a 'null' value.
+
+ elsif Directly_Designated_Type (Typ) = Any_Type
+ or else Nkind (N) = N_Null
+ then
+ return True;
+ end if;
+
+ if not Is_Overloaded (N) then
+ if Is_Access_Object_Type (Etype (N)) then
+ return Check_Designated_Types
+ (Designated_Type (Typ), Designated_Type (Etype (N)));
+ end if;
+ else
+ declare
+ Typ_Is_Anonymous : constant Boolean :=
+ Is_Anonymous_Access_Type (Typ);
+
+ I : Interp_Index;
+ It : Interp;
+
+ begin
+ Get_First_Interp (N, I, It);
+ while Present (It.Typ) loop
+
+ -- The check on designated types if only relevant when one
+ -- of the types is anonymous, ignore other (non relevant)
+ -- types.
+
+ if (Typ_Is_Anonymous
+ or else Is_Anonymous_Access_Type (It.Typ))
+ and then Is_Access_Object_Type (It.Typ)
+ then
+ if Check_Designated_Types
+ (Designated_Type (Typ), Designated_Type (It.Typ))
+ then
+ return True;
+ end if;
+ end if;
+
+ Get_Next_Interp (I, It);
+ end loop;
+ end;
+ end if;
+
+ return False;
+ end Check_Access_Object_Types;
+
+ -------------------------------
+ -- Check_Compatible_Profiles --
+ -------------------------------
+
+ procedure Check_Compatible_Profiles (N : Node_Id; Typ : Entity_Id) is
+ I : Interp_Index;
+ It : Interp;
+ I1 : Interp_Index := 0;
+ Found : Boolean := False;
+ Tmp : Entity_Id := Empty;
+
+ begin
+ if not Is_Overloaded (N) then
+ Check_Subtype_Conformant
+ (Designated_Type (Etype (N)), Designated_Type (Typ), N);
+ else
+ Get_First_Interp (N, I, It);
+ while Present (It.Typ) loop
+ if Is_Access_Subprogram_Type (It.Typ) then
+ if not Found then
+ Found := True;
+ Tmp := It.Typ;
+ I1 := I;
+
+ else
+ It := Disambiguate (N, I1, I, Any_Type);
+
+ if It /= No_Interp then
+ Tmp := It.Typ;
+ I1 := I;
+ else
+ Found := False;
+ exit;
+ end if;
+ end if;
+ end if;
+
+ Get_Next_Interp (I, It);
+ end loop;
+
+ if Found then
+ Check_Subtype_Conformant
+ (Designated_Type (Tmp), Designated_Type (Typ), N);
+ end if;
+ end if;
+ end Check_Compatible_Profiles;
+
+ --------------------------------------
+ -- References_Anonymous_Access_Type --
+ --------------------------------------
+
+ function References_Anonymous_Access_Type
+ (N : Node_Id; Typ : Entity_Id) return Boolean
+ is
+ I : Interp_Index;
+ It : Interp;
+ begin
+ if not Is_Overloaded (N) then
+ return Is_Anonymous_Access_Type (Etype (N));
+ else
+ Get_First_Interp (N, I, It);
+ while Present (It.Typ) loop
+ if Is_Anonymous_Access_Type (It.Typ)
+ and then (Covers (It.Typ, Typ) or else Covers (Typ, It.Typ))
+ then
+ return True;
+ end if;
+
+ Get_Next_Interp (I, It);
+ end loop;
+
+ return False;
+ end if;
+ end References_Anonymous_Access_Type;
+
--------------------
-- Try_One_Interp --
--------------------
procedure Try_One_Interp (T1 : Entity_Id) is
- Bas : Entity_Id;
+ Universal_Access : Boolean;
+ Bas : Entity_Id;
begin
-- Perform a sanity check in case of previous errors
@@ -6637,6 +6861,9 @@ package body Sem_Ch4 is
-- In Ada 2005, the equality operator for anonymous access types
-- is declared in Standard, and preference rules apply to it.
+ Universal_Access := Is_Anonymous_Access_Type (T1)
+ or else References_Anonymous_Access_Type (R, T1);
+
if Present (Scop) then
-- Note that we avoid returning if we are currently within a
@@ -6657,48 +6884,28 @@ package body Sem_Ch4 is
then
null;
- elsif Ekind (T1) = E_Anonymous_Access_Type
- and then Scop = Standard_Standard
- then
- null;
+ elsif Scop /= Standard_Standard or else not Universal_Access then
- else
-- The scope does not contain an operator for the type
return;
end if;
-- If we have infix notation, the operator must be usable. Within
- -- an instance, if the type is already established we know it is
- -- correct. If an operand is universal it is compatible with any
- -- numeric type.
+ -- an instance, the type may have been immediately visible if the
+ -- types are compatible.
elsif In_Open_Scopes (Scope (Bas))
or else Is_Potentially_Use_Visible (Bas)
or else In_Use (Bas)
or else (In_Use (Scope (Bas)) and then not Is_Hidden (Bas))
-
- -- In an instance, the type may have been immediately visible.
- -- Either the types are compatible, or one operand is universal
- -- (numeric or null).
-
or else
((In_Instance or else In_Inlined_Body)
- and then
- (First_Subtype (T1) = First_Subtype (Etype (R))
- or else Nkind (R) = N_Null
- or else
- (Is_Numeric_Type (T1)
- and then Is_Universal_Numeric_Type (Etype (R)))))
-
- -- In Ada 2005, the equality on anonymous access types is declared
- -- in Standard, and is always visible.
-
- or else Ekind (T1) = E_Anonymous_Access_Type
+ and then Has_Compatible_Type (R, T1))
then
null;
- else
+ elsif not Universal_Access then
-- Save candidate type for subsequent error message, if any
if not Is_Limited_Type (T1) then
@@ -6711,9 +6918,7 @@ 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_2005
- and then Ekind (T1) = E_Anonymous_Access_Type
- then
+ if Ada_Version < Ada_2005 and then Universal_Access then
return;
end if;
@@ -6725,15 +6930,16 @@ package body Sem_Ch4 is
-- in Standard to be chosen, and the "/=" will be rewritten as a
-- negation of "=" (see the end of Analyze_Equality_Op). This ensures
-- that rewriting happens during analysis rather than being
- -- delayed until expansion (this is needed for ASIS, which only sees
- -- the unexpanded tree). Note that if the node is N_Op_Ne, but Op_Id
+ -- delayed until expansion (is this still needed now that ASIS mode
+ -- is gone???). Note that if the node is N_Op_Ne, but Op_Id
-- is Name_Op_Eq then we still proceed with the interpretation,
-- because that indicates the potential rewriting case where the
-- interpretation to consider is actually "=" and the node may be
-- about to be rewritten by Analyze_Equality_Op.
+ -- Finally, also check for RM 4.5.2 (9.6/2).
if T1 /= Standard_Void_Type
- and then Has_Compatible_Type (R, T1)
+ and then (Universal_Access or else Has_Compatible_Type (R, T1))
and then
((not Is_Limited_Type (T1)
@@ -6748,6 +6954,9 @@ package body Sem_Ch4 is
(Nkind (N) /= N_Op_Ne
or else not Is_Tagged_Type (T1)
or else Chars (Op_Id) = Name_Op_Eq)
+
+ and then (not Universal_Access
+ or else Check_Access_Object_Types (R, T1))
then
if Found
and then Base_Type (T1) /= Base_Type (T_F)
@@ -6761,12 +6970,14 @@ package body Sem_Ch4 is
else
T_F := It.Typ;
+ Is_Universal_Access := Universal_Access;
end if;
else
Found := True;
T_F := T1;
I_F := Index;
+ Is_Universal_Access := Universal_Access;
end if;
if not Analyzed (L) then
@@ -6780,11 +6991,6 @@ package body Sem_Ch4 is
if Etype (N) = Any_Type then
Found := False;
end if;
-
- elsif Scop = Standard_Standard
- and then Ekind (T1) = E_Anonymous_Access_Type
- then
- Found := True;
end if;
end Try_One_Interp;
@@ -6819,7 +7025,6 @@ package body Sem_Ch4 is
if not Is_Overloaded (L) then
Try_One_Interp (Etype (L));
-
else
Get_First_Interp (L, Index, It);
while Present (It.Typ) loop
@@ -6827,6 +7032,18 @@ package body Sem_Ch4 is
Get_Next_Interp (Index, It);
end loop;
end if;
+
+ if Is_Universal_Access then
+ if Is_Access_Subprogram_Type (Etype (L))
+ and then Nkind (L) /= N_Null
+ and then Nkind (R) /= N_Null
+ then
+ Check_Compatible_Profiles (R, Etype (L));
+ end if;
+
+ Check_Access_Attribute (R);
+ Check_Access_Attribute (L);
+ end if;
end Find_Equality_Types;
-------------------------
@@ -7182,7 +7399,7 @@ package body Sem_Ch4 is
-- pretty much know that the other operand should be Boolean, so
-- resolve it that way (generating an error).
- elsif Nkind_In (N, N_Op_And, N_Op_Or, N_Op_Xor) then
+ elsif Nkind (N) in N_Op_And | N_Op_Or | N_Op_Xor then
if Etype (L) = Standard_Boolean then
Resolve (R, Standard_Boolean);
return;
@@ -7196,17 +7413,16 @@ package body Sem_Ch4 is
-- is not the same numeric type. If it is a non-numeric type,
-- then probably it is intended to match the other operand.
- elsif Nkind_In (N, N_Op_Add,
- N_Op_Divide,
- N_Op_Ge,
- N_Op_Gt,
- N_Op_Le)
- or else
- Nkind_In (N, N_Op_Lt,
- N_Op_Mod,
- N_Op_Multiply,
- N_Op_Rem,
- N_Op_Subtract)
+ elsif Nkind (N) in N_Op_Add
+ | N_Op_Divide
+ | N_Op_Ge
+ | N_Op_Gt
+ | N_Op_Le
+ | N_Op_Lt
+ | N_Op_Mod
+ | N_Op_Multiply
+ | N_Op_Rem
+ | N_Op_Subtract
then
-- If Allow_Integer_Address is active, check whether the
-- operation becomes legal after converting an operand.
@@ -7215,10 +7431,14 @@ package body Sem_Ch4 is
and then not Is_Numeric_Type (Etype (R))
then
if Address_Integer_Convert_OK (Etype (R), Etype (L)) then
+ Rewrite (L,
+ Unchecked_Convert_To (
+ Standard_Address, Relocate_Node (L)));
Rewrite (R,
- Unchecked_Convert_To (Etype (L), Relocate_Node (R)));
+ Unchecked_Convert_To (
+ Standard_Address, Relocate_Node (R)));
- if Nkind_In (N, N_Op_Ge, N_Op_Gt, N_Op_Le, N_Op_Lt) then
+ if Nkind (N) in N_Op_Ge | N_Op_Gt | N_Op_Le | N_Op_Lt then
Analyze_Comparison_Op (N);
else
Analyze_Arithmetic_Op (N);
@@ -7234,9 +7454,13 @@ package body Sem_Ch4 is
then
if Address_Integer_Convert_OK (Etype (L), Etype (R)) then
Rewrite (L,
- Unchecked_Convert_To (Etype (R), Relocate_Node (L)));
+ Unchecked_Convert_To (
+ Standard_Address, Relocate_Node (L)));
+ Rewrite (R,
+ Unchecked_Convert_To (
+ Standard_Address, Relocate_Node (R)));
- if Nkind_In (N, N_Op_Ge, N_Op_Gt, N_Op_Le, N_Op_Lt) then
+ if Nkind (N) in N_Op_Ge | N_Op_Gt | N_Op_Le | N_Op_Lt then
Analyze_Comparison_Op (N);
else
Analyze_Arithmetic_Op (N);
@@ -7261,12 +7485,12 @@ package body Sem_Ch4 is
begin
Rewrite (L,
Unchecked_Convert_To (
- Standard_Integer, Relocate_Node (L)));
+ Standard_Address, Relocate_Node (L)));
Rewrite (R,
Unchecked_Convert_To (
- Standard_Integer, Relocate_Node (R)));
+ Standard_Address, Relocate_Node (R)));
- if Nkind_In (N, N_Op_Ge, N_Op_Gt, N_Op_Le, N_Op_Lt) then
+ if Nkind (N) in N_Op_Ge | N_Op_Gt | N_Op_Le | N_Op_Lt then
Analyze_Comparison_Op (N);
else
Analyze_Arithmetic_Op (N);
@@ -7290,7 +7514,7 @@ package body Sem_Ch4 is
elsif Null_To_Null_Address_Convert_OK (N) then
Replace_Null_By_Null_Address (N);
- if Nkind_In (N, N_Op_Ge, N_Op_Gt, N_Op_Le, N_Op_Lt) then
+ if Nkind (N) in N_Op_Ge | N_Op_Gt | N_Op_Le | N_Op_Lt then
Analyze_Comparison_Op (N);
else
Analyze_Arithmetic_Op (N);
@@ -7302,7 +7526,7 @@ package body Sem_Ch4 is
-- Comparisons on A'Access are common enough to deserve a
-- special message.
- elsif Nkind_In (N, N_Op_Eq, N_Op_Ne)
+ elsif Nkind (N) in N_Op_Eq | N_Op_Ne
and then Ekind (Etype (L)) = E_Access_Attribute_Type
and then Ekind (Etype (R)) = E_Access_Attribute_Type
then
@@ -7360,10 +7584,14 @@ package body Sem_Ch4 is
return;
- elsif Nkind_In (N, N_Op_Eq, N_Op_Ne) then
+ elsif Nkind (N) in N_Op_Eq | N_Op_Ne then
if Address_Integer_Convert_OK (Etype (R), Etype (L)) then
+ Rewrite (L,
+ Unchecked_Convert_To (
+ Standard_Address, Relocate_Node (L)));
Rewrite (R,
- Unchecked_Convert_To (Etype (L), Relocate_Node (R)));
+ Unchecked_Convert_To (
+ Standard_Address, Relocate_Node (R)));
Analyze_Equality_Op (N);
return;
@@ -7447,7 +7675,7 @@ package body Sem_Ch4 is
-- indicate that the integer operand should be of
-- type Integer.
- if Nkind_In (N, N_Op_Multiply, N_Op_Divide)
+ if Nkind (N) in N_Op_Multiply | N_Op_Divide
and then Is_Fixed_Point_Type (Etype (L))
and then Is_Integer_Type (Etype (R))
then
@@ -7481,48 +7709,6 @@ package body Sem_Ch4 is
end if;
end Operator_Check;
- -----------------------------------------
- -- Process_Implicit_Dereference_Prefix --
- -----------------------------------------
-
- function Process_Implicit_Dereference_Prefix
- (E : Entity_Id;
- P : Entity_Id) return Entity_Id
- is
- Ref : Node_Id;
- Typ : constant Entity_Id := Designated_Type (Etype (P));
-
- begin
- if Present (E)
- and then (Operating_Mode = Check_Semantics or else not Expander_Active)
- then
- -- We create a dummy reference to E to ensure that the reference is
- -- not considered as part of an assignment (an implicit dereference
- -- can never assign to its prefix). The Comes_From_Source attribute
- -- needs to be propagated for accurate warnings.
-
- Ref := New_Occurrence_Of (E, Sloc (P));
- Set_Comes_From_Source (Ref, Comes_From_Source (P));
- Generate_Reference (E, Ref);
- end if;
-
- -- An implicit dereference is a legal occurrence of an incomplete type
- -- imported through a limited_with clause, if the full view is visible.
-
- if From_Limited_With (Typ)
- and then not From_Limited_With (Scope (Typ))
- and then
- (Is_Immediately_Visible (Scope (Typ))
- or else
- (Is_Child_Unit (Scope (Typ))
- and then Is_Visible_Lib_Unit (Scope (Typ))))
- then
- return Available_View (Typ);
- else
- return Typ;
- end if;
- end Process_Implicit_Dereference_Prefix;
-
--------------------------------
-- Remove_Abstract_Operations --
--------------------------------
@@ -7563,7 +7749,7 @@ package body Sem_Ch4 is
Formal := First_Entity (It.Nam);
if Op = Second_Op then
- Formal := Next_Entity (Formal);
+ Next_Entity (Formal);
end if;
if Is_Descendant_Of_Address (Etype (Formal)) then
@@ -7791,7 +7977,7 @@ package body Sem_Ch4 is
Prefix : Node_Id;
Exprs : List_Id) return Boolean
is
- Pref_Typ : constant Entity_Id := Etype (Prefix);
+ Pref_Typ : Entity_Id := Etype (Prefix);
function Constant_Indexing_OK return Boolean;
-- Constant_Indexing is legal if there is no Variable_Indexing defined
@@ -7842,8 +8028,8 @@ package body Sem_Ch4 is
-- resolution does not depend on the type of the parameter that
-- includes the indexing operation.
- elsif Nkind_In (Parent (Par), N_Function_Call,
- N_Procedure_Call_Statement)
+ elsif Nkind (Parent (Par)) in
+ N_Function_Call | N_Procedure_Call_Statement
and then Is_Entity_Name (Name (Parent (Par)))
then
declare
@@ -8227,6 +8413,25 @@ package body Sem_Ch4 is
return True;
end if;
+ -- An explicit dereference needs to be created in the case of a prefix
+ -- that's an access.
+
+ -- It seems that this should be done elsewhere, but not clear where that
+ -- should happen. Normally Insert_Explicit_Dereference is called via
+ -- Resolve_Implicit_Dereference, called from Resolve_Indexed_Component,
+ -- but that won't be called in this case because we transform the
+ -- indexing to a call. Resolve_Call.Check_Prefixed_Call takes care of
+ -- implicit dereferencing and referencing on prefixed calls, but that
+ -- would be too late, even if we expanded to a prefix call, because
+ -- Process_Indexed_Component will flag an error before the resolution
+ -- happens. ???
+
+ if Is_Access_Type (Pref_Typ) then
+ Pref_Typ := Implicitly_Designated_Type (Pref_Typ);
+ Insert_Explicit_Dereference (Prefix);
+ Error_Msg_NW (Warn_On_Dereference, "?d?implicit dereference", N);
+ end if;
+
C_Type := Pref_Typ;
-- If indexing a class-wide container, obtain indexing primitive from
@@ -8268,7 +8473,8 @@ package body Sem_Ch4 is
-- as such and retry.
if Has_Implicit_Dereference (Pref_Typ) then
- Build_Explicit_Dereference (Prefix, First_Discriminant (Pref_Typ));
+ Build_Explicit_Dereference
+ (Prefix, Get_Reference_Discriminant (Pref_Typ));
return Try_Container_Indexing (N, Prefix, Exprs);
-- Otherwise this is definitely not container indexing
@@ -8290,8 +8496,8 @@ package body Sem_Ch4 is
-- the Controlled types. The code below is motivated by containers that
-- are derived from other types with a Reference aspect.
-- Note as well that we need to examine the base type, given that
- -- the container object may be a constrained subtype or itype which
- -- does not have an explicit declaration,
+ -- the container object may be a constrained subtype or itype that
+ -- does not have an explicit declaration.
elsif Is_Derived_Type (C_Type)
and then Etype (First_Formal (Entity (Func_Name))) /= Pref_Typ
@@ -8348,6 +8554,12 @@ package body Sem_Ch4 is
if not Is_Overloaded (Func_Name) then
Func := Entity (Func_Name);
+ -- Can happen in case of e.g. cascaded errors
+
+ if No (Func) then
+ return False;
+ end if;
+
Indexing :=
Make_Function_Call (Loc,
Name => New_Occurrence_Of (Func, Loc),
@@ -8630,7 +8842,9 @@ package body Sem_Ch4 is
-- Transform Obj.Operation (X, Y, ...) into Operation (Obj, X, Y ...).
-- Call_Node is the resulting subprogram call, Node_To_Replace is
-- either N or the parent of N, and Subprog is a reference to the
- -- subprogram we are trying to match.
+ -- subprogram we are trying to match. Note that the transformation
+ -- may be partially destructive for the parent of N, so it needs to
+ -- be undone in the case where Try_Object_Operation returns false.
function Try_Class_Wide_Operation
(Call_Node : Node_Id;
@@ -8888,14 +9102,6 @@ package body Sem_Ch4 is
Actuals : List_Id;
begin
- -- Obj may already have been rewritten if it involves an implicit
- -- dereference (e.g. if it is an access to a limited view). Preserve
- -- a link to the original node for ASIS use.
-
- if not Comes_From_Source (Obj) then
- Set_Original_Node (Dummy, Original_Node (Obj));
- end if;
-
-- Common case covering 1) Call to a procedure and 2) Call to a
-- function that has some additional actuals.
@@ -8909,7 +9115,7 @@ package body Sem_Ch4 is
-- example:
-- Some_Subprogram (..., Obj.Operation, ...)
- and then Name (Parent_Node) = N
+ and then N = Name (Parent_Node)
then
Node_To_Replace := Parent_Node;
@@ -9058,7 +9264,7 @@ package body Sem_Ch4 is
Hom := Current_Entity (Subprog);
while Present (Hom) loop
- if Ekind_In (Hom, E_Procedure, E_Function)
+ if Ekind (Hom) in E_Procedure | E_Function
and then Present (Renamed_Entity (Hom))
and then Is_Generic_Actual_Subprogram (Hom)
and then In_Open_Scopes (Scope (Hom))
@@ -9068,7 +9274,7 @@ package body Sem_Ch4 is
Candidate := Hom;
end if;
- if Ekind_In (Candidate, E_Function, E_Procedure)
+ if Ekind (Candidate) in E_Function | E_Procedure
and then (not Is_Hidden (Candidate) or else In_Instance)
and then Scope (Candidate) = Scope (Base_Type (Anc_Type))
and then First_Formal_Match (Candidate, CW_Typ)
@@ -9246,8 +9452,8 @@ package body Sem_Ch4 is
Obj_Type := Designated_Type (Obj_Type);
end if;
- if Ekind_In (Obj_Type, E_Private_Subtype,
- E_Record_Subtype_With_Private)
+ if Ekind (Obj_Type)
+ in E_Private_Subtype | E_Record_Subtype_With_Private
then
Obj_Type := Base_Type (Obj_Type);
end if;
@@ -9417,7 +9623,7 @@ package body Sem_Ch4 is
if Is_Derived_Type (T) then
return Primitive_Operations (T);
- elsif Ekind_In (Scope (T), E_Procedure, E_Function) then
+ elsif Ekind (Scope (T)) in E_Procedure | E_Function then
-- Scan the list of generic formals to find subprograms
-- that may have a first controlling formal of the type.
@@ -9480,7 +9686,7 @@ package body Sem_Ch4 is
Type_Scope : constant Entity_Id := Scope (T);
Op_List : Elist_Id := Primitive_Operations (T);
begin
- if Ekind_In (Type_Scope, E_Package, E_Generic_Package)
+ if Is_Package_Or_Generic_Package (Type_Scope)
and then ((In_Package_Body (Type_Scope)
and then In_Open_Scopes (Type_Scope)) or else In_Instance_Body)
then
@@ -9947,8 +10153,20 @@ package body Sem_Ch4 is
return True;
else
- -- There was no candidate operation, so report it as an error
- -- in the caller: Analyze_Selected_Component.
+ -- There was no candidate operation, but Analyze_Selected_Component
+ -- may continue the analysis so we need to undo the change possibly
+ -- made to the Parent of N earlier by Transform_Object_Operation.
+
+ declare
+ Parent_Node : constant Node_Id := Parent (N);
+
+ begin
+ if Node_To_Replace = Parent_Node then
+ Remove (First (Parameter_Associations (New_Call_Node)));
+ Set_Parent
+ (Parameter_Associations (New_Call_Node), Parent_Node);
+ end if;
+ end;
return False;
end if;