aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada/sem_res.adb
diff options
context:
space:
mode:
authorGiuliano Belinassi <giuliano.belinassi@usp.br>2020-08-22 17:43:43 -0300
committerGiuliano Belinassi <giuliano.belinassi@usp.br>2020-08-22 17:43:43 -0300
commita926878ddbd5a98b272c22171ce58663fc04c3e0 (patch)
tree86af256e5d9a9c06263c00adc90e5fe348008c43 /gcc/ada/sem_res.adb
parent542730f087133690b47e036dfd43eb0db8a650ce (diff)
parent07cbaed8ba7d1b6e4ab3a9f44175502a4e1ecdb1 (diff)
downloadgcc-devel/autopar_devel.zip
gcc-devel/autopar_devel.tar.gz
gcc-devel/autopar_devel.tar.bz2
Merge branch 'autopar_rebase2' into autopar_develdevel/autopar_devel
Quickly commit changes in the rebase branch.
Diffstat (limited to 'gcc/ada/sem_res.adb')
-rw-r--r--gcc/ada/sem_res.adb1563
1 files changed, 826 insertions, 737 deletions
diff --git a/gcc/ada/sem_res.adb b/gcc/ada/sem_res.adb
index 21cbe0a..50a4287 100644
--- a/gcc/ada/sem_res.adb
+++ b/gcc/ada/sem_res.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- --
@@ -23,6 +23,7 @@
-- --
------------------------------------------------------------------------------
+with Aspects; use Aspects;
with Atree; use Atree;
with Checks; use Checks;
with Debug; use Debug;
@@ -177,6 +178,7 @@ package body Sem_Res is
procedure Resolve_Case_Expression (N : Node_Id; Typ : Entity_Id);
procedure Resolve_Character_Literal (N : Node_Id; Typ : Entity_Id);
procedure Resolve_Comparison_Op (N : Node_Id; Typ : Entity_Id);
+ procedure Resolve_Declare_Expression (N : Node_Id; Typ : Entity_Id);
procedure Resolve_Entity_Name (N : Node_Id; Typ : Entity_Id);
procedure Resolve_Equality_Op (N : Node_Id; Typ : Entity_Id);
procedure Resolve_Explicit_Dereference (N : Node_Id; Typ : Entity_Id);
@@ -226,6 +228,12 @@ package body Sem_Res is
-- is the context type, which is used when the operation is a protected
-- function with no arguments, and the return value is indexed.
+ procedure Resolve_Implicit_Dereference (P : Node_Id);
+ -- Called when P is the prefix of an indexed component, or of a selected
+ -- component, or of a slice. If P is of an access type, we unconditionally
+ -- rewrite it as an explicit dereference. This ensures that the expander
+ -- and the code generator have a fully explicit tree to work with.
+
procedure Resolve_Intrinsic_Operator (N : Node_Id; Typ : Entity_Id);
-- A call to a user-defined intrinsic operator is rewritten as a call to
-- the corresponding predefined operator, with suitable conversions. Note
@@ -265,8 +273,7 @@ package body Sem_Res is
procedure Simplify_Type_Conversion (N : Node_Id);
-- Called after N has been resolved and evaluated, but before range checks
- -- have been applied. Currently simplifies a combination of floating-point
- -- to integer conversion and Rounding or Truncation attribute.
+ -- have been applied. This rewrites the conversion into a simpler form.
function Unique_Fixed_Point_Type (N : Node_Id) return Entity_Id;
-- A universal_fixed expression in an universal context is unambiguous if
@@ -448,8 +455,8 @@ package body Sem_Res is
and then not
(Nkind (Parent (P)) = N_Subtype_Indication
and then
- Nkind_In (Parent (Parent (P)), N_Component_Definition,
- N_Subtype_Declaration)
+ Nkind (Parent (Parent (P))) in N_Component_Definition
+ | N_Subtype_Declaration
and then Paren_Count (N) = 0)
then
Error_Msg_N
@@ -573,8 +580,8 @@ package body Sem_Res is
-- Legal case is in index or discriminant constraint
- elsif Nkind_In (PN, N_Index_Or_Discriminant_Constraint,
- N_Discriminant_Association)
+ elsif Nkind (PN) in N_Index_Or_Discriminant_Constraint
+ | N_Discriminant_Association
then
if Paren_Count (N) > 0 then
Error_Msg_N
@@ -595,9 +602,8 @@ package body Sem_Res is
else
D := PN;
P := Parent (PN);
- while not Nkind_In (P, N_Component_Declaration,
- N_Subtype_Indication,
- N_Entry_Declaration)
+ while Nkind (P) not in
+ N_Component_Declaration | N_Subtype_Indication | N_Entry_Declaration
loop
D := P;
P := Parent (P);
@@ -610,8 +616,8 @@ package body Sem_Res is
-- course a double fault.
if (Nkind (P) = N_Subtype_Indication
- and then Nkind_In (Parent (P), N_Component_Definition,
- N_Derived_Type_Definition)
+ and then Nkind (Parent (P)) in N_Component_Definition
+ | N_Derived_Type_Definition
and then D = Constraint (P))
-- The constraint itself may be given by a subtype indication,
@@ -803,12 +809,12 @@ package body Sem_Res is
function Is_Conditional_Statement (N : Node_Id) return Boolean is
begin
return
- Nkind_In (N, N_And_Then,
- N_Case_Expression,
- N_Case_Statement,
- N_If_Expression,
- N_If_Statement,
- N_Or_Else);
+ Nkind (N) in N_And_Then
+ | N_Case_Expression
+ | N_Case_Statement
+ | N_If_Expression
+ | N_If_Statement
+ | N_Or_Else;
end Is_Conditional_Statement;
-------------------------------
@@ -834,7 +840,7 @@ package body Sem_Res is
begin
return
Nkind (HSS) = N_Handled_Sequence_Of_Statements
- and then Nkind_In (Parent (HSS), N_Entry_Body, N_Subprogram_Body)
+ and then Nkind (Parent (HSS)) in N_Entry_Body | N_Subprogram_Body
and then Is_List_Member (N)
and then List_Containing (N) = Statements (HSS);
end Is_Immediately_Within_Body;
@@ -1142,9 +1148,8 @@ package body Sem_Res is
-- functions, this is never a parameterless call (RM 4.1.4(6)).
if Nkind (Parent (N)) = N_Attribute_Reference
- and then Nam_In (Attribute_Name (Parent (N)), Name_Address,
- Name_Code_Address,
- Name_Access)
+ and then Attribute_Name (Parent (N))
+ in Name_Address | Name_Code_Address | Name_Access
then
return False;
end if;
@@ -1194,9 +1199,9 @@ package body Sem_Res is
and then Ekind (Entity (N)) = E_Procedure
and then not Is_Overloaded (N)
and then
- Nkind_In (Parent (N), N_Parameter_Association,
- N_Function_Call,
- N_Procedure_Call_Statement)
+ Nkind (Parent (N)) in N_Parameter_Association
+ | N_Function_Call
+ | N_Procedure_Call_Statement
then
return;
end if;
@@ -1231,8 +1236,8 @@ package body Sem_Res is
(Nkind (N) = N_Selected_Component
and then (Ekind (Entity (Selector_Name (N))) = E_Function
or else
- (Ekind_In (Entity (Selector_Name (N)), E_Entry,
- E_Procedure)
+ (Ekind (Entity (Selector_Name (N))) in
+ E_Entry | E_Procedure
and then Is_Overloaded (Selector_Name (N)))))
-- If one of the above three conditions is met, rewrite as call. Apply
@@ -1540,9 +1545,9 @@ package body Sem_Res is
elsif In_Instance then
null;
- elsif Nam_In (Op_Name, Name_Op_Multiply, Name_Op_Divide)
- and then Is_Fixed_Point_Type (Etype (Left_Opnd (Op_Node)))
- and then Is_Fixed_Point_Type (Etype (Right_Opnd (Op_Node)))
+ elsif Op_Name in Name_Op_Multiply | Name_Op_Divide
+ and then Is_Fixed_Point_Type (Etype (Act1))
+ and then Is_Fixed_Point_Type (Etype (Act2))
then
if Pack /= Standard_Standard then
Error := True;
@@ -1552,8 +1557,9 @@ package body Sem_Res is
-- available.
elsif Ada_Version >= Ada_2005
- and then Nam_In (Op_Name, Name_Op_Eq, Name_Op_Ne)
- and then Ekind (Etype (Act1)) = E_Anonymous_Access_Type
+ and then Op_Name in Name_Op_Eq | Name_Op_Ne
+ and then (Is_Anonymous_Access_Type (Etype (Act1))
+ or else Is_Anonymous_Access_Type (Etype (Act2)))
then
null;
@@ -1662,7 +1668,7 @@ package body Sem_Res is
and then not In_Instance
then
if Is_Fixed_Point_Type (Typ)
- and then Nam_In (Op_Name, Name_Op_Multiply, Name_Op_Divide)
+ and then Op_Name in Name_Op_Multiply | Name_Op_Divide
then
-- Already checked above
@@ -1699,7 +1705,7 @@ package body Sem_Res is
-- the equality node will not resolve any remaining ambiguity, and it
-- assumes that the first operand is not overloaded.
- if Nam_In (Op_Name, Name_Op_Eq, Name_Op_Ne)
+ if Op_Name in Name_Op_Eq | Name_Op_Ne
and then Ekind (Func) = E_Function
and then Is_Overloaded (Act1)
then
@@ -1752,78 +1758,6 @@ package body Sem_Res is
else
Resolve (N, Typ);
end if;
-
- -- If in ASIS_Mode, propagate operand types to original actuals of
- -- function call, which would otherwise not be fully resolved. If
- -- the call has already been constant-folded, nothing to do. We
- -- relocate the operand nodes rather than copy them, to preserve
- -- original_node pointers, given that the operands themselves may
- -- have been rewritten. If the call was itself a rewriting of an
- -- operator node, nothing to do.
-
- if ASIS_Mode
- and then Nkind (N) in N_Op
- and then Nkind (Original_Node (N)) = N_Function_Call
- then
- declare
- L : Node_Id;
- R : constant Node_Id := Right_Opnd (N);
-
- Old_First : constant Node_Id :=
- First (Parameter_Associations (Original_Node (N)));
- Old_Sec : Node_Id;
-
- begin
- if Is_Binary then
- L := Left_Opnd (N);
- Old_Sec := Next (Old_First);
-
- -- If the original call has named associations, replace the
- -- explicit actual parameter in the association with the proper
- -- resolved operand.
-
- if Nkind (Old_First) = N_Parameter_Association then
- if Chars (Selector_Name (Old_First)) =
- Chars (First_Entity (Op_Id))
- then
- Rewrite (Explicit_Actual_Parameter (Old_First),
- Relocate_Node (L));
- else
- Rewrite (Explicit_Actual_Parameter (Old_First),
- Relocate_Node (R));
- end if;
-
- else
- Rewrite (Old_First, Relocate_Node (L));
- end if;
-
- if Nkind (Old_Sec) = N_Parameter_Association then
- if Chars (Selector_Name (Old_Sec)) =
- Chars (First_Entity (Op_Id))
- then
- Rewrite (Explicit_Actual_Parameter (Old_Sec),
- Relocate_Node (L));
- else
- Rewrite (Explicit_Actual_Parameter (Old_Sec),
- Relocate_Node (R));
- end if;
-
- else
- Rewrite (Old_Sec, Relocate_Node (R));
- end if;
-
- else
- if Nkind (Old_First) = N_Parameter_Association then
- Rewrite (Explicit_Actual_Parameter (Old_First),
- Relocate_Node (R));
- else
- Rewrite (Old_First, Relocate_Node (R));
- end if;
- end if;
- end;
-
- Set_Parent (Original_Node (N), Parent (N));
- end if;
end Make_Call_Into_Operator;
-------------------
@@ -2209,6 +2143,12 @@ package body Sem_Res is
return;
end Resolution_Failed;
+ Literal_Aspect_Map :
+ constant array (N_Numeric_Or_String_Literal) of Aspect_Id :=
+ (N_Integer_Literal => Aspect_Integer_Literal,
+ N_Real_Literal => Aspect_Real_Literal,
+ N_String_Literal => Aspect_String_Literal);
+
-- Start of processing for Resolve
begin
@@ -2220,9 +2160,9 @@ package body Sem_Res is
-- access-to-subprogram type.
if Nkind (N) = N_Attribute_Reference
- and then Nam_In (Attribute_Name (N), Name_Access,
- Name_Unrestricted_Access,
- Name_Unchecked_Access)
+ and then Attribute_Name (N) in Name_Access
+ | Name_Unrestricted_Access
+ | Name_Unchecked_Access
and then Comes_From_Source (N)
and then Is_Entity_Name (Prefix (N))
and then Is_Subprogram (Entity (Prefix (N)))
@@ -2344,10 +2284,18 @@ package body Sem_Res is
Check_Parameterless_Call (N);
-- The resolution of an Expression_With_Actions is determined by
- -- its Expression.
+ -- its Expression, but if the node comes from source it is a
+ -- Declare_Expression and requires scope management.
if Nkind (N) = N_Expression_With_Actions then
- Resolve (Expression (N), Typ);
+ if Comes_From_Source (N)
+ and then N = Original_Node (N)
+ then
+ Resolve_Declare_Expression (N, Typ);
+
+ else
+ Resolve (Expression (N), Typ);
+ end if;
Found := True;
Expr_Type := Etype (Expression (N));
@@ -2632,10 +2580,10 @@ package body Sem_Res is
Set_Entity (N, Seen);
Generate_Reference (Seen, N);
- elsif Nkind_In (N, N_Case_Expression,
- N_Character_Literal,
- N_Delta_Aggregate,
- N_If_Expression)
+ elsif Nkind (N) in N_Case_Expression
+ | N_Character_Literal
+ | N_Delta_Aggregate
+ | N_If_Expression
then
Set_Etype (N, Expr_Type);
@@ -2701,15 +2649,15 @@ package body Sem_Res is
-- with a name that is an explicit dereference, there is
-- nothing to be done at this point.
- elsif Nkind_In (N, N_Attribute_Reference,
- N_And_Then,
- N_Explicit_Dereference,
- N_Identifier,
- N_Indexed_Component,
- N_Or_Else,
- N_Range,
- N_Selected_Component,
- N_Slice)
+ elsif Nkind (N) in N_Attribute_Reference
+ | N_And_Then
+ | N_Explicit_Dereference
+ | N_Identifier
+ | N_Indexed_Component
+ | N_Or_Else
+ | N_Range
+ | N_Selected_Component
+ | N_Slice
or else Nkind (Name (N)) = N_Explicit_Dereference
then
null;
@@ -2826,6 +2774,17 @@ package body Sem_Res is
elsif Nkind (N) = N_Aggregate
and then Etype (N) = Any_Composite
then
+ if Ada_Version >= Ada_2020
+ and then Has_Aspect (Typ, Aspect_Aggregate)
+ then
+ Resolve_Container_Aggregate (N, Typ);
+
+ if Expander_Active then
+ Expand (N);
+ end if;
+ return;
+ end if;
+
-- Disable expansion in any case. If there is a type mismatch
-- it may be fatal to try to expand the aggregate. The flag
-- would otherwise be set to false when the error is posted.
@@ -2912,6 +2871,80 @@ package body Sem_Res is
end;
end if;
+ -- Rewrite Literal as a call if the corresponding literal aspect
+ -- is set.
+
+ if Nkind (N) in N_Numeric_Or_String_Literal
+ and then Present
+ (Find_Aspect (Typ, Literal_Aspect_Map (Nkind (N))))
+ then
+ declare
+ function Literal_Text (N : Node_Id) return String_Id;
+ -- Returns the text of a literal node
+
+ -------------------
+ -- Literal_Text --
+ -------------------
+
+ function Literal_Text (N : Node_Id) return String_Id is
+ begin
+ pragma Assert (Nkind (N) in N_Numeric_Or_String_Literal);
+
+ if Nkind (N) = N_String_Literal then
+ return Strval (N);
+ else
+ return String_From_Numeric_Literal (N);
+ end if;
+ end Literal_Text;
+
+ Lit_Aspect : constant Aspect_Id :=
+ Literal_Aspect_Map (Nkind (N));
+
+ Callee : constant Entity_Id :=
+ Entity (Expression (Find_Aspect (Typ, Lit_Aspect)));
+
+ Loc : constant Source_Ptr := Sloc (N);
+
+ Name : constant Node_Id :=
+ Make_Identifier (Loc, Chars (Callee));
+
+ Param : constant Node_Id :=
+ Make_String_Literal (Loc, Literal_Text (N));
+
+ Params : constant List_Id := New_List (Param);
+
+ Call : Node_Id :=
+ Make_Function_Call
+ (Sloc => Loc,
+ Name => Name,
+ Parameter_Associations => Params);
+ begin
+ Set_Entity (Name, Callee);
+ Set_Is_Overloaded (Name, False);
+ if Lit_Aspect = Aspect_String_Literal then
+ Set_Etype (Param, Standard_Wide_Wide_String);
+ else
+ Set_Etype (Param, Standard_String);
+ end if;
+ Set_Etype (Call, Etype (Callee));
+
+ -- Conversion needed in case of an inherited aspect
+ -- of a derived type.
+ --
+ -- ??? Need to do something different here for downward
+ -- tagged conversion case (which is only possible in the
+ -- case of a null extension); the current call to
+ -- Convert_To results in an error message about an illegal
+ -- downward conversion.
+
+ Call := Convert_To (Typ, Call);
+
+ Rewrite (N, Call);
+ end;
+ Analyze_And_Resolve (N, Typ);
+ return;
+ end if;
+
-- Looks like we have a type error, but check for special case
-- of Address wanted, integer found, with the configuration pragma
-- Allow_Integer_Address active. If we have this case, introduce
@@ -2925,7 +2958,7 @@ package body Sem_Res is
return;
-- Under relaxed RM semantics silently replace occurrences of null
- -- by System.Address_Null.
+ -- by System.Null_Address.
elsif Null_To_Null_Address_Convert_OK (N, Typ) then
Replace_Null_By_Null_Address (N);
@@ -3000,7 +3033,7 @@ package body Sem_Res is
Resolution_Failed;
return;
- -- Only one intepretation
+ -- Only one interpretation
else
-- In Ada 2005, if we have something like "X : T := 2 + 2;", where
@@ -3395,7 +3428,7 @@ package body Sem_Res is
procedure Flag_Effectively_Volatile_Objects (Expr : Node_Id);
-- Emit an error concerning the illegal usage of an effectively volatile
- -- object in interfering context (SPARK RM 7.13(12)).
+ -- object in interfering context (SPARK RM 7.1.3(10)).
procedure Insert_Default;
-- If the actual is missing in a call, insert in the actuals list
@@ -3680,7 +3713,7 @@ package body Sem_Res is
then
Error_Msg_N
("volatile object cannot appear in this context (SPARK "
- & "RM 7.1.3(11))", N);
+ & "RM 7.1.3(10))", N);
return Skip;
end if;
end if;
@@ -4077,69 +4110,107 @@ package body Sem_Res is
and then not Is_Class_Wide_Type (Etype (Expression (A)))
and then not Is_Interface (Etype (A))
then
- if Ekind (F) = E_In_Out_Parameter
- and then Is_Array_Type (Etype (F))
- then
- -- In a view conversion, the conversion must be legal in
- -- both directions, and thus both component types must be
- -- aliased, or neither (4.6 (8)).
+ declare
+ Expr_Typ : constant Entity_Id := Etype (Expression (A));
- -- The extra rule in 4.6 (24.9.2) seems unduly restrictive:
- -- the privacy requirement should not apply to generic
- -- types, and should be checked in an instance. ARG query
- -- is in order ???
+ begin
+ -- Check RM 4.6 (24.2/2)
- if Has_Aliased_Components (Etype (Expression (A))) /=
- Has_Aliased_Components (Etype (F))
+ if Is_Array_Type (Etype (F))
+ and then Is_View_Conversion (A)
then
- Error_Msg_N
- ("both component types in a view conversion must be"
- & " aliased, or neither", A);
+ -- In a view conversion, the conversion must be legal in
+ -- both directions, and thus both component types must be
+ -- aliased, or neither (4.6 (8)).
- -- Comment here??? what set of cases???
+ -- Check RM 4.6 (24.8/2)
- elsif
- not Same_Ancestor (Etype (F), Etype (Expression (A)))
- then
- -- Check view conv between unrelated by ref array types
+ if Has_Aliased_Components (Expr_Typ) /=
+ Has_Aliased_Components (Etype (F))
+ then
+ -- This normally illegal conversion is legal in an
+ -- expanded instance body because of RM 12.3(11).
+ -- At runtime, conversion must create a new object.
+
+ if not In_Instance then
+ Error_Msg_N
+ ("both component types in a view conversion must"
+ & " be aliased, or neither", A);
+ end if;
- if Is_By_Reference_Type (Etype (F))
- or else Is_By_Reference_Type (Etype (Expression (A)))
+ -- Check RM 4.6 (24/3)
+
+ elsif not Same_Ancestor (Etype (F), Expr_Typ) then
+ -- Check view conv between unrelated by ref array
+ -- types.
+
+ if Is_By_Reference_Type (Etype (F))
+ or else Is_By_Reference_Type (Expr_Typ)
+ then
+ Error_Msg_N
+ ("view conversion between unrelated by reference "
+ & "array types not allowed (\'A'I-00246)", A);
+
+ -- In Ada 2005 mode, check view conversion component
+ -- type cannot be private, tagged, or volatile. Note
+ -- that we only apply this to source conversions. The
+ -- generated code can contain conversions which are
+ -- not subject to this test, and we cannot extract the
+ -- component type in such cases since it is not
+ -- present.
+
+ elsif Comes_From_Source (A)
+ and then Ada_Version >= Ada_2005
+ then
+ declare
+ Comp_Type : constant Entity_Id :=
+ Component_Type (Expr_Typ);
+ begin
+ if (Is_Private_Type (Comp_Type)
+ and then not Is_Generic_Type (Comp_Type))
+ or else Is_Tagged_Type (Comp_Type)
+ or else Is_Volatile (Comp_Type)
+ then
+ Error_Msg_N
+ ("component type of a view conversion " &
+ "cannot be private, tagged, or volatile" &
+ " (RM 4.6 (24))",
+ Expression (A));
+ end if;
+ end;
+ end if;
+ end if;
+
+ -- AI12-0074 & AI12-0377
+ -- Check 6.4.1: If the mode is out, the actual parameter is
+ -- a view conversion, and the type of the formal parameter
+ -- is a scalar type, then either:
+ -- - the target and operand type both do not have the
+ -- Default_Value aspect specified; or
+ -- - the target and operand type both have the
+ -- Default_Value aspect specified, and there shall exist
+ -- a type (other than a root numeric type) that is an
+ -- ancestor of both the target type and the operand
+ -- type.
+
+ elsif Ekind (F) = E_Out_Parameter
+ and then Is_Scalar_Type (Etype (F))
+ then
+ if Has_Default_Aspect (Etype (F)) /=
+ Has_Default_Aspect (Expr_Typ)
then
Error_Msg_N
- ("view conversion between unrelated by reference "
- & "array types not allowed (\'A'I-00246)", A);
-
- -- In Ada 2005 mode, check view conversion component
- -- type cannot be private, tagged, or volatile. Note
- -- that we only apply this to source conversions. The
- -- generated code can contain conversions which are
- -- not subject to this test, and we cannot extract the
- -- component type in such cases since it is not present.
-
- elsif Comes_From_Source (A)
- and then Ada_Version >= Ada_2005
+ ("view conversion requires Default_Value on both " &
+ "types (RM 6.4.1)", A);
+ elsif Has_Default_Aspect (Expr_Typ)
+ and then not Same_Ancestor (Etype (F), Expr_Typ)
then
- declare
- Comp_Type : constant Entity_Id :=
- Component_Type
- (Etype (Expression (A)));
- begin
- if (Is_Private_Type (Comp_Type)
- and then not Is_Generic_Type (Comp_Type))
- or else Is_Tagged_Type (Comp_Type)
- or else Is_Volatile (Comp_Type)
- then
- Error_Msg_N
- ("component type of a view conversion cannot"
- & " be private, tagged, or volatile"
- & " (RM 4.6 (24))",
- Expression (A));
- end if;
- end;
+ Error_Msg_N
+ ("view conversion between unrelated types with "
+ & "Default_Value not allowed (RM 6.4.1)", A);
end if;
end if;
- end if;
+ end;
-- Resolve expression if conversion is all OK
@@ -4349,71 +4420,6 @@ package body Sem_Res is
("invalid use of untagged formal incomplete type", A);
end if;
- if Comes_From_Source (Original_Node (N))
- and then Nkind_In (Original_Node (N), N_Function_Call,
- N_Procedure_Call_Statement)
- then
- -- In formal mode, check that actual parameters matching
- -- formals of tagged types are objects (or ancestor type
- -- conversions of objects), not general expressions.
-
- if Is_Actual_Tagged_Parameter (A) then
- if Is_SPARK_05_Object_Reference (A) then
- null;
-
- elsif Nkind (A) = N_Type_Conversion then
- declare
- Operand : constant Node_Id := Expression (A);
- Operand_Typ : constant Entity_Id := Etype (Operand);
- Target_Typ : constant Entity_Id := A_Typ;
-
- begin
- if not Is_SPARK_05_Object_Reference (Operand) then
- Check_SPARK_05_Restriction
- ("object required", Operand);
-
- -- In formal mode, the only view conversions are those
- -- involving ancestor conversion of an extended type.
-
- elsif not
- (Is_Tagged_Type (Target_Typ)
- and then not Is_Class_Wide_Type (Target_Typ)
- and then Is_Tagged_Type (Operand_Typ)
- and then not Is_Class_Wide_Type (Operand_Typ)
- and then Is_Ancestor (Target_Typ, Operand_Typ))
- then
- if Ekind_In
- (F, E_Out_Parameter, E_In_Out_Parameter)
- then
- Check_SPARK_05_Restriction
- ("ancestor conversion is the only permitted "
- & "view conversion", A);
- else
- Check_SPARK_05_Restriction
- ("ancestor conversion required", A);
- end if;
-
- else
- null;
- end if;
- end;
-
- else
- Check_SPARK_05_Restriction ("object required", A);
- end if;
-
- -- In formal mode, the only view conversions are those
- -- involving ancestor conversion of an extended type.
-
- elsif Nkind (A) = N_Type_Conversion
- and then Ekind_In (F, E_Out_Parameter, E_In_Out_Parameter)
- then
- Check_SPARK_05_Restriction
- ("ancestor conversion is the only permitted view "
- & "conversion", A);
- end if;
- end if;
-
-- has warnings suppressed, then we reset Never_Set_In_Source for
-- the calling entity. The reason for this is to catch cases like
-- GNAT.Spitbol.Patterns.Vstring_Var where the called subprogram
@@ -4551,7 +4557,7 @@ package body Sem_Res is
-- Apply appropriate constraint/predicate checks for IN [OUT] case
- if Ekind_In (F, E_In_Parameter, E_In_Out_Parameter) then
+ if Ekind (F) in E_In_Parameter | E_In_Out_Parameter then
-- Apply predicate tests except in certain special cases. Note
-- that it might be more consistent to apply these only when
@@ -4633,7 +4639,7 @@ package body Sem_Res is
-- Checks for OUT parameters and IN OUT parameters
- if Ekind_In (F, E_Out_Parameter, E_In_Out_Parameter) then
+ if Ekind (F) in E_Out_Parameter | E_In_Out_Parameter then
-- If there is a type conversion, make sure the return value
-- meets the constraints of the variable before the conversion.
@@ -4646,6 +4652,7 @@ package body Sem_Res is
-- This is for Starlet only though, so long obsolete.
if Mechanism (F) = By_Reference
+ and then Ekind (Nam) = E_Procedure
and then Is_Valued_Procedure (Nam)
then
null;
@@ -4871,7 +4878,7 @@ package body Sem_Res is
-- An effectively volatile object may act as an actual when the
-- corresponding formal is of a non-scalar effectively volatile
- -- type (SPARK RM 7.1.3(11)).
+ -- type (SPARK RM 7.1.3(10)).
if not Is_Scalar_Type (Etype (F))
and then Is_Effectively_Volatile (Etype (F))
@@ -4880,7 +4887,7 @@ package body Sem_Res is
-- An effectively volatile object may act as an actual in a
-- call to an instance of Unchecked_Conversion.
- -- (SPARK RM 7.1.3(11)).
+ -- (SPARK RM 7.1.3(10)).
elsif Is_Unchecked_Conversion_Instance (Nam) then
null;
@@ -4890,7 +4897,7 @@ package body Sem_Res is
elsif Is_Effectively_Volatile_Object (A) then
Error_Msg_N
("volatile object cannot act as actual in a call (SPARK "
- & "RM 7.1.3(11))", A);
+ & "RM 7.1.3(10))", A);
-- Otherwise the actual denotes an expression. Inspect the
-- expression and flag each effectively volatile object with
@@ -4951,7 +4958,7 @@ package body Sem_Res is
if Comes_From_Source (Nam)
and then Is_Ghost_Entity (Nam)
- and then Ekind_In (F, E_In_Out_Parameter, E_Out_Parameter)
+ and then Ekind (F) in E_In_Out_Parameter | E_Out_Parameter
and then Is_Entity_Name (A)
and then Present (Entity (A))
and then not Is_Ghost_Entity (Entity (A))
@@ -5092,7 +5099,7 @@ package body Sem_Res is
Expr := Next (First (Expressions (Disc_Exp)));
if Present (Expr) then
Check_Allocator_Discrim_Accessibility_Exprs (Expr, Alloc_Typ);
- Expr := Next (Expr);
+ Next (Expr);
if Present (Expr) then
Check_Allocator_Discrim_Accessibility_Exprs
(Expr, Alloc_Typ);
@@ -5158,8 +5165,9 @@ package body Sem_Res is
("class-wide allocator not allowed for this access type", N);
end if;
- Resolve (Expression (E), Etype (E));
- Check_Non_Static_Context (Expression (E));
+ -- Do a full resolution to apply constraint and predicate checks
+
+ Resolve_Qualified_Expression (E, Etype (E));
Check_Unset_Reference (Expression (E));
-- Allocators generated by the build-in-place expansion mechanism
@@ -5193,16 +5201,6 @@ package body Sem_Res is
end if;
end if;
- -- A qualified expression requires an exact match of the type. Class-
- -- wide matching is not allowed.
-
- if (Is_Class_Wide_Type (Etype (Expression (E)))
- or else Is_Class_Wide_Type (Etype (E)))
- and then Base_Type (Etype (Expression (E))) /= Base_Type (Etype (E))
- then
- Wrong_Type (Expression (E), Etype (E));
- end if;
-
-- Calls to build-in-place functions are not currently supported in
-- allocators for access types associated with a simple storage pool.
-- Supporting such allocators may require passing additional implicit
@@ -5247,7 +5245,7 @@ package body Sem_Res is
Aggr := Original_Node (Expression (E));
if Has_Discriminants (Subtyp)
- and then Nkind_In (Aggr, N_Aggregate, N_Extension_Aggregate)
+ and then Nkind (Aggr) in N_Aggregate | N_Extension_Aggregate
then
Discrim := First_Discriminant (Base_Type (Subtyp));
@@ -5604,18 +5602,18 @@ package body Sem_Res is
-- N is the expression after "delta" in a fixed_point_definition;
-- see RM-3.5.9(6):
- return Nkind_In (Parent (N), N_Ordinary_Fixed_Point_Definition,
- N_Decimal_Fixed_Point_Definition,
+ return Nkind (Parent (N)) in N_Ordinary_Fixed_Point_Definition
+ | N_Decimal_Fixed_Point_Definition
-- N is one of the bounds in a real_range_specification;
-- see RM-3.5.7(5):
- N_Real_Range_Specification,
+ | N_Real_Range_Specification
-- N is the expression of a delta_constraint;
-- see RM-J.3(3):
- N_Delta_Constraint);
+ | N_Delta_Constraint;
end Expected_Type_Is_Any_Real;
-----------------------------
@@ -5697,7 +5695,7 @@ package body Sem_Res is
-- a conversion will be applied to each operand, so resolve it
-- with its own type.
- if Nkind_In (Parent (N), N_Op_Divide, N_Op_Multiply) then
+ if Nkind (Parent (N)) in N_Op_Divide | N_Op_Multiply then
Resolve (N);
else
@@ -5785,7 +5783,7 @@ package body Sem_Res is
-- involving a fixed-point operand) the conditional expression must
-- resolve to a unique visible fixed_point type, normally Duration.
- elsif Nkind_In (N, N_Case_Expression, N_If_Expression)
+ elsif Nkind (N) in N_Case_Expression | N_If_Expression
and then Etype (N) = Universal_Real
and then Is_Fixed_Point_Type (B_Typ)
then
@@ -5850,7 +5848,7 @@ package body Sem_Res is
and then (Is_Integer_Or_Universal (L)
or else
Is_Integer_Or_Universal (R))))
- and then Nkind_In (N, N_Op_Multiply, N_Op_Divide)
+ and then Nkind (N) in N_Op_Multiply | N_Op_Divide
then
if TL = Universal_Integer or else TR = Universal_Integer then
Check_For_Visible_Operator (N, B_Typ);
@@ -5896,8 +5894,8 @@ package body Sem_Res is
then
if B_Typ = Universal_Fixed
and then not Expected_Type_Is_Any_Real (N)
- and then not Nkind_In (Parent (N), N_Type_Conversion,
- N_Unchecked_Type_Conversion)
+ and then Nkind (Parent (N)) not in
+ N_Type_Conversion | N_Unchecked_Type_Conversion
then
Error_Msg_N ("type cannot be determined from context!", N);
Error_Msg_N ("\explicit conversion to result type required", N);
@@ -5908,9 +5906,8 @@ package body Sem_Res is
else
if Ada_Version = Ada_83
and then Etype (N) = Universal_Fixed
- and then not
- Nkind_In (Parent (N), N_Type_Conversion,
- N_Unchecked_Type_Conversion)
+ and then Nkind (Parent (N)) not in
+ N_Type_Conversion | N_Unchecked_Type_Conversion
then
Error_Msg_N
("(Ada 83) fixed-point operation needs explicit "
@@ -5989,20 +5986,6 @@ package body Sem_Res is
Analyze_Dimension (N);
Eval_Arithmetic_Op (N);
- -- In SPARK, a multiplication or division with operands of fixed point
- -- types must be qualified or explicitly converted to identify the
- -- result type.
-
- if (Is_Fixed_Point_Type (Etype (L))
- or else Is_Fixed_Point_Type (Etype (R)))
- and then Nkind_In (N, N_Op_Multiply, N_Op_Divide)
- and then
- not Nkind_In (Parent (N), N_Qualified_Expression, N_Type_Conversion)
- then
- Check_SPARK_05_Restriction
- ("operation should be qualified or explicitly converted", N);
- end if;
-
-- Set overflow and division checking bit
if Nkind (N) in N_Op then
@@ -6012,7 +5995,7 @@ package body Sem_Res is
-- Give warning if explicit division by zero
- if Nkind_In (N, N_Op_Divide, N_Op_Rem, N_Op_Mod)
+ if Nkind (N) in N_Op_Divide | N_Op_Rem | N_Op_Mod
and then not Division_Checks_Suppressed (Etype (N))
then
Rop := Right_Opnd (N);
@@ -6093,7 +6076,7 @@ package body Sem_Res is
-- if both operands can be negative.
if Restriction_Check_Required (No_Implicit_Conditionals)
- and then Nkind_In (N, N_Op_Rem, N_Op_Mod)
+ and then Nkind (N) in N_Op_Rem | N_Op_Mod
then
declare
Lo : Uint;
@@ -6243,9 +6226,8 @@ package body Sem_Res is
-- operations use the same circuitry because the name in the call
-- can be an arbitrary expression with special resolution rules.
- elsif Nkind_In (Subp, N_Selected_Component, N_Indexed_Component)
- or else (Is_Entity_Name (Subp)
- and then Ekind_In (Entity (Subp), E_Entry, E_Entry_Family))
+ elsif Nkind (Subp) in N_Selected_Component | N_Indexed_Component
+ or else (Is_Entity_Name (Subp) and then Is_Entry (Entity (Subp)))
then
Resolve_Entry_Call (N, Typ);
@@ -6293,26 +6275,6 @@ package body Sem_Res is
end loop;
end if;
- if Is_Access_Subprogram_Type (Base_Type (Etype (Nam)))
- and then not Is_Access_Subprogram_Type (Base_Type (Typ))
- and then Nkind (Subp) /= N_Explicit_Dereference
- and then Present (Parameter_Associations (N))
- then
- -- The prefix is a parameterless function call that returns an access
- -- to subprogram. If parameters are present in the current call, add
- -- add an explicit dereference. We use the base type here because
- -- within an instance these may be subtypes.
-
- -- The dereference is added either in Analyze_Call or here. Should
- -- be consolidated ???
-
- Set_Is_Overloaded (Subp, False);
- Set_Etype (Subp, Etype (Nam));
- Insert_Explicit_Dereference (Subp);
- Nam := Designated_Type (Etype (Nam));
- Resolve (Subp, Nam);
- end if;
-
-- Check that a call to Current_Task does not occur in an entry body
if Is_RTE (Nam, RE_Current_Task) then
@@ -6381,30 +6343,6 @@ package body Sem_Res is
end if;
end if;
- -- If the SPARK_05 restriction is active, we are not allowed
- -- to have a call to a subprogram before we see its completion.
-
- if not Has_Completion (Nam)
- and then Restriction_Check_Required (SPARK_05)
-
- -- Don't flag strange internal calls
-
- and then Comes_From_Source (N)
- and then Comes_From_Source (Nam)
-
- -- Only flag calls in extended main source
-
- and then In_Extended_Main_Source_Unit (Nam)
- and then In_Extended_Main_Source_Unit (N)
-
- -- Exclude enumeration literals from this processing
-
- and then Ekind (Nam) /= E_Enumeration_Literal
- then
- Check_SPARK_05_Restriction
- ("call to subprogram cannot appear before its body", N);
- end if;
-
-- Check that this is not a call to a protected procedure or entry from
-- within a protected function.
@@ -6565,7 +6503,6 @@ package body Sem_Res is
Set_Etype (Prefix (N), Ret_Type);
Set_Etype (N, Typ);
- Resolve_Indexed_Component (N, Typ);
if Legacy_Elaboration_Checks then
Check_Elab_Call (Prefix (N));
@@ -6577,6 +6514,8 @@ package body Sem_Res is
-- the ABE Processing phase.
Build_Call_Marker (Prefix (N));
+
+ Resolve_Indexed_Component (N, Typ);
end if;
end if;
@@ -6639,21 +6578,12 @@ package body Sem_Res is
if Comes_From_Source (N) then
Scop := Current_Scope;
- -- Check violation of SPARK_05 restriction which does not permit
- -- a subprogram body to contain a call to the subprogram directly.
-
- if Restriction_Check_Required (SPARK_05)
- and then Same_Or_Aliased_Subprograms (Nam, Scop)
- then
- Check_SPARK_05_Restriction
- ("subprogram may not contain direct call to itself", N);
- end if;
-
-- Issue warning for possible infinite recursion in the absence
-- of the No_Recursion restriction.
if Same_Or_Aliased_Subprograms (Nam, Scop)
and then not Restriction_Active (No_Recursion)
+ and then not Is_Static_Function (Scop)
and then Check_Infinite_Recursion (N)
then
-- Here we detected and flagged an infinite recursion, so we do
@@ -6671,6 +6601,19 @@ package body Sem_Res is
Scope_Loop : while Scop /= Standard_Standard loop
if Same_Or_Aliased_Subprograms (Nam, Scop) then
+ -- Ada 202x (AI12-0075): Static functions are never allowed
+ -- to make a recursive call, as specified by 6.8(5.4/5).
+
+ if Is_Static_Function (Scop) then
+ Error_Msg_N
+ ("recursive call not allowed in static expression "
+ & "function", N);
+
+ Set_Error_Posted (Scop);
+
+ exit Scope_Loop;
+ end if;
+
-- Although in general case, recursion is not statically
-- checkable, the case of calling an immediately containing
-- subprogram is easy to catch.
@@ -6714,8 +6657,8 @@ package body Sem_Res is
begin
P := Prev (N);
while Present (P) loop
- if not Nkind_In (P, N_Assignment_Statement,
- N_Raise_Constraint_Error)
+ if Nkind (P) not in N_Assignment_Statement
+ | N_Raise_Constraint_Error
then
exit Scope_Loop;
end if;
@@ -6808,6 +6751,11 @@ package body Sem_Res is
-- is already present. It may not be available if e.g. the subprogram is
-- declared in a child instance.
+ -- g) If the subprogram is a static expression function and the call is
+ -- a static call (the actuals are all static expressions), then we never
+ -- want to create a transient scope (this could occur in the case of a
+ -- static string-returning call).
+
if Is_Inlined (Nam)
and then Has_Pragma_Inline (Nam)
and then Nkind (Unit_Declaration_Node (Nam)) = N_Subprogram_Declaration
@@ -6819,6 +6767,7 @@ package body Sem_Res is
or else Is_Build_In_Place_Function (Nam)
or else Is_Intrinsic_Subprogram (Nam)
or else Is_Inlinable_Expression_Function (Nam)
+ or else Is_Static_Function_Call (N)
then
null;
@@ -6826,7 +6775,7 @@ package body Sem_Res is
-- secondary stack (or any other one).
elsif Expander_Active
- and then Ekind_In (Nam, E_Function, E_Subprogram_Type)
+ and then Ekind (Nam) in E_Function | E_Subprogram_Type
and then Requires_Transient_Scope (Etype (Nam))
and then not Is_Ignored_Ghost_Entity (Nam)
then
@@ -6925,7 +6874,7 @@ package body Sem_Res is
F := First_Formal (Nam);
A := First_Actual (N);
while Present (F) and then Present (A) loop
- if Ekind_In (F, E_Out_Parameter, E_In_Out_Parameter)
+ if Ekind (F) in E_Out_Parameter | E_In_Out_Parameter
and then Warn_On_Modified_As_Out_Parameter (F)
and then Is_Entity_Name (A)
and then Present (Entity (A))
@@ -7006,17 +6955,6 @@ package body Sem_Res is
Check_For_Eliminated_Subprogram (Subp, Nam);
- -- In formal mode, the primitive operations of a tagged type or type
- -- extension do not include functions that return the tagged type.
-
- if Nkind (N) = N_Function_Call
- and then Is_Tagged_Type (Etype (N))
- and then Is_Entity_Name (Name (N))
- and then Is_Inherited_Operation_For_Type (Entity (Name (N)), Etype (N))
- then
- Check_SPARK_05_Restriction ("function not inherited", N);
- end if;
-
-- Implement rule in 12.5.1 (23.3/2): In an instance, if the actual is
-- class-wide and the call dispatches on result in a context that does
-- not provide a tag, the call raises Program_Error.
@@ -7094,12 +7032,26 @@ package body Sem_Res is
Warn_On_Overlapping_Actuals (Nam, N);
+ -- Ada 202x (AI12-0075): If the call is a static call to a static
+ -- expression function, then we want to "inline" the call, replacing
+ -- it with the folded static result. This is not done if the checking
+ -- for a potentially static expression is enabled or if an error has
+ -- been posted on the call (which may be due to the check for recursive
+ -- calls, in which case we don't want to fall into infinite recursion
+ -- when doing the inlining).
+
+ if not Checking_Potentially_Static_Expression
+ and then Is_Static_Function_Call (N)
+ and then not Error_Posted (Ultimate_Alias (Nam))
+ then
+ Inline_Static_Function_Call (N, Ultimate_Alias (Nam));
+
-- In GNATprove mode, expansion is disabled, but we want to inline some
-- subprograms to facilitate formal verification. Indirect calls through
-- a subprogram type or within a generic cannot be inlined. Inlining is
-- performed only for calls subject to SPARK_Mode on.
- if GNATprove_Mode
+ elsif GNATprove_Mode
and then SPARK_Mode = On
and then Is_Overloadable (Nam)
and then not Inside_A_Generic
@@ -7449,20 +7401,6 @@ package body Sem_Res is
Generate_Operator_Reference (N, T);
Check_Low_Bound_Tested (N);
- -- In SPARK, ordering operators <, <=, >, >= are not defined for Boolean
- -- types or array types except String.
-
- if Is_Boolean_Type (T) then
- Check_SPARK_05_Restriction
- ("comparison is not defined on Boolean type", N);
-
- elsif Is_Array_Type (T)
- and then Base_Type (T) /= Standard_String
- then
- Check_SPARK_05_Restriction
- ("comparison is not defined on array types other than String", N);
- end if;
-
-- Check comparison on unordered enumeration
if Bad_Unordered_Enumeration_Reference (N, Etype (L)) then
@@ -7491,6 +7429,49 @@ package body Sem_Res is
end if;
end Resolve_Comparison_Op;
+ --------------------------------
+ -- Resolve_Declare_Expression --
+ --------------------------------
+
+ procedure Resolve_Declare_Expression
+ (N : Node_Id;
+ Typ : Entity_Id)
+ is
+ Decl : Node_Id;
+ begin
+ -- Install the scope created for local declarations, if
+ -- any. The syntax allows a Declare_Expression with no
+ -- declarations, in analogy with block statements.
+
+ Decl := First (Actions (N));
+
+ while Present (Decl) loop
+ exit when Nkind (Decl) = N_Object_Declaration;
+ Next (Decl);
+ end loop;
+
+ if Present (Decl) then
+ Push_Scope (Scope (Defining_Identifier (Decl)));
+
+ declare
+ E : Entity_Id := First_Entity (Current_Scope);
+
+ begin
+ while Present (E) loop
+ Set_Current_Entity (E);
+ Set_Is_Immediately_Visible (E);
+ Next_Entity (E);
+ end loop;
+ end;
+
+ Resolve (Expression (N), Typ);
+ End_Scope;
+
+ else
+ Resolve (Expression (N), Typ);
+ end if;
+ end Resolve_Declare_Expression;
+
-----------------------------------------
-- Resolve_Discrete_Subtype_Indication --
-----------------------------------------
@@ -7595,6 +7576,10 @@ package body Sem_Res is
-- Determine whether node Context denotes an assignment statement or an
-- object declaration whose expression is node Expr.
+ function Is_Attribute_Expression (Expr : Node_Id) return Boolean;
+ -- Determine whether Expr is part of an N_Attribute_Reference
+ -- expression.
+
----------------------------------------
-- Is_Assignment_Or_Object_Expression --
----------------------------------------
@@ -7604,8 +7589,8 @@ package body Sem_Res is
Expr : Node_Id) return Boolean
is
begin
- if Nkind_In (Context, N_Assignment_Statement,
- N_Object_Declaration)
+ if Nkind (Context) in
+ N_Assignment_Statement | N_Object_Declaration
and then Expression (Context) = Expr
then
return True;
@@ -7613,15 +7598,15 @@ package body Sem_Res is
-- Check whether a construct that yields a name is the expression of
-- an assignment statement or an object declaration.
- elsif (Nkind_In (Context, N_Attribute_Reference,
- N_Explicit_Dereference,
- N_Indexed_Component,
- N_Selected_Component,
- N_Slice)
+ elsif (Nkind (Context) in N_Attribute_Reference
+ | N_Explicit_Dereference
+ | N_Indexed_Component
+ | N_Selected_Component
+ | N_Slice
and then Prefix (Context) = Expr)
or else
- (Nkind_In (Context, N_Type_Conversion,
- N_Unchecked_Type_Conversion)
+ (Nkind (Context) in N_Type_Conversion
+ | N_Unchecked_Type_Conversion
and then Expression (Context) = Expr)
then
return
@@ -7637,6 +7622,24 @@ package body Sem_Res is
end if;
end Is_Assignment_Or_Object_Expression;
+ -----------------------------
+ -- Is_Attribute_Expression --
+ -----------------------------
+
+ function Is_Attribute_Expression (Expr : Node_Id) return Boolean is
+ N : Node_Id := Expr;
+ begin
+ while Present (N) loop
+ if Nkind (N) = N_Attribute_Reference then
+ return True;
+ end if;
+
+ N := Parent (N);
+ end loop;
+
+ return False;
+ end Is_Attribute_Expression;
+
-- Local variables
E : constant Entity_Id := Entity (N);
@@ -7707,8 +7710,8 @@ package body Sem_Res is
-- array types (i.e. bounds and length) are legal.
elsif Ekind (E) = E_Out_Parameter
- and then (Nkind (Parent (N)) /= N_Attribute_Reference
- or else Is_Scalar_Type (Etype (E)))
+ and then (Is_Scalar_Type (Etype (E))
+ or else not Is_Attribute_Expression (Parent (N)))
and then (Nkind (Parent (N)) in N_Op
or else Nkind (Parent (N)) = N_Explicit_Dereference
@@ -7768,7 +7771,7 @@ package body Sem_Res is
-- An effectively volatile object subject to enabled properties
-- Async_Writers or Effective_Reads must appear in non-interfering
- -- context (SPARK RM 7.1.3(12)).
+ -- context (SPARK RM 7.1.3(10)).
if Is_Object (E)
and then Is_Effectively_Volatile (E)
@@ -7778,7 +7781,7 @@ package body Sem_Res is
then
SPARK_Msg_N
("volatile object cannot appear in this context "
- & "(SPARK RM 7.1.3(12))", N);
+ & "(SPARK RM 7.1.3(10))", N);
end if;
-- Check for possible elaboration issues with respect to reads of
@@ -7854,7 +7857,7 @@ package body Sem_Res is
-- to the discriminant of the same name in the target task. If the
-- entry name is the target of a requeue statement and the entry is
-- in the current protected object, the bound to be used is the
- -- discriminal of the object (see Apply_Range_Checks for details of
+ -- discriminal of the object (see Apply_Range_Check for details of
-- the transformation).
-----------------------------
@@ -8014,10 +8017,23 @@ package body Sem_Res is
if Nkind (Entry_Name) = N_Selected_Component then
Resolve (Prefix (Entry_Name));
+ Resolve_Implicit_Dereference (Prefix (Entry_Name));
else pragma Assert (Nkind (Entry_Name) = N_Indexed_Component);
Nam := Entity (Selector_Name (Prefix (Entry_Name)));
Resolve (Prefix (Prefix (Entry_Name)));
+ Resolve_Implicit_Dereference (Prefix (Prefix (Entry_Name)));
+
+ -- We do not resolve the prefix because an Entry_Family has no type,
+ -- although it has the semantics of an array since it can be indexed.
+ -- In order to perform the associated range check, we would need to
+ -- build an array type on the fly and set it on the prefix, but this
+ -- would be wasteful since only the index type matters. Therefore we
+ -- attach this index type directly, so that Actual_Index_Expression
+ -- can pick it up later in order to generate the range check.
+
+ Set_Etype (Prefix (Entry_Name), Actual_Index_Type (Nam));
+
Index := First (Expressions (Entry_Name));
Resolve (Index, Entry_Index_Type (Nam));
@@ -8033,7 +8049,7 @@ package body Sem_Res is
if Nkind (Index) = N_Parameter_Association then
Error_Msg_N ("expect expression for entry index", Index);
else
- Apply_Range_Check (Index, Actual_Index_Type (Nam));
+ Apply_Scalar_Range_Check (Index, Etype (Prefix (Entry_Name)));
end if;
end if;
end Resolve_Entry;
@@ -8159,7 +8175,7 @@ package body Sem_Res is
end;
end if;
- if Ekind_In (Nam, E_Entry, E_Entry_Family)
+ if Is_Entry (Nam)
and then Present (Contract_Wrapper (Nam))
and then Current_Scope /= Contract_Wrapper (Nam)
then
@@ -8230,7 +8246,7 @@ package body Sem_Res is
Generate_Reference (Nam, Entry_Name, 's');
- if Ekind_In (Nam, E_Entry, E_Entry_Family) then
+ if Is_Entry (Nam) then
Check_Potentially_Blocking_Operation (N);
end if;
@@ -8312,6 +8328,13 @@ package body Sem_Res is
then
Establish_Transient_Scope (N, Manage_Sec_Stack => True);
end if;
+
+ -- Now we know that this is not a call to a function that returns an
+ -- array type; moreover, we know the name of the called entry. Detect
+ -- overlapping actuals, just like for a subprogram call.
+
+ Warn_On_Overlapping_Actuals (Nam, N);
+
end Resolve_Entry_Call;
-------------------------
@@ -8447,13 +8470,11 @@ package body Sem_Res is
S : Entity_Id;
begin
- if Ekind_In (Etype (R), E_Allocator_Type,
- E_Access_Attribute_Type)
+ if Ekind (Etype (R)) in E_Allocator_Type | E_Access_Attribute_Type
then
Acc := Designated_Type (Etype (R));
- elsif Ekind_In (Etype (L), E_Allocator_Type,
- E_Access_Attribute_Type)
+ elsif Ekind (Etype (L)) in E_Allocator_Type | E_Access_Attribute_Type
then
Acc := Designated_Type (Etype (L));
else
@@ -8506,7 +8527,7 @@ package body Sem_Res is
return;
elsif T = Any_Access
- or else Ekind_In (T, E_Allocator_Type, E_Access_Attribute_Type)
+ or else Ekind (T) in E_Allocator_Type | E_Access_Attribute_Type
then
T := Find_Unique_Access_Type;
@@ -8523,10 +8544,8 @@ package body Sem_Res is
-- Why no similar processing for case expressions???
elsif Ada_Version >= Ada_2012
- and then Ekind_In (Etype (L), E_Anonymous_Access_Type,
- E_Anonymous_Access_Subprogram_Type)
- and then Ekind_In (Etype (R), E_Anonymous_Access_Type,
- E_Anonymous_Access_Subprogram_Type)
+ and then Is_Anonymous_Access_Type (Etype (L))
+ and then Is_Anonymous_Access_Type (Etype (R))
then
Check_If_Expression (L);
Check_If_Expression (R);
@@ -8535,27 +8554,6 @@ package body Sem_Res is
Resolve (L, T);
Resolve (R, T);
- -- In SPARK, equality operators = and /= for array types other than
- -- String are only defined when, for each index position, the
- -- operands have equal static bounds.
-
- if Is_Array_Type (T) then
-
- -- Protect call to Matching_Static_Array_Bounds to avoid costly
- -- operation if not needed.
-
- if Restriction_Check_Required (SPARK_05)
- and then Base_Type (T) /= Standard_String
- and then Base_Type (Etype (L)) = Base_Type (Etype (R))
- and then Etype (L) /= Any_Composite -- or else L in error
- and then Etype (R) /= Any_Composite -- or else R in error
- and then not Matching_Static_Array_Bounds (Etype (L), Etype (R))
- then
- Check_SPARK_05_Restriction
- ("array types should have matching static bounds", N);
- end if;
- end if;
-
-- If the unique type is a class-wide type then it will be expanded
-- into a dispatching call to the predefined primitive. Therefore we
-- check here for potential violation of such restriction.
@@ -8670,8 +8668,8 @@ package body Sem_Res is
if Expander_Active
and then
- (Ekind_In (T, E_Anonymous_Access_Type,
- E_Anonymous_Access_Subprogram_Type)
+ (Ekind (T) in E_Anonymous_Access_Type
+ | E_Anonymous_Access_Subprogram_Type
or else Is_Private_Type (T))
then
if Etype (L) /= T then
@@ -8827,18 +8825,102 @@ package body Sem_Res is
-------------------------------------
procedure Resolve_Expression_With_Actions (N : Node_Id; Typ : Entity_Id) is
+
+ function OK_For_Static (Act : Node_Id) return Boolean;
+ -- True if Act is an action of a declare_expression that is allowed in a
+ -- static declare_expression.
+
+ function All_OK_For_Static return Boolean;
+ -- True if all actions of N are allowed in a static declare_expression.
+
+ function Get_Literal (Expr : Node_Id) return Node_Id;
+ -- Expr is an expression with compile-time-known value. This returns the
+ -- literal node that reprsents that value.
+
+ function OK_For_Static (Act : Node_Id) return Boolean is
+ begin
+ case Nkind (Act) is
+ when N_Object_Declaration =>
+ if Constant_Present (Act)
+ and then Is_Static_Expression (Expression (Act))
+ then
+ return True;
+ end if;
+
+ when N_Object_Renaming_Declaration =>
+ if Statically_Names_Object (Name (Act)) then
+ return True;
+ end if;
+
+ when others =>
+ -- No other declarations, nor even pragmas, are allowed in a
+ -- declare expression, so if we see something else, it must be
+ -- an internally generated expression_with_actions.
+ null;
+ end case;
+
+ return False;
+ end OK_For_Static;
+
+ function All_OK_For_Static return Boolean is
+ Act : Node_Id := First (Actions (N));
+ begin
+ while Present (Act) loop
+ if not OK_For_Static (Act) then
+ return False;
+ end if;
+
+ Next (Act);
+ end loop;
+
+ return True;
+ end All_OK_For_Static;
+
+ function Get_Literal (Expr : Node_Id) return Node_Id is
+ pragma Assert (Compile_Time_Known_Value (Expr));
+ Result : Node_Id;
+ begin
+ case Nkind (Expr) is
+ when N_Has_Entity =>
+ if Ekind (Entity (Expr)) = E_Enumeration_Literal then
+ Result := Expr;
+ else
+ Result := Constant_Value (Entity (Expr));
+ end if;
+ when N_Numeric_Or_String_Literal =>
+ Result := Expr;
+ when others =>
+ raise Program_Error;
+ end case;
+
+ pragma Assert
+ (Nkind (Result) in N_Numeric_Or_String_Literal
+ or else Ekind (Entity (Result)) = E_Enumeration_Literal);
+ return Result;
+ end Get_Literal;
+
+ Loc : constant Source_Ptr := Sloc (N);
+
begin
Set_Etype (N, Typ);
- -- If N has no actions, and its expression has been constant folded,
- -- then rewrite N as just its expression. Note, we can't do this in
- -- the general case of Is_Empty_List (Actions (N)) as this would cause
- -- Expression (N) to be expanded again.
+ if Is_Empty_List (Actions (N)) then
+ pragma Assert (All_OK_For_Static); null;
+ end if;
+
+ -- If the value of the expression is known at compile time, and all
+ -- of the actions (if any) are suitable, then replace the declare
+ -- expression with its expression. This allows the declare expression
+ -- as a whole to be static if appropriate. See AI12-0368.
- if Is_Empty_List (Actions (N))
- and then Compile_Time_Known_Value (Expression (N))
- then
- Rewrite (N, Expression (N));
+ if Compile_Time_Known_Value (Expression (N)) then
+ if Is_Empty_List (Actions (N)) then
+ Rewrite (N, Expression (N));
+ elsif All_OK_For_Static then
+ Rewrite
+ (N, New_Copy_Tree
+ (Get_Literal (Expression (N)), New_Sloc => Loc));
+ end if;
end if;
end Resolve_Expression_With_Actions;
@@ -8848,47 +8930,9 @@ package body Sem_Res is
procedure Resolve_Generalized_Indexing (N : Node_Id; Typ : Entity_Id) is
Indexing : constant Node_Id := Generalized_Indexing (N);
- Call : Node_Id;
- Indexes : List_Id;
- Pref : Node_Id;
-
begin
- -- In ASIS mode, propagate the information about the indexes back to
- -- to the original indexing node. The generalized indexing is either
- -- a function call, or a dereference of one. The actuals include the
- -- prefix of the original node, which is the container expression.
-
- if ASIS_Mode then
- Resolve (Indexing, Typ);
- Set_Etype (N, Etype (Indexing));
- Set_Is_Overloaded (N, False);
-
- Call := Indexing;
- while Nkind_In (Call, N_Explicit_Dereference, N_Selected_Component)
- loop
- Call := Prefix (Call);
- end loop;
-
- if Nkind (Call) = N_Function_Call then
- Indexes := New_Copy_List (Parameter_Associations (Call));
- Pref := Remove_Head (Indexes);
- Set_Expressions (N, Indexes);
-
- -- If expression is to be reanalyzed, reset Generalized_Indexing
- -- to recreate call node, as is the case when the expression is
- -- part of an expression function.
-
- if In_Spec_Expression then
- Set_Generalized_Indexing (N, Empty);
- end if;
-
- Set_Prefix (N, Pref);
- end if;
-
- else
- Rewrite (N, Indexing);
- Resolve (N, Typ);
- end if;
+ Rewrite (N, Indexing);
+ Resolve (N, Typ);
end Resolve_Generalized_Indexing;
---------------------------
@@ -9013,6 +9057,32 @@ package body Sem_Res is
Analyze_Dimension (N);
end Resolve_If_Expression;
+ ----------------------------------
+ -- Resolve_Implicit_Dereference --
+ ----------------------------------
+
+ procedure Resolve_Implicit_Dereference (P : Node_Id) is
+ Desig_Typ : Entity_Id;
+
+ begin
+ -- In an instance the proper view may not always be correct for
+ -- private types, see e.g. Sem_Type.Covers for similar handling.
+
+ if Is_Private_Type (Etype (P))
+ and then Present (Full_View (Etype (P)))
+ and then Is_Access_Type (Full_View (Etype (P)))
+ and then In_Instance
+ then
+ Set_Etype (P, Full_View (Etype (P)));
+ end if;
+
+ if Is_Access_Type (Etype (P)) then
+ Desig_Typ := Implicitly_Designated_Type (Etype (P));
+ Insert_Explicit_Dereference (P);
+ Analyze_And_Resolve (P, Desig_Typ);
+ end if;
+ end Resolve_Implicit_Dereference;
+
-------------------------------
-- Resolve_Indexed_Component --
-------------------------------
@@ -9085,15 +9155,15 @@ package body Sem_Res is
Resolve (Name, Array_Type);
Array_Type := Get_Actual_Subtype_If_Available (Name);
- -- If prefix is access type, dereference to get real array type.
- -- Note: we do not apply an access check because the expander always
- -- introduces an explicit dereference, and the check will happen there.
+ -- If the prefix's type is an access type, get to the real array type.
+ -- Note: we do not apply an access check because an explicit dereference
+ -- will be introduced later, and the check will happen there.
if Is_Access_Type (Array_Type) then
- Array_Type := Designated_Type (Array_Type);
+ Array_Type := Implicitly_Designated_Type (Array_Type);
end if;
- -- If name was overloaded, set component type correctly now
+ -- If name was overloaded, set component type correctly now.
-- If a misplaced call to an entry family (which has no index types)
-- return. Error will be diagnosed from calling context.
@@ -9115,21 +9185,18 @@ package body Sem_Res is
Resolve (Expr, Standard_Positive);
else
- while Present (Index) and Present (Expr) loop
+ while Present (Index) and then Present (Expr) loop
Resolve (Expr, Etype (Index));
Check_Unset_Reference (Expr);
- if Is_Scalar_Type (Etype (Expr)) then
- Apply_Scalar_Range_Check (Expr, Etype (Index));
- else
- Apply_Range_Check (Expr, Get_Actual_Subtype (Index));
- end if;
+ Apply_Scalar_Range_Check (Expr, Etype (Index));
Next_Index (Index);
Next (Expr);
end loop;
end if;
+ Resolve_Implicit_Dereference (Prefix (N));
Analyze_Dimension (N);
-- Do not generate the warning on suspicious index if we are analyzing
@@ -9145,10 +9212,10 @@ package body Sem_Res is
Eval_Indexed_Component (N);
end if;
- -- If the array type is atomic, and the component is not atomic, then
- -- this is worth a warning, since we have a situation where the access
- -- to the component may cause extra read/writes of the atomic array
- -- object, or partial word accesses, which could be unexpected.
+ -- If the array type is atomic and the component is not, then this is
+ -- worth a warning before Ada 2020, since we have a situation where the
+ -- access to the component may cause extra read/writes of the atomic
+ -- object, or partial word accesses, both of which may be unexpected.
if Nkind (N) = N_Indexed_Component
and then Is_Atomic_Ref_With_Address (N)
@@ -9157,6 +9224,7 @@ package body Sem_Res is
and then Has_Atomic_Components
(Entity (Prefix (N)))))
and then not Is_Atomic (Component_Type (Array_Type))
+ and then Ada_Version < Ada_2020
then
Error_Msg_N
("??access to non-atomic component of atomic array", Prefix (N));
@@ -9198,7 +9266,7 @@ package body Sem_Res is
Res : Node_Id;
begin
- if Nkind_In (Opnd, N_Integer_Literal, N_Real_Literal) then
+ if Nkind (Opnd) in N_Integer_Literal | N_Real_Literal then
Res :=
Make_Qualified_Expression (Loc,
Subtype_Mark => New_Occurrence_Of (Btyp, Loc),
@@ -9391,7 +9459,7 @@ package body Sem_Res is
if Short_Circuit_And_Or
and then B_Typ = Standard_Boolean
- and then Nkind_In (N, N_Op_And, N_Op_Or)
+ and then Nkind (N) in N_Op_And | N_Op_Or
then
-- Mark the corresponding putative SCO operator as truly a logical
-- (and short-circuit) operator.
@@ -9432,34 +9500,6 @@ package body Sem_Res is
Set_Etype (N, B_Typ);
Generate_Operator_Reference (N, B_Typ);
Eval_Logical_Op (N);
-
- -- In SPARK, logical operations AND, OR and XOR for arrays are defined
- -- only when both operands have same static lower and higher bounds. Of
- -- course the types have to match, so only check if operands are
- -- compatible and the node itself has no errors.
-
- if Is_Array_Type (B_Typ)
- and then Nkind (N) in N_Binary_Op
- then
- declare
- Left_Typ : constant Node_Id := Etype (Left_Opnd (N));
- Right_Typ : constant Node_Id := Etype (Right_Opnd (N));
-
- begin
- -- Protect call to Matching_Static_Array_Bounds to avoid costly
- -- operation if not needed.
-
- if Restriction_Check_Required (SPARK_05)
- and then Base_Type (Left_Typ) = Base_Type (Right_Typ)
- and then Left_Typ /= Any_Composite -- or Left_Opnd in error
- and then Right_Typ /= Any_Composite -- or Right_Opnd in error
- and then not Matching_Static_Array_Bounds (Left_Typ, Right_Typ)
- then
- Check_SPARK_05_Restriction
- ("array types should have matching static bounds", N);
- end if;
- end;
- end if;
end Resolve_Logical_Op;
---------------------------
@@ -9478,8 +9518,8 @@ package body Sem_Res is
T : Entity_Id;
procedure Resolve_Set_Membership;
- -- Analysis has determined a unique type for the left operand. Use it to
- -- resolve the disjuncts.
+ -- Analysis has determined a unique type for the left operand. Use it as
+ -- the basis to resolve the disjuncts.
----------------------------
-- Resolve_Set_Membership --
@@ -9487,18 +9527,17 @@ package body Sem_Res is
procedure Resolve_Set_Membership is
Alt : Node_Id;
- Ltyp : Entity_Id;
begin
-- If the left operand is overloaded, find type compatible with not
-- overloaded alternative of the right operand.
+ Alt := First (Alternatives (N));
if Is_Overloaded (L) then
- Ltyp := Empty;
- Alt := First (Alternatives (N));
+ T := Empty;
while Present (Alt) loop
if not Is_Overloaded (Alt) then
- Ltyp := Intersect_Types (L, Alt);
+ T := Intersect_Types (L, Alt);
exit;
else
Next (Alt);
@@ -9508,15 +9547,15 @@ package body Sem_Res is
-- Unclear how to resolve expression if all alternatives are also
-- overloaded.
- if No (Ltyp) then
+ if No (T) then
Error_Msg_N ("ambiguous expression", N);
end if;
else
- Ltyp := Etype (L);
+ T := Intersect_Types (L, Alt);
end if;
- Resolve (L, Ltyp);
+ Resolve (L, T);
Alt := First (Alternatives (N));
while Present (Alt) loop
@@ -9527,7 +9566,7 @@ package body Sem_Res is
if not Is_Entity_Name (Alt)
or else not Is_Type (Entity (Alt))
then
- Resolve (Alt, Ltyp);
+ Resolve (Alt, T);
end if;
Next (Alt);
@@ -9535,7 +9574,7 @@ package body Sem_Res is
-- Check for duplicates for discrete case
- if Is_Discrete_Type (Ltyp) then
+ if Is_Discrete_Type (T) then
declare
type Ent is record
Alt : Node_Id;
@@ -9553,9 +9592,9 @@ package body Sem_Res is
Alt := First (Alternatives (N));
while Present (Alt) loop
if Is_OK_Static_Expression (Alt)
- and then (Nkind_In (Alt, N_Integer_Literal,
- N_Character_Literal)
- or else Nkind (Alt) in N_Has_Entity)
+ and then Nkind (Alt) in N_Integer_Literal
+ | N_Character_Literal
+ | N_Has_Entity
then
Nalts := Nalts + 1;
Alts (Nalts) := (Alt, Expr_Value (Alt));
@@ -9568,7 +9607,7 @@ package body Sem_Res is
end loop;
end if;
- Alt := Next (Alt);
+ Next (Alt);
end loop;
end;
end if;
@@ -9578,11 +9617,11 @@ package body Sem_Res is
-- equality for the type. This may be confusing to users, and the
-- following warning appears useful for the most common case.
- if Is_Scalar_Type (Ltyp)
- and then Present (Get_User_Defined_Eq (Ltyp))
+ if Is_Scalar_Type (Etype (L))
+ and then Present (Get_User_Defined_Eq (Etype (L)))
then
Error_Msg_NE
- ("membership test on& uses predefined equality?", N, Ltyp);
+ ("membership test on& uses predefined equality?", N, Etype (L));
Error_Msg_N
("\even if user-defined equality exists (RM 4.5.2 (28.1/3)?", N);
end if;
@@ -9817,11 +9856,6 @@ package body Sem_Res is
exit when NN = N;
NN := Parent (NN);
end loop;
-
- if Base_Type (Etype (N)) /= Standard_String then
- Check_SPARK_05_Restriction
- ("result of concatenation should have type String", N);
- end if;
end Resolve_Op_Concat;
---------------------------
@@ -9946,34 +9980,6 @@ package body Sem_Res is
Resolve (Arg, Btyp);
end if;
- -- Concatenation is restricted in SPARK: each operand must be either a
- -- string literal, the name of a string constant, a static character or
- -- string expression, or another concatenation. Arg cannot be a
- -- concatenation here as callers of Resolve_Op_Concat_Arg call it
- -- separately on each final operand, past concatenation operations.
-
- if Is_Character_Type (Etype (Arg)) then
- if not Is_OK_Static_Expression (Arg) then
- Check_SPARK_05_Restriction
- ("character operand for concatenation should be static", Arg);
- end if;
-
- elsif Is_String_Type (Etype (Arg)) then
- if not (Nkind_In (Arg, N_Identifier, N_Expanded_Name)
- and then Is_Constant_Object (Entity (Arg)))
- and then not Is_OK_Static_Expression (Arg)
- then
- Check_SPARK_05_Restriction
- ("string operand for concatenation should be static", Arg);
- end if;
-
- -- Do not issue error on an operand that is neither a character nor a
- -- string, as the error is issued in Resolve_Op_Concat.
-
- else
- null;
- end if;
-
Check_Unset_Reference (Arg);
end Resolve_Op_Concat_Arg;
@@ -10241,7 +10247,7 @@ package body Sem_Res is
begin
if B_Typ = Standard_Boolean
- and then Nkind_In (Opnd, N_Op_Eq, N_Op_Ne)
+ and then Nkind (Opnd) in N_Op_Eq | N_Op_Ne
and then Is_Overloaded (Opnd)
then
Resolve_Equality_Op (Opnd, B_Typ);
@@ -10299,19 +10305,6 @@ package body Sem_Res is
begin
Resolve (Expr, Target_Typ);
- -- Protect call to Matching_Static_Array_Bounds to avoid costly
- -- operation if not needed.
-
- if Restriction_Check_Required (SPARK_05)
- and then Is_Array_Type (Target_Typ)
- and then Is_Array_Type (Etype (Expr))
- and then Etype (Expr) /= Any_Composite -- or else Expr in error
- and then not Matching_Static_Array_Bounds (Target_Typ, Etype (Expr))
- then
- Check_SPARK_05_Restriction
- ("array types should have matching static bounds", N);
- end if;
-
-- A qualified expression requires an exact match of the type, class-
-- wide matching is not allowed. However, if the qualifying type is
-- specific and the expression has a class-wide type, it may still be
@@ -10330,10 +10323,12 @@ package body Sem_Res is
-- If the target type is unconstrained, then we reset the type of the
-- result from the type of the expression. For other cases, the actual
- -- subtype of the expression is the target type.
+ -- subtype of the expression is the target type. But we avoid doing it
+ -- for an allocator since this is not needed and might be problematic.
if Is_Composite_Type (Target_Typ)
and then not Is_Constrained (Target_Typ)
+ and then Nkind (Parent (N)) /= N_Allocator
then
Set_Etype (N, Etype (Expr));
end if;
@@ -10347,31 +10342,19 @@ package body Sem_Res is
-- check may convert an illegal static expression and result in warning
-- rather than giving an error (e.g Integer'(Integer'Last + 1)).
- if Nkind (N) = N_Qualified_Expression and then Is_Scalar_Type (Typ) then
- Apply_Scalar_Range_Check (Expr, Typ);
+ if Nkind (N) = N_Qualified_Expression
+ and then Is_Scalar_Type (Target_Typ)
+ then
+ Apply_Scalar_Range_Check (Expr, Target_Typ);
end if;
- -- Finally, check whether a predicate applies to the target type. This
- -- comes from AI12-0100. As for type conversions, check the enclosing
- -- context to prevent an infinite expansion.
+ -- AI12-0100: Once the qualified expression is resolved, check whether
+ -- operand statisfies a static predicate of the target subtype, if any.
+ -- In the static expression case, a predicate check failure is an error.
if Has_Predicates (Target_Typ) then
- if Nkind (Parent (N)) = N_Function_Call
- and then Present (Name (Parent (N)))
- and then (Is_Predicate_Function (Entity (Name (Parent (N))))
- or else
- Is_Predicate_Function_M (Entity (Name (Parent (N)))))
- then
- null;
-
- -- In the case of a qualified expression in an allocator, the check
- -- is applied when expanding the allocator, so avoid redundant check.
-
- elsif Nkind (N) = N_Qualified_Expression
- and then Nkind (Parent (N)) /= N_Allocator
- then
- Apply_Predicate_Check (N, Target_Typ);
- end if;
+ Check_Expression_Against_Static_Predicate
+ (Expr, Target_Typ, Static_Failure_Is_Error => True);
end if;
end Resolve_Qualified_Expression;
@@ -10436,13 +10419,8 @@ package body Sem_Res is
begin
Set_Etype (N, Typ);
- -- The lower bound should be in Typ. The higher bound can be in Typ's
- -- base type if the range is null. It may still be invalid if it is
- -- higher than the lower bound. This is checked later in the context in
- -- which the range appears.
-
Resolve (L, Typ);
- Resolve (H, Base_Type (Typ));
+ Resolve (H, Typ);
-- Reanalyze the lower bound after both bounds have been analyzed, so
-- that the range is known to be static or not by now. This may trigger
@@ -10712,7 +10690,7 @@ package body Sem_Res is
while Present (Comp1)
and then Chars (Comp1) /= Chars (S)
loop
- Comp1 := Next_Entity (Comp1);
+ Next_Entity (Comp1);
end loop;
end if;
@@ -10721,7 +10699,7 @@ package body Sem_Res is
end if;
end if;
- Comp := Next_Entity (Comp);
+ Next_Entity (Comp);
end loop;
end if;
@@ -10777,12 +10755,12 @@ package body Sem_Res is
Generate_Reference (Entity (S), S, 'r');
end if;
- -- If prefix is an access type, the node will be transformed into an
- -- explicit dereference during expansion. The type of the node is the
- -- designated type of that of the prefix.
+ -- If the prefix's type is an access type, get to the real record type.
+ -- Note: we do not apply an access check because an explicit dereference
+ -- will be introduced later, and the check will happen there.
if Is_Access_Type (Etype (P)) then
- T := Designated_Type (Etype (P));
+ T := Implicitly_Designated_Type (Etype (P));
Check_Fully_Declared_Prefix (T, P);
else
@@ -10838,15 +10816,16 @@ package body Sem_Res is
-- Note: No Eval processing is required, because the prefix is of a
-- record type, or protected type, and neither can possibly be static.
- -- If the record type is atomic, and the component is non-atomic, then
- -- this is worth a warning, since we have a situation where the access
- -- to the component may cause extra read/writes of the atomic array
+ -- If the record type is atomic and the component is not, then this is
+ -- worth a warning before Ada 2020, since we have a situation where the
+ -- access to the component may cause extra read/writes of the atomic
-- object, or partial word accesses, both of which may be unexpected.
if Nkind (N) = N_Selected_Component
and then Is_Atomic_Ref_With_Address (N)
and then not Is_Atomic (Entity (S))
and then not Is_Atomic (Etype (Entity (S)))
+ and then Ada_Version < Ada_2020
then
Error_Msg_N
("??access to non-atomic component of atomic record",
@@ -10856,6 +10835,7 @@ package body Sem_Res is
Prefix (N));
end if;
+ Resolve_Implicit_Dereference (Prefix (N));
Analyze_Dimension (N);
end Resolve_Selected_Component;
@@ -10913,7 +10893,7 @@ package body Sem_Res is
-- Set Comes_From_Source on L to preserve warnings for unset
-- reference.
- Set_Comes_From_Source (L, Comes_From_Source (Reloc_L));
+ Preserve_Comes_From_Source (L, Reloc_L);
end;
end if;
@@ -11086,9 +11066,12 @@ package body Sem_Res is
Resolve (Name, Array_Type);
+ -- If the prefix's type is an access type, get to the real array type.
+ -- Note: we do not apply an access check because an explicit dereference
+ -- will be introduced later, and the check will happen there.
+
if Is_Access_Type (Array_Type) then
- Apply_Access_Check (N);
- Array_Type := Designated_Type (Array_Type);
+ Array_Type := Implicitly_Designated_Type (Array_Type);
-- If the prefix is an access to an unconstrained array, we must use
-- the actual subtype of the object to perform the index checks. The
@@ -11232,6 +11215,7 @@ package body Sem_Res is
Warn_On_Suspicious_Index (Name, High_Bound (Drange));
end if;
+ Resolve_Implicit_Dereference (Prefix (N));
Analyze_Dimension (N);
Eval_Slice (N);
end Resolve_Slice;
@@ -11281,10 +11265,10 @@ package body Sem_Res is
elsif Nkind (Parent (N)) = N_Op_Concat
and then not Need_Check
- and then not Nkind_In (Original_Node (N), N_Character_Literal,
- N_Attribute_Reference,
- N_Qualified_Expression,
- N_Type_Conversion)
+ and then Nkind (Original_Node (N)) not in N_Character_Literal
+ | N_Attribute_Reference
+ | N_Qualified_Expression
+ | N_Type_Conversion
then
Subtype_Id := Typ;
@@ -11570,14 +11554,14 @@ package body Sem_Res is
-- precision.
if Is_Fixed_Point_Type (Typ)
- and then Nkind_In (Operand, N_Op_Divide, N_Op_Multiply)
+ and then Nkind (Operand) in N_Op_Divide | N_Op_Multiply
and then Etype (Left_Opnd (Operand)) = Any_Fixed
and then Etype (Right_Opnd (Operand)) = Any_Fixed
then
Set_Etype (Operand, Universal_Real);
elsif Is_Numeric_Type (Typ)
- and then Nkind_In (Operand, N_Op_Multiply, N_Op_Divide)
+ and then Nkind (Operand) in N_Op_Multiply | N_Op_Divide
and then (Etype (Right_Opnd (Operand)) = Universal_Real
or else
Etype (Left_Opnd (Operand)) = Universal_Real)
@@ -11633,35 +11617,6 @@ package body Sem_Res is
Resolve (Operand);
- -- In SPARK, a type conversion between array types should be restricted
- -- to types which have matching static bounds.
-
- -- Protect call to Matching_Static_Array_Bounds to avoid costly
- -- operation if not needed.
-
- if Restriction_Check_Required (SPARK_05)
- and then Is_Array_Type (Target_Typ)
- and then Is_Array_Type (Operand_Typ)
- and then Operand_Typ /= Any_Composite -- or else Operand in error
- and then not Matching_Static_Array_Bounds (Target_Typ, Operand_Typ)
- then
- Check_SPARK_05_Restriction
- ("array types should have matching static bounds", N);
- end if;
-
- -- In formal mode, the operand of an ancestor type conversion must be an
- -- object (not an expression).
-
- if Is_Tagged_Type (Target_Typ)
- and then not Is_Class_Wide_Type (Target_Typ)
- and then Is_Tagged_Type (Operand_Typ)
- and then not Is_Class_Wide_Type (Operand_Typ)
- and then Is_Ancestor (Target_Typ, Operand_Typ)
- and then not Is_SPARK_05_Object_Reference (Operand)
- then
- Check_SPARK_05_Restriction ("object required", Operand);
- end if;
-
Analyze_Dimension (N);
-- Note: we do the Eval_Type_Conversion call before applying the
@@ -11732,6 +11687,7 @@ package body Sem_Res is
-- odd subtype coming from the bounds).
if (Is_Entity_Name (Orig_N)
+ and then Present (Entity (Orig_N))
and then
(Etype (Entity (Orig_N)) = Orig_T
or else
@@ -11767,11 +11723,11 @@ package body Sem_Res is
-- newer language version.
elsif Nkind (Orig_N) = N_Qualified_Expression
- and then Nkind_In (Parent (N), N_Attribute_Reference,
- N_Indexed_Component,
- N_Selected_Component,
- N_Slice,
- N_Explicit_Dereference)
+ and then Nkind (Parent (N)) in N_Attribute_Reference
+ | N_Indexed_Component
+ | N_Selected_Component
+ | N_Slice
+ | N_Explicit_Dereference
then
null;
@@ -11786,17 +11742,15 @@ package body Sem_Res is
-- entity, give the name of the entity in the message. If not,
-- just mention the expression.
- -- Shoudn't we test Warn_On_Redundant_Constructs here ???
-
else
if Is_Entity_Name (Orig_N) then
Error_Msg_Node_2 := Orig_T;
Error_Msg_NE -- CODEFIX
- ("??redundant conversion, & is of type &!",
+ ("?r?redundant conversion, & is of type &!",
N, Entity (Orig_N));
else
Error_Msg_NE
- ("??redundant conversion, expression is of type&!",
+ ("?r?redundant conversion, expression is of type&!",
N, Orig_T);
end if;
end if;
@@ -11903,7 +11857,7 @@ package body Sem_Res is
-- Handle subtypes
- if Ekind_In (Opnd, E_Protected_Subtype, E_Task_Subtype) then
+ if Ekind (Opnd) in E_Protected_Subtype | E_Task_Subtype then
Opnd := Etype (Opnd);
end if;
@@ -11924,11 +11878,13 @@ package body Sem_Res is
end;
end if;
- -- Ada 2012: once the type conversion is resolved, check whether the
- -- operand statisfies the static predicate of the target type.
+ -- Ada 2012: Once the type conversion is resolved, check whether the
+ -- operand statisfies a static predicate of the target subtype, if any.
+ -- In the static expression case, a predicate check failure is an error.
if Has_Predicates (Target_Typ) then
- Check_Expression_Against_Static_Predicate (N, Target_Typ);
+ Check_Expression_Against_Static_Predicate
+ (N, Target_Typ, Static_Failure_Is_Error => True);
end if;
-- If at this stage we have a real to integer conversion, make sure that
@@ -11980,12 +11936,6 @@ package body Sem_Res is
Hi : Uint;
begin
- if Is_Modular_Integer_Type (Typ) and then Nkind (N) /= N_Op_Not then
- Error_Msg_Name_1 := Chars (Typ);
- Check_SPARK_05_Restriction
- ("unary operator not defined for modular type%", N);
- end if;
-
-- Deal with intrinsic unary operators
if Comes_From_Source (N)
@@ -12065,7 +12015,7 @@ package body Sem_Res is
-- mod. These are the cases where the grouping can affect results.
if Paren_Count (Rorig) = 0
- and then Nkind_In (Rorig, N_Op_Mod, N_Op_Multiply, N_Op_Divide)
+ and then Nkind (Rorig) in N_Op_Mod | N_Op_Multiply | N_Op_Divide
then
-- For mod, we always give the warning, since the value is
-- affected by the parenthesization (e.g. (-5) mod 315 /=
@@ -12147,7 +12097,7 @@ package body Sem_Res is
-- overflow is impossible (divisor > 1) or we have a case of
-- division by zero in any case.
- if Nkind_In (Rorig, N_Op_Divide, N_Op_Rem)
+ if Nkind (Rorig) in N_Op_Divide | N_Op_Rem
and then Compile_Time_Known_Value (Right_Opnd (Rorig))
and then UI_Abs (Expr_Value (Right_Opnd (Rorig))) /= 1
then
@@ -12196,6 +12146,18 @@ package body Sem_Res is
Resolve (Operand, Opnd_Type);
+ -- If the expression is a conversion to universal integer of an
+ -- an expression with an integer type, then we can eliminate the
+ -- intermediate conversion to universal integer.
+
+ if Nkind (Operand) = N_Type_Conversion
+ and then Entity (Subtype_Mark (Operand)) = Universal_Integer
+ and then Is_Integer_Type (Etype (Expression (Operand)))
+ then
+ Rewrite (Operand, Relocate_Node (Expression (Operand)));
+ Analyze_And_Resolve (Operand);
+ end if;
+
-- In an inlined context, the unchecked conversion may be applied
-- to a literal, in which case its type is the type of the context.
-- (In other contexts conversions cannot apply to literals).
@@ -12477,37 +12439,51 @@ package body Sem_Res is
-- If the lower bound is not static we create a range for the string
-- literal, using the index type and the known length of the literal.
- -- The index type is not necessarily Positive, so the upper bound is
- -- computed as T'Val (T'Pos (Low_Bound) + L - 1).
+ -- If the length is 1, then the upper bound is set to a mere copy of
+ -- the lower bound; or else, if the index type is a signed integer,
+ -- then the upper bound is computed as Low_Bound + L - 1; otherwise,
+ -- the upper bound is computed as T'Val (T'Pos (Low_Bound) + L - 1).
else
declare
- Index_List : constant List_Id := New_List;
- Index_Type : constant Entity_Id := Etype (First_Index (Typ));
- High_Bound : constant Node_Id :=
- Make_Attribute_Reference (Loc,
- Attribute_Name => Name_Val,
- Prefix =>
- New_Occurrence_Of (Index_Type, Loc),
- Expressions => New_List (
- Make_Op_Add (Loc,
- Left_Opnd =>
- Make_Attribute_Reference (Loc,
- Attribute_Name => Name_Pos,
- Prefix =>
- New_Occurrence_Of (Index_Type, Loc),
- Expressions =>
- New_List (New_Copy_Tree (Low_Bound))),
- Right_Opnd =>
- Make_Integer_Literal (Loc,
- String_Length (Strval (N)) - 1))));
-
+ Length : constant Nat := String_Length (Strval (N));
+ Index_List : constant List_Id := New_List;
+ Index_Type : constant Entity_Id := Etype (First_Index (Typ));
Array_Subtype : Entity_Id;
Drange : Node_Id;
+ High_Bound : Node_Id;
Index : Node_Id;
Index_Subtype : Entity_Id;
begin
+ if Length = 1 then
+ High_Bound := New_Copy_Tree (Low_Bound);
+
+ elsif Is_Signed_Integer_Type (Index_Type) then
+ High_Bound :=
+ Make_Op_Add (Loc,
+ Left_Opnd => New_Copy_Tree (Low_Bound),
+ Right_Opnd => Make_Integer_Literal (Loc, Length - 1));
+
+ else
+ High_Bound :=
+ Make_Attribute_Reference (Loc,
+ Attribute_Name => Name_Val,
+ Prefix =>
+ New_Occurrence_Of (Index_Type, Loc),
+ Expressions => New_List (
+ Make_Op_Add (Loc,
+ Left_Opnd =>
+ Make_Attribute_Reference (Loc,
+ Attribute_Name => Name_Pos,
+ Prefix =>
+ New_Occurrence_Of (Index_Type, Loc),
+ Expressions =>
+ New_List (New_Copy_Tree (Low_Bound))),
+ Right_Opnd =>
+ Make_Integer_Literal (Loc, Length - 1))));
+ end if;
+
if Is_Integer_Type (Index_Type) then
Set_String_Literal_Low_Bound
(Subtype_Id, Make_Integer_Literal (Loc, 1));
@@ -12522,10 +12498,10 @@ package body Sem_Res is
Attribute_Name => Name_First,
Prefix =>
New_Occurrence_Of (Base_Type (Index_Type), Loc)));
- Set_Etype (String_Literal_Low_Bound (Subtype_Id), Index_Type);
end if;
- Analyze_And_Resolve (String_Literal_Low_Bound (Subtype_Id));
+ Analyze_And_Resolve
+ (String_Literal_Low_Bound (Subtype_Id), Base_Type (Index_Type));
-- Build bona fide subtype for the string, and wrap it in an
-- unchecked conversion, because the back end expects the
@@ -12599,9 +12575,9 @@ package body Sem_Res is
or else (Is_Fixed_Point_Type (Target_Typ)
and then Conversion_OK (N)))
and then Nkind (Operand) = N_Attribute_Reference
- and then Nam_In (Attribute_Name (Operand), Name_Rounding,
- Name_Machine_Rounding,
- Name_Truncation)
+ and then Attribute_Name (Operand) in Name_Rounding
+ | Name_Machine_Rounding
+ | Name_Truncation
then
declare
Truncate : constant Boolean :=
@@ -12611,6 +12587,30 @@ package body Sem_Res is
Relocate_Node (First (Expressions (Operand))));
Set_Float_Truncate (N, Truncate);
end;
+
+ -- Special processing for the conversion of an integer literal to
+ -- a dynamic type: we first convert the literal to the root type
+ -- and then convert the result to the target type, the goal being
+ -- to avoid doing range checks in universal integer.
+
+ elsif Is_Integer_Type (Target_Typ)
+ and then not Is_Generic_Type (Root_Type (Target_Typ))
+ and then Nkind (Operand) = N_Integer_Literal
+ and then Opnd_Typ = Universal_Integer
+ then
+ Convert_To_And_Rewrite (Root_Type (Target_Typ), Operand);
+ Analyze_And_Resolve (Operand);
+
+ -- If the expression is a conversion to universal integer of an
+ -- an expression with an integer type, then we can eliminate the
+ -- intermediate conversion to universal integer.
+
+ elsif Nkind (Operand) = N_Type_Conversion
+ and then Entity (Subtype_Mark (Operand)) = Universal_Integer
+ and then Is_Integer_Type (Etype (Expression (Operand)))
+ then
+ Rewrite (Operand, Relocate_Node (Expression (Operand)));
+ Analyze_And_Resolve (Operand);
end if;
end;
end if;
@@ -12710,7 +12710,7 @@ package body Sem_Res is
-- When the context is a type conversion, issue the warning on the
-- expression of the conversion because it is the actual operation.
- if Nkind_In (N, N_Type_Conversion, N_Unchecked_Type_Conversion) then
+ if Nkind (N) in N_Type_Conversion | N_Unchecked_Type_Conversion then
ErrN := Expression (N);
else
ErrN := N;
@@ -12757,6 +12757,18 @@ package body Sem_Res is
-- are not rechecked because type visbility may lead to spurious errors,
-- but conversions in an actual for a formal object must be checked.
+ function Is_Discrim_Of_Bad_Access_Conversion_Argument
+ (Expr : Node_Id) return Boolean;
+ -- Implicit anonymous-to-named access type conversions are not allowed
+ -- if the "statically deeper than" relationship does not apply to the
+ -- type of the conversion operand. See RM 8.6(28.1) and AARM 8.6(28.d).
+ -- We deal with most such cases elsewhere so that we can emit more
+ -- specific error messages (e.g., if the operand is an access parameter
+ -- or a saooaaat (stand-alone object of an anonymous access type)), but
+ -- here is where we catch the case where the operand is an access
+ -- discriminant selected from a dereference of another such "bad"
+ -- conversion argument.
+
function Valid_Tagged_Conversion
(Target_Type : Entity_Id;
Opnd_Type : Entity_Id) return Boolean;
@@ -12859,6 +12871,73 @@ package body Sem_Res is
end if;
end In_Instance_Code;
+ --------------------------------------------------
+ -- Is_Discrim_Of_Bad_Access_Conversion_Argument --
+ --------------------------------------------------
+
+ function Is_Discrim_Of_Bad_Access_Conversion_Argument
+ (Expr : Node_Id) return Boolean
+ is
+ Exp_Type : Entity_Id := Base_Type (Etype (Expr));
+ pragma Assert (Is_Access_Type (Exp_Type));
+
+ Associated_Node : Node_Id;
+ Deref_Prefix : Node_Id;
+ begin
+ if not Is_Anonymous_Access_Type (Exp_Type) then
+ return False;
+ end if;
+
+ pragma Assert (Is_Itype (Exp_Type));
+ Associated_Node := Associated_Node_For_Itype (Exp_Type);
+
+ if Nkind (Associated_Node) /= N_Discriminant_Specification then
+ return False; -- not the type of an access discriminant
+ end if;
+
+ -- return False if Expr not of form <prefix>.all.Some_Component
+
+ if (Nkind (Expr) /= N_Selected_Component)
+ or else (Nkind (Prefix (Expr)) /= N_Explicit_Dereference)
+ then
+ -- conditional expressions, declare expressions ???
+ return False;
+ end if;
+
+ Deref_Prefix := Prefix (Prefix (Expr));
+ Exp_Type := Base_Type (Etype (Deref_Prefix));
+
+ -- The "statically deeper relationship" does not apply
+ -- to generic formal access types, so a prefix of such
+ -- a type is a "bad" prefix.
+
+ if Is_Generic_Formal (Exp_Type) then
+ return True;
+
+ -- The "statically deeper relationship" does apply to
+ -- any other named access type.
+
+ elsif not Is_Anonymous_Access_Type (Exp_Type) then
+ return False;
+ end if;
+
+ pragma Assert (Is_Itype (Exp_Type));
+ Associated_Node := Associated_Node_For_Itype (Exp_Type);
+
+ -- The "statically deeper relationship" applies to some
+ -- anonymous access types and not to others. Return
+ -- True for the cases where it does not apply. Also check
+ -- recursively for the
+ -- <prefix>.all.Access_Discrim.all.Access_Discrim case,
+ -- where the correct result depends on <prefix>.
+
+ return Nkind (Associated_Node) in
+ N_Procedure_Specification | -- access parameter
+ N_Function_Specification | -- access parameter
+ N_Object_Declaration -- saooaaat
+ or else Is_Discrim_Of_Bad_Access_Conversion_Argument (Deref_Prefix);
+ end Is_Discrim_Of_Bad_Access_Conversion_Argument;
+
----------------------------
-- Valid_Array_Conversion --
----------------------------
@@ -12929,9 +13008,9 @@ package body Sem_Res is
-- checks that must be applied to such conversions to prevent
-- out-of-scope references.
- elsif Ekind_In
- (Target_Comp_Base, E_Anonymous_Access_Type,
- E_Anonymous_Access_Subprogram_Type)
+ elsif Ekind (Target_Comp_Base) in
+ E_Anonymous_Access_Type
+ | E_Anonymous_Access_Subprogram_Type
and then Ekind (Opnd_Comp_Base) = Ekind (Target_Comp_Base)
and then
Subtypes_Statically_Match (Target_Comp_Type, Opnd_Comp_Type)
@@ -13240,8 +13319,8 @@ package body Sem_Res is
-- interface type.
elsif Is_Access_Type (Opnd_Type)
- and then Ekind_In (Target_Type, E_General_Access_Type,
- E_Anonymous_Access_Type)
+ and then Ekind (Target_Type) in
+ E_General_Access_Type | E_Anonymous_Access_Type
and then Is_Interface (Directly_Designated_Type (Target_Type))
then
-- Check the static accessibility rule of 4.6(17). Note that the
@@ -13321,7 +13400,7 @@ package body Sem_Res is
if Is_Entity_Name (Operand)
and then not Is_Local_Anonymous_Access (Opnd_Type)
and then
- Ekind_In (Entity (Operand), E_In_Parameter, E_Constant)
+ Ekind (Entity (Operand)) in E_In_Parameter | E_Constant
and then Present (Discriminal_Link (Entity (Operand)))
then
Conversion_Error_N
@@ -13336,14 +13415,15 @@ package body Sem_Res is
-- General and anonymous access types
- elsif Ekind_In (Target_Type, E_General_Access_Type,
- E_Anonymous_Access_Type)
+ elsif Ekind (Target_Type) in
+ E_General_Access_Type | E_Anonymous_Access_Type
and then
Conversion_Check
(Is_Access_Type (Opnd_Type)
- and then not
- Ekind_In (Opnd_Type, E_Access_Subprogram_Type,
- E_Access_Protected_Subprogram_Type),
+ and then
+ Ekind (Opnd_Type) not in
+ E_Access_Subprogram_Type |
+ E_Access_Protected_Subprogram_Type,
"must be an access-to-object type")
then
if Is_Access_Constant (Opnd_Type)
@@ -13395,26 +13475,24 @@ package body Sem_Res is
return False;
-- Implicit conversions aren't allowed for anonymous access
- -- parameters. The "not Is_Local_Anonymous_Access_Type" test
- -- is done to exclude anonymous access results.
+ -- parameters. We exclude anonymous access results as well
+ -- as universal_access "=".
elsif not Is_Local_Anonymous_Access (Opnd_Type)
- and then Nkind_In (Associated_Node_For_Itype (Opnd_Type),
- N_Function_Specification,
- N_Procedure_Specification)
+ and then Nkind (Associated_Node_For_Itype (Opnd_Type)) in
+ N_Function_Specification |
+ N_Procedure_Specification
+ and then Nkind (Parent (N)) not in N_Op_Eq | N_Op_Ne
then
Conversion_Error_N
- ("implicit conversion of anonymous access formal "
+ ("implicit conversion of anonymous access parameter "
& "not allowed", Operand);
return False;
- -- This is a case where there's an enclosing object whose
- -- to which the "statically deeper than" relationship does
- -- not apply (such as an access discriminant selected from
- -- a dereference of an access parameter).
+ -- Detect access discriminant values that are illegal
+ -- implicit anonymous-to-named access conversion operands.
- elsif Object_Access_Level (Operand)
- = Scope_Depth (Standard_Standard)
+ elsif Is_Discrim_Of_Bad_Access_Conversion_Argument (Operand)
then
Conversion_Error_N
("implicit conversion of anonymous access value "
@@ -13426,7 +13504,7 @@ package body Sem_Res is
-- implicit conversion is disallowed (by RM12-8.6(27.1/3)).
elsif Type_Access_Level (Opnd_Type) >
- Deepest_Type_Access_Level (Target_Type)
+ Deepest_Type_Access_Level (Target_Type)
then
Conversion_Error_N
("implicit conversion of anonymous access value "
@@ -13435,8 +13513,19 @@ package body Sem_Res is
end if;
end if;
+ -- Check if the operand is deeper than the target type, taking
+ -- care to avoid the case where we are converting a result of a
+ -- function returning an anonymous access type since the "master
+ -- of the call" would be target type of the conversion unless
+ -- the target type is anonymous access as well - see RM 3.10.2
+ -- (10.3/3).
+
elsif Type_Access_Level (Opnd_Type) >
Deepest_Type_Access_Level (Target_Type)
+ and then (Nkind (Associated_Node_For_Itype (Opnd_Type)) /=
+ N_Function_Specification
+ or else Ekind (Target_Type) in
+ Anonymous_Access_Kind)
then
-- In an instance, this is a run-time check, but one we know
-- will fail, so generate an appropriate warning. The raise
@@ -13507,7 +13596,7 @@ package body Sem_Res is
if Is_Entity_Name (Operand)
and then
- Ekind_In (Entity (Operand), E_In_Parameter, E_Constant)
+ Ekind (Entity (Operand)) in E_In_Parameter | E_Constant
and then Present (Discriminal_Link (Entity (Operand)))
then
Conversion_Error_N