summaryrefslogtreecommitdiff
path: root/gcc/ada/sem_ch4.adb
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/ada/sem_ch4.adb')
-rw-r--r--gcc/ada/sem_ch4.adb168
1 files changed, 130 insertions, 38 deletions
diff --git a/gcc/ada/sem_ch4.adb b/gcc/ada/sem_ch4.adb
index 421cd81b5c3..83d71aa8aa2 100644
--- a/gcc/ada/sem_ch4.adb
+++ b/gcc/ada/sem_ch4.adb
@@ -413,8 +413,8 @@ package body Sem_Ch4 is
if Comes_From_Source (N) then
Check_Restriction (No_Allocators, N);
- -- Processing for No_Allocators_After_Elaboration, loop to look at
- -- enclosing context, checking task case and main subprogram case.
+ -- Processing for No_Standard_Allocators_After_Elaboration, loop to
+ -- look at enclosing context, checking task/main subprogram case.
C := N;
P := Parent (C);
@@ -431,7 +431,8 @@ package body Sem_Ch4 is
-- violation of No_Allocators_After_Elaboration we can detect.
if Nkind (Original_Node (Parent (P))) = N_Task_Body then
- Check_Restriction (No_Allocators_After_Elaboration, N);
+ Check_Restriction
+ (No_Standard_Allocators_After_Elaboration, N);
exit;
end if;
@@ -866,6 +867,11 @@ package body Sem_Ch4 is
-- Flag indicates whether an interpretation of the prefix is a
-- parameterless call that returns an access_to_subprogram.
+ procedure Check_Ghost_Function_Call;
+ -- Verify the legality of a call to a ghost function. Such calls can
+ -- appear only in assertion expressions except subtype predicates or
+ -- from within another ghost function.
+
procedure Check_Mixed_Parameter_And_Named_Associations;
-- Check that parameter and named associations are not mixed. This is
-- a restriction in SPARK mode.
@@ -880,6 +886,38 @@ package body Sem_Ch4 is
procedure No_Interpretation;
-- Output error message when no valid interpretation exists
+ -------------------------------
+ -- Check_Ghost_Function_Call --
+ -------------------------------
+
+ procedure Check_Ghost_Function_Call is
+ S : Entity_Id;
+
+ begin
+ -- The ghost function appears inside an assertion expression
+
+ if In_Assertion_Expression (N) then
+ return;
+
+ else
+ S := Current_Scope;
+ while Present (S) and then S /= Standard_Standard loop
+
+ -- The call appears inside another ghost function
+
+ if Is_Ghost_Function (S) then
+ return;
+ end if;
+
+ S := Scope (S);
+ end loop;
+ end if;
+
+ Error_Msg_N
+ ("call to ghost function must appear in assertion expression or "
+ & "another ghost function", N);
+ end Check_Ghost_Function_Call;
+
--------------------------------------------------
-- Check_Mixed_Parameter_And_Named_Associations --
--------------------------------------------------
@@ -970,6 +1008,12 @@ package body Sem_Ch4 is
Check_Mixed_Parameter_And_Named_Associations;
end if;
+ -- Mark a function that appears inside an assertion expression
+
+ if Nkind (N) = N_Function_Call and then In_Assertion_Expr > 0 then
+ Set_In_Assertion_Expression (N);
+ end if;
+
-- Initialize the type of the result of the call to the error type,
-- which will be reset if the type is successfully resolved.
@@ -1076,6 +1120,8 @@ package body Sem_Ch4 is
Set_Etype (Nam_Ent, Etype (N));
end if;
+ -- Overloaded call
+
else
-- An overloaded selected component must denote overloaded operations
-- of a concurrent type. The interpretations are attached to the
@@ -1160,9 +1206,9 @@ package body Sem_Ch4 is
Get_Next_Interp (X, It);
end loop;
- -- If the name is the result of a function call, it can only
- -- be a call to a function returning an access to subprogram.
- -- Insert explicit dereference.
+ -- If the name is the result of a function call, it can only be a
+ -- call to a function returning an access to subprogram. Insert
+ -- explicit dereference.
if Nkind (Nam) = N_Function_Call then
Insert_Explicit_Dereference (Nam);
@@ -1241,6 +1287,13 @@ package body Sem_Ch4 is
End_Interp_List;
end if;
+
+ -- A call to a ghost function is allowed only in assertion expressions,
+ -- excluding subtype predicates, or from within another ghost function.
+
+ if Is_Ghost_Function (Get_Subprogram_Entity (N)) then
+ Check_Ghost_Function_Call;
+ end if;
end Analyze_Call;
-----------------------------
@@ -1248,14 +1301,8 @@ package body Sem_Ch4 is
-----------------------------
procedure Analyze_Case_Expression (N : Node_Id) is
- Expr : constant Node_Id := Expression (N);
- FirstX : constant Node_Id := Expression (First (Alternatives (N)));
- Alt : Node_Id;
- Exp_Type : Entity_Id;
- Exp_Btype : Entity_Id;
-
- Dont_Care : Boolean;
- Others_Present : Boolean;
+ function Has_Static_Predicate (Subtyp : Entity_Id) return Boolean;
+ -- Determine whether subtype Subtyp has aspect Static_Predicate
procedure Non_Static_Choice_Error (Choice : Node_Id);
-- Error routine invoked by the generic instantiation below when
@@ -1270,6 +1317,28 @@ package body Sem_Ch4 is
Process_Associated_Node => No_OP);
use Case_Choices_Processing;
+ --------------------------
+ -- Has_Static_Predicate --
+ --------------------------
+
+ function Has_Static_Predicate (Subtyp : Entity_Id) return Boolean is
+ Item : Node_Id;
+
+ begin
+ Item := First_Rep_Item (Subtyp);
+ while Present (Item) loop
+ if Nkind (Item) = N_Aspect_Specification
+ and then Chars (Identifier (Item)) = Name_Static_Predicate
+ then
+ return True;
+ end if;
+
+ Next_Rep_Item (Item);
+ end loop;
+
+ return False;
+ end Has_Static_Predicate;
+
-----------------------------
-- Non_Static_Choice_Error --
-----------------------------
@@ -1280,6 +1349,17 @@ package body Sem_Ch4 is
("choice given in case expression is not static!", Choice);
end Non_Static_Choice_Error;
+ -- Local variables
+
+ Expr : constant Node_Id := Expression (N);
+ FirstX : constant Node_Id := Expression (First (Alternatives (N)));
+ Alt : Node_Id;
+ Exp_Type : Entity_Id;
+ Exp_Btype : Entity_Id;
+
+ Dont_Care : Boolean;
+ Others_Present : Boolean;
+
-- Start of processing for Analyze_Case_Expression
begin
@@ -1364,9 +1444,22 @@ package body Sem_Ch4 is
Exp_Type := Exp_Btype;
end if;
+ -- The case expression alternatives cover the range of a static subtype
+ -- subject to aspect Static_Predicate. Do not check the choices when the
+ -- case expression has not been fully analyzed yet because this may lead
+ -- to bogus errors.
+
+ if Is_Static_Subtype (Exp_Type)
+ and then Has_Static_Predicate (Exp_Type)
+ and then In_Spec_Expression
+ then
+ null;
+
-- Call instantiated Analyze_Choices which does the rest of the work
- Analyze_Choices (N, Exp_Type, Dont_Care, Others_Present);
+ else
+ Analyze_Choices (N, Exp_Type, Dont_Care, Others_Present);
+ end if;
if Exp_Type = Universal_Integer and then not Others_Present then
Error_Msg_N
@@ -1896,13 +1989,15 @@ package body Sem_Ch4 is
begin
A := First (Actions (N));
- loop
+ while Present (A) loop
Analyze (A);
Next (A);
- exit when No (A);
end loop;
- -- This test needs a comment ???
+ -- We currently hijack Expression_With_Actions with a VOID type and
+ -- a NULL statement in the Expression. This will ultimately be replaced
+ -- by a proper separate N_Compound_Statement node, at which point the
+ -- test below can go away???
if Nkind (Expression (N)) = N_Null_Statement then
Set_Etype (N, Standard_Void_Type);
@@ -4016,13 +4111,11 @@ package body Sem_Ch4 is
and then Nkind (Name) /= N_Selected_Component)
or else
(Nkind (Parent_N) = N_Attribute_Reference
- and then (Attribute_Name (Parent_N) = Name_First
- or else
- Attribute_Name (Parent_N) = Name_Last
- or else
- Attribute_Name (Parent_N) = Name_Length
- or else
- Attribute_Name (Parent_N) = Name_Range)))
+ and then
+ Nam_In (Attribute_Name (Parent_N), Name_First,
+ Name_Last,
+ Name_Length,
+ Name_Range)))
then
Set_Etype (N, Etype (Comp));
@@ -4685,9 +4778,9 @@ package body Sem_Ch4 is
elsif Nkind (Expr) = N_Attribute_Reference
and then
- (Attribute_Name (Expr) = Name_Access or else
- Attribute_Name (Expr) = Name_Unchecked_Access or else
- Attribute_Name (Expr) = Name_Unrestricted_Access)
+ Nam_In (Attribute_Name (Expr), Name_Access,
+ Name_Unchecked_Access,
+ Name_Unrestricted_Access)
then
Error_Msg_N ("argument of conversion cannot be access", N);
Error_Msg_N ("\use qualified expression instead", N);
@@ -4942,8 +5035,7 @@ package body Sem_Ch4 is
-- Start of processing for Check_Arithmetic_Pair
begin
- if Op_Name = Name_Op_Add or else Op_Name = Name_Op_Subtract then
-
+ if Nam_In (Op_Name, Name_Op_Add, Name_Op_Subtract) then
if Is_Numeric_Type (T1)
and then Is_Numeric_Type (T2)
and then (Covers (T1 => T1, T2 => T2)
@@ -4953,11 +5045,9 @@ package body Sem_Ch4 is
Add_One_Interp (N, Op_Id, Specific_Type (T1, T2));
end if;
- elsif Op_Name = Name_Op_Multiply or else Op_Name = Name_Op_Divide then
-
+ elsif Nam_In (Op_Name, Name_Op_Multiply, Name_Op_Divide) then
if Is_Fixed_Point_Type (T1)
- and then (Is_Fixed_Point_Type (T2)
- or else T2 = Universal_Real)
+ and then (Is_Fixed_Point_Type (T2) or else T2 = Universal_Real)
then
-- If Treat_Fixed_As_Integer is set then the Etype is already set
-- and no further processing is required (this is the case of an
@@ -4995,7 +5085,7 @@ package body Sem_Ch4 is
elsif Is_Fixed_Point_Type (T1)
and then (Base_Type (T2) = Base_Type (Standard_Integer)
- or else T2 = Universal_Integer)
+ or else T2 = Universal_Integer)
then
Add_One_Interp (N, Op_Id, T1);
@@ -5012,7 +5102,7 @@ package body Sem_Ch4 is
elsif Is_Fixed_Point_Type (T2)
and then (Base_Type (T1) = Base_Type (Standard_Integer)
- or else T1 = Universal_Integer)
+ or else T1 = Universal_Integer)
and then Op_Name = Name_Op_Multiply
then
Add_One_Interp (N, Op_Id, T2);
@@ -6622,11 +6712,13 @@ package body Sem_Ch4 is
Func_Name := Empty;
if Is_Variable (Prefix) then
- Func_Name := Find_Aspect (Etype (Prefix), Aspect_Variable_Indexing);
+ Func_Name :=
+ Find_Value_Of_Aspect (Etype (Prefix), Aspect_Variable_Indexing);
end if;
if No (Func_Name) then
- Func_Name := Find_Aspect (Etype (Prefix), Aspect_Constant_Indexing);
+ Func_Name :=
+ Find_Value_Of_Aspect (Etype (Prefix), Aspect_Constant_Indexing);
end if;
-- If aspect does not exist the expression is illegal. Error is