aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada/sem_res.adb
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/ada/sem_res.adb')
-rw-r--r--gcc/ada/sem_res.adb540
1 files changed, 325 insertions, 215 deletions
diff --git a/gcc/ada/sem_res.adb b/gcc/ada/sem_res.adb
index f6e0eab..03d747e 100644
--- a/gcc/ada/sem_res.adb
+++ b/gcc/ada/sem_res.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 1992-2020, Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2021, 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,65 +23,70 @@
-- --
------------------------------------------------------------------------------
-with Aspects; use Aspects;
-with Atree; use Atree;
-with Checks; use Checks;
-with Debug; use Debug;
-with Debug_A; use Debug_A;
-with Einfo; use Einfo;
-with Errout; use Errout;
-with Expander; use Expander;
-with Exp_Ch6; use Exp_Ch6;
-with Exp_Ch7; use Exp_Ch7;
-with Exp_Disp; use Exp_Disp;
-with Exp_Tss; use Exp_Tss;
-with Exp_Util; use Exp_Util;
-with Freeze; use Freeze;
-with Ghost; use Ghost;
-with Inline; use Inline;
-with Itypes; use Itypes;
-with Lib; use Lib;
-with Lib.Xref; use Lib.Xref;
-with Namet; use Namet;
-with Nmake; use Nmake;
-with Nlists; use Nlists;
-with Opt; use Opt;
-with Output; use Output;
-with Par_SCO; use Par_SCO;
-with Restrict; use Restrict;
-with Rident; use Rident;
-with Rtsfind; use Rtsfind;
-with Sem; use Sem;
-with Sem_Aggr; use Sem_Aggr;
-with Sem_Attr; use Sem_Attr;
-with Sem_Aux; use Sem_Aux;
-with Sem_Cat; use Sem_Cat;
-with Sem_Ch3; use Sem_Ch3;
-with Sem_Ch4; use Sem_Ch4;
-with Sem_Ch6; use Sem_Ch6;
-with Sem_Ch8; use Sem_Ch8;
-with Sem_Ch13; use Sem_Ch13;
-with Sem_Dim; use Sem_Dim;
-with Sem_Disp; use Sem_Disp;
-with Sem_Dist; use Sem_Dist;
-with Sem_Elab; use Sem_Elab;
-with Sem_Elim; use Sem_Elim;
-with Sem_Eval; use Sem_Eval;
-with Sem_Intr; use Sem_Intr;
-with Sem_Mech; use Sem_Mech;
-with Sem_Type; use Sem_Type;
-with Sem_Util; use Sem_Util;
-with Sem_Warn; use Sem_Warn;
-with Sinfo; use Sinfo;
-with Sinfo.CN; use Sinfo.CN;
-with Snames; use Snames;
-with Stand; use Stand;
-with Stringt; use Stringt;
-with Style; use Style;
-with Targparm; use Targparm;
-with Tbuild; use Tbuild;
-with Uintp; use Uintp;
-with Urealp; use Urealp;
+with Aspects; use Aspects;
+with Atree; use Atree;
+with Checks; use Checks;
+with Debug; use Debug;
+with Debug_A; use Debug_A;
+with Einfo; use Einfo;
+with Einfo.Entities; use Einfo.Entities;
+with Einfo.Utils; use Einfo.Utils;
+with Errout; use Errout;
+with Expander; use Expander;
+with Exp_Ch6; use Exp_Ch6;
+with Exp_Ch7; use Exp_Ch7;
+with Exp_Disp; use Exp_Disp;
+with Exp_Tss; use Exp_Tss;
+with Exp_Util; use Exp_Util;
+with Freeze; use Freeze;
+with Ghost; use Ghost;
+with Inline; use Inline;
+with Itypes; use Itypes;
+with Lib; use Lib;
+with Lib.Xref; use Lib.Xref;
+with Namet; use Namet;
+with Nmake; use Nmake;
+with Nlists; use Nlists;
+with Opt; use Opt;
+with Output; use Output;
+with Par_SCO; use Par_SCO;
+with Restrict; use Restrict;
+with Rident; use Rident;
+with Rtsfind; use Rtsfind;
+with Sem; use Sem;
+with Sem_Aggr; use Sem_Aggr;
+with Sem_Attr; use Sem_Attr;
+with Sem_Aux; use Sem_Aux;
+with Sem_Case; use Sem_Case;
+with Sem_Cat; use Sem_Cat;
+with Sem_Ch3; use Sem_Ch3;
+with Sem_Ch4; use Sem_Ch4;
+with Sem_Ch6; use Sem_Ch6;
+with Sem_Ch8; use Sem_Ch8;
+with Sem_Ch13; use Sem_Ch13;
+with Sem_Dim; use Sem_Dim;
+with Sem_Disp; use Sem_Disp;
+with Sem_Dist; use Sem_Dist;
+with Sem_Elab; use Sem_Elab;
+with Sem_Elim; use Sem_Elim;
+with Sem_Eval; use Sem_Eval;
+with Sem_Intr; use Sem_Intr;
+with Sem_Mech; use Sem_Mech;
+with Sem_Type; use Sem_Type;
+with Sem_Util; use Sem_Util;
+with Sem_Warn; use Sem_Warn;
+with Sinfo; use Sinfo;
+with Sinfo.Nodes; use Sinfo.Nodes;
+with Sinfo.Utils; use Sinfo.Utils;
+with Sinfo.CN; use Sinfo.CN;
+with Snames; use Snames;
+with Stand; use Stand;
+with Stringt; use Stringt;
+with Style; use Style;
+with Targparm; use Targparm;
+with Tbuild; use Tbuild;
+with Uintp; use Uintp;
+with Urealp; use Urealp;
package body Sem_Res is
@@ -649,9 +654,9 @@ package body Sem_Res is
end if;
end Check_For_Visible_Operator;
- ----------------------------------
- -- Check_Fully_Declared_Prefix --
- ----------------------------------
+ ---------------------------------
+ -- Check_Fully_Declared_Prefix --
+ ---------------------------------
procedure Check_Fully_Declared_Prefix
(Typ : Entity_Id;
@@ -1285,8 +1290,10 @@ package body Sem_Res is
Check_Parameterless_Call (Explicit_Actual_Parameter (N));
elsif Nkind (N) = N_Operator_Symbol then
- Change_Operator_Symbol_To_String_Literal (N);
+ Set_Etype (N, Empty);
+ Set_Entity (N, Empty);
Set_Is_Overloaded (N, False);
+ Change_Operator_Symbol_To_String_Literal (N);
Set_Etype (N, Any_String);
end if;
end Check_Parameterless_Call;
@@ -1879,9 +1886,9 @@ package body Sem_Res is
Expander_Mode_Restore;
Full_Analysis := Save_Full_Analysis;
- Set_Must_Not_Freeze (N, Save_Must_Not_Freeze);
if not With_Freezing then
+ Set_Must_Not_Freeze (N, Save_Must_Not_Freeze);
Inside_Preanalysis_Without_Freezing :=
Inside_Preanalysis_Without_Freezing - 1;
end if;
@@ -2114,7 +2121,7 @@ package body Sem_Res is
end loop;
end if;
- -- Additional message and hint if the ambiguity involves an Ada2020
+ -- Additional message and hint if the ambiguity involves an Ada 2022
-- container aggregate.
Check_Ambiguous_Aggregate (N);
@@ -2233,7 +2240,7 @@ package body Sem_Res is
then
Is_Remote := False;
Error_Msg_N
- ("prefix must statically denote a remote subprogram ",
+ ("prefix must statically denote a remote subprogram",
N);
end if;
@@ -2344,8 +2351,7 @@ package body Sem_Res is
if Ada_Version >= Ada_2005
and then It.Typ = Typ
- and then Typ /= Universal_Integer
- and then Typ /= Universal_Real
+ and then not Is_Universal_Numeric_Type (Typ)
and then Present (It.Abstract_Op)
then
if Debug_Flag_V then
@@ -2781,7 +2787,7 @@ package body Sem_Res is
elsif Nkind (N) = N_Aggregate
and then Etype (N) = Any_Composite
then
- if Ada_Version >= Ada_2020
+ if Ada_Version >= Ada_2022
and then Has_Aspect (Typ, Aspect_Aggregate)
then
Resolve_Container_Aggregate (N, Typ);
@@ -2928,6 +2934,11 @@ package body Sem_Res is
else
UI_Image (Norm_Num (Expr_Value_R (Expr)), Decimal);
Start_String;
+
+ if UR_Is_Negative (Expr_Value_R (Expr)) then
+ Store_String_Chars ("-");
+ end if;
+
Store_String_Chars
(UI_Image_Buffer (1 .. UI_Image_Length));
Param1 := Make_String_Literal (Loc, End_String);
@@ -3385,12 +3396,9 @@ package body Sem_Res is
-- Here we are resolving the corresponding expanded body, so we do
-- need to perform normal freezing.
- -- As elsewhere we do not emit freeze node within a generic. We make
- -- an exception for entities that are expressions, only to detect
- -- misuses of deferred constants and preserve the output of various
- -- tests.
+ -- As elsewhere we do not emit freeze node within a generic.
- if not Inside_A_Generic or else Is_Entity_Name (N) then
+ if not Inside_A_Generic then
Freeze_Expression (N);
end if;
@@ -3749,26 +3757,34 @@ package body Sem_Res is
Id : Entity_Id;
begin
- -- Do not consider nested function calls because they have already
- -- been processed during their own resolution.
+ case Nkind (N) is
+ -- Do not consider nested function calls because they have
+ -- already been processed during their own resolution.
- if Nkind (N) = N_Function_Call then
- return Skip;
+ when N_Function_Call =>
+ return Skip;
- elsif Is_Entity_Name (N) and then Present (Entity (N)) then
- Id := Entity (N);
+ when N_Identifier | N_Expanded_Name =>
+ Id := Entity (N);
+
+ if Present (Id)
+ and then Is_Object (Id)
+ and then Is_Effectively_Volatile_For_Reading (Id)
+ and then
+ not Is_OK_Volatile_Context (Context => Parent (N),
+ Obj_Ref => N,
+ Check_Actuals => True)
+ then
+ Error_Msg_N
+ ("volatile object cannot appear in this context"
+ & " (SPARK RM 7.1.3(10))", N);
+ end if;
- if Is_Object (Id)
- and then Is_Effectively_Volatile_For_Reading (Id)
- then
- Error_Msg_N
- ("volatile object cannot appear in this context (SPARK "
- & "RM 7.1.3(10))", N);
return Skip;
- end if;
- end if;
- return OK;
+ when others =>
+ return OK;
+ end case;
end Flag_Object;
procedure Flag_Objects is new Traverse_Proc (Flag_Object);
@@ -4747,6 +4763,13 @@ package body Sem_Res is
-- Expand_Actuals routine in Exp_Ch6.
end if;
+ -- If the formal is of an unconstrained array subtype with fixed
+ -- lower bound, then sliding to that bound may be needed.
+
+ if Is_Fixed_Lower_Bound_Array_Subtype (F_Typ) then
+ Expand_Sliding_Conversion (A, F_Typ);
+ end if;
+
-- An actual associated with an access parameter is implicitly
-- converted to the anonymous access type of the formal and must
-- satisfy the legality checks for access conversions.
@@ -4774,11 +4797,11 @@ package body Sem_Res is
-- Check illegal cases of atomic/volatile/VFA actual (RM C.6(12))
- if (Is_By_Reference_Type (Etype (F)) or else Is_Aliased (F))
+ if (Is_By_Reference_Type (F_Typ) or else Is_Aliased (F))
and then Comes_From_Source (N)
then
if Is_Atomic_Object (A)
- and then not Is_Atomic (Etype (F))
+ and then not Is_Atomic (F_Typ)
then
Error_Msg_NE
("cannot pass atomic object to nonatomic formal&",
@@ -4786,8 +4809,8 @@ package body Sem_Res is
Error_Msg_N
("\which is passed by reference (RM C.6(12))", A);
- elsif Is_Volatile_Object (A)
- and then not Is_Volatile (Etype (F))
+ elsif Is_Volatile_Object_Ref (A)
+ and then not Is_Volatile (F_Typ)
then
Error_Msg_NE
("cannot pass volatile object to nonvolatile formal&",
@@ -4795,8 +4818,8 @@ package body Sem_Res is
Error_Msg_N
("\which is passed by reference (RM C.6(12))", A);
- elsif Is_Volatile_Full_Access_Object (A)
- and then not Is_Volatile_Full_Access (Etype (F))
+ elsif Is_Volatile_Full_Access_Object_Ref (A)
+ and then not Is_Volatile_Full_Access (F_Typ)
then
Error_Msg_NE
("cannot pass full access object to nonfull access "
@@ -4806,9 +4829,9 @@ package body Sem_Res is
end if;
-- Check for nonatomic subcomponent of a full access object
- -- in Ada 2020 (RM C.6 (12)).
+ -- in Ada 2022 (RM C.6 (12)).
- if Ada_Version >= Ada_2020
+ if Ada_Version >= Ada_2022
and then Is_Subcomponent_Of_Full_Access_Object (A)
and then not Is_Atomic_Object (A)
then
@@ -4831,9 +4854,9 @@ package body Sem_Res is
if Is_Controlling_Formal (F) then
Set_Is_Controlling_Actual (A);
- if Ekind (Etype (F)) = E_Anonymous_Access_Type then
+ if Ekind (F_Typ) = E_Anonymous_Access_Type then
declare
- Desig : constant Entity_Id := Designated_Type (Etype (F));
+ Desig : constant Entity_Id := Designated_Type (F_Typ);
begin
if Ekind (Desig) = E_Incomplete_Type
and then No (Full_View (Desig))
@@ -4938,40 +4961,14 @@ package body Sem_Res is
if SPARK_Mode = On and then Comes_From_Source (A) then
- -- An effectively volatile object for reading may act as an
- -- actual when the corresponding formal is of a non-scalar
- -- effectively volatile type for reading (SPARK RM 7.1.3(10)).
-
- if not Is_Scalar_Type (Etype (F))
- and then Is_Effectively_Volatile_For_Reading (Etype (F))
- then
- null;
-
- -- An effectively volatile object for reading may act as an
- -- actual in a call to an instance of Unchecked_Conversion.
- -- (SPARK RM 7.1.3(10)).
-
- elsif Is_Unchecked_Conversion_Instance (Nam) then
- null;
-
- -- The actual denotes an object
+ -- Inspect the expression and flag each effectively volatile
+ -- object for reading as illegal because it appears within
+ -- an interfering context. Note that this is usually done
+ -- in Resolve_Entity_Name, but when the effectively volatile
+ -- object for reading appears as an actual in a call, the call
+ -- must be resolved first.
- elsif Is_Effectively_Volatile_Object_For_Reading (A) then
- Error_Msg_N
- ("volatile object cannot act as actual in a call (SPARK "
- & "RM 7.1.3(10))", A);
-
- -- Otherwise the actual denotes an expression. Inspect the
- -- expression and flag each effectively volatile object
- -- for reading as illegal because it apprears within an
- -- interfering context. Note that this is usually done in
- -- Resolve_Entity_Name, but when the effectively volatile
- -- object for reading appears as an actual in a call, the
- -- call must be resolved first.
-
- else
- Flag_Effectively_Volatile_Objects (A);
- end if;
+ Flag_Effectively_Volatile_Objects (A);
-- An effectively volatile variable cannot act as an actual
-- parameter in a procedure call when the variable has enabled
@@ -5036,6 +5033,41 @@ package body Sem_Res is
end if;
end if;
+ -- (AI12-0397): The target of a subprogram call that occurs within
+ -- the expression of an Default_Initial_Condition aspect and has
+ -- an actual that is the current instance of the type must be
+ -- either a primitive of the type or a class-wide subprogram,
+ -- because the type of the current instance in such an aspect is
+ -- considered to be a notional formal derived type whose only
+ -- operations correspond to the primitives of the enclosing type.
+ -- Nonprimitives can be called, but the current instance must be
+ -- converted rather than passed directly. Note that a current
+ -- instance of a type with DIC will occur as a reference to an
+ -- in-mode formal of an enclosing DIC procedure or partial DIC
+ -- procedure. (It seems that this check should perhaps also apply
+ -- to calls within Type_Invariant'Class, but not Type_Invariant,
+ -- aspects???)
+
+ if Nkind (A) = N_Identifier
+ and then Ekind (Entity (A)) = E_In_Parameter
+
+ and then Is_Subprogram (Scope (Entity (A)))
+ and then Is_DIC_Procedure (Scope (Entity (A)))
+
+ -- We check Comes_From_Source to exclude inherited primitives
+ -- from being flagged, because such subprograms turn out to not
+ -- always have the Is_Primitive flag set. ???
+
+ and then Comes_From_Source (Nam)
+
+ and then not Is_Primitive (Nam)
+ and then not Is_Class_Wide_Type (F_Typ)
+ then
+ Error_Msg_NE
+ ("call to nonprimitive & with current instance not allowed " &
+ "for aspect", A, Nam);
+ end if;
+
Next_Actual (A);
-- Case where actual is not present
@@ -5696,14 +5728,12 @@ package body Sem_Res is
if not Is_Overloaded (N) then
T := Etype (N);
return Base_Type (T) = Base_Type (Standard_Integer)
- or else T = Universal_Integer
- or else T = Universal_Real;
+ or else Is_Universal_Numeric_Type (T);
else
Get_First_Interp (N, Index, It);
while Present (It.Typ) loop
if Base_Type (It.Typ) = Base_Type (Standard_Integer)
- or else It.Typ = Universal_Integer
- or else It.Typ = Universal_Real
+ or else Is_Universal_Numeric_Type (It.Typ)
then
return True;
end if;
@@ -5738,8 +5768,7 @@ package body Sem_Res is
elsif Universal_Interpretation (N) = Universal_Real
and then (T = Base_Type (Standard_Integer)
- or else T = Universal_Integer
- or else T = Universal_Real)
+ or else Is_Universal_Numeric_Type (T))
then
-- A universal real can appear in a fixed-type context. We resolve
-- the literal with that context, even though this might raise an
@@ -5872,9 +5901,7 @@ package body Sem_Res is
procedure Set_Operand_Type (N : Node_Id) is
begin
- if Etype (N) = Universal_Integer
- or else Etype (N) = Universal_Real
- then
+ if Is_Universal_Numeric_Type (Etype (N)) then
Set_Etype (N, T);
end if;
end Set_Operand_Type;
@@ -5899,7 +5926,7 @@ package body Sem_Res is
-- Set the type of the node to its universal interpretation because
-- legality checks on an exponentiation operand need the context.
- elsif (B_Typ = Universal_Integer or else B_Typ = Universal_Real)
+ elsif Is_Universal_Numeric_Type (B_Typ)
and then Present (Universal_Interpretation (L))
and then Present (Universal_Interpretation (R))
then
@@ -6012,9 +6039,9 @@ package body Sem_Res is
end if;
else
- if (TL = Universal_Integer or else TL = Universal_Real)
+ if Is_Universal_Numeric_Type (TL)
and then
- (TR = Universal_Integer or else TR = Universal_Real)
+ Is_Universal_Numeric_Type (TR)
then
Check_For_Visible_Operator (N, B_Typ);
end if;
@@ -6124,13 +6151,6 @@ package body Sem_Res is
raise Program_Error;
end case;
- -- In GNATprove mode, we enable the division check so that
- -- GNATprove will issue a message if it cannot be proved.
-
- if GNATprove_Mode then
- Activate_Division_Check (N);
- end if;
-
-- Otherwise just set the flag to check at run time
else
@@ -6645,7 +6665,7 @@ 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
+ -- Ada 2022 (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
@@ -7076,7 +7096,7 @@ 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
+ -- Ada 2022 (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
@@ -7506,7 +7526,7 @@ package body Sem_Res is
end;
if Need_Transient_Scope then
- Establish_Transient_Scope (Decl, True);
+ Establish_Transient_Scope (Decl, Manage_Sec_Stack => True);
else
Push_Scope (Scope (Defining_Identifier (Decl)));
end if;
@@ -7646,8 +7666,7 @@ package body Sem_Res is
Expr : Node_Id) return Boolean
is
begin
- if Nkind (Context) in
- N_Assignment_Statement | N_Object_Declaration
+ if Nkind (Context) in N_Assignment_Statement | N_Object_Declaration
and then Expression (Context) = Expr
then
return True;
@@ -7689,6 +7708,11 @@ package body Sem_Res is
while Present (N) loop
if Nkind (N) = N_Attribute_Reference then
return True;
+
+ -- Prevent the search from going too far
+
+ elsif Is_Body_Or_Package_Declaration (N) then
+ return False;
end if;
N := Parent (N);
@@ -7734,10 +7758,12 @@ package body Sem_Res is
-- Case of (sub)type name appearing in a context where an expression
-- is expected. This is legal if occurrence is a current instance.
- -- See RM 8.6 (17/3).
+ -- See RM 8.6 (17/3). It is also legal if the expression is
+ -- part of a choice pattern for a case stmt/expr having a
+ -- non-discrete selecting expression.
elsif Is_Type (E) then
- if Is_Current_Instance (N) then
+ if Is_Current_Instance (N) or else Is_Case_Choice_Pattern (N) then
null;
-- Any other use is an error
@@ -7831,7 +7857,8 @@ package body Sem_Res is
if Is_Object (E)
and then Is_Effectively_Volatile_For_Reading (E)
- and then not Is_OK_Volatile_Context (Par, N)
+ and then
+ not Is_OK_Volatile_Context (Par, N, Check_Actuals => False)
then
SPARK_Msg_N
("volatile object cannot appear in this context "
@@ -8791,18 +8818,12 @@ package body Sem_Res is
or else Is_Private_Type (T))
then
if Etype (L) /= T then
- Rewrite (L,
- Make_Unchecked_Type_Conversion (Sloc (L),
- Subtype_Mark => New_Occurrence_Of (T, Sloc (L)),
- Expression => Relocate_Node (L)));
+ Rewrite (L, Unchecked_Convert_To (T, L));
Analyze_And_Resolve (L, T);
end if;
if (Etype (R)) /= T then
- Rewrite (R,
- Make_Unchecked_Type_Conversion (Sloc (R),
- Subtype_Mark => New_Occurrence_Of (Etype (L), Sloc (R)),
- Expression => Relocate_Node (R)));
+ Rewrite (R, Unchecked_Convert_To (Etype (L), R));
Analyze_And_Resolve (R, T);
end if;
end if;
@@ -9065,6 +9086,16 @@ package body Sem_Res is
-- that the context in general allows sliding, while a qualified
-- expression forces equality of bounds.
+ Result_Type : Entity_Id := Typ;
+ -- So in most cases the type of the If_Expression and of its
+ -- dependent expressions is that of the context. However, if
+ -- the expression is the index of an Indexed_Component, we must
+ -- ensure that a proper index check is applied, rather than a
+ -- range check on the index type (which might be discriminant
+ -- dependent). In this case we resolve with the base type of the
+ -- index type, and the index check is generated in the resolution
+ -- of the indexed_component above.
+
-----------------
-- Apply_Check --
-----------------
@@ -9088,10 +9119,10 @@ package body Sem_Res is
else
Rewrite (Expr,
Make_Qualified_Expression (Loc,
- Subtype_Mark => New_Occurrence_Of (Typ, Loc),
+ Subtype_Mark => New_Occurrence_Of (Result_Type, Loc),
Expression => Relocate_Node (Expr)));
- Analyze_And_Resolve (Expr, Typ);
+ Analyze_And_Resolve (Expr, Result_Type);
end if;
end Apply_Check;
@@ -9110,6 +9141,13 @@ package body Sem_Res is
return;
end if;
+ if Present (Parent (N))
+ and then (Nkind (Parent (N)) = N_Indexed_Component
+ or else Nkind (Parent (Parent (N))) = N_Indexed_Component)
+ then
+ Result_Type := Base_Type (Typ);
+ end if;
+
Then_Expr := Next (Condition);
if No (Then_Expr) then
@@ -9119,7 +9157,7 @@ package body Sem_Res is
Else_Expr := Next (Then_Expr);
Resolve (Condition, Any_Boolean);
- Resolve (Then_Expr, Typ);
+ Resolve (Then_Expr, Result_Type);
Apply_Check (Then_Expr);
-- If ELSE expression present, just resolve using the determined type
@@ -9133,7 +9171,7 @@ package body Sem_Res is
Resolve (Else_Expr, Any_Real);
else
- Resolve (Else_Expr, Typ);
+ Resolve (Else_Expr, Result_Type);
end if;
Apply_Check (Else_Expr);
@@ -9157,7 +9195,7 @@ package body Sem_Res is
elsif Root_Type (Typ) = Standard_Boolean then
Else_Expr :=
Convert_To (Typ, New_Occurrence_Of (Standard_True, Sloc (N)));
- Analyze_And_Resolve (Else_Expr, Typ);
+ Analyze_And_Resolve (Else_Expr, Result_Type);
Append_To (Expressions (N), Else_Expr);
else
@@ -9165,7 +9203,7 @@ package body Sem_Res is
Append_To (Expressions (N), Error);
end if;
- Set_Etype (N, Typ);
+ Set_Etype (N, Result_Type);
if not Error_Posted (N) then
Eval_If_Expression (N);
@@ -9330,7 +9368,7 @@ package body Sem_Res is
end if;
-- 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
+ -- worth a warning before Ada 2022, 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.
@@ -9341,7 +9379,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
+ and then Ada_Version < Ada_2022
then
Error_Msg_N
("??access to non-atomic component of atomic array", Prefix (N));
@@ -9756,10 +9794,7 @@ package body Sem_Res is
goto SM_Exit;
elsif not Is_Overloaded (R)
- and then
- (Etype (R) = Universal_Integer
- or else
- Etype (R) = Universal_Real)
+ and then Is_Universal_Numeric_Type (Etype (R))
and then Is_Overloaded (L)
then
T := Etype (R);
@@ -10201,9 +10236,7 @@ package body Sem_Res is
return;
end if;
- if Etype (Left_Opnd (N)) = Universal_Integer
- or else Etype (Left_Opnd (N)) = Universal_Real
- then
+ if Is_Universal_Numeric_Type (Etype (Left_Opnd (N))) then
Check_For_Visible_Operator (N, B_Typ);
end if;
@@ -10466,8 +10499,57 @@ package body Sem_Res is
if Typ = Raise_Type then
Error_Msg_N ("cannot find unique type for raise expression", N);
Set_Etype (N, Any_Type);
+
else
Set_Etype (N, Typ);
+
+ -- Apply check for required parentheses in the enclosing
+ -- context of raise_expressions (RM 11.3 (2)), including default
+ -- expressions in contexts that can include aspect specifications,
+ -- and ancestor parts of extension aggregates.
+
+ declare
+ Par : Node_Id := Parent (N);
+ Parentheses_Found : Boolean := Paren_Count (N) > 0;
+
+ begin
+ while Present (Par)
+ and then Nkind (Par) in N_Has_Etype
+ loop
+ if Paren_Count (Par) > 0 then
+ Parentheses_Found := True;
+ end if;
+
+ if Nkind (Par) = N_Extension_Aggregate
+ and then N = Ancestor_Part (Par)
+ then
+ exit;
+ end if;
+
+ Par := Parent (Par);
+ end loop;
+
+ if not Parentheses_Found
+ and then Comes_From_Source (Par)
+ and then
+ ((Nkind (Par) in N_Modular_Type_Definition
+ | N_Floating_Point_Definition
+ | N_Ordinary_Fixed_Point_Definition
+ | N_Decimal_Fixed_Point_Definition
+ | N_Extension_Aggregate
+ | N_Discriminant_Specification
+ | N_Parameter_Specification
+ | N_Formal_Object_Declaration)
+
+ or else (Nkind (Par) = N_Object_Declaration
+ and then
+ Nkind (Parent (Par)) /= N_Extended_Return_Statement))
+ then
+ Error_Msg_N
+ ("raise_expression must be parenthesized in this context",
+ N);
+ end if;
+ end;
end if;
end Resolve_Raise_Expression;
@@ -10501,12 +10583,9 @@ package body Sem_Res is
PL : constant Node_Id := Prefix (Lorig);
PH : constant Node_Id := Prefix (Horig);
begin
- if Is_Entity_Name (PL)
+ return Is_Entity_Name (PL)
and then Is_Entity_Name (PH)
- and then Entity (PL) = Entity (PH)
- then
- return True;
- end if;
+ and then Entity (PL) = Entity (PH);
end;
end if;
@@ -10575,11 +10654,11 @@ package body Sem_Res is
if Is_Discrete_Type (Typ) and then Expander_Active then
if Is_OK_Static_Expression (L) then
- Fold_Uint (L, Expr_Value (L), Is_OK_Static_Expression (L));
+ Fold_Uint (L, Expr_Value (L), Static => True);
end if;
if Is_OK_Static_Expression (H) then
- Fold_Uint (H, Expr_Value (H), Is_OK_Static_Expression (H));
+ Fold_Uint (H, Expr_Value (H), Static => True);
end if;
end if;
end Resolve_Range;
@@ -10919,7 +10998,7 @@ package body Sem_Res is
if Nkind (N) = N_Selected_Component then
-- 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
+ -- is worth a warning before Ada 2022, 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.
@@ -10927,7 +11006,7 @@ package body Sem_Res is
if 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
+ and then Ada_Version < Ada_2022
then
Error_Msg_N
("??access to non-atomic component of atomic record",
@@ -11530,14 +11609,14 @@ package body Sem_Res is
Comp_Typ_Hi : constant Node_Id :=
Type_High_Bound (Component_Type (Typ));
- Char_Val : Uint;
+ Char_Val : Int;
begin
if Compile_Time_Known_Value (Comp_Typ_Lo)
and then Compile_Time_Known_Value (Comp_Typ_Hi)
then
for J in 1 .. Strlen loop
- Char_Val := UI_From_Int (Int (Get_String_Char (Str, J)));
+ Char_Val := Int (Get_String_Char (Str, J));
if Char_Val < Expr_Value (Comp_Typ_Lo)
or else Char_Val > Expr_Value (Comp_Typ_Hi)
@@ -11562,7 +11641,7 @@ package body Sem_Res is
-- heavy artillery for this situation, but it is hard work to avoid.
declare
- Lits : constant List_Id := New_List;
+ Lits : constant List_Id := New_List;
P : Source_Ptr := Loc + 1;
C : Char_Code;
@@ -12045,16 +12124,35 @@ package body Sem_Res is
-- Deal with universal cases
- if Etype (R) = Universal_Integer
- or else
- Etype (R) = Universal_Real
- then
+ if Is_Universal_Numeric_Type (Etype (R)) then
Check_For_Visible_Operator (N, B_Typ);
end if;
Set_Etype (N, B_Typ);
Resolve (R, B_Typ);
+ -- Generate warning for negative literal of a modular type, unless it is
+ -- enclosed directly in a type qualification or a type conversion, as it
+ -- is likely not what the user intended. We don't issue the warning for
+ -- the common use of -1 to denote OxFFFF_FFFF...
+
+ if Warn_On_Suspicious_Modulus_Value
+ and then Nkind (N) = N_Op_Minus
+ and then Nkind (R) = N_Integer_Literal
+ and then Is_Modular_Integer_Type (B_Typ)
+ and then Nkind (Parent (N)) not in N_Qualified_Expression
+ | N_Type_Conversion
+ and then Expr_Value (R) > Uint_1
+ then
+ Error_Msg_N
+ ("?M?negative literal of modular type is in fact positive", N);
+ Error_Msg_Uint_1 := (-Expr_Value (R)) mod Modulus (B_Typ);
+ Error_Msg_Uint_2 := Expr_Value (R);
+ Error_Msg_N ("\do you really mean^ when writing -^ '?", N);
+ Error_Msg_N
+ ("\if you do, use qualification to avoid this warning", N);
+ end if;
+
-- Generate warning for expressions like abs (x mod 2)
if Warn_On_Redundant_Constructs
@@ -12496,10 +12594,9 @@ package body Sem_Res is
-- the point where actions for the slice are analyzed). Note that this
-- is different from freezing the itype immediately, which might be
-- premature (e.g. if the slice is within a transient scope). This needs
- -- to be done only if expansion is enabled, or in GNATprove mode to
- -- capture the associated run-time exceptions if any.
+ -- to be done only if expansion is enabled.
- elsif Expander_Active or GNATprove_Mode then
+ elsif Expander_Active then
Ensure_Defined (Typ => Slice_Subtype, N => N);
end if;
end Set_Slice_Subtype;
@@ -12630,10 +12727,7 @@ package body Sem_Res is
Set_Etype (Array_Subtype, Base_Type (Typ));
Set_Is_Constrained (Array_Subtype, True);
- Rewrite (N,
- Make_Unchecked_Type_Conversion (Loc,
- Subtype_Mark => New_Occurrence_Of (Array_Subtype, Loc),
- Expression => Relocate_Node (N)));
+ Rewrite (N, Unchecked_Convert_To (Array_Subtype, N));
Set_Etype (N, Array_Subtype);
end;
end if;
@@ -13570,12 +13664,24 @@ package body Sem_Res is
then
if Is_Itype (Opnd_Type) then
+ -- When applying restriction No_Dynamic_Accessibility_Check,
+ -- implicit conversions are allowed when the operand type is
+ -- not deeper than the target type.
+
+ if No_Dynamic_Accessibility_Checks_Enabled (N) then
+ if Type_Access_Level (Opnd_Type)
+ > Deepest_Type_Access_Level (Target_Type)
+ then
+ Conversion_Error_N
+ ("operand has deeper level than target", Operand);
+ end if;
+
-- Implicit conversions aren't allowed for objects of an
-- anonymous access type, since such objects have nonstatic
-- levels in Ada 2012.
- if Nkind (Associated_Node_For_Itype (Opnd_Type)) =
- N_Object_Declaration
+ elsif Nkind (Associated_Node_For_Itype (Opnd_Type))
+ = N_Object_Declaration
then
Conversion_Error_N
("implicit conversion of stand-alone anonymous "
@@ -13628,12 +13734,16 @@ package body Sem_Res is
-- 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)
+ -- Note that when the restriction No_Dynamic_Accessibility_Checks
+ -- is in effect wei also want to proceed with the conversion check
+ -- described above.
+
+ elsif Type_Access_Level (Opnd_Type, Assoc_Ent => Operand)
+ > 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
+ or else No_Dynamic_Accessibility_Checks_Enabled (N))
-- Check we are not in a return value ???
@@ -13952,7 +14062,7 @@ package body Sem_Res is
then
Conversion_Error_N ("target type must be general access type!", N);
Conversion_Error_NE -- CODEFIX
- ("add ALL to }!", N, Target_Type);
+ ("\add ALL to }!", N, Target_Type);
return False;
-- Here we have a real conversion error