summaryrefslogtreecommitdiff
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.adb581
1 files changed, 397 insertions, 184 deletions
diff --git a/gcc/ada/sem_res.adb b/gcc/ada/sem_res.adb
index cc55d26d2d5..fdba2bdec03 100644
--- a/gcc/ada/sem_res.adb
+++ b/gcc/ada/sem_res.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 1992-2005, Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2005 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- --
@@ -31,6 +31,7 @@ with Debug_A; use Debug_A;
with Einfo; use Einfo;
with Errout; use Errout;
with Expander; use Expander;
+with Exp_Disp; use Exp_Disp;
with Exp_Ch7; use Exp_Ch7;
with Exp_Tss; use Exp_Tss;
with Exp_Util; use Exp_Util;
@@ -357,7 +358,9 @@ package body Sem_Res is
procedure Check_Direct_Boolean_Op (N : Node_Id) is
begin
- if Root_Type (Etype (Left_Opnd (N))) = Standard_Boolean then
+ if Nkind (N) in N_Op
+ and then Root_Type (Etype (Left_Opnd (N))) = Standard_Boolean
+ then
Check_Restriction (No_Direct_Boolean_Operators, N);
end if;
end Check_Direct_Boolean_Op;
@@ -538,6 +541,12 @@ package body Sem_Res is
if Paren_Count (N) > 0 then
Error_Msg_N
("discriminant in constraint must appear alone", N);
+
+ elsif Nkind (N) = N_Expanded_Name
+ and then Comes_From_Source (N)
+ then
+ Error_Msg_N
+ ("discriminant must appear alone as a direct name", N);
end if;
return;
@@ -2120,7 +2129,7 @@ package body Sem_Res is
if Typ = Any_Real
and then Expr_Type = Any_Fixed
then
- Error_Msg_N ("Illegal context for mixed mode operation", N);
+ Error_Msg_N ("illegal context for mixed mode operation", N);
Set_Etype (N, Universal_Real);
Ctx_Type := Universal_Real;
end if;
@@ -2590,9 +2599,23 @@ package body Sem_Res is
if Has_Aliased_Components (Etype (Expression (A)))
/= Has_Aliased_Components (Etype (F))
then
- Error_Msg_N
- ("both component types in a view conversion must be"
- & " aliased, or neither", A);
+ if Ada_Version < Ada_05 then
+ Error_Msg_N
+ ("both component types in a view conversion must be"
+ & " aliased, or neither", A);
+
+ -- Ada 2005: rule is relaxed (see AI-363)
+
+ elsif Has_Aliased_Components (Etype (F))
+ and then
+ not Has_Aliased_Components (Etype (Expression (A)))
+ then
+ Error_Msg_N
+ ("view conversion operand must have aliased " &
+ "components", N);
+ Error_Msg_N
+ ("\since target type has aliased components", N);
+ end if;
elsif not Same_Ancestor (Etype (F), Etype (Expression (A)))
and then
@@ -2600,8 +2623,8 @@ package body Sem_Res is
or else Is_By_Reference_Type (Etype (Expression (A))))
then
Error_Msg_N
- ("view conversion between unrelated by_reference "
- & "array types not allowed (\A\I-00246)?", A);
+ ("view conversion between unrelated by reference " &
+ "array types not allowed (\'A'I-00246)", A);
end if;
end if;
@@ -2620,19 +2643,16 @@ package body Sem_Res is
or else Is_Limited_Type (Etype (Expression (A))))
then
Error_Msg_N
- ("Conversion between unrelated limited array types "
- & "not allowed (\A\I-00246)?", A);
-
- -- Disable explanation (which produces additional errors)
- -- until AI is approved and warning becomes an error.
+ ("conversion between unrelated limited array types " &
+ "not allowed (\A\I-00246)", A);
- -- if Is_Limited_Type (Etype (F)) then
- -- Explain_Limited_Type (Etype (F), A);
- -- end if;
+ if Is_Limited_Type (Etype (F)) then
+ Explain_Limited_Type (Etype (F), A);
+ end if;
- -- if Is_Limited_Type (Etype (Expression (A))) then
- -- Explain_Limited_Type (Etype (Expression (A)), A);
- -- end if;
+ if Is_Limited_Type (Etype (Expression (A))) then
+ Explain_Limited_Type (Etype (Expression (A)), A);
+ end if;
end if;
Resolve (A, Etype (F));
@@ -2668,9 +2688,9 @@ package body Sem_Res is
Check_Unset_Reference (A);
end if;
- -- In Ada 83 we cannot pass an OUT parameter as an IN
- -- or IN OUT actual to a nested call, since this is a
- -- case of reading an out parameter, which is not allowed.
+ -- In Ada 83 we cannot pass an OUT parameter as an IN or IN OUT
+ -- actual to a nested call, since this is case of reading an
+ -- out parameter, which is not allowed.
if Ada_Version = Ada_83
and then Is_Entity_Name (A)
@@ -3035,6 +3055,46 @@ package body Sem_Res is
end if;
end if;
+ -- Ada 2005 (AI-344): A class-wide allocator requires an accessibility
+ -- check that the level of the type of the created object is not deeper
+ -- than the level of the allocator's access type, since extensions can
+ -- now occur at deeper levels than their ancestor types. This is a
+ -- static accessibility level check; a run-time check is also needed in
+ -- the case of an initialized allocator with a class-wide argument (see
+ -- Expand_Allocator_Expression).
+
+ if Ada_Version >= Ada_05
+ and then Is_Class_Wide_Type (Designated_Type (Typ))
+ then
+ declare
+ Exp_Typ : Entity_Id;
+
+ begin
+ if Nkind (E) = N_Qualified_Expression then
+ Exp_Typ := Etype (E);
+ elsif Nkind (E) = N_Subtype_Indication then
+ Exp_Typ := Entity (Subtype_Mark (Original_Node (E)));
+ else
+ Exp_Typ := Entity (E);
+ end if;
+
+ if Type_Access_Level (Exp_Typ) > Type_Access_Level (Typ) then
+ if In_Instance_Body then
+ Error_Msg_N ("?type in allocator has deeper level than" &
+ " designated class-wide type", E);
+ Error_Msg_N ("?Program_Error will be raised at run time", E);
+ Rewrite (N,
+ Make_Raise_Program_Error (Sloc (N),
+ Reason => PE_Accessibility_Check_Failed));
+ Set_Etype (N, Typ);
+ else
+ Error_Msg_N ("type in allocator has deeper level than" &
+ " designated class-wide type", E);
+ end if;
+ end if;
+ end;
+ end if;
+
-- Check for allocation from an empty storage pool
if No_Pool_Assigned (Typ) then
@@ -3126,8 +3186,8 @@ package body Sem_Res is
if Universal_Interpretation (N) = Universal_Integer then
-- A universal integer literal is resolved as standard integer
- -- except in the case of a fixed-point result, where we leave
- -- it as universal (to be handled by Exp_Fixd later on)
+ -- except in the case of a fixed-point result, where we leave it
+ -- as universal (to be handled by Exp_Fixd later on)
if Is_Fixed_Point_Type (T) then
Resolve (N, Universal_Integer);
@@ -3209,11 +3269,11 @@ package body Sem_Res is
Get_Next_Interp (Index, It);
end loop;
- -- Reanalyze the literal with the fixed type of the context.
- -- If context is Universal_Fixed, we are within a conversion,
- -- leave the literal as a universal real because there is no
- -- usable fixed type, and the target of the conversion plays
- -- no role in the resolution.
+ -- Reanalyze the literal with the fixed type of the context. If
+ -- context is Universal_Fixed, we are within a conversion, leave
+ -- the literal as a universal real because there is no usable
+ -- fixed type, and the target of the conversion plays no role in
+ -- the resolution.
declare
Op2 : Node_Id;
@@ -3466,11 +3526,11 @@ package body Sem_Res is
W : Node_Id;
begin
- -- The context imposes a unique interpretation with type Typ on
- -- a procedure or function call. Find the entity of the subprogram
- -- that yields the expected type, and propagate the corresponding
- -- formal constraints on the actuals. The caller has established
- -- that an interpretation exists, and emitted an error if not unique.
+ -- The context imposes a unique interpretation with type Typ on a
+ -- procedure or function call. Find the entity of the subprogram that
+ -- yields the expected type, and propagate the corresponding formal
+ -- constraints on the actuals. The caller has established that an
+ -- interpretation exists, and emitted an error if not unique.
-- First deal with the case of a call to an access-to-subprogram,
-- dereference made explicit in Analyze_Call.
@@ -3480,9 +3540,9 @@ package body Sem_Res is
Nam := Etype (Subp);
else
- -- Find the interpretation whose type (a subprogram type)
- -- has a return type that is compatible with the context.
- -- Analysis of the node has established that one exists.
+ -- Find the interpretation whose type (a subprogram type) has a
+ -- return type that is compatible with the context. Analysis of
+ -- the node has established that one exists.
Get_First_Interp (Subp, I, It);
Nam := Empty;
@@ -3507,18 +3567,18 @@ package body Sem_Res is
Resolve (Subp, Nam);
end if;
- -- For an indirect call, we always invalidate checks, since we
- -- do not know whether the subprogram is local or global. Yes
- -- we could do better here, e.g. by knowing that there are no
- -- local subprograms, but it does not seem worth the effort.
- -- Similarly, we kill al knowledge of current constant values.
+ -- For an indirect call, we always invalidate checks, since we do not
+ -- know whether the subprogram is local or global. Yes we could do
+ -- better here, e.g. by knowing that there are no local subprograms,
+ -- but it does not seem worth the effort. Similarly, we kill al
+ -- knowledge of current constant values.
Kill_Current_Values;
- -- If this is a procedure call which is really an entry call, do
- -- the conversion of the procedure call to an entry call. Protected
- -- operations use the same circuitry because the name in the call
- -- can be an arbitrary expression with special resolution rules.
+ -- If this is a procedure call which is really an entry call, do the
+ -- conversion of the procedure call to an entry call. Protected
+ -- operations use the same circuitry because the name in the call can be
+ -- an arbitrary expression with special resolution rules.
elsif Nkind (Subp) = N_Selected_Component
or else Nkind (Subp) = N_Indexed_Component
@@ -3589,12 +3649,12 @@ package body Sem_Res is
Error_Msg_N ("cannot call thread body directly", N);
end if;
- -- If the subprogram is not global, then kill all checks. This is
- -- a bit conservative, since in many cases we could do better, but
- -- it is not worth the effort. Similarly, we kill constant values.
- -- However we do not need to do this for internal entities (unless
- -- they are inherited user-defined subprograms), since they are not
- -- in the business of molesting global values.
+ -- If the subprogram is not global, then kill all checks. This is a bit
+ -- conservative, since in many cases we could do better, but it is not
+ -- worth the effort. Similarly, we kill constant values. However we do
+ -- not need to do this for internal entities (unless they are inherited
+ -- user-defined subprograms), since they are not in the business of
+ -- molesting global values.
if not Is_Library_Level_Entity (Nam)
and then (Comes_From_Source (Nam)
@@ -3604,43 +3664,47 @@ package body Sem_Res is
Kill_Current_Values;
end if;
- -- Check for call to obsolescent subprogram
+ -- Deal with call to obsolescent subprogram. Note that we always allow
+ -- such calls in the compiler itself and the run-time, since we assume
+ -- that we know what we are doing in such cases. For example, the calls
+ -- in Ada.Characters.Handling to its own obsolescent subprograms are
+ -- just fine.
- if Warn_On_Obsolescent_Feature
- and then Is_Subprogram (Nam)
- and then Is_Obsolescent (Nam)
- then
- Error_Msg_NE ("call to obsolescent subprogram&?", N, Nam);
+ if Is_Obsolescent (Nam) and then not GNAT_Mode then
+ Check_Restriction (No_Obsolescent_Features, N);
- -- Output additional warning if present
+ if Warn_On_Obsolescent_Feature then
+ Error_Msg_NE ("call to obsolescent subprogram&?", N, Nam);
- W := Obsolescent_Warning (Nam);
+ -- Output additional warning if present
- if Present (W) then
- Name_Buffer (1) := '|';
- Name_Buffer (2) := '?';
- Name_Len := 2;
+ W := Obsolescent_Warning (Nam);
- -- Add characters to message, protecting all of them
+ if Present (W) then
+ Name_Buffer (1) := '|';
+ Name_Buffer (2) := '?';
+ Name_Len := 2;
- for J in 1 .. String_Length (Strval (W)) loop
- Add_Char_To_Name_Buffer (''');
- Add_Char_To_Name_Buffer
- (Get_Character (Get_String_Char (Strval (W), J)));
- end loop;
+ -- Add characters to message, and output message
+
+ for J in 1 .. String_Length (Strval (W)) loop
+ Add_Char_To_Name_Buffer (''');
+ Add_Char_To_Name_Buffer
+ (Get_Character (Get_String_Char (Strval (W), J)));
+ end loop;
- Error_Msg_N (Name_Buffer (1 .. Name_Len), N);
+ Error_Msg_N (Name_Buffer (1 .. Name_Len), N);
+ end if;
end if;
end if;
- -- Check that a procedure call does not occur in the context
- -- of the entry call statement of a conditional or timed
- -- entry call. Note that the case of a call to a subprogram
- -- renaming of an entry will also be rejected. The test
- -- for N not being an N_Entry_Call_Statement is defensive,
- -- covering the possibility that the processing of entry
- -- calls might reach this point due to later modifications
- -- of the code above.
+ -- Check that a procedure call does not occur in the context of the
+ -- entry call statement of a conditional or timed entry call. Note that
+ -- the case of a call to a subprogram renaming of an entry will also be
+ -- rejected. The test for N not being an N_Entry_Call_Statement is
+ -- defensive, covering the possibility that the processing of entry
+ -- calls might reach this point due to later modifications of the code
+ -- above.
if Nkind (Parent (N)) = N_Entry_Call_Alternative
and then Nkind (N) /= N_Entry_Call_Statement
@@ -3662,34 +3726,33 @@ package body Sem_Res is
Error_Msg_N ("\cannot call operation that may modify it", N);
end if;
- -- Freeze the subprogram name if not in default expression. Note
- -- that we freeze procedure calls as well as function calls.
- -- Procedure calls are not frozen according to the rules (RM
- -- 13.14(14)) because it is impossible to have a procedure call to
- -- a non-frozen procedure in pure Ada, but in the code that we
- -- generate in the expander, this rule needs extending because we
- -- can generate procedure calls that need freezing.
+ -- Freeze the subprogram name if not in default expression. Note that we
+ -- freeze procedure calls as well as function calls. Procedure calls are
+ -- not frozen according to the rules (RM 13.14(14)) because it is
+ -- impossible to have a procedure call to a non-frozen procedure in pure
+ -- Ada, but in the code that we generate in the expander, this rule
+ -- needs extending because we can generate procedure calls that need
+ -- freezing.
if Is_Entity_Name (Subp) and then not In_Default_Expression then
Freeze_Expression (Subp);
end if;
- -- For a predefined operator, the type of the result is the type
- -- imposed by context, except for a predefined operation on universal
- -- fixed. Otherwise The type of the call is the type returned by the
- -- subprogram being called.
+ -- For a predefined operator, the type of the result is the type imposed
+ -- by context, except for a predefined operation on universal fixed.
+ -- Otherwise The type of the call is the type returned by the subprogram
+ -- being called.
if Is_Predefined_Op (Nam) then
if Etype (N) /= Universal_Fixed then
Set_Etype (N, Typ);
end if;
- -- If the subprogram returns an array type, and the context
- -- requires the component type of that array type, the node is
- -- really an indexing of the parameterless call. Resolve as such.
- -- A pathological case occurs when the type of the component is
- -- an access to the array type. In this case the call is truly
- -- ambiguous.
+ -- If the subprogram returns an array type, and the context requires the
+ -- component type of that array type, the node is really an indexing of
+ -- the parameterless call. Resolve as such. A pathological case occurs
+ -- when the type of the component is an access to the array type. In
+ -- this case the call is truly ambiguous.
elsif Needs_No_Actuals (Nam)
and then
@@ -3760,10 +3823,10 @@ package body Sem_Res is
Set_Is_Overloaded (Subp, False);
Set_Is_Overloaded (N, False);
- -- If we are calling the current subprogram from immediately within
- -- its body, then that is the case where we can sometimes detect
- -- cases of infinite recursion statically. Do not try this in case
- -- restriction No_Recursion is in effect anyway.
+ -- If we are calling the current subprogram from immediately within its
+ -- body, then that is the case where we can sometimes detect cases of
+ -- infinite recursion statically. Do not try this in case restriction
+ -- No_Recursion is in effect anyway.
Scop := Current_Scope;
@@ -4018,8 +4081,6 @@ package body Sem_Res is
T : Entity_Id;
begin
- Check_Direct_Boolean_Op (N);
-
-- If this is an intrinsic operation which is not predefined, use
-- the types of its declared arguments to resolve the possibly
-- overloaded operands. Otherwise the operands are unambiguous and
@@ -4059,6 +4120,7 @@ package body Sem_Res is
Check_Unset_Reference (R);
Generate_Operator_Reference (N, T);
Eval_Relational_Op (N);
+ Check_Direct_Boolean_Op (N);
end if;
end if;
end Resolve_Comparison_Op;
@@ -4213,7 +4275,7 @@ package body Sem_Res is
null;
else
Error_Msg_N
- ("Invalid use of subtype mark in expression or call", N);
+ ("invalid use of subtype mark in expression or call", N);
end if;
-- Check discriminant use if entity is discriminant in current scope,
@@ -4636,7 +4698,7 @@ package body Sem_Res is
elsif Ekind (Scope (Nam)) = E_Task_Type
and then not In_Open_Scopes (Scope (Nam))
then
- Error_Msg_N ("Task has no entry with this name", Entry_Name);
+ Error_Msg_N ("task has no entry with this name", Entry_Name);
end if;
end if;
@@ -4752,8 +4814,6 @@ package body Sem_Res is
-- Start of processing for Resolve_Equality_Op
begin
- Check_Direct_Boolean_Op (N);
-
Set_Etype (N, Base_Type (Typ));
Generate_Reference (T, N, ' ');
@@ -4822,6 +4882,8 @@ package body Sem_Res is
then
Error_Msg_NE ("cannot call abstract subprogram &!", N, Entity (N));
end if;
+
+ Check_Direct_Boolean_Op (N);
end if;
end Resolve_Equality_Op;
@@ -4837,20 +4899,35 @@ package body Sem_Res is
It : Interp;
begin
- -- Now that we know the type, check that this is not a
- -- dereference of an uncompleted type. Note that this
- -- is not entirely correct, because dereferences of
- -- private types are legal in default expressions.
- -- This consideration also applies to similar checks
- -- for allocators, qualified expressions, and type
- -- conversions. ???
-
- Check_Fully_Declared (Typ, N);
+ -- Now that we know the type, check that this is not dereference of an
+ -- uncompleted type. Note that this is not entirely correct, because
+ -- dereferences of private types are legal in default expressions. This
+ -- exception is taken care of in Check_Fully_Declared.
+
+ -- This consideration also applies to similar checks for allocators,
+ -- qualified expressions, and type conversions.
+
+ -- An additional exception concerns other per-object expressions that
+ -- are not directly related to component declarations, in particular
+ -- representation pragmas for tasks. These will be per-object
+ -- expressions if they depend on discriminants or some global entity.
+ -- If the task has access discriminants, the designated type may be
+ -- incomplete at the point the expression is resolved. This resolution
+ -- takes place within the body of the initialization procedure, where
+ -- the discriminant is replaced by its discriminal.
+
+ if Is_Entity_Name (Prefix (N))
+ and then Ekind (Entity (Prefix (N))) = E_In_Parameter
+ then
+ null;
+ else
+ Check_Fully_Declared (Typ, N);
+ end if;
if Is_Overloaded (P) then
- -- Use the context type to select the prefix that has the
- -- correct designated type.
+ -- Use the context type to select the prefix that has the correct
+ -- designated type.
Get_First_Interp (P, I, It);
while Present (It.Typ) loop
@@ -4863,13 +4940,12 @@ package body Sem_Res is
if Present (It.Typ) then
Resolve (P, It.Typ);
else
- -- If no interpretation covers the designated type of the
- -- prefix, this is the pathological case where not all
- -- implementations of the prefix allow the interpretation
- -- of the node as a call. Now that the expected type is known,
- -- Remove other interpretations from prefix, rewrite it as
- -- a call, and resolve again, so that the proper call node
- -- is generated.
+ -- If no interpretation covers the designated type of the prefix,
+ -- this is the pathological case where not all implementations of
+ -- the prefix allow the interpretation of the node as a call. Now
+ -- that the expected type is known, Remove other interpretations
+ -- from prefix, rewrite it as a call, and resolve again, so that
+ -- the proper call node is generated.
Get_First_Interp (P, I, It);
while Present (It.Typ) loop
@@ -4903,14 +4979,13 @@ package body Sem_Res is
Apply_Access_Check (N);
end if;
- -- If the designated type is a packed unconstrained array type,
- -- and the explicit dereference is not in the context of an
- -- attribute reference, then we must compute and set the actual
- -- subtype, since it is needed by Gigi. The reason we exclude
- -- the attribute case is that this is handled fine by Gigi, and
- -- in fact we use such attributes to build the actual subtype.
- -- We also exclude generated code (which builds actual subtypes
- -- directly if they are needed).
+ -- If the designated type is a packed unconstrained array type, and the
+ -- explicit dereference is not in the context of an attribute reference,
+ -- then we must compute and set the actual subtype, since it is needed
+ -- by Gigi. The reason we exclude the attribute case is that this is
+ -- handled fine by Gigi, and in fact we use such attributes to build the
+ -- actual subtype. We also exclude generated code (which builds actual
+ -- subtypes directly if they are needed).
if Is_Array_Type (Etype (N))
and then Is_Packed (Etype (N))
@@ -4921,9 +4996,9 @@ package body Sem_Res is
Set_Etype (N, Get_Actual_Subtype (N));
end if;
- -- Note: there is no Eval processing required for an explicit
- -- deference, because the type is known to be an allocators, and
- -- allocator expressions can never be static.
+ -- Note: there is no Eval processing required for an explicit deference,
+ -- because the type is known to be an allocators, and allocator
+ -- expressions can never be static.
end Resolve_Explicit_Dereference;
@@ -4940,8 +5015,8 @@ package body Sem_Res is
begin
if Is_Overloaded (Name) then
- -- Use the context type to select the prefix that yields the
- -- correct component type.
+ -- Use the context type to select the prefix that yields the correct
+ -- component type.
declare
I : Interp_Index;
@@ -4953,6 +5028,9 @@ package body Sem_Res is
begin
Get_First_Interp (P, I, It);
+ -- the task has access discriminants, the designated type may be
+ -- incomplete at the point the expression is resolved. This resolution
+ -- takes place within the body of the initialization proc
while Present (It.Typ) loop
if (Is_Array_Type (It.Typ)
@@ -5009,10 +5087,10 @@ package body Sem_Res is
Index := First_Index (Array_Type);
Expr := First (Expressions (N));
- -- The prefix may have resolved to a string literal, in which case
- -- its etype has a special representation. This is only possible
- -- currently if the prefix is a static concatenation, written in
- -- functional notation.
+ -- The prefix may have resolved to a string literal, in which case its
+ -- etype has a special representation. This is only possible currently
+ -- if the prefix is a static concatenation, written in functional
+ -- notation.
if Ekind (Array_Type) = E_String_Literal_Subtype then
Resolve (Expr, Standard_Positive);
@@ -5067,9 +5145,9 @@ package body Sem_Res is
Set_Entity (N, Op);
Set_Is_Overloaded (N, False);
- -- If the operand type is private, rewrite with suitable
- -- conversions on the operands and the result, to expose
- -- the proper underlying numeric type.
+ -- If the operand type is private, rewrite with suitable conversions on
+ -- the operands and the result, to expose the proper underlying numeric
+ -- type.
if Is_Private_Type (Typ) then
Arg1 := Unchecked_Convert_To (Btyp, Left_Opnd (N));
@@ -5167,11 +5245,9 @@ package body Sem_Res is
B_Typ : Entity_Id;
begin
- Check_Direct_Boolean_Op (N);
-
- -- Predefined operations on scalar types yield the base type. On
- -- the other hand, logical operations on arrays yield the type of
- -- the arguments (and the context).
+ -- Predefined operations on scalar types yield the base type. On the
+ -- other hand, logical operations on arrays yield the type of the
+ -- arguments (and the context).
if Is_Array_Type (Typ) then
B_Typ := Typ;
@@ -5211,6 +5287,7 @@ package body Sem_Res is
Set_Etype (N, B_Typ);
Generate_Operator_Reference (N, B_Typ);
Eval_Logical_Op (N);
+ Check_Direct_Boolean_Op (N);
end Resolve_Logical_Op;
---------------------------
@@ -5269,8 +5346,8 @@ package body Sem_Res is
procedure Resolve_Null (N : Node_Id; Typ : Entity_Id) is
begin
- -- Handle restriction against anonymous null access values
- -- This restriction can be turned off using -gnatdh.
+ -- Handle restriction against anonymous null access values This
+ -- restriction can be turned off using -gnatdh.
-- Ada 2005 (AI-231): Remove restriction
@@ -5417,9 +5494,9 @@ package body Sem_Res is
Explain_Limited_Type (Btyp, N);
end if;
- -- If the operands are themselves concatenations, resolve them as
- -- such directly. This removes several layers of recursion and allows
- -- GNAT to handle larger multiple concatenations.
+ -- If the operands are themselves concatenations, resolve them as such
+ -- directly. This removes several layers of recursion and allows GNAT to
+ -- handle larger multiple concatenations.
if Nkind (Op1) = N_Op_Concat
and then not Is_Array_Type (Component_Type (Typ))
@@ -5468,8 +5545,8 @@ package body Sem_Res is
begin
-- Catch attempts to do fixed-point exponentation with universal
- -- operands, which is a case where the illegality is not caught
- -- during normal operator analysis.
+ -- operands, which is a case where the illegality is not caught during
+ -- normal operator analysis.
if Is_Fixed_Point_Type (Typ) and then Comes_From_Source (N) then
Error_Msg_N ("exponentiation not available for fixed point", N);
@@ -5560,9 +5637,9 @@ package body Sem_Res is
-- Start of processing for Resolve_Op_Not
begin
- -- Predefined operations on scalar types yield the base type. On
- -- the other hand, logical operations on arrays yield the type of
- -- the arguments (and the context).
+ -- Predefined operations on scalar types yield the base type. On the
+ -- other hand, logical operations on arrays yield the type of the
+ -- arguments (and the context).
if Is_Array_Type (Typ) then
B_Typ := Typ;
@@ -5669,12 +5746,12 @@ package body Sem_Res is
Check_Unset_Reference (H);
-- We have to check the bounds for being within the base range as
- -- required for a non-static context. Normally this is automatic
- -- and done as part of evaluating expressions, but the N_Range
- -- node is an exception, since in GNAT we consider this node to
- -- be a subexpression, even though in Ada it is not. The circuit
- -- in Sem_Eval could check for this, but that would put the test
- -- on the main evaluation path for expressions.
+ -- required for a non-static context. Normally this is automatic and
+ -- done as part of evaluating expressions, but the N_Range node is an
+ -- exception, since in GNAT we consider this node to be a subexpression,
+ -- even though in Ada it is not. The circuit in Sem_Eval could check for
+ -- this, but that would put the test on the main evaluation path for
+ -- expressions.
Check_Non_Static_Context (L);
Check_Non_Static_Context (H);
@@ -5756,8 +5833,6 @@ package body Sem_Res is
Realval => Small_Value (Typ) * Cint));
Set_Is_Static_Expression (N, Stat);
-
-
end if;
-- In all cases, set the corresponding integer field
@@ -6389,8 +6464,8 @@ package body Sem_Res is
-----------------------------
procedure Resolve_Type_Conversion (N : Node_Id; Typ : Entity_Id) is
- Target_Type : constant Entity_Id := Etype (N);
- Conv_OK : constant Boolean := Conversion_OK (N);
+ Conv_OK : constant Boolean := Conversion_OK (N);
+ Target_Type : Entity_Id := Etype (N);
Operand : Node_Id;
Opnd_Type : Entity_Id;
Rop : Node_Id;
@@ -6525,6 +6600,43 @@ package body Sem_Res is
("?useless conversion, & has this type", N, Entity (Orig_N));
end if;
end if;
+
+ -- Ada 2005 (AI-251): Handle conversions to abstract interface types
+
+ if Ada_Version >= Ada_05 then
+ if Is_Access_Type (Target_Type) then
+ Target_Type := Directly_Designated_Type (Target_Type);
+ end if;
+
+ if Is_Class_Wide_Type (Target_Type) then
+ Target_Type := Etype (Target_Type);
+ end if;
+
+ if Is_Interface (Target_Type) then
+ if Is_Class_Wide_Type (Opnd_Type) then
+ Opnd_Type := Etype (Opnd_Type);
+ end if;
+
+ if not Interface_Present_In_Ancestor
+ (Typ => Opnd_Type,
+ Iface => Target_Type)
+ then
+ if Nkind (Operand) = N_Attribute_Reference then
+ Error_Msg_Name_1 := Chars (Prefix (Operand));
+ else
+ Error_Msg_Name_1 := Chars (Operand);
+ end if;
+
+ Error_Msg_Name_2 := Chars (Target_Type);
+ Error_Msg_NE
+ ("(Ada 2005) % does not implement interface %",
+ Operand, Target_Type);
+
+ else
+ Expand_Interface_Conversion (N);
+ end if;
+ end if;
+ end if;
end Resolve_Type_Conversion;
----------------------
@@ -6998,6 +7110,13 @@ package body Sem_Res is
return
Conversion_Check (False,
"downward conversion of tagged objects not allowed");
+
+ -- Ada 2005 (AI-251): The conversion of a tagged type to an
+ -- abstract interface type is always valid
+
+ elsif Is_Interface (Target_Type) then
+ return True;
+
else
Error_Msg_NE
("invalid tagged conversion, not compatible with}",
@@ -7162,6 +7281,94 @@ package body Sem_Res is
return True;
+ -- Ada 2005 (AI-251)
+
+ elsif (Ekind (Target_Type) = E_General_Access_Type
+ or else Ekind (Target_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
+ -- check is not enforced when within an instance body, since the RM
+ -- requires such cases to be caught at run time.
+
+ if Ekind (Target_Type) /= E_Anonymous_Access_Type then
+ if Type_Access_Level (Opnd_Type) >
+ Type_Access_Level (Target_Type)
+ then
+ -- In an instance, this is a run-time check, but one we know
+ -- will fail, so generate an appropriate warning. The raise
+ -- will be generated by Expand_N_Type_Conversion.
+
+ if In_Instance_Body then
+ Error_Msg_N
+ ("?cannot convert local pointer to non-local access type",
+ Operand);
+ Error_Msg_N
+ ("?Program_Error will be raised at run time", Operand);
+
+ else
+ Error_Msg_N
+ ("cannot convert local pointer to non-local access type",
+ Operand);
+ return False;
+ end if;
+
+ -- Special accessibility checks are needed in the case of access
+ -- discriminants declared for a limited type.
+
+ elsif Ekind (Opnd_Type) = E_Anonymous_Access_Type
+ and then not Is_Local_Anonymous_Access (Opnd_Type)
+ then
+ -- When the operand is a selected access discriminant the check
+ -- needs to be made against the level of the object denoted by
+ -- the prefix of the selected name. (Object_Access_Level
+ -- handles checking the prefix of the operand for this case.)
+
+ if Nkind (Operand) = N_Selected_Component
+ and then Object_Access_Level (Operand)
+ > Type_Access_Level (Target_Type)
+ then
+ -- In an instance, this is a run-time check, but one we
+ -- know will fail, so generate an appropriate warning.
+ -- The raise will be generated by Expand_N_Type_Conversion.
+
+ if In_Instance_Body then
+ Error_Msg_N
+ ("?cannot convert access discriminant to non-local" &
+ " access type", Operand);
+ Error_Msg_N
+ ("?Program_Error will be raised at run time", Operand);
+
+ else
+ Error_Msg_N
+ ("cannot convert access discriminant to non-local" &
+ " access type", Operand);
+ return False;
+ end if;
+ end if;
+
+ -- The case of a reference to an access discriminant from
+ -- within a limited type declaration (which will appear as
+ -- a discriminal) is always illegal because the level of the
+ -- discriminant is considered to be deeper than any (namable)
+ -- access type.
+
+ if Is_Entity_Name (Operand)
+ and then not Is_Local_Anonymous_Access (Opnd_Type)
+ and then (Ekind (Entity (Operand)) = E_In_Parameter
+ or else Ekind (Entity (Operand)) = E_Constant)
+ and then Present (Discriminal_Link (Entity (Operand)))
+ then
+ Error_Msg_N
+ ("discriminant has deeper accessibility level than target",
+ Operand);
+ return False;
+ end if;
+ end if;
+ end if;
+
+ return True;
+
elsif (Ekind (Target_Type) = E_General_Access_Type
or else Ekind (Target_Type) = E_Anonymous_Access_Type)
and then
@@ -7181,11 +7388,13 @@ package body Sem_Res is
return False;
end if;
- -- Check the static accessibility rule of 4.6(17). Note that
- -- the check is not enforced when within an instance body, since
- -- the RM requires such cases to be caught at run time.
+ -- Check the static accessibility rule of 4.6(17). Note that the
+ -- check is not enforced when within an instance body, since the RM
+ -- requires such cases to be caught at run time.
- if Ekind (Target_Type) /= E_Anonymous_Access_Type then
+ if Ekind (Target_Type) /= E_Anonymous_Access_Type
+ or else Is_Local_Anonymous_Access (Target_Type)
+ then
if Type_Access_Level (Opnd_Type)
> Type_Access_Level (Target_Type)
then
@@ -7207,13 +7416,17 @@ package body Sem_Res is
return False;
end if;
- elsif Ekind (Opnd_Type) = E_Anonymous_Access_Type then
+ -- Special accessibility checks are needed in the case of access
+ -- discriminants declared for a limited type.
+
+ elsif Ekind (Opnd_Type) = E_Anonymous_Access_Type
+ and then not Is_Local_Anonymous_Access (Opnd_Type)
+ then
- -- When the operand is a selected access discriminant
- -- the check needs to be made against the level of the
- -- object denoted by the prefix of the selected name.
- -- (Object_Access_Level handles checking the prefix
- -- of the operand for this case.)
+ -- When the operand is a selected access discriminant the check
+ -- needs to be made against the level of the object denoted by
+ -- the prefix of the selected name. (Object_Access_Level
+ -- handles checking the prefix of the operand for this case.)
if Nkind (Operand) = N_Selected_Component
and then Object_Access_Level (Operand)
@@ -7238,11 +7451,11 @@ package body Sem_Res is
end if;
end if;
- -- The case of a reference to an access discriminant
- -- from within a type declaration (which will appear
- -- as a discriminal) is always illegal because the
- -- level of the discriminant is considered to be
- -- deeper than any (namable) access type.
+ -- The case of a reference to an access discriminant from
+ -- within a limited type declaration (which will appear as
+ -- a discriminal) is always illegal because the level of the
+ -- discriminant is considered to be deeper than any (namable)
+ -- access type.
if Is_Entity_Name (Operand)
and then (Ekind (Entity (Operand)) = E_In_Parameter