sem_ch4.adb (Try_Primitive_Operation): Code cleanup to ensure that we generate the same errors compiling under -gnatc.
2006-10-31 Ed Schonberg <schonberg@adacore.com> Javier Miranda <miranda@adacore.com> Robert Dewar <dewar@adacore.com> * sem_ch4.adb (Try_Primitive_Operation): Code cleanup to ensure that we generate the same errors compiling under -gnatc. (Try_Object_Operation): If no candidate interpretation succeeds, but there is at least one primitive operation with the right name, report error in call rather than on a malformed selected component. (Analyze_Selected_Component): If the prefix is an incomplete type from a limited view, and the full view is available, use the full view to determine whether this is a prefixed call to a primitive operation. (Operator_Check): Verify that a candidate interpretation is a binary operation before checking the type of its second formal. (Analyze_Call): Add additional warnings for function call contexts not yet supported. (Analyze_Allocator): Move the check for "initialization not allowed for limited types" after analyzing the expression. This is necessary, because OK_For_Limited_Init looks at the structure of the expression. Before analysis, we don't necessarily know what sort of expression it is. For example, we don't know whether F(X) is a function call or an indexed component; the former is legal in Ada 2005; the latter is not. (Analyze_Allocator): Correct code for AI-287 -- extension aggregates were missing. We also didn't handle qualified expressions. Now also allow function calls. Use new common routine OK_For_Limited_Init. (Analyze_Type_Conversion): Do not perform some legality checks in an instance, because the error message will be redundant or spurious. (Analyze_Overloaded_Selected_Component): Do not do style check when setting an entity, since we do not know it is the right entity yet. (Analyze_Selected_Component): Move Generate_Reference call to Sem_Res (Analyze_Overloaded_Selected_Component): Same change (Analyze_Selected_Component): Remove unnecessary prefix type retrieval since regular incomplete subtypes are transformed into corresponding subtypes of their full views. (Complete_Object_Operation): Treat name of transformed subprogram call as coming from source, for browsing purposes. (Try_Primitive_Operation): If formal is an access parameter, compare with base type of object to determine whether it is a primitive operation. (Operator_Check): If no interpretation of the operator matches, check whether a use clause on any candidate might make the operation legal. (Try_Class_Wide_Operation): Check whether the first parameter is an access type whose designated type is class-wide. From-SVN: r118302
This commit is contained in:
parent
affbee12f4
commit
b67a385c62
1 changed files with 191 additions and 64 deletions
|
@ -41,11 +41,11 @@ with Opt; use Opt;
|
|||
with Output; use Output;
|
||||
with Restrict; use Restrict;
|
||||
with Rident; use Rident;
|
||||
with Rtsfind; use Rtsfind;
|
||||
with Sem; use Sem;
|
||||
with Sem_Cat; use Sem_Cat;
|
||||
with Sem_Ch3; use Sem_Ch3;
|
||||
with Sem_Ch8; use Sem_Ch8;
|
||||
with Sem_Disp; use Sem_Disp;
|
||||
with Sem_Dist; use Sem_Dist;
|
||||
with Sem_Eval; use Sem_Eval;
|
||||
with Sem_Res; use Sem_Res;
|
||||
|
@ -298,9 +298,7 @@ package body Sem_Ch4 is
|
|||
-- Start of processing for Ambiguous_Operands
|
||||
|
||||
begin
|
||||
if Nkind (N) = N_In
|
||||
or else Nkind (N) = N_Not_In
|
||||
then
|
||||
if Nkind (N) in N_Membership_Test then
|
||||
Error_Msg_N ("ambiguous operands for membership", N);
|
||||
|
||||
elsif Nkind (N) = N_Op_Eq
|
||||
|
@ -341,7 +339,7 @@ package body Sem_Ch4 is
|
|||
procedure Analyze_Allocator (N : Node_Id) is
|
||||
Loc : constant Source_Ptr := Sloc (N);
|
||||
Sav_Errs : constant Nat := Serious_Errors_Detected;
|
||||
E : Node_Id := Expression (N);
|
||||
E : Node_Id := Expression (N);
|
||||
Acc_Type : Entity_Id;
|
||||
Type_Id : Entity_Id;
|
||||
|
||||
|
@ -357,27 +355,18 @@ package body Sem_Ch4 is
|
|||
Check_Fully_Declared (Type_Id, N);
|
||||
Set_Directly_Designated_Type (Acc_Type, Type_Id);
|
||||
|
||||
Analyze_And_Resolve (Expression (E), Type_Id);
|
||||
|
||||
if Is_Limited_Type (Type_Id)
|
||||
and then Comes_From_Source (N)
|
||||
and then not In_Instance_Body
|
||||
then
|
||||
-- Ada 2005 (AI-287): Do not post an error if the expression
|
||||
-- corresponds to a limited aggregate. Limited aggregates
|
||||
-- are checked in sem_aggr in a per-component manner
|
||||
-- (compare with handling of Get_Value subprogram).
|
||||
|
||||
if Ada_Version >= Ada_05
|
||||
and then Nkind (Expression (E)) = N_Aggregate
|
||||
then
|
||||
null;
|
||||
else
|
||||
if not OK_For_Limited_Init (Expression (E)) then
|
||||
Error_Msg_N ("initialization not allowed for limited types", N);
|
||||
Explain_Limited_Type (Type_Id, N);
|
||||
end if;
|
||||
end if;
|
||||
|
||||
Analyze_And_Resolve (Expression (E), Type_Id);
|
||||
|
||||
-- A qualified expression requires an exact match of the type,
|
||||
-- class-wide matching is not allowed.
|
||||
|
||||
|
@ -928,6 +917,26 @@ package body Sem_Ch4 is
|
|||
|
||||
End_Interp_List;
|
||||
end if;
|
||||
|
||||
-- Check for not-yet-implemented cases of AI-318.
|
||||
-- We only need to check for inherently limited types,
|
||||
-- because other limited types will be returned by copy,
|
||||
-- which works just fine.
|
||||
|
||||
if Ada_Version >= Ada_05
|
||||
and then not Debug_Flag_Dot_L
|
||||
and then Is_Inherently_Limited_Type (Etype (N))
|
||||
and then (Nkind (Parent (N)) = N_Selected_Component
|
||||
or else Nkind (Parent (N)) = N_Indexed_Component
|
||||
or else Nkind (Parent (N)) = N_Slice
|
||||
or else Nkind (Parent (N)) = N_Attribute_Reference
|
||||
or else Nkind (Parent (N)) = N_Component_Declaration
|
||||
or else Nkind (Parent (N)) = N_Formal_Object_Declaration
|
||||
or else Nkind (Parent (N)) = N_Generic_Association)
|
||||
then
|
||||
Error_Msg_N ("(Ada 2005) limited function call in this context" &
|
||||
" is not yet implemented", N);
|
||||
end if;
|
||||
end Analyze_Call;
|
||||
|
||||
---------------------------
|
||||
|
@ -2333,9 +2342,7 @@ package body Sem_Ch4 is
|
|||
if Chars (Comp) = Chars (Sel)
|
||||
and then Is_Visible_Component (Comp)
|
||||
then
|
||||
Set_Entity_With_Style_Check (Sel, Comp);
|
||||
Generate_Reference (Comp, Sel);
|
||||
|
||||
Set_Entity (Sel, Comp);
|
||||
Set_Etype (Sel, Etype (Comp));
|
||||
Add_One_Interp (N, Etype (Comp), Etype (Comp));
|
||||
|
||||
|
@ -2610,6 +2617,18 @@ package body Sem_Ch4 is
|
|||
end if;
|
||||
|
||||
Prefix_Type := Designated_Type (Prefix_Type);
|
||||
|
||||
-- (Ada 2005): if the prefix is the limited view of a type, and
|
||||
-- the context already includes the full view, use the full view
|
||||
-- in what follows, either to retrieve a component of to find
|
||||
-- a primitive operation.
|
||||
|
||||
if Is_Incomplete_Type (Prefix_Type)
|
||||
and then From_With_Type (Prefix_Type)
|
||||
and then Present (Non_Limited_View (Prefix_Type))
|
||||
then
|
||||
Prefix_Type := Non_Limited_View (Prefix_Type);
|
||||
end if;
|
||||
end if;
|
||||
|
||||
if Ekind (Prefix_Type) = E_Private_Subtype then
|
||||
|
@ -2661,8 +2680,6 @@ package body Sem_Ch4 is
|
|||
and then Is_Visible_Component (Comp)
|
||||
then
|
||||
Set_Entity_With_Style_Check (Sel, Comp);
|
||||
Generate_Reference (Comp, Sel);
|
||||
|
||||
Set_Etype (Sel, Etype (Comp));
|
||||
|
||||
if Ekind (Comp) = E_Discriminant then
|
||||
|
@ -2687,19 +2704,22 @@ package body Sem_Ch4 is
|
|||
|
||||
Resolve (Name);
|
||||
|
||||
-- Ada 2005 (AI-50217): Check wrong use of incomplete type.
|
||||
-- Ada 2005 (AI-50217): Check wrong use of incomplete types or
|
||||
-- subtypes in a package specification.
|
||||
-- Example:
|
||||
|
||||
-- limited with Pkg;
|
||||
-- package Pkg is
|
||||
-- type Acc_Inc is access Pkg.T;
|
||||
-- X : Acc_Inc;
|
||||
-- N : Natural := X.all.Comp; -- ERROR
|
||||
-- end Pkg;
|
||||
-- N : Natural := X.all.Comp; -- ERROR, limited view
|
||||
-- end Pkg; -- Comp is not visible
|
||||
|
||||
if Nkind (Name) = N_Explicit_Dereference
|
||||
and then From_With_Type (Etype (Prefix (Name)))
|
||||
and then not Is_Potentially_Use_Visible (Etype (Name))
|
||||
and then Nkind (Parent (Cunit_Entity (Current_Sem_Unit))) =
|
||||
N_Package_Specification
|
||||
then
|
||||
Error_Msg_NE
|
||||
("premature usage of incomplete}", Prefix (Name),
|
||||
|
@ -3182,6 +3202,15 @@ package body Sem_Ch4 is
|
|||
if not Comes_From_Source (N) then
|
||||
return;
|
||||
|
||||
-- If there was an error in a generic unit, no need to replicate the
|
||||
-- error message. Conversely, constant-folding in the generic may
|
||||
-- transform the argument of a conversion into a string literal, which
|
||||
-- is legal. Therefore the following tests are not performed in an
|
||||
-- instance.
|
||||
|
||||
elsif In_Instance then
|
||||
return;
|
||||
|
||||
elsif Nkind (Expr) = N_Null then
|
||||
Error_Msg_N ("argument of conversion cannot be null", N);
|
||||
Error_Msg_N ("\use qualified expression instead", N);
|
||||
|
@ -4372,8 +4401,9 @@ package body Sem_Ch4 is
|
|||
|
||||
if Etype (N) = Any_Type then
|
||||
declare
|
||||
L : Node_Id;
|
||||
R : Node_Id;
|
||||
L : Node_Id;
|
||||
R : Node_Id;
|
||||
Op_Id : Entity_Id := Empty;
|
||||
|
||||
begin
|
||||
R := Right_Opnd (N);
|
||||
|
@ -4546,11 +4576,51 @@ package body Sem_Ch4 is
|
|||
Error_Msg_N ("there is no applicable operator& for}", N);
|
||||
|
||||
else
|
||||
Error_Msg_N ("invalid operand types for operator&", N);
|
||||
-- Another attempt to find a fix: one of the candidate
|
||||
-- interpretations may not be use-visible. This has
|
||||
-- already been checked for predefined operators, so
|
||||
-- we examine only user-defined functions.
|
||||
|
||||
if Nkind (N) /= N_Op_Concat then
|
||||
Error_Msg_NE ("\left operand has}!", N, Etype (L));
|
||||
Error_Msg_NE ("\right operand has}!", N, Etype (R));
|
||||
Op_Id := Get_Name_Entity_Id (Chars (N));
|
||||
|
||||
while Present (Op_Id) loop
|
||||
if Ekind (Op_Id) /= E_Operator
|
||||
and then Is_Overloadable (Op_Id)
|
||||
then
|
||||
if not Is_Immediately_Visible (Op_Id)
|
||||
and then not In_Use (Scope (Op_Id))
|
||||
and then not Is_Abstract (Op_Id)
|
||||
and then not Is_Hidden (Op_Id)
|
||||
and then Ekind (Scope (Op_Id)) = E_Package
|
||||
and then
|
||||
Has_Compatible_Type
|
||||
(L, Etype (First_Formal (Op_Id)))
|
||||
and then Present
|
||||
(Next_Formal (First_Formal (Op_Id)))
|
||||
and then
|
||||
Has_Compatible_Type
|
||||
(R,
|
||||
Etype (Next_Formal (First_Formal (Op_Id))))
|
||||
then
|
||||
Error_Msg_N
|
||||
("No legal interpretation for operator&", N);
|
||||
Error_Msg_NE
|
||||
("\use clause on& would make operation legal",
|
||||
N, Scope (Op_Id));
|
||||
exit;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
Op_Id := Homonym (Op_Id);
|
||||
end loop;
|
||||
|
||||
if No (Op_Id) then
|
||||
Error_Msg_N ("invalid operand types for operator&", N);
|
||||
|
||||
if Nkind (N) /= N_Op_Concat then
|
||||
Error_Msg_NE ("\left operand has}!", N, Etype (L));
|
||||
Error_Msg_NE ("\right operand has}!", N, Etype (R));
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
|
@ -4913,15 +4983,21 @@ package body Sem_Ch4 is
|
|||
--------------------------
|
||||
|
||||
function Try_Object_Operation (N : Node_Id) return Boolean is
|
||||
K : constant Node_Kind := Nkind (Parent (N));
|
||||
Loc : constant Source_Ptr := Sloc (N);
|
||||
Is_Subprg_Call : constant Boolean := K = N_Procedure_Call_Statement
|
||||
or else K = N_Function_Call;
|
||||
Obj : constant Node_Id := Prefix (N);
|
||||
Subprog : constant Node_Id := Selector_Name (N);
|
||||
K : constant Node_Kind := Nkind (Parent (N));
|
||||
Loc : constant Source_Ptr := Sloc (N);
|
||||
Candidate : Entity_Id := Empty;
|
||||
Is_Subprg_Call : constant Boolean := K = N_Procedure_Call_Statement
|
||||
or else K = N_Function_Call;
|
||||
Obj : constant Node_Id := Prefix (N);
|
||||
Subprog : constant Node_Id := Selector_Name (N);
|
||||
Success : Boolean := False;
|
||||
|
||||
Report_Error : Boolean := False;
|
||||
-- If no candidate interpretation matches the context, redo the
|
||||
-- analysis with error enabled to provide additional information.
|
||||
|
||||
Actual : Node_Id;
|
||||
New_Call_Node : Node_Id := Empty;
|
||||
New_Call_Node : Node_Id := Empty;
|
||||
Node_To_Replace : Node_Id;
|
||||
Obj_Type : Entity_Id := Etype (Obj);
|
||||
|
||||
|
@ -4971,6 +5047,12 @@ package body Sem_Ch4 is
|
|||
First_Actual := First (Parameter_Associations (Call_Node));
|
||||
Set_Name (Call_Node, Subprog);
|
||||
|
||||
-- For cross-reference purposes, treat the new node as being in
|
||||
-- the source if the original one is.
|
||||
|
||||
Set_Comes_From_Source (Subprog, Comes_From_Source (N));
|
||||
Set_Comes_From_Source (Call_Node, Comes_From_Source (N));
|
||||
|
||||
if Nkind (N) = N_Selected_Component
|
||||
and then not Inside_A_Generic
|
||||
then
|
||||
|
@ -5111,6 +5193,7 @@ package body Sem_Ch4 is
|
|||
Node_To_Replace : Node_Id) return Boolean
|
||||
is
|
||||
Anc_Type : Entity_Id;
|
||||
Cls_Type : Entity_Id;
|
||||
Hom : Entity_Id;
|
||||
Hom_Ref : Node_Id;
|
||||
Success : Boolean;
|
||||
|
@ -5118,25 +5201,29 @@ package body Sem_Ch4 is
|
|||
begin
|
||||
-- Loop through ancestor types, traverse the homonym chain of the
|
||||
-- subprogram, and try out those homonyms whose first formal has the
|
||||
-- class-wide type of the ancestor.
|
||||
|
||||
-- Should we verify that it is declared in the same package as the
|
||||
-- ancestor type ???
|
||||
-- class-wide type of the ancestor, or an access type to it.
|
||||
|
||||
Anc_Type := Obj_Type;
|
||||
|
||||
loop
|
||||
Cls_Type := Class_Wide_Type (Anc_Type);
|
||||
|
||||
Hom := Current_Entity (Subprog);
|
||||
while Present (Hom) loop
|
||||
if (Ekind (Hom) = E_Procedure
|
||||
or else
|
||||
Ekind (Hom) = E_Function)
|
||||
and then Scope (Hom) = Scope (Anc_Type)
|
||||
and then Present (First_Formal (Hom))
|
||||
and then Etype (First_Formal (Hom)) =
|
||||
Class_Wide_Type (Anc_Type)
|
||||
and then
|
||||
(Etype (First_Formal (Hom)) = Cls_Type
|
||||
or else
|
||||
(Is_Access_Type (Etype (First_Formal (Hom)))
|
||||
and then
|
||||
Designated_Type (Etype (First_Formal (Hom))) =
|
||||
Cls_Type))
|
||||
then
|
||||
Hom_Ref := New_Reference_To (Hom, Sloc (Subprog));
|
||||
|
||||
Set_Etype (Call_Node, Any_Type);
|
||||
Set_Parent (Call_Node, Parent (Node_To_Replace));
|
||||
|
||||
|
@ -5145,7 +5232,7 @@ package body Sem_Ch4 is
|
|||
Analyze_One_Call
|
||||
(N => Call_Node,
|
||||
Nam => Hom,
|
||||
Report => False,
|
||||
Report => Report_Error,
|
||||
Success => Success,
|
||||
Skip_First => True);
|
||||
|
||||
|
@ -5218,15 +5305,15 @@ package body Sem_Ch4 is
|
|||
|
||||
or else
|
||||
(Ekind (Typ) = E_Anonymous_Access_Type
|
||||
and then Designated_Type (Typ) = Obj_Type);
|
||||
and then Designated_Type (Typ) = Base_Type (Obj_Type));
|
||||
end Valid_First_Argument_Of;
|
||||
|
||||
-- Start of processing for Try_Primitive_Operation
|
||||
|
||||
begin
|
||||
-- Look for subprograms in the list of primitive operations
|
||||
-- The name must be identical, and the kind of call indicates
|
||||
-- the expected kind of operation (function or procedure).
|
||||
-- The name must be identical, and the kind of call indicates the
|
||||
-- expected kind of operation (function or procedure).
|
||||
|
||||
Elmt := First_Elmt (Primitive_Operations (Obj_Type));
|
||||
while Present (Elmt) loop
|
||||
|
@ -5239,21 +5326,22 @@ package body Sem_Ch4 is
|
|||
(Nkind (Call_Node) = N_Function_Call)
|
||||
= (Ekind (Prim_Op) = E_Function)
|
||||
then
|
||||
-- If this primitive operation corresponds with an immediate
|
||||
-- ancestor interface there is no need to add it to the list
|
||||
-- of interpretations; the corresponding aliased primitive is
|
||||
-- also in this list of primitive operations and will be
|
||||
-- used instead.
|
||||
-- Ada 2005 (AI-251): If this primitive operation corresponds
|
||||
-- with an immediate ancestor interface there is no need to add
|
||||
-- it to the list of interpretations; the corresponding aliased
|
||||
-- primitive is also in this list of primitive operations and
|
||||
-- will be used instead.
|
||||
|
||||
if Present (Abstract_Interface_Alias (Prim_Op))
|
||||
and then Present (DTC_Entity (Alias (Prim_Op)))
|
||||
and then Etype (DTC_Entity (Alias (Prim_Op))) = RTE (RE_Tag)
|
||||
and then Is_Ancestor (Find_Dispatching_Type
|
||||
(Alias (Prim_Op)), Obj_Type)
|
||||
then
|
||||
goto Continue;
|
||||
end if;
|
||||
|
||||
if not Success then
|
||||
Prim_Op_Ref := New_Reference_To (Prim_Op, Sloc (Subprog));
|
||||
Candidate := Prim_Op;
|
||||
|
||||
Set_Etype (Call_Node, Any_Type);
|
||||
Set_Parent (Call_Node, Parent (Node_To_Replace));
|
||||
|
@ -5263,7 +5351,7 @@ package body Sem_Ch4 is
|
|||
Analyze_One_Call
|
||||
(N => Call_Node,
|
||||
Nam => Prim_Op,
|
||||
Report => False,
|
||||
Report => Report_Error,
|
||||
Success => Success,
|
||||
Skip_First => True);
|
||||
|
||||
|
@ -5357,15 +5445,54 @@ package body Sem_Ch4 is
|
|||
Set_Etype (New_Call_Node, Any_Type);
|
||||
Set_Parent (New_Call_Node, Parent (Node_To_Replace));
|
||||
|
||||
return
|
||||
Try_Primitive_Operation
|
||||
(Call_Node => New_Call_Node,
|
||||
Node_To_Replace => Node_To_Replace)
|
||||
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);
|
||||
Try_Class_Wide_Operation
|
||||
(Call_Node => New_Call_Node,
|
||||
Node_To_Replace => Node_To_Replace)
|
||||
then
|
||||
return True;
|
||||
|
||||
elsif Present (Candidate) then
|
||||
|
||||
-- The argument list is not type correct. Re-analyze with error
|
||||
-- reporting enabled, and use one of the possible candidates.
|
||||
-- In all_errors mode, re-analyze all failed interpretations.
|
||||
|
||||
if All_Errors_Mode then
|
||||
Report_Error := True;
|
||||
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;
|
||||
|
||||
else
|
||||
Analyze_One_Call
|
||||
(N => New_Call_Node,
|
||||
Nam => Candidate,
|
||||
Report => True,
|
||||
Success => Success,
|
||||
Skip_First => True);
|
||||
end if;
|
||||
|
||||
return True; -- No need for further errors.
|
||||
|
||||
else
|
||||
-- There was no candidate operation, so report it as an error
|
||||
-- in the caller: Analyze_Selected_Component.
|
||||
|
||||
return False;
|
||||
end if;
|
||||
end Try_Object_Operation;
|
||||
|
||||
end Sem_Ch4;
|
||||
|
|
Loading…
Add table
Reference in a new issue