aboutsummaryrefslogtreecommitdiff
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.adb246
1 files changed, 171 insertions, 75 deletions
diff --git a/gcc/ada/sem_ch4.adb b/gcc/ada/sem_ch4.adb
index d1cdeeabf..9d63e886a 100644
--- a/gcc/ada/sem_ch4.adb
+++ b/gcc/ada/sem_ch4.adb
@@ -1570,79 +1570,6 @@ package body Sem_Ch4 is
Operator_Check (N);
end Analyze_Concatenation_Rest;
- ------------------------------------
- -- Analyze_Conditional_Expression --
- ------------------------------------
-
- procedure Analyze_Conditional_Expression (N : Node_Id) is
- Condition : constant Node_Id := First (Expressions (N));
- Then_Expr : constant Node_Id := Next (Condition);
- Else_Expr : Node_Id;
-
- begin
- -- Defend against error of missing expressions from previous error
-
- if No (Then_Expr) then
- return;
- end if;
-
- Check_SPARK_Restriction ("conditional expression is not allowed", N);
-
- Else_Expr := Next (Then_Expr);
-
- if Comes_From_Source (N) then
- Check_Compiler_Unit (N);
- end if;
-
- Analyze_Expression (Condition);
- Analyze_Expression (Then_Expr);
-
- if Present (Else_Expr) then
- Analyze_Expression (Else_Expr);
- end if;
-
- -- If then expression not overloaded, then that decides the type
-
- if not Is_Overloaded (Then_Expr) then
- Set_Etype (N, Etype (Then_Expr));
-
- -- Case where then expression is overloaded
-
- else
- declare
- I : Interp_Index;
- It : Interp;
-
- begin
- Set_Etype (N, Any_Type);
-
- -- Shouldn't the following statement be down in the ELSE of the
- -- following loop? ???
-
- Get_First_Interp (Then_Expr, I, It);
-
- -- if no Else_Expression the conditional must be boolean
-
- if No (Else_Expr) then
- Set_Etype (N, Standard_Boolean);
-
- -- Else_Expression Present. For each possible intepretation of
- -- the Then_Expression, add it only if the Else_Expression has
- -- a compatible type.
-
- else
- while Present (It.Nam) loop
- if Has_Compatible_Type (Else_Expr, It.Typ) then
- Add_One_Interp (N, It.Typ, It.Typ);
- end if;
-
- Get_Next_Interp (I, It);
- end loop;
- end if;
- end;
- end if;
- end Analyze_Conditional_Expression;
-
-------------------------
-- Analyze_Equality_Op --
-------------------------
@@ -1981,6 +1908,79 @@ package body Sem_Ch4 is
Set_Etype (N, Etype (Expression (N)));
end Analyze_Expression_With_Actions;
+ ---------------------------
+ -- Analyze_If_Expression --
+ ---------------------------
+
+ procedure Analyze_If_Expression (N : Node_Id) is
+ Condition : constant Node_Id := First (Expressions (N));
+ Then_Expr : constant Node_Id := Next (Condition);
+ Else_Expr : Node_Id;
+
+ begin
+ -- Defend against error of missing expressions from previous error
+
+ if No (Then_Expr) then
+ return;
+ end if;
+
+ Check_SPARK_Restriction ("if expression is not allowed", N);
+
+ Else_Expr := Next (Then_Expr);
+
+ if Comes_From_Source (N) then
+ Check_Compiler_Unit (N);
+ end if;
+
+ Analyze_Expression (Condition);
+ Analyze_Expression (Then_Expr);
+
+ if Present (Else_Expr) then
+ Analyze_Expression (Else_Expr);
+ end if;
+
+ -- If then expression not overloaded, then that decides the type
+
+ if not Is_Overloaded (Then_Expr) then
+ Set_Etype (N, Etype (Then_Expr));
+
+ -- Case where then expression is overloaded
+
+ else
+ declare
+ I : Interp_Index;
+ It : Interp;
+
+ begin
+ Set_Etype (N, Any_Type);
+
+ -- Shouldn't the following statement be down in the ELSE of the
+ -- following loop? ???
+
+ Get_First_Interp (Then_Expr, I, It);
+
+ -- if no Else_Expression the conditional must be boolean
+
+ if No (Else_Expr) then
+ Set_Etype (N, Standard_Boolean);
+
+ -- Else_Expression Present. For each possible intepretation of
+ -- the Then_Expression, add it only if the Else_Expression has
+ -- a compatible type.
+
+ else
+ while Present (It.Nam) loop
+ if Has_Compatible_Type (Else_Expr, It.Typ) then
+ Add_One_Interp (N, It.Typ, It.Typ);
+ end if;
+
+ Get_Next_Interp (I, It);
+ end loop;
+ end if;
+ end;
+ end if;
+ end Analyze_If_Expression;
+
------------------------------------
-- Analyze_Indexed_Component_Form --
------------------------------------
@@ -2386,6 +2386,8 @@ package body Sem_Ch4 is
Process_Indexed_Component_Or_Slice;
end if;
end if;
+
+ Analyze_Dimension (N);
end Analyze_Indexed_Component_Form;
------------------------
@@ -3404,6 +3406,50 @@ package body Sem_Ch4 is
procedure Analyze_Quantified_Expression (N : Node_Id) is
QE_Scop : Entity_Id;
+ function Is_Empty_Range (Typ : Entity_Id) return Boolean;
+ -- If the iterator is part of a quantified expression, and the range is
+ -- known to be statically empty, emit a warning and replace expression
+ -- with its static value. Returns True if the replacement occurs.
+
+ --------------------
+ -- Is_Empty_Range --
+ --------------------
+
+ function Is_Empty_Range (Typ : Entity_Id) return Boolean is
+ Loc : constant Source_Ptr := Sloc (N);
+
+ begin
+ if Is_Array_Type (Typ)
+ and then Compile_Time_Known_Bounds (Typ)
+ and then
+ (Expr_Value (Type_Low_Bound (Etype (First_Index (Typ)))) >
+ Expr_Value (Type_High_Bound (Etype (First_Index (Typ)))))
+ then
+ Preanalyze_And_Resolve (Condition (N), Standard_Boolean);
+
+ if All_Present (N) then
+ Error_Msg_N
+ ("?quantified expression with ALL "
+ & "over a null range has value True", N);
+ Rewrite (N, New_Occurrence_Of (Standard_True, Loc));
+
+ else
+ Error_Msg_N
+ ("?quantified expression with SOME "
+ & "over a null range has value False", N);
+ Rewrite (N, New_Occurrence_Of (Standard_False, Loc));
+ end if;
+
+ Analyze (N);
+ return True;
+
+ else
+ return False;
+ end if;
+ end Is_Empty_Range;
+
+ -- Start of processing for Analyze_Quantified_Expression
+
begin
Check_SPARK_Restriction ("quantified expression is not allowed", N);
@@ -3425,6 +3471,13 @@ package body Sem_Ch4 is
if Present (Iterator_Specification (N)) then
Preanalyze (Iterator_Specification (N));
+
+ if Is_Entity_Name (Name (Iterator_Specification (N)))
+ and then Is_Empty_Range (Etype (Name (Iterator_Specification (N))))
+ then
+ return;
+ end if;
+
else
Preanalyze (Loop_Parameter_Specification (N));
end if;
@@ -5601,8 +5654,24 @@ package body Sem_Ch4 is
return;
end if;
+ -- If the right operand has a type compatible with T1, check for an
+ -- acceptable interpretation, unless T1 is limited (no predefined
+ -- equality available), or this is use of a "/=" for a tagged type.
+ -- In the latter case, possible interpretations of equality need to
+ -- be considered, we don't want the default inequality declared in
+ -- Standard to be chosen, and the "/=" will be rewritten as a
+ -- negation of "=" (see the end of Analyze_Equality_Op). This ensures
+ -- that that rewriting happens during analysis rather than being
+ -- delayed until expansion (this is needed for ASIS, which only sees
+ -- the unexpanded tree). Note that if the node is N_Op_Ne, but Op_Id
+ -- is Name_Op_Eq then we still proceed with the interpretation,
+ -- because that indicates the potential rewriting case where the
+ -- interpretation to consider is actually "=" and the node may be
+ -- about to be rewritten by Analyze_Equality_Op.
+
if T1 /= Standard_Void_Type
and then Has_Compatible_Type (R, T1)
+
and then
((not Is_Limited_Type (T1)
and then not Is_Limited_Composite (T1))
@@ -5611,6 +5680,11 @@ package body Sem_Ch4 is
(Is_Array_Type (T1)
and then not Is_Limited_Type (Component_Type (T1))
and then Available_Full_View_Of_Component (T1)))
+
+ and then
+ (Nkind (N) /= N_Op_Ne
+ or else not Is_Tagged_Type (T1)
+ or else Chars (Op_Id) = Name_Op_Eq)
then
if Found
and then Base_Type (T1) /= Base_Type (T_F)
@@ -5814,14 +5888,36 @@ package body Sem_Ch4 is
begin
if not Is_Overloaded (R) then
if Is_Numeric_Type (Etype (R)) then
- Add_One_Interp (N, Op_Id, Base_Type (Etype (R)));
+
+ -- In an instance a generic actual may be a numeric type even if
+ -- the formal in the generic unit was not. In that case, the
+ -- predefined operator was not a possible interpretation in the
+ -- generic, and cannot be one in the instance.
+
+ if In_Instance
+ and then
+ not Is_Numeric_Type (Corresponding_Generic_Type (Etype (R)))
+ then
+ null;
+ else
+ Add_One_Interp (N, Op_Id, Base_Type (Etype (R)));
+ end if;
end if;
else
Get_First_Interp (R, Index, It);
while Present (It.Typ) loop
if Is_Numeric_Type (It.Typ) then
- Add_One_Interp (N, Op_Id, Base_Type (It.Typ));
+ if In_Instance
+ and then
+ not Is_Numeric_Type
+ (Corresponding_Generic_Type (Etype (It.Typ)))
+ then
+ null;
+
+ else
+ Add_One_Interp (N, Op_Id, Base_Type (It.Typ));
+ end if;
end if;
Get_Next_Interp (Index, It);