aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada/sem_warn.adb
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/ada/sem_warn.adb')
-rw-r--r--gcc/ada/sem_warn.adb321
1 files changed, 167 insertions, 154 deletions
diff --git a/gcc/ada/sem_warn.adb b/gcc/ada/sem_warn.adb
index 04e7acf..b67bb7d 100644
--- a/gcc/ada/sem_warn.adb
+++ b/gcc/ada/sem_warn.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 1999-2019, Free Software Foundation, Inc. --
+-- Copyright (C) 1999-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- --
@@ -1165,7 +1165,7 @@ package body Sem_Warn is
if Ekind (E1) = E_Variable
or else
- (Ekind_In (E1, E_Out_Parameter, E_In_Out_Parameter)
+ (Ekind (E1) in E_Out_Parameter | E_In_Out_Parameter
and then not Is_Protected_Type (Current_Scope))
then
-- If the formal has a class-wide type, retrieve its type
@@ -1469,9 +1469,9 @@ package body Sem_Warn is
UR := Original_Node (UR);
loop
- if Nkind_In (UR, N_Expression_With_Actions,
- N_Qualified_Expression,
- N_Type_Conversion)
+ if Nkind (UR) in N_Expression_With_Actions
+ | N_Qualified_Expression
+ | N_Type_Conversion
then
UR := Expression (UR);
@@ -1612,9 +1612,9 @@ package body Sem_Warn is
and then (Is_Object (E1)
or else Is_Type (E1)
or else Ekind (E1) = E_Label
- or else Ekind_In (E1, E_Exception,
- E_Named_Integer,
- E_Named_Real)
+ or else Ekind (E1) in E_Exception
+ | E_Named_Integer
+ | E_Named_Real
or else Is_Overloadable (E1)
-- Package case, if the main unit is a package spec
@@ -1835,7 +1835,7 @@ package body Sem_Warn is
elsif Nkind (Pref) = N_Explicit_Dereference then
return True;
- -- If prefix is itself a component reference or slice check prefix
+ -- If prefix is itself a component reference or slice check prefix
elsif Nkind (Pref) = N_Slice
or else Nkind (Pref) = N_Indexed_Component
@@ -1872,7 +1872,7 @@ package body Sem_Warn is
-- have a reference from generated code, it is bogus (e.g. calls to init
-- procs to set default discriminant values).
- if not Comes_From_Source (N) then
+ if not Comes_From_Source (Original_Node (N)) then
return;
end if;
@@ -1895,7 +1895,7 @@ package body Sem_Warn is
E : constant Entity_Id := Entity (N);
begin
- if Ekind_In (E, E_Variable, E_Out_Parameter)
+ if Ekind (E) in E_Variable | E_Out_Parameter
and then Never_Set_In_Source_Check_Spec (E)
and then not Has_Initial_Value (E)
and then (No (Unset_Reference (E))
@@ -1975,10 +1975,11 @@ package body Sem_Warn is
Nod := Parent (N);
while Present (Nod) loop
if Nkind (Nod) = N_Pragma
- and then Nam_In (Pragma_Name_Unmapped (Nod),
- Name_Postcondition,
- Name_Refined_Post,
- Name_Contract_Cases)
+ and then
+ Pragma_Name_Unmapped (Nod)
+ in Name_Postcondition
+ | Name_Refined_Post
+ | Name_Contract_Cases
then
return True;
@@ -2102,7 +2103,7 @@ package body Sem_Warn is
P := Parent (P);
exit when No (P);
- if Nkind_In (P, N_If_Statement, N_Elsif_Part)
+ if Nkind (P) in N_If_Statement | N_Elsif_Part
and then Ref_In (Condition (P))
then
return;
@@ -2993,6 +2994,13 @@ package body Sem_Warn is
exception
when others =>
+ -- With debug flag K we will get an exception unless an error has
+ -- already occurred (useful for debugging).
+
+ if Debug_Flag_K then
+ Check_Error_Detected;
+ end if;
+
return False;
end Operand_Has_Warnings_Suppressed;
@@ -3181,7 +3189,7 @@ package body Sem_Warn is
-- Reference to obsolescent component
- elsif Ekind_In (E, E_Component, E_Discriminant) then
+ elsif Ekind (E) in E_Component | E_Discriminant then
Error_Msg_NE
("??reference to obsolescent component& declared#", N, E);
@@ -3386,11 +3394,11 @@ package body Sem_Warn is
if True_Result then
Error_Msg_N
- ("condition can only be False if invalid values present??", Op);
+ ("condition can only be False if invalid values present?c?", Op);
elsif False_Result then
Error_Msg_N
- ("condition can only be True if invalid values present??", Op);
+ ("condition can only be True if invalid values present?c?", Op);
end if;
end if;
end Warn_On_Constant_Valid_Condition;
@@ -3520,6 +3528,7 @@ package body Sem_Warn is
if Constant_Condition_Warnings
and then Is_Known_Branch
and then Comes_From_Source (Orig)
+ and then Nkind (Orig) in N_Has_Entity
and then not In_Instance
then
-- Don't warn if comparison of result of attribute against a constant
@@ -3559,8 +3568,9 @@ package body Sem_Warn is
-- node, since assert pragmas get rewritten at analysis time.
elsif Nkind (Original_Node (P)) = N_Pragma
- and then Nam_In (Pragma_Name_Unmapped (Original_Node (P)),
- Name_Assert, Name_Check)
+ and then
+ Pragma_Name_Unmapped (Original_Node (P))
+ in Name_Assert | Name_Check
then
return;
end if;
@@ -3643,9 +3653,6 @@ package body Sem_Warn is
---------------------------------
procedure Warn_On_Overlapping_Actuals (Subp : Entity_Id; N : Node_Id) is
- function Is_Covered_Formal (Formal : Node_Id) return Boolean;
- -- Return True if Formal is covered by the rule
-
function Refer_Same_Object
(Act1 : Node_Id;
Act2 : Node_Id) return Boolean;
@@ -3658,19 +3665,6 @@ package body Sem_Warn is
-- (RM 6.4.1(6.11/3))
-----------------------
- -- Is_Covered_Formal --
- -----------------------
-
- function Is_Covered_Formal (Formal : Node_Id) return Boolean is
- begin
- return
- Ekind_In (Formal, E_Out_Parameter, E_In_Out_Parameter)
- and then (Is_Elementary_Type (Etype (Formal))
- or else Is_Record_Type (Etype (Formal))
- or else Is_Array_Type (Etype (Formal)));
- end Is_Covered_Formal;
-
- -----------------------
-- Refer_Same_Object --
-----------------------
@@ -3690,9 +3684,6 @@ package body Sem_Warn is
Act2 : Node_Id;
Form1 : Entity_Id;
Form2 : Entity_Id;
- Warn_Only : Boolean;
- -- GNAT warns on overlapping in-out parameters of any type, not just for
- -- elementary in-out parameters (as specified in RM 6.4.1 (15/3-17/3)).
-- Start of processing for Warn_On_Overlapping_Actuals
@@ -3702,29 +3693,6 @@ package body Sem_Warn is
return;
end if;
- -- The call is illegal only if there are at least two in-out parameters
- -- of the same elementary type.
-
- Warn_Only := True;
- Form1 := First_Formal (Subp);
- while Present (Form1) loop
- Form2 := Next_Formal (Form1);
- while Present (Form2) loop
- if Is_Elementary_Type (Etype (Form1))
- and then Is_Elementary_Type (Etype (Form2))
- and then Ekind (Form1) /= E_In_Parameter
- and then Ekind (Form2) /= E_In_Parameter
- then
- Warn_Only := False;
- exit;
- end if;
-
- Next_Formal (Form2);
- end loop;
-
- Next_Formal (Form1);
- end loop;
-
-- Exclude calls rewritten as enumeration literals
if Nkind (N) not in N_Subprogram_Call
@@ -3738,91 +3706,137 @@ package body Sem_Warn is
-- N that is passed as a parameter of mode in out or out to the call C,
-- there is no other name among the other parameters of mode in out or
-- out to C that is known to denote the same object (RM 6.4.1(6.15/3))
+ -- This has been clarified in AI12-0216 to indicate that the illegality
+ -- only occurs if both formals are of an elementary type, because of the
+ -- nondeterminism on the write-back of the corresponding actuals.
+ -- Earlier versions of the language made it illegal if only one of the
+ -- actuals was an elementary parameter that overlapped a composite
+ -- actual, and both were writable.
-- If appropriate warning switch is set, we also report warnings on
- -- overlapping parameters that are record types or array types.
+ -- overlapping parameters that are composite types. Users find these
+ -- warnings useful, and they are used in style guides.
+
+ -- It is also worthwhile to warn on overlaps of composite objects when
+ -- only one of the formals is (in)-out. Note that the RM rule above is
+ -- a legality rule. We choose to implement this check as a warning to
+ -- avoid major incompatibilities with legacy code.
+
+ -- Note also that the rule in 6.4.1 (6.17/3), introduced by AI12-0324,
+ -- is potentially more expensive to verify, and is not yet implemented.
Form1 := First_Formal (Subp);
Act1 := First_Actual (N);
while Present (Form1) and then Present (Act1) loop
- if Is_Covered_Formal (Form1) then
- Form2 := First_Formal (Subp);
- Act2 := First_Actual (N);
+ if Is_Generic_Type (Etype (Act1)) then
+ return;
+ end if;
+
+ -- One of the formals must be either (in)-out or composite.
+ -- The other must be (in)-out.
+
+ if Is_Elementary_Type (Etype (Act1))
+ and then Ekind (Form1) = E_In_Parameter
+ then
+ null;
+
+ else
+ Form2 := Next_Formal (Form1);
+ Act2 := Next_Actual (Act1);
while Present (Form2) and then Present (Act2) loop
- if Form1 /= Form2
- and then Is_Covered_Formal (Form2)
- and then Refer_Same_Object (Act1, Act2)
- then
- -- Guard against previous errors
+ if Refer_Same_Object (Act1, Act2) then
+ if Is_Generic_Type (Etype (Act2)) then
+ return;
+ end if;
- if Error_Posted (N)
- or else No (Etype (Act1))
- or else No (Etype (Act2))
- then
- null;
+ -- First case : two writable elementary parameters
+ -- that overlap.
- -- If the actual is a function call in prefix notation,
- -- there is no real overlap.
+ if (Is_Elementary_Type (Etype (Form1))
+ and then Is_Elementary_Type (Etype (Form2))
+ and then Ekind (Form1) /= E_In_Parameter
+ and then Ekind (Form2) /= E_In_Parameter)
- elsif Nkind (Act2) = N_Function_Call then
- null;
+ -- Second case : two composite parameters that overlap,
+ -- one of which is writable.
- -- If type is not by-copy, assume that aliasing is intended
+ or else (Is_Composite_Type (Etype (Form1))
+ and then Is_Composite_Type (Etype (Form2))
+ and then (Ekind (Form1) /= E_In_Parameter
+ or else Ekind (Form2) /= E_In_Parameter))
- elsif
- Present (Underlying_Type (Etype (Form1)))
- and then
- (Is_By_Reference_Type (Underlying_Type (Etype (Form1)))
- or else
- Convention (Underlying_Type (Etype (Form1))) =
- Convention_Ada_Pass_By_Reference)
- then
- null;
+ -- Third case : an elementary writable parameter that
+ -- overlaps a composite one.
- -- Under Ada 2012 we only report warnings on overlapping
- -- arrays and record types if switch is set.
+ or else (Is_Elementary_Type (Etype (Form1))
+ and then Ekind (Form1) /= E_In_Parameter
+ and then Is_Composite_Type (Etype (Form2)))
- elsif Ada_Version >= Ada_2012
- and then not Is_Elementary_Type (Etype (Form1))
- and then not Warn_On_Overlap
+ or else (Is_Elementary_Type (Etype (Form2))
+ and then Ekind (Form2) /= E_In_Parameter
+ and then Is_Composite_Type (Etype (Form1)))
then
- null;
- -- Here we may need to issue overlap message
+ -- Guard against previous errors
- else
- Error_Msg_Warn :=
+ if Error_Posted (N)
+ or else No (Etype (Act1))
+ or else No (Etype (Act2))
+ then
+ null;
- -- Overlap checking is an error only in Ada 2012. For
- -- earlier versions of Ada, this is a warning.
+ -- If the actual is a function call in prefix notation,
+ -- there is no real overlap.
- Ada_Version < Ada_2012
+ elsif Nkind (Act2) = N_Function_Call then
+ null;
- -- Overlap is only illegal in Ada 2012 in the case of
- -- elementary types (passed by copy). For other types,
- -- we always have a warning in all Ada versions.
+ -- If type is explicitly not by-copy, assume that
+ -- aliasing is intended.
+
+ elsif
+ Present (Underlying_Type (Etype (Form1)))
+ and then
+ (Is_By_Reference_Type
+ (Underlying_Type (Etype (Form1)))
+ or else
+ Convention (Underlying_Type (Etype (Form1))) =
+ Convention_Ada_Pass_By_Reference)
+ then
+ null;
- or else not Is_Elementary_Type (Etype (Form1))
+ -- Under Ada 2012 we only report warnings on overlapping
+ -- arrays and record types if switch is set.
- -- debug flag -gnatd.E changes the error to a warning
- -- even in Ada 2012 mode.
+ elsif Ada_Version >= Ada_2012
+ and then not Is_Elementary_Type (Etype (Form1))
+ and then not Warn_On_Overlap
+ then
+ null;
- or else Error_To_Warning
- or else Warn_Only;
+ -- Here we may need to issue overlap message
- declare
- Act : Node_Id;
- Form : Entity_Id;
+ else
+ Error_Msg_Warn :=
- begin
- -- Find matching actual
+ -- Overlap checking is an error only in Ada 2012.
+ -- For earlier versions of Ada, this is a warning.
- Act := First_Actual (N);
- Form := First_Formal (Subp);
- while Act /= Act2 loop
- Next_Formal (Form);
- Next_Actual (Act);
- end loop;
+ Ada_Version < Ada_2012
+
+ -- Overlap is only illegal in Ada 2012 in the case
+ -- of elementary types (passed by copy). For other
+ -- types we always have a warning in all versions.
+ -- This is clarified by AI12-0216.
+
+ or else not
+ (Is_Elementary_Type (Etype (Form1))
+ and then Is_Elementary_Type (Etype (Form2)))
+
+ -- debug flag -gnatd.E changes the error to a
+ -- warning even in Ada 2012 mode.
+
+ or else Error_To_Warning;
if Is_Elementary_Type (Etype (Act1))
and then Ekind (Form2) = E_In_Parameter
@@ -3836,12 +3850,12 @@ package body Sem_Warn is
-- If the call was written in prefix notation, and
-- thus its prefix before rewriting was a selected
- -- component, count only visible actuals in the call.
+ -- component, count only visible actuals in call.
elsif Is_Entity_Name (First_Actual (N))
and then Nkind (Original_Node (N)) = Nkind (N)
and then Nkind (Name (Original_Node (N))) =
- N_Selected_Component
+ N_Selected_Component
and then
Is_Entity_Name (Prefix (Name (Original_Node (N))))
and then
@@ -3850,30 +3864,30 @@ package body Sem_Warn is
then
if Act1 = First_Actual (N) then
Error_Msg_FE
- ("<<`IN OUT` prefix overlaps with "
- & "actual for&", Act1, Form);
+ ("<I<`IN OUT` prefix overlaps with "
+ & "actual for&", Act1, Form2);
else
-- For greater clarity, give name of formal
- Error_Msg_Node_2 := Form;
+ Error_Msg_Node_2 := Form2;
Error_Msg_FE
- ("<<writable actual for & overlaps with "
- & "actual for&", Act1, Form);
+ ("<I<writable actual for & overlaps with "
+ & "actual for&", Act1, Form2);
end if;
else
-- For greater clarity, give name of formal
- Error_Msg_Node_2 := Form;
+ Error_Msg_Node_2 := Form2;
-- This is one of the messages
Error_Msg_FE
- ("<<writable actual for & overlaps with "
+ ("<I<writable actual for & overlaps with "
& "actual for&", Act1, Form1);
end if;
- end;
+ end if;
end if;
return;
@@ -4220,7 +4234,7 @@ package body Sem_Warn is
-- Only process if warnings activated
if Warn_On_Suspicious_Contract then
- if Nkind_In (Par, N_Op_Eq, N_Op_Ne) then
+ if Nkind (Par) in N_Op_Eq | N_Op_Ne then
if N = Left_Opnd (Par) then
Arg := Right_Opnd (Par);
else
@@ -4330,11 +4344,10 @@ package body Sem_Warn is
-- the message if the variable is volatile, has an address
-- clause, is aliased, or is a renaming, or is imported.
- if Referenced_As_LHS_Check_Spec (E)
- and then No (Address_Clause (E))
- and then not Is_Volatile (E)
- then
+ if Referenced_As_LHS_Check_Spec (E) then
if Warn_On_Modified_Unread
+ and then No (Address_Clause (E))
+ and then not Is_Volatile (E)
and then not Is_Imported (E)
and then not Is_Aliased (E)
and then No (Renamed_Object (E))
@@ -4411,10 +4424,10 @@ package body Sem_Warn is
B : constant Node_Id := Parent (Parent (Scope (E)));
S : Entity_Id := Empty;
begin
- if Nkind_In (B,
- N_Expression_Function,
- N_Subprogram_Body,
- N_Subprogram_Renaming_Declaration)
+ if Nkind (B) in
+ N_Expression_Function |
+ N_Subprogram_Body |
+ N_Subprogram_Renaming_Declaration
then
S := Corresponding_Spec (B);
end if;
@@ -4576,10 +4589,10 @@ package body Sem_Warn is
-- When we hit a package/subprogram body, issue warning and exit
- elsif Nkind_In (P, N_Entry_Body,
- N_Package_Body,
- N_Subprogram_Body,
- N_Task_Body)
+ elsif Nkind (P) in N_Entry_Body
+ | N_Package_Body
+ | N_Subprogram_Body
+ | N_Task_Body
then
-- Case of assigned value never referenced
@@ -4603,8 +4616,8 @@ package body Sem_Warn is
-- Give appropriate message, distinguishing between
-- assignment statements and out parameters.
- if Nkind_In (Parent (LA), N_Parameter_Association,
- N_Procedure_Call_Statement)
+ if Nkind (Parent (LA)) in N_Parameter_Association
+ | N_Procedure_Call_Statement
then
Error_Msg_NE
("?m?& modified by call, but value might not be "
@@ -4630,8 +4643,8 @@ package body Sem_Warn is
-- Give appropriate message, distinguishing between
-- assignment statements and out parameters.
- if Nkind_In (Parent (LA), N_Procedure_Call_Statement,
- N_Parameter_Association)
+ if Nkind (Parent (LA)) in N_Procedure_Call_Statement
+ | N_Parameter_Association
then
Error_Msg_NE
("?m?& modified by call, but value overwritten #!",
@@ -4662,10 +4675,10 @@ package body Sem_Warn is
-- not generate the warning, since the variable in question
-- may be accessed after an exception in the outer block.
- if not Nkind_In (Parent (P), N_Entry_Body,
- N_Package_Body,
- N_Subprogram_Body,
- N_Task_Body)
+ if Nkind (Parent (P)) not in N_Entry_Body
+ | N_Package_Body
+ | N_Subprogram_Body
+ | N_Task_Body
then
Set_Last_Assignment (Ent, Empty);
return;
@@ -4690,7 +4703,7 @@ package body Sem_Warn is
return;
end if;
- X := Next (X);
+ Next (X);
end loop;
end if;
end if;