------------------------------------------------------------------------------
--                                                                          --
--                         GNAT COMPILER COMPONENTS                         --
--                                                                          --
--                             S E M _ W A R N                              --
--                                                                          --
--                                 B o d y                                  --
--                                                                          --
--          Copyright (C) 1999-2022, 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- --
-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
-- or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License --
-- for  more details.  You should have  received  a copy of the GNU General --
-- Public License  distributed with GNAT; see file COPYING3.  If not, go to --
-- http://www.gnu.org/licenses for a complete copy of the license.          --
--                                                                          --
-- GNAT was originally developed  by the GNAT team at  New York University. --
-- Extensive contributions were provided by Ada Core Technologies Inc.      --
--                                                                          --
------------------------------------------------------------------------------

with Atree;          use Atree;
with Debug;          use Debug;
with Einfo;          use Einfo;
with Einfo.Entities; use Einfo.Entities;
with Einfo.Utils;    use Einfo.Utils;
with Errout;         use Errout;
with Exp_Code;       use Exp_Code;
with Lib;            use Lib;
with Namet;          use Namet;
with Nlists;         use Nlists;
with Opt;            use Opt;
with Par_SCO;        use Par_SCO;
with Rtsfind;        use Rtsfind;
with Sem;            use Sem;
with Sem_Ch8;        use Sem_Ch8;
with Sem_Aux;        use Sem_Aux;
with Sem_Eval;       use Sem_Eval;
with Sem_Prag;       use Sem_Prag;
with Sem_Util;       use Sem_Util;
with Sinfo;          use Sinfo;
with Sinfo.Nodes;    use Sinfo.Nodes;
with Sinfo.Utils;    use Sinfo.Utils;
with Sinput;         use Sinput;
with Snames;         use Snames;
with Stand;          use Stand;
with Stringt;        use Stringt;
with Tbuild;         use Tbuild;
with Uintp;          use Uintp;

package body Sem_Warn is

   --  The following table collects Id's of entities that are potentially
   --  unreferenced. See Check_Unset_Reference for further details.
   --  ??? Check_Unset_Reference has zero information about this table.

   package Unreferenced_Entities is new Table.Table (
     Table_Component_Type => Entity_Id,
     Table_Index_Type     => Nat,
     Table_Low_Bound      => 1,
     Table_Initial        => Alloc.Unreferenced_Entities_Initial,
     Table_Increment      => Alloc.Unreferenced_Entities_Increment,
     Table_Name           => "Unreferenced_Entities");

   --  The following table collects potential warnings for IN OUT parameters
   --  that are referenced but not modified. These warnings are processed when
   --  the front end calls the procedure Output_Non_Modified_In_Out_Warnings.
   --  The reason that we defer output of these messages is that we want to
   --  detect the case where the relevant procedure is used as a generic actual
   --  in an instantiation, since we suppress the warnings in this case. The
   --  flag Used_As_Generic_Actual will be set in this case, but only at the
   --  point of usage. Similarly, we suppress the message if the address of the
   --  procedure is taken, where the flag Address_Taken may be set later.

   package In_Out_Warnings is new Table.Table (
     Table_Component_Type => Entity_Id,
     Table_Index_Type     => Nat,
     Table_Low_Bound      => 1,
     Table_Initial        => Alloc.In_Out_Warnings_Initial,
     Table_Increment      => Alloc.In_Out_Warnings_Increment,
     Table_Name           => "In_Out_Warnings");

   --------------------------------------------------------
   -- Handling of Warnings Off, Unmodified, Unreferenced --
   --------------------------------------------------------

   --  The functions Has_Warnings_Off, Has_Unmodified, Has_Unreferenced must
   --  generally be used instead of Warnings_Off, Has_Pragma_Unmodified and
   --  Has_Pragma_Unreferenced, as noted in the specs in Einfo.

   --  In order to avoid losing warnings in -gnatw.w (warn on unnecessary
   --  warnings off pragma) mode, i.e. to avoid false negatives, the code
   --  must follow some important rules.

   --  Call these functions as late as possible, after completing all other
   --  tests, just before the warnings is given. For example, don't write:

   --     if not Has_Warnings_Off (E)
   --       and then some-other-predicate-on-E then ..

   --  Instead the following is preferred

   --     if some-other-predicate-on-E
   --       and then Has_Warnings_Off (E)

   --  This way if some-other-predicate is false, we avoid a false indication
   --  that a Warnings (Off, E) pragma was useful in preventing a warning.

   --  The second rule is that if both Has_Unmodified and Has_Warnings_Off, or
   --  Has_Unreferenced and Has_Warnings_Off are called, make sure that the
   --  call to Has_Unmodified/Has_Unreferenced comes first, this way we record
   --  that the Warnings (Off) could have been Unreferenced or Unmodified. In
   --  fact Has_Unmodified/Has_Unreferenced includes a test for Warnings Off,
   --  and so a subsequent test is not needed anyway (though it is harmless).

   -----------------------
   -- Local Subprograms --
   -----------------------

   function Generic_Package_Spec_Entity (E : Entity_Id) return Boolean;
   --  This returns true if the entity E is declared within a generic package.
   --  The point of this is to detect variables which are not assigned within
   --  the generic, but might be assigned outside the package for any given
   --  instance. These are cases where we leave the warnings to be posted for
   --  the instance, when we will know more.

   function Goto_Spec_Entity (E : Entity_Id) return Entity_Id;
   --  If E is a parameter entity for a subprogram body, then this function
   --  returns the corresponding spec entity, if not, E is returned unchanged.

   function Has_Pragma_Unmodified_Check_Spec (E : Entity_Id) return Boolean;
   --  Tests Has_Pragma_Unmodified flag for entity E. If E is not a formal,
   --  this is simply the setting of the flag Has_Pragma_Unmodified. If E is
   --  a body formal, the setting of the flag in the corresponding spec is
   --  also checked (and True returned if either flag is True).

   function Has_Pragma_Unreferenced_Check_Spec (E : Entity_Id) return Boolean;
   --  Tests Has_Pragma_Unreferenced flag for entity E. If E is not a formal,
   --  this is simply the setting of the flag Has_Pragma_Unreferenced. If E is
   --  a body formal, the setting of the flag in the corresponding spec is
   --  also checked (and True returned if either flag is True).

   function Is_Attribute_And_Known_Value_Comparison
     (Op : Node_Id) return Boolean;
   --  Determine whether operator Op denotes a comparison where the left
   --  operand is an attribute reference and the value of the right operand is
   --  known at compile time.

   function Never_Set_In_Source_Check_Spec (E : Entity_Id) return Boolean;
   --  Tests Never_Set_In_Source status for entity E. If E is not a formal,
   --  this is simply the setting of the flag Never_Set_In_Source. If E is
   --  a body formal, the setting of the flag in the corresponding spec is
   --  also checked (and False returned if either flag is False).

   function Operand_Has_Warnings_Suppressed (N : Node_Id) return Boolean;
   --  This function traverses the expression tree represented by the node N
   --  and determines if any sub-operand is a reference to an entity for which
   --  the Warnings_Off flag is set. True is returned if such an entity is
   --  encountered, and False otherwise.

   function Referenced_Check_Spec (E : Entity_Id) return Boolean;
   --  Tests Referenced status for entity E. If E is not a formal, this is
   --  simply the setting of the flag Referenced. If E is a body formal, the
   --  setting of the flag in the corresponding spec is also checked (and True
   --  returned if either flag is True).

   function Referenced_As_LHS_Check_Spec (E : Entity_Id) return Boolean;
   --  Tests Referenced_As_LHS status for entity E. If E is not a formal, this
   --  is simply the setting of the flag Referenced_As_LHS. If E is a body
   --  formal, the setting of the flag in the corresponding spec is also
   --  checked (and True returned if either flag is True).

   function Referenced_As_Out_Parameter_Check_Spec
     (E : Entity_Id) return Boolean;
   --  Tests Referenced_As_Out_Parameter status for entity E. If E is not a
   --  formal, this is simply the setting of Referenced_As_Out_Parameter. If E
   --  is a body formal, the setting of the flag in the corresponding spec is
   --  also checked (and True returned if either flag is True).

   procedure Warn_On_Unreferenced_Entity
     (Spec_E : Entity_Id;
      Body_E : Entity_Id := Empty);
   --  Output warnings for unreferenced entity E. For the case of an entry
   --  formal, Body_E is the corresponding body entity for a particular
   --  accept statement, and the message is posted on Body_E. In all other
   --  cases, Body_E is ignored and must be Empty.

   function Warnings_Off_Check_Spec (E : Entity_Id) return Boolean;
   --  Returns True if Warnings_Off is set for the entity E or (in the case
   --  where there is a Spec_Entity), Warnings_Off is set for the Spec_Entity.

   --------------------------
   -- Check_Code_Statement --
   --------------------------

   procedure Check_Code_Statement (N : Node_Id) is
   begin
      --  If volatile, nothing to worry about

      if Is_Asm_Volatile (N) then
         return;
      end if;

      --  Warn if no input or no output

      Setup_Asm_Inputs (N);

      if No (Asm_Input_Value) then
         Error_Msg_F
           ("??code statement with no inputs should usually be Volatile!", N);
         return;
      end if;

      Setup_Asm_Outputs (N);

      if No (Asm_Output_Variable) then
         Error_Msg_F
           ("??code statement with no outputs should usually be Volatile!", N);
         return;
      end if;
   end Check_Code_Statement;

   ---------------------------------
   -- Check_Infinite_Loop_Warning --
   ---------------------------------

   --  The case we look for is a while loop which tests a local variable, where
   --  there is no obvious direct or possible indirect update of the variable
   --  within the body of the loop.

   procedure Check_Infinite_Loop_Warning (Loop_Statement : Node_Id) is
      Expression : Node_Id := Empty;
      --  Set to WHILE or EXIT WHEN condition to be tested

      Ref : Node_Id := Empty;
      --  Reference in Expression to variable that might not be modified
      --  in loop, indicating a possible infinite loop.

      Var : Entity_Id := Empty;
      --  Corresponding entity (entity of Ref)

      Function_Call_Found : Boolean := False;
      --  True if Find_Var found a function call in the condition

      procedure Find_Var (N : Node_Id);
      --  Inspect condition to see if it depends on a single entity reference.
      --  If so, Ref is set to point to the reference node, and Var is set to
      --  the referenced Entity.

      function Has_Condition_Actions (Iter : Node_Id) return Boolean;
      --  Determine whether iteration scheme Iter has meaningful condition
      --  actions.

      function Has_Indirection (T : Entity_Id) return Boolean;
      --  If the controlling variable is an access type, or is a record type
      --  with access components, assume that it is changed indirectly and
      --  suppress the warning. As a concession to low-level programming, in
      --  particular within Declib, we also suppress warnings on a record
      --  type that contains components of type Address or Short_Address.

      function Is_Suspicious_Function_Name (E : Entity_Id) return Boolean;
      --  Given an entity name, see if the name appears to have something to
      --  do with I/O or network stuff, and if so, return True. Used to kill
      --  some false positives on a heuristic basis that such functions will
      --  likely have some strange side effect dependencies. A rather strange
      --  test, but warning messages are in the heuristics business.

      function Test_Ref (N : Node_Id) return Traverse_Result;
      --  Test for reference to variable in question. Returns Abandon if
      --  matching reference found. Used in instantiation of No_Ref_Found.

      function No_Ref_Found is new Traverse_Func (Test_Ref);
      --  Function to traverse body of procedure. Returns Abandon if matching
      --  reference found.

      --------------
      -- Find_Var --
      --------------

      procedure Find_Var (N : Node_Id) is
      begin
         --  Expression is a direct variable reference

         if Is_Entity_Name (N) then
            Ref := N;
            Var := Entity (Ref);

         --  If expression is an operator, check its operands

         elsif Nkind (N) in N_Binary_Op then
            if Compile_Time_Known_Value (Right_Opnd (N)) then
               Find_Var (Left_Opnd (N));

            elsif Compile_Time_Known_Value (Left_Opnd (N)) then
               Find_Var (Right_Opnd (N));

            --  Ignore any other comparison

            else
               return;
            end if;

         --  If expression is a unary operator, check its operand

         elsif Nkind (N) in N_Unary_Op then
            Find_Var (Right_Opnd (N));

         --  Case of condition is function call

         elsif Nkind (N) = N_Function_Call then

            Function_Call_Found := True;

            --  Forget it if function name is not entity, who knows what
            --  we might be calling?

            if not Is_Entity_Name (Name (N)) then
               return;

            --  Forget it if function name is suspicious. A strange test
            --  but warning generation is in the heuristics business.

            elsif Is_Suspicious_Function_Name (Entity (Name (N))) then
               return;

            --  Forget it if function is marked Volatile_Function

            elsif Is_Volatile_Function (Entity (Name (N))) then
               return;

            --  Forget it if warnings are suppressed on function entity

            elsif Has_Warnings_Off (Entity (Name (N))) then
               return;

            --  Forget it if the parameter is not In

            elsif Has_Out_Or_In_Out_Parameter (Entity (Name (N))) then
               return;
            end if;

            --  OK, see if we have one argument

            declare
               PA : constant List_Id := Parameter_Associations (N);

            begin
               --  One argument, so check the argument

               if Present (PA) and then List_Length (PA) = 1 then
                  if Nkind (First (PA)) = N_Parameter_Association then
                     Find_Var (Explicit_Actual_Parameter (First (PA)));
                  else
                     Find_Var (First (PA));
                  end if;

               --  Not one argument

               else
                  return;
               end if;
            end;

         --  Any other kind of node is not something we warn for

         else
            return;
         end if;
      end Find_Var;

      ---------------------------
      -- Has_Condition_Actions --
      ---------------------------

      function Has_Condition_Actions (Iter : Node_Id) return Boolean is
         Action : Node_Id;

      begin
         --  A call marker is not considered a meaningful action because it
         --  acts as an annotation and has no runtime semantics.

         Action := First (Condition_Actions (Iter));
         while Present (Action) loop
            if Nkind (Action) /= N_Call_Marker then
               return True;
            end if;

            Next (Action);
         end loop;

         return False;
      end Has_Condition_Actions;

      ---------------------
      -- Has_Indirection --
      ---------------------

      function Has_Indirection (T : Entity_Id) return Boolean is
         Comp : Entity_Id;
         Rec  : Entity_Id;

      begin
         if Is_Access_Type (T) then
            return True;

         elsif Is_Private_Type (T)
           and then Present (Full_View (T))
           and then Is_Access_Type (Full_View (T))
         then
            return True;

         elsif Is_Record_Type (T) then
            Rec := T;

         elsif Is_Private_Type (T)
           and then Present (Full_View (T))
           and then Is_Record_Type (Full_View (T))
         then
            Rec := Full_View (T);
         else
            return False;
         end if;

         Comp := First_Component (Rec);
         while Present (Comp) loop
            if Is_Access_Type (Etype (Comp))
              or else Is_Descendant_Of_Address (Etype (Comp))
            then
               return True;
            end if;

            Next_Component (Comp);
         end loop;

         return False;
      end Has_Indirection;

      ---------------------------------
      -- Is_Suspicious_Function_Name --
      ---------------------------------

      function Is_Suspicious_Function_Name (E : Entity_Id) return Boolean is
         function Substring_Present (S : String) return Boolean;
         --  Returns True if name buffer has given string delimited by non-
         --  alphabetic characters or by end of string. S is lower case.

         -----------------------
         -- Substring_Present --
         -----------------------

         function Substring_Present (S : String) return Boolean is
            Len : constant Natural := S'Length;

         begin
            for J in 1 .. Name_Len - (Len - 1) loop
               if Name_Buffer (J .. J + (Len - 1)) = S
                 and then (J = 1 or else Name_Buffer (J - 1) not in 'a' .. 'z')
                 and then
                   (J + Len > Name_Len
                     or else Name_Buffer (J + Len) not in 'a' .. 'z')
               then
                  return True;
               end if;
            end loop;

            return False;
         end Substring_Present;

         --  Local variables

         S : Entity_Id;

      --  Start of processing for Is_Suspicious_Function_Name

      begin
         S := E;
         while Present (S) and then S /= Standard_Standard loop
            Get_Name_String (Chars (S));

            if Substring_Present ("io")
              or else Substring_Present ("file")
              or else Substring_Present ("network")
            then
               return True;
            else
               S := Scope (S);
            end if;
         end loop;

         return False;
      end Is_Suspicious_Function_Name;

      --------------
      -- Test_Ref --
      --------------

      function Test_Ref (N : Node_Id) return Traverse_Result is
      begin
         --  Waste of time to look at the expression we are testing

         if N = Expression then
            return Skip;

         --  Direct reference to variable in question

         elsif Is_Entity_Name (N)
           and then Present (Entity (N))
           and then Entity (N) = Var
         then
            --  If this is an lvalue, then definitely abandon, since
            --  this could be a direct modification of the variable.

            if Known_To_Be_Assigned (N) then
               return Abandon;
            end if;

            --  If the condition contains a function call, we consider it may
            --  be modified by side effects from a procedure call. Otherwise,
            --  we consider the condition may not be modified, although that
            --  might happen if Variable is itself a by-reference parameter,
            --  and the procedure called modifies the global object referred to
            --  by Variable, but we actually prefer to issue a warning in this
            --  odd case. Note that the case where the procedure called has
            --  visibility over Variable is treated in another case below.

            if Function_Call_Found then
               declare
                  P : Node_Id;

               begin
                  P := N;
                  loop
                     P := Parent (P);
                     exit when P = Loop_Statement;

                     --  Abandon if at procedure call, or something strange is
                     --  going on (perhaps a node with no parent that should
                     --  have one but does not?) As always, for a warning we
                     --  prefer to just abandon the warning than get into the
                     --  business of complaining about the tree structure here.

                     if No (P)
                       or else Nkind (P) = N_Procedure_Call_Statement
                     then
                        return Abandon;
                     end if;
                  end loop;
               end;
            end if;

         --  Reference to variable renaming variable in question

         elsif Is_Entity_Name (N)
           and then Present (Entity (N))
           and then Ekind (Entity (N)) = E_Variable
           and then Present (Renamed_Object (Entity (N)))
           and then Is_Entity_Name (Renamed_Object (Entity (N)))
           and then Entity (Renamed_Object (Entity (N))) = Var
           and then Known_To_Be_Assigned (N)
         then
            return Abandon;

         --  Call to subprogram

         elsif Nkind (N) in N_Subprogram_Call then

            --  If subprogram is within the scope of the entity we are dealing
            --  with as the loop variable, then it could modify this parameter,
            --  so we abandon in this case. In the case of a subprogram that is
            --  not an entity we also abandon. The check for no entity being
            --  present is a defense against previous errors.

            if not Is_Entity_Name (Name (N))
              or else No (Entity (Name (N)))
              or else Scope_Within (Entity (Name (N)), Scope (Var))
            then
               return Abandon;
            end if;

            --  If any of the arguments are of type access to subprogram, then
            --  we may have funny side effects, so no warning in this case.

            declare
               Actual : Node_Id;
            begin
               Actual := First_Actual (N);
               while Present (Actual) loop
                  if Is_Access_Subprogram_Type (Etype (Actual)) then
                     return Abandon;
                  else
                     Next_Actual (Actual);
                  end if;
               end loop;
            end;

         --  Declaration of the variable in question

         elsif Nkind (N) = N_Object_Declaration
           and then Defining_Identifier (N) = Var
         then
            return Abandon;
         end if;

         --  All OK, continue scan

         return OK;
      end Test_Ref;

   --  Start of processing for Check_Infinite_Loop_Warning

   begin
      --  Skip processing if debug flag gnatd.w is set

      if Debug_Flag_Dot_W then
         return;
      end if;

      --  Deal with Iteration scheme present

      declare
         Iter : constant Node_Id := Iteration_Scheme (Loop_Statement);

      begin
         if Present (Iter) then

            --  While iteration

            if Present (Condition (Iter)) then

               --  Skip processing for while iteration with conditions actions,
               --  since they make it too complicated to get the warning right.

               if Has_Condition_Actions (Iter) then
                  return;
               end if;

               --  Capture WHILE condition

               Expression := Condition (Iter);

            --  For Loop_Parameter_Specification, do not process, since loop
            --  will always terminate. For Iterator_Specification, also do not
            --  process. Either it will always terminate (e.g. "for X of
            --  Some_Array ..."), or we can't tell if it's going to terminate
            --  without looking at the iterator, so any warning here would be
            --  noise.

            elsif Present (Loop_Parameter_Specification (Iter))
              or else Present (Iterator_Specification (Iter))
            then
               return;
            end if;
         end if;
      end;

      --  Check chain of EXIT statements, we only process loops that have a
      --  single exit condition (either a single EXIT WHEN statement, or a
      --  WHILE loop not containing any EXIT WHEN statements).

      declare
         Ident     : constant Node_Id := Identifier (Loop_Statement);
         Exit_Stmt : Node_Id;

      begin
         --  If we don't have a proper chain set, ignore call entirely. This
         --  happens because of previous errors.

         if No (Entity (Ident))
           or else Ekind (Entity (Ident)) /= E_Loop
         then
            Check_Error_Detected;
            return;
         end if;

         --  Otherwise prepare to scan list of EXIT statements

         Exit_Stmt := First_Exit_Statement (Entity (Ident));
         while Present (Exit_Stmt) loop

            --  Check for EXIT WHEN

            if Present (Condition (Exit_Stmt)) then

               --  Quit processing if EXIT WHEN in WHILE loop, or more than
               --  one EXIT WHEN statement present in the loop.

               if Present (Expression) then
                  return;

               --  Otherwise capture condition from EXIT WHEN statement

               else
                  Expression := Condition (Exit_Stmt);
               end if;

            --  If an unconditional exit statement is the last statement in the
            --  loop, assume that no warning is needed, without any attempt at
            --  checking whether the exit is reachable.

            elsif Exit_Stmt = Last (Statements (Loop_Statement)) then
               return;
            end if;

            Exit_Stmt := Next_Exit_Statement (Exit_Stmt);
         end loop;
      end;

      --  Return if no condition to test

      if No (Expression) then
         return;
      end if;

      --  Initial conditions met, see if condition is of right form

      Find_Var (Expression);

      --  Nothing to do if local variable from source not found. If it's a
      --  renaming, it is probably renaming something too complicated to deal
      --  with here.

      if No (Var)
        or else Ekind (Var) /= E_Variable
        or else Is_Library_Level_Entity (Var)
        or else not Comes_From_Source (Var)
        or else Nkind (Parent (Var)) = N_Object_Renaming_Declaration
      then
         return;

      --  Nothing to do if there is some indirection involved (assume that the
      --  designated variable might be modified in some way we don't see).
      --  However, if no function call was found, then we don't care about
      --  indirections, because the condition must be something like "while X
      --  /= null loop", so we don't care if X.all is modified in the loop.

      elsif Function_Call_Found and then Has_Indirection (Etype (Var)) then
         return;

      --  Same sort of thing for volatile variable, might be modified by
      --  some other task or by the operating system in some way.

      elsif Is_Volatile (Var) then
         return;
      end if;

      --  Filter out case of original statement sequence starting with delay.
      --  We assume this is a multi-tasking program and that the condition
      --  is affected by other threads (some kind of busy wait).

      declare
         Fstm : constant Node_Id :=
                  Original_Node (First (Statements (Loop_Statement)));
      begin
         if Nkind (Fstm) in N_Delay_Statement then
            return;
         end if;
      end;

      --  We have a variable reference of the right form, now we scan the loop
      --  body to see if it looks like it might not be modified

      if No_Ref_Found (Loop_Statement) = OK then
         Error_Msg_NE
           ("??variable& is not modified in loop body!", Ref, Var);
         Error_Msg_N
           ("\??possible infinite loop!", Ref);
      end if;
   end Check_Infinite_Loop_Warning;

   ----------------------------
   -- Check_Low_Bound_Tested --
   ----------------------------

   procedure Check_Low_Bound_Tested (Expr : Node_Id) is
      procedure Check_Low_Bound_Tested_For (Opnd : Node_Id);
      --  Determine whether operand Opnd denotes attribute 'First whose prefix
      --  is a formal parameter. If this is the case, mark the entity of the
      --  prefix as having its low bound tested.

      --------------------------------
      -- Check_Low_Bound_Tested_For --
      --------------------------------

      procedure Check_Low_Bound_Tested_For (Opnd : Node_Id) is
      begin
         if Nkind (Opnd) = N_Attribute_Reference
           and then Attribute_Name (Opnd) = Name_First
           and then Is_Entity_Name (Prefix (Opnd))
           and then Present (Entity (Prefix (Opnd)))
           and then Is_Formal (Entity (Prefix (Opnd)))
         then
            Set_Low_Bound_Tested (Entity (Prefix (Opnd)));
         end if;
      end Check_Low_Bound_Tested_For;

   --  Start of processing for Check_Low_Bound_Tested

   begin
      if Comes_From_Source (Expr) then
         Check_Low_Bound_Tested_For (Left_Opnd  (Expr));
         Check_Low_Bound_Tested_For (Right_Opnd (Expr));
      end if;
   end Check_Low_Bound_Tested;

   ----------------------
   -- Check_References --
   ----------------------

   procedure Check_References (E : Entity_Id; Anod : Node_Id := Empty) is
      E1  : Entity_Id;
      E1T : Entity_Id;
      UR  : Node_Id;

      function Body_Formal
        (E                : Entity_Id;
         Accept_Statement : Node_Id) return Entity_Id;
      --  For an entry formal entity from an entry declaration, find the
      --  corresponding body formal from the given accept statement.

      function Generic_Body_Formal (E : Entity_Id) return Entity_Id;
      --  Warnings on unused formals of subprograms are placed on the entity
      --  in the subprogram body, which seems preferable because it suggests
      --  a better codefix for GNAT Studio. The analysis of generic subprogram
      --  bodies uses a different circuitry, so the choice for the proper
      --  placement of the warning in the generic case takes place here, by
      --  finding the body entity that corresponds to a formal in a spec.

      procedure May_Need_Initialized_Actual (Ent : Entity_Id);
      --  If an entity of a generic type has default initialization, then the
      --  corresponding actual type should be fully initialized, or else there
      --  will be uninitialized components in the instantiation, that might go
      --  unreported. This routine marks the type of the uninitialized variable
      --  appropriately to allow the compiler to emit an appropriate warning
      --  in the instance. In a sense, the use of a type that requires full
      --  initialization is a weak part of the generic contract.

      function Missing_Subunits return Boolean;
      --  We suppress warnings when there are missing subunits, because this
      --  may generate too many false positives: entities in a parent may only
      --  be referenced in one of the subunits. We make an exception for
      --  subunits that contain no other stubs.

      procedure Output_Reference_Error (M : String);
      --  Used to output an error message. Deals with posting the error on the
      --  body formal in the accept case.

      function Publicly_Referenceable (Ent : Entity_Id) return Boolean;
      --  This is true if the entity in question is potentially referenceable
      --  from another unit. This is true for entities in packages that are at
      --  the library level.

      function Warnings_Off_E1 return Boolean;
      --  Return True if Warnings_Off is set for E1, or for its Etype (E1T),
      --  or for the base type of E1T.

      -----------------
      -- Body_Formal --
      -----------------

      function Body_Formal
        (E                : Entity_Id;
         Accept_Statement : Node_Id) return Entity_Id
      is
         Body_Param : Node_Id;
         Body_E     : Entity_Id;

      begin
         --  Loop to find matching parameter in accept statement

         Body_Param := First (Parameter_Specifications (Accept_Statement));
         while Present (Body_Param) loop
            Body_E := Defining_Identifier (Body_Param);

            if Chars (Body_E) = Chars (E) then
               return Body_E;
            end if;

            Next (Body_Param);
         end loop;

         --  Should never fall through, should always find a match

         raise Program_Error;
      end Body_Formal;

      -------------------------
      -- Generic_Body_Formal --
      -------------------------

      function Generic_Body_Formal (E : Entity_Id) return Entity_Id is
         Gen_Decl : constant Node_Id   := Unit_Declaration_Node (Scope (E));
         Gen_Body : constant Entity_Id := Corresponding_Body (Gen_Decl);
         Form     : Entity_Id;

      begin
         if No (Gen_Body) then
            return E;

         else
            Form := First_Entity (Gen_Body);
            while Present (Form) loop
               if Chars (Form) = Chars (E) then
                  return Form;
               end if;

               Next_Entity (Form);
            end loop;
         end if;

         --  Should never fall through, should always find a match

         raise Program_Error;
      end Generic_Body_Formal;

      ---------------------------------
      -- May_Need_Initialized_Actual --
      ---------------------------------

      procedure May_Need_Initialized_Actual (Ent : Entity_Id) is
         T   : constant Entity_Id := Etype (Ent);
         Par : constant Node_Id   := Parent (T);

      begin
         if not Is_Generic_Type (T) then
            null;

         elsif (Nkind (Par)) = N_Private_Extension_Declaration then

            --  We only indicate the first such variable in the generic.

            if No (Uninitialized_Variable (Par)) then
               Set_Uninitialized_Variable (Par, Ent);
            end if;

         elsif (Nkind (Par)) = N_Formal_Type_Declaration
           and then Nkind (Formal_Type_Definition (Par)) =
                                         N_Formal_Private_Type_Definition
         then
            if No (Uninitialized_Variable (Formal_Type_Definition (Par))) then
               Set_Uninitialized_Variable (Formal_Type_Definition (Par), Ent);
            end if;
         end if;
      end May_Need_Initialized_Actual;

      ----------------------
      -- Missing_Subunits --
      ----------------------

      function Missing_Subunits return Boolean is
         D : Node_Id;

      begin
         if not Unloaded_Subunits then

            --  Normal compilation, all subunits are present

            return False;

         elsif E /= Main_Unit_Entity then

            --  No warnings on a stub that is not the main unit

            return True;

         elsif Nkind (Unit_Declaration_Node (E)) in N_Proper_Body then
            D := First (Declarations (Unit_Declaration_Node (E)));
            while Present (D) loop

               --  No warnings if the proper body contains nested stubs

               if Nkind (D) in N_Body_Stub then
                  return True;
               end if;

               Next (D);
            end loop;

            return False;

         else
            --  Missing stubs elsewhere

            return True;
         end if;
      end Missing_Subunits;

      ----------------------------
      -- Output_Reference_Error --
      ----------------------------

      procedure Output_Reference_Error (M : String) is
      begin
         --  Never issue messages for internal names or renamings

         if Is_Internal_Name (Chars (E1))
           or else Nkind (Parent (E1)) = N_Object_Renaming_Declaration
         then
            return;
         end if;

         --  Don't output message for IN OUT formal unless we have the warning
         --  flag specifically set. It is a bit odd to distinguish IN OUT
         --  formals from other cases. This distinction is historical in
         --  nature. Warnings for IN OUT formals were added fairly late.

         if Ekind (E1) = E_In_Out_Parameter
           and then not Check_Unreferenced_Formals
         then
            return;
         end if;

         --  Other than accept case, post error on defining identifier

         if No (Anod) then
            Error_Msg_N (M, E1);

         --  Accept case, find body formal to post the message

         else
            Error_Msg_NE (M, Body_Formal (E1, Accept_Statement => Anod), E1);

         end if;
      end Output_Reference_Error;

      ----------------------------
      -- Publicly_Referenceable --
      ----------------------------

      function Publicly_Referenceable (Ent : Entity_Id) return Boolean is
         P    : Node_Id;
         Prev : Node_Id;

      begin
         --  A formal parameter is never referenceable outside the body of its
         --  subprogram or entry.

         if Is_Formal (Ent) then
            return False;
         end if;

         --  Examine parents to look for a library level package spec. But if
         --  we find a body or block or other similar construct along the way,
         --  we cannot be referenced.

         Prev := Ent;
         P    := Parent (Ent);
         loop
            case Nkind (P) is

               --  If we get to top of tree, then publicly referenceable

               when N_Empty =>
                  return True;

               --  If we reach a generic package declaration, then always
               --  consider this referenceable, since any instantiation will
               --  have access to the entities in the generic package. Note
               --  that the package itself may not be instantiated, but then
               --  we will get a warning for the package entity.

               --  Note that generic formal parameters are themselves not
               --  publicly referenceable in an instance, and warnings on them
               --  are useful.

               when N_Generic_Package_Declaration =>
                  return
                    not Is_List_Member (Prev)
                      or else List_Containing (Prev) /=
                                            Generic_Formal_Declarations (P);

               --  Similarly, the generic formals of a generic subprogram are
               --  not accessible.

               when N_Generic_Subprogram_Declaration =>
                  if Is_List_Member (Prev)
                    and then List_Containing (Prev) =
                               Generic_Formal_Declarations (P)
                  then
                     return False;
                  else
                     P := Parent (P);
                  end if;

               --  If we reach a subprogram body, entity is not referenceable
               --  unless it is the defining entity of the body. This will
               --  happen, e.g. when a function is an attribute renaming that
               --  is rewritten as a body.

               when N_Subprogram_Body  =>
                  if Ent /= Defining_Entity (P) then
                     return False;
                  else
                     P := Parent (P);
                  end if;

               --  If we reach any other body, definitely not referenceable

               when N_Block_Statement
                  | N_Entry_Body
                  | N_Package_Body
                  | N_Protected_Body
                  | N_Subunit
                  | N_Task_Body
               =>
                  return False;

               --  For all other cases, keep looking up tree

               when others =>
                  Prev := P;
                  P    := Parent (P);
            end case;
         end loop;
      end Publicly_Referenceable;

      ---------------------
      -- Warnings_Off_E1 --
      ---------------------

      function Warnings_Off_E1 return Boolean is
      begin
         return Has_Warnings_Off (E1T)
           or else Has_Warnings_Off (Base_Type (E1T))
           or else Warnings_Off_Check_Spec (E1);
      end Warnings_Off_E1;

   --  Start of processing for Check_References

   begin
      --  No messages if warnings are suppressed, or if we have detected any
      --  real errors so far (this last check avoids junk messages resulting
      --  from errors, e.g. a subunit that is not loaded).

      if Warning_Mode = Suppress or else Serious_Errors_Detected /= 0 then
         return;
      end if;

      --  We also skip the messages if any subunits were not loaded (see
      --  comment in Sem_Ch10 to understand how this is set, and why it is
      --  necessary to suppress the warnings in this case).

      if Missing_Subunits then
         return;
      end if;

      --  Otherwise loop through entities, looking for suspicious stuff

      E1 := First_Entity (E);
      while Present (E1) loop
         E1T := Etype (E1);

         --  We are only interested in source entities. We also don't issue
         --  warnings within instances, since the proper place for such
         --  warnings is on the template when it is compiled, and we don't
         --  issue warnings for variables with names like Junk, Discard etc.

         if Comes_From_Source (E1)
           and then Instantiation_Location (Sloc (E1)) = No_Location
         then
            --  We are interested in variables and out/in-out parameters, but
            --  we exclude protected types, too complicated to worry about.

            if Ekind (E1) = E_Variable
              or else
                (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
               --  because checks below depend on its private nature.

               if Is_Class_Wide_Type (E1T) then
                  E1T := Etype (E1T);
               end if;

               --  Case of an unassigned variable

               --  First gather any Unset_Reference indication for E1. In the
               --  case of an 'out' parameter, it is the Spec_Entity that is
               --  relevant.

               if Ekind (E1) = E_Out_Parameter
                 and then Present (Spec_Entity (E1))
               then
                  UR := Unset_Reference (Spec_Entity (E1));
               else
                  UR := Unset_Reference (E1);
               end if;

               --  Special processing for access types

               if Present (UR) and then Is_Access_Type (E1T) then

                  --  For access types, the only time we made a UR entry was
                  --  for a dereference, and so we post the appropriate warning
                  --  here (note that the dereference may not be explicit in
                  --  the source, for example in the case of a dispatching call
                  --  with an anonymous access controlling formal, or of an
                  --  assignment of a pointer involving discriminant check on
                  --  the designated object).

                  if not Warnings_Off_E1 then
                     Error_Msg_NE ("??& may be null!", UR, E1);
                  end if;

                  goto Continue;

               --  Case of variable that could be a constant. Note that we
               --  never signal such messages for generic package entities,
               --  since a given instance could have modifications outside
               --  the package.

               --  Note that we used to check Address_Taken here, but we don't
               --  want to do that since it can be set for non-source cases,
               --  e.g. the Unrestricted_Access from a valid attribute, and
               --  the wanted effect is included in Never_Set_In_Source.

               elsif Warn_On_Constant
                 and then Ekind (E1) = E_Variable
                 and then Has_Initial_Value (E1)
                 and then Never_Set_In_Source_Check_Spec (E1)
                 and then not Generic_Package_Spec_Entity (E1)
               then
                  --  A special case, if this variable is volatile and not
                  --  imported, it is not helpful to tell the programmer
                  --  to mark the variable as constant, since this would be
                  --  illegal by virtue of RM C.6(13). Instead we suggest
                  --  using pragma Export (can't be Import because of the
                  --  initial value).

                  if (Is_Volatile (E1) or else Has_Volatile_Components (E1))
                    and then not Is_Imported (E1)
                  then
                     Error_Msg_N
                       ("?k?& is not modified, consider pragma Export for "
                        & "volatile variable!", E1);

                  --  Another special case, Exception_Occurrence, this catches
                  --  the case of exception choice (and a bit more too, but not
                  --  worth doing more investigation here).

                  elsif Is_RTE (E1T, RE_Exception_Occurrence) then
                     null;

                  --  Here we give the warning if referenced and no pragma
                  --  Unreferenced or Unmodified is present.

                  else
                     --  Variable case

                     if Ekind (E1) = E_Variable then
                        if Referenced_Check_Spec (E1)
                          and then not Has_Pragma_Unreferenced_Check_Spec (E1)
                          and then not Has_Pragma_Unmodified_Check_Spec (E1)
                        then
                           if not Warnings_Off_E1
                             and then not Has_Junk_Name (E1)
                           then
                              Error_Msg_N -- CODEFIX
                                ("?k?& is not modified, "
                                 & "could be declared constant!",
                                 E1);
                           end if;
                        end if;
                     end if;
                  end if;

               --  Other cases of a variable or parameter never set in source

               elsif Never_Set_In_Source_Check_Spec (E1)

                 --  No warning if address taken somewhere

                 and then not Address_Taken (E1)

                 --  No warning if explicit initial value

                 and then not Has_Initial_Value (E1)

                 --  No warning for generic package spec entities, since we
                 --  might set them in a child unit or something like that

                 and then not Generic_Package_Spec_Entity (E1)

                 --  No warning if fully initialized type, except that for
                 --  this purpose we do not consider access types to qualify
                 --  as fully initialized types (relying on an access type
                 --  variable being null when it is never set is a bit odd).

                 --  Also we generate warning for an out parameter that is
                 --  never referenced, since again it seems odd to rely on
                 --  default initialization to set an out parameter value.

                 and then (Is_Access_Type (E1T)
                             or else Ekind (E1) = E_Out_Parameter
                             or else not Is_Fully_Initialized_Type (E1T))
               then
                  --  Do not output complaint about never being assigned a
                  --  value if a pragma Unmodified applies to the variable
                  --  we are examining, or if it is a parameter, if there is
                  --  a pragma Unreferenced for the corresponding spec, or
                  --  if the type is marked as having unreferenced objects.
                  --  The last is a little peculiar, but better too few than
                  --  too many warnings in this situation.

                  if Has_Pragma_Unreferenced_Objects (E1T)
                    or else Has_Pragma_Unmodified_Check_Spec (E1)
                  then
                     null;

                  --  IN OUT parameter case where parameter is referenced. We
                  --  separate this out, since this is the case where we delay
                  --  output of the warning until more information is available
                  --  (about use in an instantiation or address being taken).

                  elsif Ekind (E1) = E_In_Out_Parameter
                    and then Referenced_Check_Spec (E1)
                  then
                     --  Suppress warning if private type, and the procedure
                     --  has a separate declaration in a different unit. This
                     --  is the case where the client of a package sees only
                     --  the private type, and it may be quite reasonable
                     --  for the logical view to be IN OUT, even if the
                     --  implementation ends up using access types or some
                     --  other method to achieve the local effect of a
                     --  modification. On the other hand if the spec and body
                     --  are in the same unit, we are in the package body and
                     --  there we have less excuse for a junk IN OUT parameter.

                     if Has_Private_Declaration (E1T)
                       and then Present (Spec_Entity (E1))
                       and then not In_Same_Source_Unit (E1, Spec_Entity (E1))
                     then
                        null;

                     --  Suppress warning for any parameter of a dispatching
                     --  operation, since it is quite reasonable to have an
                     --  operation that is overridden, and for some subclasses
                     --  needs the formal to be IN OUT and for others happens
                     --  not to assign it.

                     elsif Is_Dispatching_Operation
                             (Scope (Goto_Spec_Entity (E1)))
                     then
                        null;

                     --  Suppress warning if composite type contains any access
                     --  component, since the logical effect of modifying a
                     --  parameter may be achieved by modifying a referenced
                     --  object. This rationale does not apply to private
                     --  types, so we warn in that case.

                     elsif Is_Composite_Type (E1T)
                       and then not Is_Private_Type (E1T)
                       and then Has_Access_Values (E1T)
                     then
                        null;

                     --  Suppress warning on formals of an entry body. All
                     --  references are attached to the formal in the entry
                     --  declaration, which are marked Is_Entry_Formal.

                     elsif Ekind (Scope (E1)) = E_Entry
                       and then not Is_Entry_Formal (E1)
                     then
                        null;

                     --  OK, looks like warning for an IN OUT parameter that
                     --  could be IN makes sense, but we delay the output of
                     --  the warning, pending possibly finding out later on
                     --  that the associated subprogram is used as a generic
                     --  actual, or its address/access is taken. In these two
                     --  cases, we suppress the warning because the context may
                     --  force use of IN OUT, even if in this particular case
                     --  the formal is not modified.

                     elsif Warn_On_No_Value_Assigned then
                        --  Suppress the warnings for a junk name

                        if not Has_Junk_Name (E1) then
                           In_Out_Warnings.Append (E1);
                        end if;
                     end if;

                  --  Other cases of formals

                  elsif Is_Formal (E1) then
                     if not Is_Trivial_Subprogram (Scope (E1)) then
                        if Referenced_Check_Spec (E1) then
                           if not Has_Pragma_Unmodified_Check_Spec (E1)
                             and then not Warnings_Off_E1
                             and then not Has_Junk_Name (E1)
                             and then Warn_On_No_Value_Assigned
                           then
                              Output_Reference_Error
                                ("?v?formal parameter& is read but "
                                 & "never assigned!");
                           end if;

                        elsif not Has_Pragma_Unreferenced_Check_Spec (E1)
                          and then not Warnings_Off_E1
                          and then not Has_Junk_Name (E1)
                          and then Check_Unreferenced_Formals
                        then
                           Output_Reference_Error
                             ("?f?formal parameter& is not referenced!");
                        end if;
                     end if;

                  --  Case of variable

                  else
                     if Referenced (E1) then
                        if Warn_On_No_Value_Assigned
                          and then not Has_Unmodified (E1)
                          and then not Warnings_Off_E1
                          and then not Has_Junk_Name (E1)
                        then
                           if Is_Access_Type (E1T)
                             or else
                               not Is_Partially_Initialized_Type (E1T, False)
                           then
                              Output_Reference_Error
                                ("?v?variable& is read but never assigned!");
                           end if;

                           May_Need_Initialized_Actual (E1);
                        end if;

                     elsif Check_Unreferenced
                       and then not Has_Unreferenced (E1)
                       and then not Warnings_Off_E1
                       and then not Has_Junk_Name (E1)
                     then
                        Output_Reference_Error -- CODEFIX
                          ("?u?variable& is never read and never assigned!");
                     end if;

                     --  Deal with special case where this variable is hidden
                     --  by a loop variable.

                     if Ekind (E1) = E_Variable
                       and then Present (Hiding_Loop_Variable (E1))
                       and then not Warnings_Off_E1
                       and then Warn_On_Hiding
                     then
                        Error_Msg_N
                          ("?h?for loop implicitly declares loop variable!",
                           Hiding_Loop_Variable (E1));

                        Error_Msg_Sloc := Sloc (E1);
                        Error_Msg_N
                          ("\?h?declaration hides & declared#!",
                           Hiding_Loop_Variable (E1));
                     end if;
                  end if;

                  goto Continue;
               end if;

               --  Check for unset reference. If type of object has
               --  preelaborable initialization, warning is misleading.

               if Warn_On_No_Value_Assigned
                 and then Present (UR)
                 and then not Known_To_Have_Preelab_Init (Etype (E1))
               then

                  --  For other than access type, go back to original node to
                  --  deal with case where original unset reference has been
                  --  rewritten during expansion.

                  --  In some cases, the original node may be a type
                  --  conversion, a qualification or an attribute reference and
                  --  in this case we want the object entity inside. Same for
                  --  an expression with actions.

                  UR := Original_Node (UR);
                  loop
                     if Nkind (UR) in N_Expression_With_Actions
                                    | N_Qualified_Expression
                                    | N_Type_Conversion
                     then
                        UR := Expression (UR);

                     elsif Nkind (UR) = N_Attribute_Reference then
                        UR := Prefix (UR);

                     else
                        exit;
                     end if;
                  end loop;

                  --  Don't issue warning if appearing inside Initial_Condition
                  --  pragma or aspect, since that expression is not evaluated
                  --  at the point where it occurs in the source.

                  if In_Pragma_Expression (UR, Name_Initial_Condition) then
                     goto Continue;
                  end if;

                  --  Here we issue the warning, all checks completed

                  --  If we have a return statement, this was a case of an OUT
                  --  parameter not being set at the time of the return. (Note:
                  --  it can't be N_Extended_Return_Statement, because those
                  --  are only for functions, and functions do not allow OUT
                  --  parameters.)

                  if not Is_Trivial_Subprogram (Scope (E1)) then
                     if Nkind (UR) = N_Simple_Return_Statement
                       and then not Has_Pragma_Unmodified_Check_Spec (E1)
                     then
                        if not Warnings_Off_E1
                          and then not Has_Junk_Name (E1)
                        then
                           Error_Msg_NE
                             ("?v?OUT parameter& not set before return",
                              UR, E1);
                        end if;

                        --  If the unset reference is a selected component
                        --  prefix from source, mention the component as well.
                        --  If the selected component comes from expansion, all
                        --  we know is that the entity is not fully initialized
                        --  at the point of the reference. Locate a random
                        --  uninitialized component to get a better message.

                     elsif Nkind (Parent (UR)) = N_Selected_Component then
                        --  Suppress possibly superfluous warning if component
                        --  is known to exist and is partially initialized.

                        if not Has_Discriminants (Etype (E1))
                          and then
                            Is_Partially_Initialized_Type
                              (Etype (Parent (UR)), False)
                        then
                           goto Continue;
                        end if;

                        Error_Msg_Node_2 := Selector_Name (Parent (UR));

                        if not Comes_From_Source (Parent (UR)) then
                           declare
                              Comp : Entity_Id;

                           begin
                              Comp := First_Component (E1T);
                              while Present (Comp) loop
                                 if Nkind (Parent (Comp)) =
                                      N_Component_Declaration
                                   and then No (Expression (Parent (Comp)))
                                 then
                                    Error_Msg_Node_2 := Comp;
                                    exit;
                                 end if;

                                 Next_Component (Comp);
                              end loop;
                           end;
                        end if;

                        --  Issue proper warning. This is a case of referencing
                        --  a variable before it has been explicitly assigned.
                        --  For access types, UR was only set for dereferences,
                        --  so the issue is that the value may be null.

                        if not Warnings_Off_E1 then
                           if Is_Access_Type (Etype (Parent (UR))) then
                              Error_Msg_N ("??`&.&` may be null!", UR);
                           else
                              Error_Msg_N
                                ("??`&.&` may be referenced before "
                                 & "it has a value!", UR);
                           end if;
                        end if;

                     --  All other cases of unset reference active

                     elsif not Warnings_Off_E1 then
                        Error_Msg_N
                          ("??& may be referenced before it has a value!", UR);
                     end if;
                  end if;

                  goto Continue;

               end if;
            end if;

            --  Then check for unreferenced entities. Note that we are only
            --  interested in entities whose Referenced flag is not set.

            if not Referenced_Check_Spec (E1)

              --  If Referenced_As_LHS is set, then that's still interesting
              --  (potential "assigned but never read" case), but not if we
              --  have pragma Unreferenced, which cancels this warning.

              and then (not Referenced_As_LHS_Check_Spec (E1)
                         or else not Has_Unreferenced (E1))

              --  Check that warnings on unreferenced entities are enabled

              and then
                ((Check_Unreferenced and then not Is_Formal (E1))

                  --  Case of warning on unreferenced formal

                  or else (Check_Unreferenced_Formals and then Is_Formal (E1))

                  --  Case of warning on unread variables modified by an
                  --  assignment, or an OUT parameter if it is the only one.

                  or else (Warn_On_Modified_Unread
                            and then Referenced_As_LHS_Check_Spec (E1))

                  --  Case of warning on any unread OUT parameter (note such
                  --  indications are only set if the appropriate warning
                  --  options were set, so no need to recheck here.)

                  or else Referenced_As_Out_Parameter_Check_Spec (E1))

              --  All other entities, including local packages that cannot be
              --  referenced from elsewhere, including those declared within a
              --  package body.

              and then (Is_Object (E1)
                         or else Is_Type (E1)
                         or else Ekind (E1) = E_Label
                         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
                         --  or generic package spec, then there may be a
                         --  corresponding body that references this package
                         --  in some other file. Otherwise we can be sure
                         --  that there is no other reference.

                         or else
                           (Ekind (E1) = E_Package
                             and then
                               not Is_Package_Or_Generic_Package
                                     (Cunit_Entity (Current_Sem_Unit))))

              --  Exclude instantiations, since there is no reason why every
              --  entity in an instantiation should be referenced.

              and then Instantiation_Location (Sloc (E1)) = No_Location

              --  Exclude formal parameters from bodies if the corresponding
              --  spec entity has been referenced in the case where there is
              --  a separate spec.

              and then not (Is_Formal (E1)
                             and then Ekind (Scope (E1)) = E_Subprogram_Body
                             and then Present (Spec_Entity (E1))
                             and then Referenced (Spec_Entity (E1)))

              --  Consider private type referenced if full view is referenced.
              --  If there is not full view, this is a generic type on which
              --  warnings are also useful.

              and then
                not (Is_Private_Type (E1)
                      and then Present (Full_View (E1))
                      and then Referenced (Full_View (E1)))

              --  Don't worry about full view, only about private type

              and then not Has_Private_Declaration (E1)

              --  Eliminate dispatching operations from consideration, we
              --  cannot tell if these are referenced or not in any easy
              --  manner (note this also catches Adjust/Finalize/Initialize).

              and then not Is_Dispatching_Operation (E1)

              --  Check entity that can be publicly referenced (we do not give
              --  messages for such entities, since there could be other
              --  units, not involved in this compilation, that contain
              --  relevant references.

              and then not Publicly_Referenceable (E1)

              --  Class wide types are marked as source entities, but they are
              --  not really source entities, and are always created, so we do
              --  not care if they are not referenced.

              and then Ekind (E1) /= E_Class_Wide_Type

              --  Objects other than parameters of task types are allowed to
              --  be non-referenced, since they start up tasks.

              and then ((Ekind (E1) /= E_Variable
                          and then Ekind (E1) /= E_Constant
                          and then Ekind (E1) /= E_Component)

                         --  Check that E1T is not a task or a composite type
                         --  with a task component.

                         or else not Has_Task (E1T))

              --  For subunits, only place warnings on the main unit itself,
              --  since parent units are not completely compiled.

              and then (Nkind (Unit (Cunit (Main_Unit))) /= N_Subunit
                         or else Get_Source_Unit (E1) = Main_Unit)

              --  No warning on a return object, because these are often
              --  created with a single expression and an implicit return.
              --  If the object is a variable there will be a warning
              --  indicating that it could be declared constant.

              and then not
                (Ekind (E1) = E_Constant and then Is_Return_Object (E1))
            then
               --  Suppress warnings in internal units if not in -gnatg mode
               --  (these would be junk warnings for an applications program,
               --  since they refer to problems in internal units).

               if GNAT_Mode or else not In_Internal_Unit (E1) then
                  --  We do not immediately flag the error. This is because we
                  --  have not expanded generic bodies yet, and they may have
                  --  the missing reference. So instead we park the entity on a
                  --  list, for later processing. However for the case of an
                  --  accept statement we want to output messages now, since
                  --  we know we already have all information at hand, and we
                  --  also want to have separate warnings for each accept
                  --  statement for the same entry.

                  if Present (Anod) then
                     pragma Assert (Is_Formal (E1));

                     --  The unreferenced entity is E1, but post the warning
                     --  on the body entity for this accept statement.

                     if not Warnings_Off_E1 then
                        Warn_On_Unreferenced_Entity
                          (E1, Body_Formal (E1, Accept_Statement => Anod));
                     end if;

                  elsif not Warnings_Off_E1
                    and then not Has_Junk_Name (E1)
                  then
                     if Is_Formal (E1)
                       and then Nkind (Unit_Declaration_Node (Scope (E1)))
                         = N_Generic_Subprogram_Declaration
                     then
                        Unreferenced_Entities.Append
                          (Generic_Body_Formal (E1));
                     else
                        Unreferenced_Entities.Append (E1);
                     end if;
                  end if;
               end if;

            --  Generic units are referenced in the generic body, but if they
            --  are not public and never instantiated we want to force a
            --  warning on them. We treat them as redundant constructs to
            --  minimize noise.

            elsif Is_Generic_Subprogram (E1)
              and then not Is_Instantiated (E1)
              and then not Publicly_Referenceable (E1)
              and then Instantiation_Depth (Sloc (E1)) = 0
              and then Warn_On_Redundant_Constructs
            then
               if not Warnings_Off_E1 and then not Has_Junk_Name (E1) then
                  Unreferenced_Entities.Append (E1);

                  --  Force warning on entity

                  Set_Referenced (E1, False);
               end if;
            end if;
         end if;

         --  Recurse into nested package or block. Do not recurse into a formal
         --  package, because the corresponding body is not analyzed.

         <<Continue>>
            if (Is_Package_Or_Generic_Package (E1)
                 and then Nkind (Parent (E1)) = N_Package_Specification
                 and then
                   Nkind (Original_Node (Unit_Declaration_Node (E1))) /=
                                                N_Formal_Package_Declaration)

              or else Ekind (E1) = E_Block
            then
               Check_References (E1);
            end if;

            Next_Entity (E1);
      end loop;
   end Check_References;

   ---------------------------
   -- Check_Unset_Reference --
   ---------------------------

   procedure Check_Unset_Reference (N : Node_Id) is
      Typ : constant Entity_Id := Etype (N);

      function Is_OK_Fully_Initialized return Boolean;
      --  This function returns true if the given node N is fully initialized
      --  so that the reference is safe as far as this routine is concerned.
      --  Safe generally means that the type of N is a fully initialized type.
      --  The one special case is that for access types, which are always fully
      --  initialized, we don't consider a dereference OK since it will surely
      --  be dereferencing a null value, which won't do.

      function Prefix_Has_Dereference (Pref : Node_Id) return Boolean;
      --  Used to test indexed or selected component or slice to see if the
      --  evaluation of the prefix depends on a dereference, and if so, returns
      --  True, in which case we always check the prefix, even if we know that
      --  the referenced component is initialized. Pref is the prefix to test.

      -----------------------------
      -- Is_OK_Fully_Initialized --
      -----------------------------

      function Is_OK_Fully_Initialized return Boolean is
      begin
         if Is_Access_Type (Typ) and then Is_Dereferenced (N) then
            return False;

         --  A type subject to pragma Default_Initial_Condition may be fully
         --  default initialized depending on inheritance and the argument of
         --  the pragma (SPARK RM 3.1 and SPARK RM 7.3.3).

         elsif Has_Fully_Default_Initializing_DIC_Pragma (Typ) then
            return True;

         else
            return Is_Fully_Initialized_Type (Typ);
         end if;
      end Is_OK_Fully_Initialized;

      ----------------------------
      -- Prefix_Has_Dereference --
      ----------------------------

      function Prefix_Has_Dereference (Pref : Node_Id) return Boolean is
      begin
         --  If prefix is of an access type, it certainly needs a dereference

         if Is_Access_Type (Etype (Pref)) then
            return True;

         --  If prefix is explicit dereference, that's a dereference for sure

         elsif Nkind (Pref) = N_Explicit_Dereference then
            return True;

         --  If prefix is itself a component reference or slice check prefix

         elsif Nkind (Pref) = N_Slice
           or else Nkind (Pref) = N_Indexed_Component
           or else Nkind (Pref) = N_Selected_Component
         then
            return Prefix_Has_Dereference (Prefix (Pref));

         --  All other cases do not involve a dereference

         else
            return False;
         end if;
      end Prefix_Has_Dereference;

   --  Start of processing for Check_Unset_Reference

   begin
      --  Nothing to do if warnings suppressed

      if Warning_Mode = Suppress then
         return;
      end if;

      --  Ignore reference unless it comes from source. Almost always if we
      --  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 (Original_Node (N)) then
         return;
      end if;

      --  Otherwise see what kind of node we have. If the entity already has an
      --  unset reference, it is not necessarily the earliest in the text,
      --  because resolution of the prefix of selected components is completed
      --  before the resolution of the selected component itself. As a result,
      --  given (R /= null and then R.X > 0), the occurrences of R are examined
      --  in right-to-left order. If there is already an unset reference, we
      --  check whether N is earlier before proceeding.

      case Nkind (N) is

         --  For identifier or expanded name, examine the entity involved

         when N_Expanded_Name
            | N_Identifier
         =>
            declare
               E : constant Entity_Id := Entity (N);

            begin
               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))
                            or else
                              Earlier_In_Extended_Unit
                                (N, Unset_Reference (E)))
                 and then not Has_Pragma_Unmodified_Check_Spec (E)
                 and then not Warnings_Off_Check_Spec (E)
                 and then not Has_Junk_Name (E)
               then
                  --  We may have an unset reference. The first test is whether
                  --  this is an access to a discriminant of a record or a
                  --  component with default initialization. Both of these
                  --  cases can be ignored, since the actual object that is
                  --  referenced is definitely initialized. Note that this
                  --  covers the case of reading discriminants of an OUT
                  --  parameter, which is OK even in Ada 83.

                  --  Note that we are only interested in a direct reference to
                  --  a record component here. If the reference is through an
                  --  access type, then the access object is being referenced,
                  --  not the record, and still deserves an unset reference.

                  if Nkind (Parent (N)) = N_Selected_Component
                    and not Is_Access_Type (Typ)
                  then
                     declare
                        ES : constant Entity_Id :=
                               Entity (Selector_Name (Parent (N)));
                     begin
                        if Ekind (ES) = E_Discriminant
                          or else
                            (Present (Declaration_Node (ES))
                               and then
                             Present (Expression (Declaration_Node (ES))))
                        then
                           return;
                        end if;
                     end;
                  end if;

                  --  Exclude fully initialized types

                  if Is_OK_Fully_Initialized then
                     return;
                  end if;

                  --  Here we have a potential unset reference. But before we
                  --  get worried about it, we have to make sure that the
                  --  entity declaration is in the same procedure as the
                  --  reference, since if they are in separate procedures, then
                  --  we have no idea about sequential execution.

                  --  The tests in the loop below catch all such cases, but do
                  --  allow the reference to appear in a loop, block, or
                  --  package spec that is nested within the declaring scope.
                  --  As always, it is possible to construct cases where the
                  --  warning is wrong, that is why it is a warning.

                  Potential_Unset_Reference : declare
                     SR : Entity_Id;
                     SE : constant Entity_Id := Scope (E);

                     function Within_Postcondition return Boolean;
                     --  Returns True if N is within a Postcondition, a
                     --  Refined_Post, an Ensures component in a Test_Case,
                     --  or a Contract_Cases.

                     --------------------------
                     -- Within_Postcondition --
                     --------------------------

                     function Within_Postcondition return Boolean is
                        Nod, P : Node_Id;

                     begin
                        Nod := Parent (N);
                        while Present (Nod) loop
                           if Nkind (Nod) = N_Pragma
                             and then
                               Pragma_Name_Unmapped (Nod)
                                in Name_Postcondition
                                 | Name_Refined_Post
                                 | Name_Contract_Cases
                           then
                              return True;

                           elsif Present (Parent (Nod)) then
                              P := Parent (Nod);

                              if Nkind (P) = N_Pragma
                                and then Pragma_Name (P) =
                                  Name_Test_Case
                                and then Nod = Test_Case_Arg (P, Name_Ensures)
                              then
                                 return True;
                              end if;

                           --  Prevent the search from going too far

                           elsif Is_Body_Or_Package_Declaration (Nod) then
                              exit;
                           end if;

                           Nod := Parent (Nod);
                        end loop;

                        return False;
                     end Within_Postcondition;

                  --  Start of processing for Potential_Unset_Reference

                  begin
                     SR := Current_Scope;
                     while SR /= SE loop
                        if SR = Standard_Standard
                          or else Is_Subprogram (SR)
                          or else Is_Concurrent_Body (SR)
                          or else Is_Concurrent_Type (SR)
                        then
                           return;
                        end if;

                        SR := Scope (SR);
                     end loop;

                     --  Case of reference has an access type. This is a
                     --  special case since access types are always set to null
                     --  so cannot be truly uninitialized, but we still want to
                     --  warn about cases of obvious null dereference.

                     if Is_Access_Type (Typ) then
                        Access_Type_Case : declare
                           P : Node_Id;

                           function Process
                             (N : Node_Id) return Traverse_Result;
                           --  Process function for instantiation of Traverse
                           --  below. Checks if N contains reference to E other
                           --  than a dereference.

                           function Ref_In (Nod : Node_Id) return Boolean;
                           --  Determines whether Nod contains a reference to
                           --  the entity E that is not a dereference.

                           -------------
                           -- Process --
                           -------------

                           function Process
                             (N : Node_Id) return Traverse_Result
                           is
                           begin
                              if Is_Entity_Name (N)
                                and then Entity (N) = E
                                and then not Is_Dereferenced (N)
                              then
                                 return Abandon;
                              else
                                 return OK;
                              end if;
                           end Process;

                           ------------
                           -- Ref_In --
                           ------------

                           function Ref_In (Nod : Node_Id) return Boolean is
                              function Traverse is new Traverse_Func (Process);
                           begin
                              return Traverse (Nod) = Abandon;
                           end Ref_In;

                        --  Start of processing for Access_Type_Case

                        begin
                           --  Don't bother if we are inside an instance, since
                           --  the compilation of the generic template is where
                           --  the warning should be issued.

                           if In_Instance then
                              return;
                           end if;

                           --  Don't bother if this is not the main unit. If we
                           --  try to give this warning for with'ed units, we
                           --  get some false positives, since we do not record
                           --  references in other units.

                           if not In_Extended_Main_Source_Unit (E)
                                or else
                              not In_Extended_Main_Source_Unit (N)
                           then
                              return;
                           end if;

                           --  We are only interested in dereferences

                           if not Is_Dereferenced (N) then
                              return;
                           end if;

                           --  One more check, don't bother with references
                           --  that are inside conditional statements or WHILE
                           --  loops if the condition references the entity in
                           --  question. This avoids most false positives.

                           P := Parent (N);
                           loop
                              P := Parent (P);
                              exit when No (P);

                              if Nkind (P) in N_If_Statement | N_Elsif_Part
                                and then Ref_In (Condition (P))
                              then
                                 return;

                              elsif Nkind (P) = N_Loop_Statement
                                and then Present (Iteration_Scheme (P))
                                and then
                                  Ref_In (Condition (Iteration_Scheme (P)))
                              then
                                 return;
                              end if;
                           end loop;
                        end Access_Type_Case;
                     end if;

                     --  One more check, don't bother if we are within a
                     --  postcondition, since the expression occurs in a
                     --  place unrelated to the actual test.

                     if not Within_Postcondition then

                        --  Here we definitely have a case for giving a warning
                        --  for a reference to an unset value. But we don't
                        --  give the warning now. Instead set Unset_Reference
                        --  in the identifier involved. The reason for this is
                        --  that if we find the variable is never ever assigned
                        --  a value then that warning is more important and
                        --  there is no point in giving the reference warning.

                        --  If this is an identifier, set the field directly

                        if Nkind (N) = N_Identifier then
                           Set_Unset_Reference (E, N);

                        --  Otherwise it is an expanded name, so set the field
                        --  of the actual identifier for the reference.

                        else
                           Set_Unset_Reference (E, Selector_Name (N));
                        end if;
                     end if;
                  end Potential_Unset_Reference;
               end if;
            end;

         --  Indexed component or slice

         when N_Indexed_Component
            | N_Slice
         =>
            --  If prefix does not involve dereferencing an access type, then
            --  we know we are OK if the component type is fully initialized,
            --  since the component will have been set as part of the default
            --  initialization.

            if not Prefix_Has_Dereference (Prefix (N))
              and then Is_OK_Fully_Initialized
            then
               return;

            --  Look at prefix in access type case, or if the component is not
            --  fully initialized.

            else
               Check_Unset_Reference (Prefix (N));
            end if;

         --  Record component

         when N_Selected_Component =>
            declare
               Pref : constant Node_Id   := Prefix (N);
               Ent  : constant Entity_Id := Entity (Selector_Name (N));

            begin
               --  If prefix involves dereferencing an access type, always
               --  check the prefix, since the issue then is whether this
               --  access value is null.

               if Prefix_Has_Dereference (Pref) then
                  null;

               --  Always go to prefix if no selector entity is set. Can this
               --  happen in the normal case? Not clear, but it definitely can
               --  happen in error cases.

               elsif No (Ent) then
                  null;

               --  For a record component, check some cases where we have
               --  reasonable cause to consider that the component is known to
               --  be or probably is initialized. In this case, we don't care
               --  if the prefix itself was explicitly initialized.

               --  Discriminants are always considered initialized

               elsif Ekind (Ent) = E_Discriminant then
                  return;

               --  An explicitly initialized component is certainly initialized

               elsif Nkind (Parent (Ent)) = N_Component_Declaration
                 and then Present (Expression (Parent (Ent)))
               then
                  return;

               --  A fully initialized component is initialized

               elsif Is_OK_Fully_Initialized then
                  return;
               end if;

               --  If none of those cases apply, check the record type prefix

               Check_Unset_Reference (Pref);
            end;

         --  Type conversions can appear in assignment statements both
         --  as variable names and as expressions. We examine their own
         --  expressions only when processing their parent node.

         when N_Type_Conversion =>
            Check_Unset_Reference (Expression (N));

         --  For explicit dereference, always check prefix, which will generate
         --  an unset reference (since this is a case of dereferencing null).

         when N_Explicit_Dereference =>
            Check_Unset_Reference (Prefix (N));

         --  All other cases are not cases of an unset reference

         when others =>
            null;
      end case;
   end Check_Unset_Reference;

   ------------------------
   -- Check_Unused_Withs --
   ------------------------

   procedure Check_Unused_Withs (Spec_Unit : Unit_Number_Type := No_Unit) is

      Munite : constant Entity_Id := Cunit_Entity (Main_Unit);
      --  This is needed for checking the special renaming case

      procedure Check_One_Unit (Unit : Unit_Number_Type);
      --  Subsidiary procedure, performs checks for specified unit

      --------------------
      -- Check_One_Unit --
      --------------------

      procedure Check_One_Unit (Unit : Unit_Number_Type) is
         Cnode : constant Node_Id := Cunit (Unit);

         Is_Visible_Renaming : Boolean := False;

         procedure Check_Inner_Package (Pack : Entity_Id);
         --  Pack is a package local to a unit in a with_clause. Both the unit
         --  and Pack are referenced. If none of the entities in Pack are
         --  referenced, then the only occurrence of Pack is in a USE clause
         --  or a pragma, and a warning is worthwhile as well.

         function Check_System_Aux (Lunit : Entity_Id) return Boolean;
         --  Before giving a warning on a with_clause for System, check whether
         --  a system extension is present.

         function Find_Package_Renaming
           (P : Entity_Id;
            L : Entity_Id) return Entity_Id;
         --  The only reference to a context unit may be in a renaming
         --  declaration. If this renaming declares a visible entity, do not
         --  warn that the context clause could be moved to the body, because
         --  the renaming may be intended to re-export the unit.

         function Has_Visible_Entities (P : Entity_Id) return Boolean;
         --  This function determines if a package has any visible entities.
         --  True is returned if there is at least one declared visible entity,
         --  otherwise False is returned (e.g. case of only pragmas present).

         -------------------------
         -- Check_Inner_Package --
         -------------------------

         procedure Check_Inner_Package (Pack : Entity_Id) is
            E  : Entity_Id;
            Un : constant Node_Id := Sinfo.Nodes.Unit (Cnode);

            function Check_Use_Clause (N : Node_Id) return Traverse_Result;
            --  If N is a use_clause for Pack, emit warning

            procedure Check_Use_Clauses is new
              Traverse_Proc (Check_Use_Clause);

            ----------------------
            -- Check_Use_Clause --
            ----------------------

            function Check_Use_Clause (N : Node_Id) return Traverse_Result is
            begin
               if Nkind (N) = N_Use_Package_Clause
                 and then Entity (Name (N)) = Pack
               then
                  --  Suppress message if any serious errors detected that turn
                  --  off expansion, and thus result in false positives for
                  --  this warning.

                  if Serious_Errors_Detected = 0 then
                     Error_Msg_Qual_Level := 1;
                     Error_Msg_NE -- CODEFIX
                       ("?u?no entities of package& are referenced!",
                          Name (N), Pack);
                     Error_Msg_Qual_Level := 0;
                  end if;
               end if;

               return OK;
            end Check_Use_Clause;

         --  Start of processing for Check_Inner_Package

         begin
            E := First_Entity (Pack);
            while Present (E) loop
               if Referenced_Check_Spec (E) then
                  return;
               end if;

               Next_Entity (E);
            end loop;

            --  No entities of the package are referenced. Check whether the
            --  reference to the package itself is a use clause, and if so
            --  place a warning on it.

            Check_Use_Clauses (Un);
         end Check_Inner_Package;

         ----------------------
         -- Check_System_Aux --
         ----------------------

         function Check_System_Aux (Lunit : Entity_Id) return Boolean is
            Ent : Entity_Id;

         begin
            if Chars (Lunit) = Name_System
               and then Scope (Lunit) = Standard_Standard
               and then Present_System_Aux
            then
               Ent := First_Entity (System_Aux_Id);
               while Present (Ent) loop
                  if Referenced_Check_Spec (Ent) then
                     return True;
                  end if;

                  Next_Entity (Ent);
               end loop;
            end if;

            return False;
         end Check_System_Aux;

         ---------------------------
         -- Find_Package_Renaming --
         ---------------------------

         function Find_Package_Renaming
           (P : Entity_Id;
            L : Entity_Id) return Entity_Id
         is
            E1 : Entity_Id;
            R  : Entity_Id;

         begin
            Is_Visible_Renaming := False;

            E1 := First_Entity (P);
            while Present (E1) loop
               if Ekind (E1) = E_Package and then Renamed_Entity (E1) = L then
                  Is_Visible_Renaming := not Is_Hidden (E1);
                  return E1;

               elsif Ekind (E1) = E_Package
                 and then No (Renamed_Entity (E1))
                 and then not Is_Generic_Instance (E1)
               then
                  R := Find_Package_Renaming (E1, L);

                  if Present (R) then
                     Is_Visible_Renaming := not Is_Hidden (R);
                     return R;
                  end if;
               end if;

               Next_Entity (E1);
            end loop;

            return Empty;
         end Find_Package_Renaming;

         --------------------------
         -- Has_Visible_Entities --
         --------------------------

         function Has_Visible_Entities (P : Entity_Id) return Boolean is
            E : Entity_Id;

         begin
            --  If unit in context is not a package, it is a subprogram that
            --  is not called or a generic unit that is not instantiated
            --  in the current unit, and warning is appropriate.

            if Ekind (P) /= E_Package then
               return True;
            end if;

            --  If unit comes from a limited_with clause, look for declaration
            --  of shadow entities.

            if Present (Limited_View (P)) then
               E := First_Entity (Limited_View (P));
            else
               E := First_Entity (P);
            end if;

            while Present (E) and then E /= First_Private_Entity (P) loop
               if Comes_From_Source (E) or else Present (Limited_View (P)) then
                  return True;
               end if;

               Next_Entity (E);
            end loop;

            return False;
         end Has_Visible_Entities;

         --  Local variables

         Ent   : Entity_Id;
         Item  : Node_Id;
         Lunit : Entity_Id;
         Pack  : Entity_Id;

      --  Start of processing for Check_One_Unit

      begin
         --  Only do check in units that are part of the extended main unit.
         --  This is actually a necessary restriction, because in the case of
         --  subprogram acting as its own specification, there can be with's in
         --  subunits that we will not see.

         if not In_Extended_Main_Source_Unit (Cnode) then
            return;
         end if;

         --  Loop through context items in this unit

         Item := First (Context_Items (Cnode));
         while Present (Item) loop
            if Nkind (Item) = N_With_Clause
              and then not Implicit_With (Item)
              and then In_Extended_Main_Source_Unit (Item)

              --  Guard for no entity present. Not clear under what conditions
              --  this happens, but it does occur, and since this is only a
              --  warning, we just suppress the warning in this case.

              and then Nkind (Name (Item)) in N_Has_Entity
              and then Present (Entity (Name (Item)))
            then
               Lunit := Entity (Name (Item));

               --  Check if this unit is referenced (skip the check if this
               --  is explicitly marked by a pragma Unreferenced).

               if not Referenced (Lunit) and then not Has_Unreferenced (Lunit)
               then
                  --  Suppress warnings in internal units if not in -gnatg mode
                  --  (these would be junk warnings for an application program,
                  --  since they refer to problems in internal units).

                  if GNAT_Mode or else not Is_Internal_Unit (Unit) then
                     --  Here we definitely have a non-referenced unit. If it
                     --  is the special call for a spec unit, then just set the
                     --  flag to be read later.

                     if Unit = Spec_Unit then
                        Set_Unreferenced_In_Spec (Item);

                     --  Otherwise simple unreferenced message, but skip this
                     --  if no visible entities, because that is most likely a
                     --  case where warning would be false positive (e.g. a
                     --  package with only a linker options pragma and nothing
                     --  else or a pragma elaborate with a body library task).

                     elsif Has_Visible_Entities (Lunit) then
                        Error_Msg_N -- CODEFIX
                          ("?u?unit& is not referenced!", Name (Item));
                     end if;
                  end if;

               --  If main unit is a renaming of this unit, then we consider
               --  the with to be OK (obviously it is needed in this case).
               --  This may be transitive: the unit in the with_clause may
               --  itself be a renaming, in which case both it and the main
               --  unit rename the same ultimate package.

               elsif Present (Renamed_Entity (Munite))
                  and then
                    (Renamed_Entity (Munite) = Lunit
                      or else Renamed_Entity (Munite) = Renamed_Entity (Lunit))
               then
                  null;

               --  If this unit is referenced, and it is a package, we do
               --  another test, to see if any of the entities in the package
               --  are referenced. If none of the entities are referenced, we
               --  still post a warning. This occurs if the only use of the
               --  package is in a use clause, or in a package renaming
               --  declaration. This check is skipped for packages that are
               --  renamed in a spec, since the entities in such a package are
               --  visible to clients via the renaming.

               elsif Ekind (Lunit) = E_Package
                 and then not Renamed_In_Spec (Lunit)
               then
                  --  If Is_Instantiated is set, it means that the package is
                  --  implicitly instantiated (this is the case of parent
                  --  instance or an actual for a generic package formal), and
                  --  this counts as a reference.

                  if Is_Instantiated (Lunit) then
                     null;

                  --  If no entities in package, and there is a pragma
                  --  Elaborate_Body present, then assume that this with is
                  --  done for purposes of this elaboration.

                  elsif No (First_Entity (Lunit))
                    and then Has_Pragma_Elaborate_Body (Lunit)
                  then
                     null;

                  --  Otherwise see if any entities have been referenced

                  else
                     if Limited_Present (Item) then
                        Ent := First_Entity (Limited_View (Lunit));
                     else
                        Ent := First_Entity (Lunit);
                     end if;

                     loop
                        --  No more entities, and we did not find one that was
                        --  referenced. Means we have a definite case of a with
                        --  none of whose entities was referenced.

                        if No (Ent) then

                           --  If in spec, just set the flag

                           if Unit = Spec_Unit then
                              Set_No_Entities_Ref_In_Spec (Item);

                           elsif Check_System_Aux (Lunit) then
                              null;

                           --  Else the warning may be needed

                           else
                              --  Warn if we unreferenced flag set and we have
                              --  not had serious errors. The reason we inhibit
                              --  the message if there are errors is to prevent
                              --  false positives from disabling expansion.

                              if not Has_Unreferenced (Lunit)
                                and then Serious_Errors_Detected = 0
                              then
                                 --  Get possible package renaming

                                 Pack := Find_Package_Renaming (Munite, Lunit);

                                 --  No warning if either the package or its
                                 --  renaming is used as a generic actual.

                                 if Used_As_Generic_Actual (Lunit)
                                   or else
                                     (Present (Pack)
                                       and then
                                         Used_As_Generic_Actual (Pack))
                                 then
                                    exit;
                                 end if;

                                 --  Here we give the warning

                                 Error_Msg_N -- CODEFIX
                                   ("?u?no entities of & are referenced!",
                                    Name (Item));

                                 --  Flag renaming of package as well. If
                                 --  the original package has warnings off,
                                 --  we suppress the warning on the renaming
                                 --  as well.

                                 if Present (Pack)
                                   and then not Has_Warnings_Off (Lunit)
                                   and then not Has_Unreferenced (Pack)
                                 then
                                    Error_Msg_NE -- CODEFIX
                                      ("?u?no entities of& are referenced!",
                                       Unit_Declaration_Node (Pack), Pack);
                                 end if;
                              end if;
                           end if;

                           exit;

                        --  Case of entity being referenced. The reference may
                        --  come from a limited_with_clause, in which case the
                        --  limited view of the entity carries the flag.

                        elsif Referenced_Check_Spec (Ent)
                          or else Referenced_As_LHS_Check_Spec (Ent)
                          or else Referenced_As_Out_Parameter_Check_Spec (Ent)
                          or else
                            (From_Limited_With (Ent)
                              and then Is_Incomplete_Type (Ent)
                              and then Present (Non_Limited_View (Ent))
                              and then Referenced (Non_Limited_View (Ent)))
                        then
                           --  This means that the with is indeed fine, in that
                           --  it is definitely needed somewhere, and we can
                           --  quit worrying about this one...

                           --  Except for one little detail: if either of the
                           --  flags was set during spec processing, this is
                           --  where we complain that the with could be moved
                           --  from the spec. If the spec contains a visible
                           --  renaming of the package, inhibit warning to move
                           --  with_clause to body.

                           if Ekind (Munite) = E_Package_Body then
                              Pack :=
                                Find_Package_Renaming
                                  (Spec_Entity (Munite), Lunit);
                           else
                              Pack := Empty;
                           end if;

                           --  If a renaming is present in the spec do not warn
                           --  because the body or child unit may depend on it.

                           if Present (Pack)
                             and then Renamed_Entity (Pack) = Lunit
                           then
                              exit;

                           elsif Unreferenced_In_Spec (Item) then
                              Error_Msg_N -- CODEFIX
                                ("?u?unit& is not referenced in spec!",
                                 Name (Item));

                           elsif No_Entities_Ref_In_Spec (Item) then
                              Error_Msg_N -- CODEFIX
                                ("?u?no entities of & are referenced in spec!",
                                 Name (Item));

                           else
                              if Ekind (Ent) = E_Package then
                                 Check_Inner_Package (Ent);
                              end if;

                              exit;
                           end if;

                           if not Is_Visible_Renaming then
                              Error_Msg_N -- CODEFIX
                                ("\?u?with clause might be moved to body!",
                                 Name (Item));
                           end if;

                           exit;

                        --  Move to next entity to continue search

                        else
                           Next_Entity (Ent);
                        end if;
                     end loop;
                  end if;

               --  For a generic package, the only interesting kind of
               --  reference is an instantiation, since entities cannot be
               --  referenced directly.

               elsif Is_Generic_Unit (Lunit) then

                  --  Unit was never instantiated, set flag for case of spec
                  --  call, or give warning for normal call.

                  if not Is_Instantiated (Lunit) then
                     if Unit = Spec_Unit then
                        Set_Unreferenced_In_Spec (Item);
                     else
                        Error_Msg_N -- CODEFIX
                          ("?u?unit& is never instantiated!", Name (Item));
                     end if;

                  --  If unit was indeed instantiated, make sure that flag is
                  --  not set showing it was uninstantiated in the spec, and if
                  --  so, give warning.

                  elsif Unreferenced_In_Spec (Item) then
                     Error_Msg_N
                       ("?u?unit& is not instantiated in spec!", Name (Item));
                     Error_Msg_N -- CODEFIX
                       ("\?u?with clause can be moved to body!", Name (Item));
                  end if;
               end if;
            end if;

            Next (Item);
         end loop;
      end Check_One_Unit;

   --  Start of processing for Check_Unused_Withs

   begin
      --  Immediate return if no semantics or warning flag not set

      if not Opt.Check_Withs or else Operating_Mode = Check_Syntax then
         return;
      end if;

      --  Flag any unused with clauses. For a subunit, check only the units
      --  in its context, not those of the parent, which may be needed by other
      --  subunits. We will get the full warnings when we compile the parent,
      --  but the following is helpful when compiling a subunit by itself.

      if Nkind (Unit (Cunit (Main_Unit))) = N_Subunit then
         if Current_Sem_Unit = Main_Unit then
            Check_One_Unit (Main_Unit);
         end if;

         return;
      end if;

      --  Process specified units

      if Spec_Unit = No_Unit then

         --  For main call, check all units

         for Unit in Main_Unit .. Last_Unit loop
            Check_One_Unit (Unit);
         end loop;

      else
         --  For call for spec, check only the spec

         Check_One_Unit (Spec_Unit);
      end if;
   end Check_Unused_Withs;

   ---------------------------------
   -- Generic_Package_Spec_Entity --
   ---------------------------------

   function Generic_Package_Spec_Entity (E : Entity_Id) return Boolean is
      S : Entity_Id;

   begin
      if Is_Package_Body_Entity (E) then
         return False;

      else
         S := Scope (E);
         loop
            if S = Standard_Standard then
               return False;

            elsif Ekind (S) = E_Generic_Package then
               return True;

            elsif Ekind (S) = E_Package then
               S := Scope (S);

            else
               return False;
            end if;
         end loop;
      end if;
   end Generic_Package_Spec_Entity;

   ----------------------
   -- Goto_Spec_Entity --
   ----------------------

   function Goto_Spec_Entity (E : Entity_Id) return Entity_Id is
   begin
      if Is_Formal (E) and then Present (Spec_Entity (E)) then
         return Spec_Entity (E);
      else
         return E;
      end if;
   end Goto_Spec_Entity;

   -------------------
   -- Has_Junk_Name --
   -------------------

   function Has_Junk_Name (E : Entity_Id) return Boolean is
      function Match (S : String) return Boolean;
      --  Return true if substring S is found in Name_Buffer (1 .. Name_Len)

      -----------
      -- Match --
      -----------

      function Match (S : String) return Boolean is
         Slen1 : constant Integer := S'Length - 1;

      begin
         for J in 1 .. Name_Len - S'Length + 1 loop
            if Name_Buffer (J .. J + Slen1) = S then
               return True;
            end if;
         end loop;

         return False;
      end Match;

   --  Start of processing for Has_Junk_Name

   begin
      Get_Unqualified_Decoded_Name_String (Chars (E));

      return
        Match ("discard") or else
        Match ("dummy")   or else
        Match ("ignore")  or else
        Match ("junk")    or else
        Match ("unuse")   or else
        Match ("tmp")     or else
        Match ("temp");
   end Has_Junk_Name;

   --------------------------------------
   -- Has_Pragma_Unmodified_Check_Spec --
   --------------------------------------

   function Has_Pragma_Unmodified_Check_Spec
     (E : Entity_Id) return Boolean
   is
   begin
      if Is_Formal (E) and then Present (Spec_Entity (E)) then

         --  Note: use of OR instead of OR ELSE here is deliberate, we want
         --  to mess with Unmodified flags on both body and spec entities.
         --  Has_Unmodified has side effects!

         return Has_Unmodified (E)
                  or
                Has_Unmodified (Spec_Entity (E));

      else
         return Has_Unmodified (E);
      end if;
   end Has_Pragma_Unmodified_Check_Spec;

   ----------------------------------------
   -- Has_Pragma_Unreferenced_Check_Spec --
   ----------------------------------------

   function Has_Pragma_Unreferenced_Check_Spec
     (E : Entity_Id) return Boolean
   is
   begin
      if Is_Formal (E) and then Present (Spec_Entity (E)) then

         --  Note: use of OR here instead of OR ELSE is deliberate, we want
         --  to mess with flags on both entities.

         return Has_Unreferenced (E)
                  or
                Has_Unreferenced (Spec_Entity (E));

      else
         return Has_Unreferenced (E);
      end if;
   end Has_Pragma_Unreferenced_Check_Spec;

   ----------------
   -- Initialize --
   ----------------

   procedure Initialize is
   begin
      Warnings_Off_Pragmas.Init;
      Unreferenced_Entities.Init;
      In_Out_Warnings.Init;
   end Initialize;

   ---------------------------------------------
   -- Is_Attribute_And_Known_Value_Comparison --
   ---------------------------------------------

   function Is_Attribute_And_Known_Value_Comparison
     (Op : Node_Id) return Boolean
   is
      Orig_Op : constant Node_Id := Original_Node (Op);

   begin
      return
        Nkind (Orig_Op) in N_Op_Compare
          and then Nkind (Original_Node (Left_Opnd (Orig_Op))) =
                     N_Attribute_Reference
          and then Compile_Time_Known_Value (Right_Opnd (Orig_Op));
   end Is_Attribute_And_Known_Value_Comparison;

   ------------------------------------
   -- Never_Set_In_Source_Check_Spec --
   ------------------------------------

   function Never_Set_In_Source_Check_Spec (E : Entity_Id) return Boolean is
   begin
      if Is_Formal (E) and then Present (Spec_Entity (E)) then
         return Never_Set_In_Source (E)
                  and then
                Never_Set_In_Source (Spec_Entity (E));
      else
         return Never_Set_In_Source (E);
      end if;
   end Never_Set_In_Source_Check_Spec;

   -------------------------------------
   -- Operand_Has_Warnings_Suppressed --
   -------------------------------------

   function Operand_Has_Warnings_Suppressed (N : Node_Id) return Boolean is

      function Check_For_Warnings (N : Node_Id) return Traverse_Result;
      --  Function used to check one node to see if it is or was originally
      --  a reference to an entity for which Warnings are off. If so, Abandon
      --  is returned, otherwise OK_Orig is returned to continue the traversal
      --  of the original expression.

      function Traverse is new Traverse_Func (Check_For_Warnings);
      --  Function used to traverse tree looking for warnings

      ------------------------
      -- Check_For_Warnings --
      ------------------------

      function Check_For_Warnings (N : Node_Id) return Traverse_Result is
         R : constant Node_Id := Original_Node (N);

      begin
         if Nkind (R) in N_Has_Entity
           and then Present (Entity (R))
           and then Has_Warnings_Off (Entity (R))
         then
            return Abandon;
         else
            return OK_Orig;
         end if;
      end Check_For_Warnings;

   --  Start of processing for Operand_Has_Warnings_Suppressed

   begin
      return Traverse (N) = Abandon;

   --  If any exception occurs, then something has gone wrong, and this is
   --  only a minor aesthetic issue anyway, so just say we did not find what
   --  we are looking for, rather than blow up.

   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;

   -----------------------------------------
   -- Output_Non_Modified_In_Out_Warnings --
   -----------------------------------------

   procedure Output_Non_Modified_In_Out_Warnings is

      function No_Warn_On_In_Out (E : Entity_Id) return Boolean;
      --  Given a formal parameter entity E, determines if there is a reason to
      --  suppress IN OUT warnings (not modified, could be IN) for formals of
      --  the subprogram. We suppress these warnings if Warnings Off is set, or
      --  if we have seen the address of the subprogram being taken, or if the
      --  subprogram is used as a generic actual (in the latter cases the
      --  context may force use of IN OUT, even if the parameter is not
      --  modified for this particular case.

      -----------------------
      -- No_Warn_On_In_Out --
      -----------------------

      function No_Warn_On_In_Out (E : Entity_Id) return Boolean is
         S  : constant Entity_Id := Scope (E);
         SE : constant Entity_Id := Spec_Entity (E);

      begin
         --  Do not warn if address is taken, since funny business may be going
         --  on in treating the parameter indirectly as IN OUT.

         if Address_Taken (S)
           or else (Present (SE) and then Address_Taken (Scope (SE)))
         then
            return True;

         --  Do not warn if used as a generic actual, since the generic may be
         --  what is forcing the use of an "unnecessary" IN OUT.

         elsif Used_As_Generic_Actual (S)
           or else (Present (SE) and then Used_As_Generic_Actual (Scope (SE)))
         then
            return True;

         --  Else test warnings off

         elsif Warnings_Off_Check_Spec (S) then
            return True;

         --  All tests for suppressing warning failed

         else
            return False;
         end if;
      end No_Warn_On_In_Out;

   --  Start of processing for Output_Non_Modified_In_Out_Warnings

   begin
      --  Loop through entities for which a warning may be needed

      for J in In_Out_Warnings.First .. In_Out_Warnings.Last loop
         declare
            E1 : constant Entity_Id := In_Out_Warnings.Table (J);

         begin
            --  Suppress warning in specific cases (see details in comments for
            --  No_Warn_On_In_Out), or if there is a pragma Unmodified.

            if Has_Pragma_Unmodified_Check_Spec (E1)
              or else No_Warn_On_In_Out (E1)
            then
               null;

            --  Here we generate the warning

            else
               --  If -gnatwk is set then output message that it could be IN

               if not Is_Trivial_Subprogram (Scope (E1)) then
                  if Warn_On_Constant then
                     Error_Msg_N
                       ("?k?formal parameter & is not modified!", E1);
                     Error_Msg_N
                       ("\?k?mode could be IN instead of `IN OUT`!", E1);

                     --  We do not generate warnings for IN OUT parameters
                     --  unless we have at least -gnatwu. This is deliberately
                     --  inconsistent with the treatment of variables, but
                     --  otherwise we get too many unexpected warnings in
                     --  default mode.

                  elsif Check_Unreferenced then
                     Error_Msg_N
                       ("?u?formal parameter& is read but "
                        & "never assigned!", E1);
                  end if;
               end if;

               --  Kill any other warnings on this entity, since this is the
               --  one that should dominate any other unreferenced warning.

               Set_Warnings_Off (E1);
            end if;
         end;
      end loop;
   end Output_Non_Modified_In_Out_Warnings;

   ----------------------------------------
   -- Output_Obsolescent_Entity_Warnings --
   ----------------------------------------

   procedure Output_Obsolescent_Entity_Warnings (N : Node_Id; E : Entity_Id) is
      P : constant Node_Id := Parent (N);
      S : Entity_Id;

   begin
      S := Current_Scope;

      --  Do not output message if we are the scope of standard. This means
      --  we have a reference from a context clause from when it is originally
      --  processed, and that's too early to tell whether it is an obsolescent
      --  unit doing the with'ing. In Sem_Ch10.Analyze_Compilation_Unit we make
      --  sure that we have a later call when the scope is available. This test
      --  also eliminates all messages for use clauses, which is fine (we do
      --  not want messages for use clauses, since they are always redundant
      --  with respect to the associated with clause).

      if S = Standard_Standard then
         return;
      end if;

      --  Do not output message if we are in scope of an obsolescent package
      --  or subprogram.

      loop
         if Is_Obsolescent (S) then
            return;
         end if;

         S := Scope (S);
         exit when S = Standard_Standard;
      end loop;

      --  Here we will output the message

      Error_Msg_Sloc := Sloc (E);

      --  Case of with clause

      if Nkind (P) = N_With_Clause then
         if Ekind (E) = E_Package then
            Error_Msg_NE
              ("?j?with of obsolescent package& declared#", N, E);
         elsif Ekind (E) = E_Procedure then
            Error_Msg_NE
              ("?j?with of obsolescent procedure& declared#", N, E);
         else
            Error_Msg_NE
              ("??with of obsolescent function& declared#", N, E);
         end if;

      --  If we do not have a with clause, then ignore any reference to an
      --  obsolescent package name. We only want to give the one warning of
      --  withing the package, not one each time it is used to qualify.

      elsif Ekind (E) = E_Package then
         return;

      --  Procedure call statement

      elsif Nkind (P) = N_Procedure_Call_Statement then
         Error_Msg_NE
           ("??call to obsolescent procedure& declared#", N, E);

      --  Function call

      elsif Nkind (P) = N_Function_Call then
         Error_Msg_NE
           ("??call to obsolescent function& declared#", N, E);

      --  Reference to obsolescent type

      elsif Is_Type (E) then
         Error_Msg_NE
           ("??reference to obsolescent type& declared#", N, E);

      --  Reference to obsolescent component

      elsif Ekind (E) in E_Component | E_Discriminant then
         Error_Msg_NE
           ("??reference to obsolescent component& declared#", N, E);

      --  Reference to obsolescent variable

      elsif Ekind (E) = E_Variable then
         Error_Msg_NE
           ("??reference to obsolescent variable& declared#", N, E);

      --  Reference to obsolescent constant

      elsif Ekind (E) = E_Constant or else Ekind (E) in Named_Kind then
         Error_Msg_NE
           ("??reference to obsolescent constant& declared#", N, E);

      --  Reference to obsolescent enumeration literal

      elsif Ekind (E) = E_Enumeration_Literal then
         Error_Msg_NE
           ("??reference to obsolescent enumeration literal& declared#", N, E);

      --  Generic message for any other case we missed

      else
         Error_Msg_NE
           ("??reference to obsolescent entity& declared#", N, E);
      end if;

      --  Output additional warning if present

      for J in Obsolescent_Warnings.First .. Obsolescent_Warnings.Last loop
         if Obsolescent_Warnings.Table (J).Ent = E then
            String_To_Name_Buffer (Obsolescent_Warnings.Table (J).Msg);
            Error_Msg_Strlen := Name_Len;
            Error_Msg_String (1 .. Name_Len) := Name_Buffer (1 .. Name_Len);
            Error_Msg_N ("\\??~", N);
            exit;
         end if;
      end loop;
   end Output_Obsolescent_Entity_Warnings;

   ----------------------------------
   -- Output_Unreferenced_Messages --
   ----------------------------------

   procedure Output_Unreferenced_Messages is
   begin
      for J in Unreferenced_Entities.First .. Unreferenced_Entities.Last loop
         Warn_On_Unreferenced_Entity (Unreferenced_Entities.Table (J));
      end loop;
   end Output_Unreferenced_Messages;

   -----------------------------------------
   -- Output_Unused_Warnings_Off_Warnings --
   -----------------------------------------

   procedure Output_Unused_Warnings_Off_Warnings is
   begin
      for J in Warnings_Off_Pragmas.First .. Warnings_Off_Pragmas.Last loop
         declare
            Wentry : Warnings_Off_Entry renames Warnings_Off_Pragmas.Table (J);
            N      : Node_Id renames Wentry.N;
            E      : Node_Id renames Wentry.E;

         begin
            --  Turn off Warnings_Off, or we won't get the warning

            Set_Warnings_Off (E, False);

            --  Nothing to do if pragma was used to suppress a general warning

            if Warnings_Off_Used (E) then
               null;

            --  If pragma was used both in unmodified and unreferenced contexts
            --  then that's as good as the general case, no warning.

            elsif Warnings_Off_Used_Unmodified (E)
                    and
                  Warnings_Off_Used_Unreferenced (E)
            then
               null;

            --  Used only in context where Unmodified would have worked

            elsif Warnings_Off_Used_Unmodified (E) then
               Error_Msg_NE
                 ("?.w?could use Unmodified instead of "
                  & "Warnings Off for &", Pragma_Identifier (N), E);

            --  Used only in context where Unreferenced would have worked

            elsif Warnings_Off_Used_Unreferenced (E) then
               Error_Msg_NE
                 ("?.w?could use Unreferenced instead of "
                  & "Warnings Off for &", Pragma_Identifier (N), E);

            --  Not used at all

            else
               Error_Msg_NE
                 ("?.w?pragma Warnings Off for & unused, "
                  & "could be omitted", N, E);
            end if;
         end;
      end loop;
   end Output_Unused_Warnings_Off_Warnings;

   ---------------------------
   -- Referenced_Check_Spec --
   ---------------------------

   function Referenced_Check_Spec (E : Entity_Id) return Boolean is
   begin
      if Is_Formal (E) and then Present (Spec_Entity (E)) then
         return Referenced (E) or else Referenced (Spec_Entity (E));
      else
         return Referenced (E);
      end if;
   end Referenced_Check_Spec;

   ----------------------------------
   -- Referenced_As_LHS_Check_Spec --
   ----------------------------------

   function Referenced_As_LHS_Check_Spec (E : Entity_Id) return Boolean is
   begin
      if Is_Formal (E) and then Present (Spec_Entity (E)) then
         return Referenced_As_LHS (E)
           or else Referenced_As_LHS (Spec_Entity (E));
      else
         return Referenced_As_LHS (E);
      end if;
   end Referenced_As_LHS_Check_Spec;

   --------------------------------------------
   -- Referenced_As_Out_Parameter_Check_Spec --
   --------------------------------------------

   function Referenced_As_Out_Parameter_Check_Spec
     (E : Entity_Id) return Boolean
   is
   begin
      if Is_Formal (E) and then Present (Spec_Entity (E)) then
         return Referenced_As_Out_Parameter (E)
           or else Referenced_As_Out_Parameter (Spec_Entity (E));
      else
         return Referenced_As_Out_Parameter (E);
      end if;
   end Referenced_As_Out_Parameter_Check_Spec;

   --------------------------------------
   -- Warn_On_Constant_Valid_Condition --
   --------------------------------------

   procedure Warn_On_Constant_Valid_Condition (Op : Node_Id) is
      Left  : constant Node_Id := Left_Opnd  (Op);
      Right : constant Node_Id := Right_Opnd (Op);

      True_Result  : Boolean;
      False_Result : Boolean;

   begin
      --  Determine the potential outcome of the comparison assuming that the
      --  scalar operands are valid.

      if Constant_Condition_Warnings
        and then Comes_From_Source (Original_Node (Op))
        and then Is_Scalar_Type (Etype (Left))
        and then Is_Scalar_Type (Etype (Right))

        --  Do not consider instances because the check was already performed
        --  in the generic.

        and then not In_Instance

        --  Do not consider comparisons between two static expressions such as
        --  constants or literals because those values cannot be invalidated.

        and then not (Is_Static_Expression (Left)
                       and then Is_Static_Expression (Right))

        --  Do not consider comparison between an attribute reference and a
        --  compile-time known value since this is most likely a conditional
        --  compilation.

        and then not Is_Attribute_And_Known_Value_Comparison (Op)

        --  Do not consider internal files to allow for various assertions and
        --  safeguards within our runtime.

        and then not In_Internal_Unit (Op)
      then
         Test_Comparison
           (Op           => Op,
            Assume_Valid => True,
            True_Result  => True_Result,
            False_Result => False_Result);

         --  Warn on a possible evaluation to False / True in the presence of
         --  invalid values. But issue no warning for an assertion expression
         --  (or a subexpression thereof); in particular, we don't want a
         --  warning about an assertion that will always succeed.

         if In_Assertion_Expression_Pragma (Op) then
            null;

         elsif True_Result then
            Error_Msg_N
              ("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?c?", Op);
         end if;
      end if;
   end Warn_On_Constant_Valid_Condition;

   -----------------------------
   -- Warn_On_Known_Condition --
   -----------------------------

   procedure Warn_On_Known_Condition (C : Node_Id) is
      Test_Result : Boolean := False;
      --  Force initialization to facilitate static analysis

      function Is_Known_Branch return Boolean;
      --  If the type of the condition is Boolean, the constant value of the
      --  condition is a boolean literal. If the type is a derived boolean
      --  type, the constant is wrapped in a type conversion of the derived
      --  literal. If the value of the condition is not a literal, no warnings
      --  can be produced. This function returns True if the result can be
      --  determined, and Test_Result is set True/False accordingly. Otherwise
      --  False is returned, and Test_Result is unchanged.

      procedure Track (N : Node_Id; Loc : Node_Id);
      --  Adds continuation warning(s) pointing to reason (assignment or test)
      --  for the operand of the conditional having a known value (or at least
      --  enough is known about the value to issue the warning). N is the node
      --  which is judged to have a known value. Loc is the warning location.

      ---------------------
      -- Is_Known_Branch --
      ---------------------

      function Is_Known_Branch return Boolean is
      begin
         if Etype (C) = Standard_Boolean
           and then Is_Entity_Name (C)
           and then
             (Entity (C) = Standard_False or else Entity (C) = Standard_True)
         then
            Test_Result := Entity (C) = Standard_True;
            return True;

         elsif Is_Boolean_Type (Etype (C))
           and then Nkind (C) = N_Unchecked_Type_Conversion
           and then Is_Entity_Name (Expression (C))
           and then Ekind (Entity (Expression (C))) = E_Enumeration_Literal
         then
            Test_Result :=
              Chars (Entity (Expression (C))) = Chars (Standard_True);
            return True;

         else
            return False;
         end if;
      end Is_Known_Branch;

      -----------
      -- Track --
      -----------

      procedure Track (N : Node_Id; Loc : Node_Id) is
         Nod : constant Node_Id := Original_Node (N);

      begin
         if Nkind (Nod) in N_Op_Compare then
            Track (Left_Opnd (Nod), Loc);
            Track (Right_Opnd (Nod), Loc);

         elsif Is_Entity_Name (Nod) and then Is_Object (Entity (Nod)) then
            declare
               CV : constant Node_Id := Current_Value (Entity (Nod));

            begin
               if Present (CV) then
                  Error_Msg_Sloc := Sloc (CV);

                  if Nkind (CV) not in N_Subexpr then
                     Error_Msg_N ("\\??(see test #)", Loc);

                  elsif Nkind (Parent (CV)) =
                          N_Case_Statement_Alternative
                  then
                     Error_Msg_N ("\\??(see case alternative #)", Loc);

                  else
                     Error_Msg_N ("\\??(see assignment #)", Loc);
                  end if;
               end if;
            end;
         end if;
      end Track;

      --  Local variables

      Orig : constant Node_Id := Original_Node (C);
      P    : Node_Id;

   --  Start of processing for Warn_On_Known_Condition

   begin
      --  Adjust SCO condition if from source

      if Generate_SCO
        and then Comes_From_Source (Orig)
        and then Is_Known_Branch
      then
         declare
            Atrue : Boolean;

         begin
            Atrue := Test_Result;

            if Present (Parent (C)) and then Nkind (Parent (C)) = N_Op_Not then
               Atrue := not Atrue;
            end if;

            Set_SCO_Condition (Orig, Atrue);
         end;
      end if;

      --  Argument replacement in an inlined body can make conditions static.
      --  Do not emit warnings in this case.

      if In_Inlined_Body then
         return;
      end if;

      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
         --  value, since this is likely legitimate conditional compilation.

         if Is_Attribute_And_Known_Value_Comparison (C) then
            return;
         end if;

         --  See if this is in a statement or a declaration

         P := Parent (C);
         loop
            --  If tree is not attached, do not issue warning (this is very
            --  peculiar, and probably arises from some other error condition).

            if No (P) then
               return;

            --  If we are in a declaration, then no warning, since in practice
            --  conditionals in declarations are used for intended tests which
            --  may be known at compile time, e.g. things like

            --    x : constant Integer := 2 + (Word'Size = 32);

            --  And a warning is annoying in such cases

            elsif Nkind (P) in N_Declaration
                    or else
                  Nkind (P) in N_Later_Decl_Item
            then
               return;

            --  Don't warn in assert or check pragma, since presumably tests in
            --  such a context are very definitely intended, and might well be
            --  known at compile time. Note that we have to test the original
            --  node, since assert pragmas get rewritten at analysis time.

            elsif Nkind (Original_Node (P)) = N_Pragma
              and then
                Pragma_Name_Unmapped (Original_Node (P))
                  in Name_Assert | Name_Check
            then
               return;
            end if;

            exit when Is_Statement (P);
            P := Parent (P);
         end loop;

         --  Here we issue the warning unless some sub-operand has warnings
         --  set off, in which case we suppress the warning for the node. If
         --  the original expression is an inequality, it has been expanded
         --  into a negation, and the value of the original expression is the
         --  negation of the equality. If the expression is an entity that
         --  appears within a negation, it is clearer to flag the negation
         --  itself, and report on its constant value.

         if not Operand_Has_Warnings_Suppressed (C) then
            declare
               True_Branch : Boolean := Test_Result;
               Cond        : Node_Id := C;

            begin
               if Present (Parent (C))
                 and then Nkind (Parent (C)) = N_Op_Not
               then
                  True_Branch := not True_Branch;
                  Cond := Parent (C);
               end if;

               --  Condition always True

               if True_Branch then
                  if Is_Entity_Name (Original_Node (C))
                    and then Nkind (Cond) /= N_Op_Not
                  then
                     Error_Msg_NE
                       ("object & is always True at this point?c?",
                        Cond, Original_Node (C));
                     Track (Original_Node (C), Cond);

                  else
                     Error_Msg_N ("condition is always True?c?", Cond);
                     Track (Cond, Cond);
                  end if;

               --  Condition always False

               else
                  if Is_Entity_Name (Original_Node (C))
                    and then Nkind (Cond) /= N_Op_Not
                  then
                     Error_Msg_NE
                       ("object & is always False at this point?c?",
                        Cond, Original_Node (C));
                     Track (Original_Node (C), Cond);

                  else
                     Error_Msg_N ("condition is always False?c?", Cond);
                     Track (Cond, Cond);
                  end if;
               end if;
            end;
         end if;
      end if;
   end Warn_On_Known_Condition;

   ---------------------------------------
   -- Warn_On_Modified_As_Out_Parameter --
   ---------------------------------------

   function Warn_On_Modified_As_Out_Parameter (E : Entity_Id) return Boolean is
   begin
      return
        (Warn_On_Modified_Unread and then Is_Only_Out_Parameter (E))
          or else Warn_On_All_Unread_Out_Parameters;
   end Warn_On_Modified_As_Out_Parameter;

   ---------------------------------
   -- Warn_On_Overlapping_Actuals --
   ---------------------------------

   procedure Warn_On_Overlapping_Actuals (Subp : Entity_Id; N : Node_Id) is
      function Explicitly_By_Reference (Formal_Id : Entity_Id) return Boolean;
      --  Returns True iff the type of Formal_Id is explicitly by-reference

      function Refer_Same_Object
        (Act1 : Node_Id;
         Act2 : Node_Id) return Boolean;
      --  Two names are known to refer to the same object if the two names
      --  are known to denote the same object; or one of the names is a
      --  selected_component, indexed_component, or slice and its prefix is
      --  known to refer to the same object as the other name; or one of the
      --  two names statically denotes a renaming declaration whose renamed
      --  object_name is known to refer to the same object as the other name
      --  (RM 6.4.1(6.11/3))

      -----------------------------
      -- Explicitly_By_Reference --
      -----------------------------

      function Explicitly_By_Reference
        (Formal_Id : Entity_Id)
         return Boolean
      is
         Typ : constant Entity_Id := Underlying_Type (Etype (Formal_Id));
      begin
         if Present (Typ) then
            return Is_By_Reference_Type (Typ)
              or else Convention (Typ) = Convention_Ada_Pass_By_Reference;
         else
            return False;
         end if;
      end Explicitly_By_Reference;

      -----------------------
      -- Refer_Same_Object --
      -----------------------

      function Refer_Same_Object
        (Act1 : Node_Id;
         Act2 : Node_Id) return Boolean
      is
      begin
         return
           Denotes_Same_Object (Act1, Act2)
             or else Denotes_Same_Prefix (Act1, Act2);
      end Refer_Same_Object;

      --  Local variables

      Act1  : Node_Id;
      Act2  : Node_Id;
      Form1 : Entity_Id;
      Form2 : Entity_Id;

   --  Start of processing for Warn_On_Overlapping_Actuals

   begin
      --  Exclude calls rewritten as enumeration literals

      if Nkind (N) not in N_Subprogram_Call | N_Entry_Call_Statement then
         return;

      --  Guard against previous errors

      elsif Error_Posted (N) then
         return;
      end if;

      --  If a call C has two or more parameters of mode in out or out that are
      --  of an elementary type, then the call is legal only if for each name
      --  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 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

         Form2 := Next_Formal (Form1);
         Act2  := Next_Actual (Act1);
         while Present (Form2) and then Present (Act2) loop

            --  Ignore formals of generic types; they will be examined when
            --  instantiated.

            if Is_Generic_Type (Etype (Form1))
              or else Is_Generic_Type (Etype (Form2))
            then
               null;

            elsif Refer_Same_Object (Act1, Act2) then

               --  Case 1: two writable elementary parameters that 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)

               --  Case 2: two composite parameters that overlap, one of
               --  which is writable.

                 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))

               --  Case 3: an elementary writable parameter that overlaps
               --  a composite one.

                 or else (Is_Elementary_Type (Etype (Form1))
                  and then Ekind (Form1) /= E_In_Parameter
                  and then Is_Composite_Type (Etype (Form2)))

                or else (Is_Elementary_Type (Etype (Form2))
                  and then Ekind (Form2) /= E_In_Parameter
                  and then Is_Composite_Type (Etype (Form1)))
               then

                  --  Guard against previous errors

                  if No (Etype (Act1))
                    or else No (Etype (Act2))
                  then
                     null;

                  --  If type is explicitly by-reference, then it is not
                  --  covered by the legality rule, which only applies to
                  --  elementary types. Actually, the aliasing is most
                  --  likely intended, so don't emit a warning either.

                  elsif Explicitly_By_Reference (Form1)
                    or else Explicitly_By_Reference (Form2)
                  then
                     null;

                  --  We only report warnings on overlapping arrays and record
                  --  types if switch is set.

                  elsif not Warn_On_Overlap
                    and then not (Is_Elementary_Type (Etype (Form1))
                                    and then
                                  Is_Elementary_Type (Etype (Form2)))
                  then
                     null;

                  --  Here we may need to issue overlap message

                  else
                     Error_Msg_Warn :=

                       --  Overlap checking is an error only in Ada 2012. For
                       --  earlier versions of Ada, this is a warning.

                       Ada_Version < Ada_2012

                       --  Overlap is only illegal since Ada 2012 and only for
                       --  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;

                     --  For greater clarity, give name of formal

                     Error_Msg_Node_2 := Form2;

                     --  This is one of the messages

                     Error_Msg_FE
                       ("<.i<writable actual for & overlaps with actual for &",
                        Act1, Form1);
                  end if;
               end if;
            end if;

            Next_Formal (Form2);
            Next_Actual (Act2);
         end loop;

         Next_Formal (Form1);
         Next_Actual (Act1);
      end loop;
   end Warn_On_Overlapping_Actuals;

   ------------------------------
   -- Warn_On_Suspicious_Index --
   ------------------------------

   procedure Warn_On_Suspicious_Index (Name : Entity_Id; X : Node_Id) is

      Low_Bound : Uint;
      --  Set to lower bound for a suspicious type

      Ent : Entity_Id;
      --  Entity for array reference

      Typ : Entity_Id;
      --  Array type

      function Is_Suspicious_Type (Typ : Entity_Id) return Boolean;
      --  Tests to see if Typ is a type for which we may have a suspicious
      --  index, namely an unconstrained array type, whose lower bound is
      --  either zero or one. If so, True is returned, and Low_Bound is set
      --  to this lower bound. If not, False is returned, and Low_Bound is
      --  undefined on return.
      --
      --  For now, we limit this to standard string types, so any other
      --  unconstrained types return False. We may change our minds on this
      --  later on, but strings seem the most important case.

      procedure Test_Suspicious_Index;
      --  Test if index is of suspicious type and if so, generate warning

      ------------------------
      -- Is_Suspicious_Type --
      ------------------------

      function Is_Suspicious_Type (Typ : Entity_Id) return Boolean is
         LB : Node_Id;

      begin
         if Is_Array_Type (Typ)
           and then not Is_Constrained (Typ)
           and then Number_Dimensions (Typ) = 1
           and then Is_Standard_String_Type (Typ)
           and then not Has_Warnings_Off (Typ)
         then
            LB := Type_Low_Bound (Etype (First_Index (Typ)));

            if Compile_Time_Known_Value (LB) then
               Low_Bound := Expr_Value (LB);
               return Low_Bound = Uint_0 or else Low_Bound = Uint_1;
            end if;
         end if;

         return False;
      end Is_Suspicious_Type;

      ---------------------------
      -- Test_Suspicious_Index --
      ---------------------------

      procedure Test_Suspicious_Index is

         function Length_Reference (N : Node_Id) return Boolean;
         --  Check if node N is of the form Name'Length

         procedure Warn1;
         --  Generate first warning line

         procedure Warn_On_Index_Below_Lower_Bound;
         --  Generate a warning on indexing the array with a literal value
         --  below the lower bound of the index type.

         procedure Warn_On_Literal_Index;
         --  Generate a warning on indexing the array with a literal value

         ----------------------
         -- Length_Reference --
         ----------------------

         function Length_Reference (N : Node_Id) return Boolean is
            R : constant Node_Id := Original_Node (N);
         begin
            return
              Nkind (R) = N_Attribute_Reference
                and then Attribute_Name (R) = Name_Length
                and then Is_Entity_Name (Prefix (R))
                and then Entity (Prefix (R)) = Ent;
         end Length_Reference;

         -----------
         -- Warn1 --
         -----------

         procedure Warn1 is
         begin
            Error_Msg_Uint_1 := Low_Bound;
            Error_Msg_FE -- CODEFIX
              ("?w?index for& may assume lower bound of^", X, Ent);
         end Warn1;

         -------------------------------------
         -- Warn_On_Index_Below_Lower_Bound --
         -------------------------------------

         procedure Warn_On_Index_Below_Lower_Bound is
         begin
            if Is_Standard_String_Type (Typ) then
               Discard_Node
                 (Compile_Time_Constraint_Error
                   (N   => X,
                    Msg => "?w?string index should be positive"));
            else
               Discard_Node
                 (Compile_Time_Constraint_Error
                   (N   => X,
                    Msg => "?w?index out of the allowed range"));
            end if;
         end Warn_On_Index_Below_Lower_Bound;

         ---------------------------
         -- Warn_On_Literal_Index --
         ---------------------------

         procedure Warn_On_Literal_Index is
         begin
            Warn1;

            --  Case where original form of subscript is an integer literal

            if Nkind (Original_Node (X)) = N_Integer_Literal then
               if Intval (X) = Low_Bound then
                  Error_Msg_FE -- CODEFIX
                    ("\?w?suggested replacement: `&''First`", X, Ent);
               else
                  Error_Msg_Uint_1 := Intval (X) - Low_Bound;
                  Error_Msg_FE -- CODEFIX
                    ("\?w?suggested replacement: `&''First + ^`", X, Ent);

               end if;

            --  Case where original form of subscript is more complex

            else
               --  Build string X'First - 1 + expression where the expression
               --  is the original subscript. If the expression starts with "1
               --  + ", then the "- 1 + 1" is elided.

               Error_Msg_String (1 .. 13) := "'First - 1 + ";
               Error_Msg_Strlen := 13;

               declare
                  Sref : Source_Ptr := Sloc (First_Node (Original_Node (X)));
                  Tref : constant Source_Buffer_Ptr :=
                           Source_Text (Get_Source_File_Index (Sref));
                  --  Tref (Sref) is used to scan the subscript

                  Pctr : Natural;
                  --  Parentheses counter when scanning subscript

               begin
                  --  Tref (Sref) points to start of subscript

                  --  Elide - 1 if subscript starts with 1 +

                  if Tref (Sref .. Sref + 2) = "1 +" then
                     Error_Msg_Strlen := Error_Msg_Strlen - 6;
                     Sref := Sref + 2;

                  elsif Tref (Sref .. Sref + 1) = "1+" then
                     Error_Msg_Strlen := Error_Msg_Strlen - 6;
                     Sref := Sref + 1;
                  end if;

                  --  Now we will copy the subscript to the string buffer

                  Pctr := 0;
                  loop
                     --  Count parens, exit if terminating right paren. Note
                     --  check to ignore paren appearing as character literal.

                     if Tref (Sref + 1) = '''
                          and then
                        Tref (Sref - 1) = '''
                     then
                        null;
                     else
                        if Tref (Sref) = '(' then
                           Pctr := Pctr + 1;
                        elsif Tref (Sref) = ')' then
                           exit when Pctr = 0;
                           Pctr := Pctr - 1;
                        end if;
                     end if;

                     --  Done if terminating double dot (slice case)

                     exit when Pctr = 0
                       and then (Tref (Sref .. Sref + 1) = ".."
                                   or else
                                 Tref (Sref .. Sref + 2) = " ..");

                     --  Quit if we have hit EOF character, something wrong

                     if Tref (Sref) = EOF then
                        return;
                     end if;

                     --  String literals are too much of a pain to handle

                     if Tref (Sref) = '"' or else Tref (Sref) = '%' then
                        return;
                     end if;

                     --  If we have a 'Range reference, then this is a case
                     --  where we cannot easily give a replacement. Don't try.

                     if Tref (Sref .. Sref + 4) = "range"
                       and then Tref (Sref - 1) < 'A'
                       and then Tref (Sref + 5) < 'A'
                     then
                        return;
                     end if;

                     --  Else store next character

                     Error_Msg_Strlen := Error_Msg_Strlen + 1;
                     Error_Msg_String (Error_Msg_Strlen) := Tref (Sref);
                     Sref := Sref + 1;

                     --  If we get more than 40 characters then the expression
                     --  is too long to copy, or something has gone wrong. In
                     --  either case, just skip the attempt at a suggested fix.

                     if Error_Msg_Strlen > 40 then
                        return;
                     end if;
                  end loop;
               end;

               --  Replacement subscript is now in string buffer

               Error_Msg_FE -- CODEFIX
                 ("\?w?suggested replacement: `&~`", Original_Node (X), Ent);
            end if;
         end Warn_On_Literal_Index;

      --  Start of processing for Test_Suspicious_Index

      begin
         --  Nothing to do if subscript does not come from source (we don't
         --  want to give garbage warnings on compiler expanded code, e.g. the
         --  loops generated for slice assignments. Such junk warnings would
         --  be placed on source constructs with no subscript in sight).

         if not Comes_From_Source (Original_Node (X)) then
            return;
         end if;

         --  Case where subscript is a constant integer

         if Nkind (X) = N_Integer_Literal then

            --  Case where subscript is lower than the lowest possible bound.
            --  This might be the case for example when programmers try to
            --  access a string at index 0, as they are used to in other
            --  programming languages like C.

            if Intval (X) < Low_Bound then
               Warn_On_Index_Below_Lower_Bound;
            else
               Warn_On_Literal_Index;
            end if;

         --  Case where subscript is of the form X'Length

         elsif Length_Reference (X) then
            Warn1;
            Error_Msg_Node_2 := Ent;
            Error_Msg_FE
              ("\?w?suggest replacement of `&''Length` by `&''Last`",
               X, Ent);

         --  Case where subscript is of the form X'Length - expression

         elsif Nkind (X) = N_Op_Subtract
           and then Length_Reference (Left_Opnd (X))
         then
            Warn1;
            Error_Msg_Node_2 := Ent;
            Error_Msg_FE
              ("\?w?suggest replacement of `&''Length` by `&''Last`",
               Left_Opnd (X), Ent);
         end if;
      end Test_Suspicious_Index;

   --  Start of processing for Warn_On_Suspicious_Index

   begin
      --  Only process if warnings activated

      if Warn_On_Assumed_Low_Bound then

         --  Test if array is simple entity name

         if Is_Entity_Name (Name) then

            --  Test if array is parameter of unconstrained string type

            Ent := Entity (Name);
            Typ := Etype (Ent);

            if Is_Formal (Ent)
              and then Is_Suspicious_Type (Typ)
              and then not Low_Bound_Tested (Ent)
            then
               Test_Suspicious_Index;
            end if;
         end if;
      end if;
   end Warn_On_Suspicious_Index;

   -------------------------------
   -- Warn_On_Suspicious_Update --
   -------------------------------

   procedure Warn_On_Suspicious_Update (N : Node_Id) is
      Par : constant Node_Id := Parent (N);
      Arg : Node_Id;

   begin
      --  Only process if warnings activated

      if Warn_On_Suspicious_Contract then
         if Nkind (Par) in N_Op_Eq | N_Op_Ne then
            if N = Left_Opnd (Par) then
               Arg := Right_Opnd (Par);
            else
               Arg := Left_Opnd (Par);
            end if;

            if Same_Object (Prefix (N), Arg) then
               if Nkind (Par) = N_Op_Eq then
                  Error_Msg_N
                    ("suspicious equality test with modified version of "
                     & "same object?.t?", Par);
               else
                  Error_Msg_N
                    ("suspicious inequality test with modified version of "
                     & "same object?.t?", Par);
               end if;
            end if;
         end if;
      end if;
   end Warn_On_Suspicious_Update;

   --------------------------------------
   -- Warn_On_Unassigned_Out_Parameter --
   --------------------------------------

   procedure Warn_On_Unassigned_Out_Parameter
     (Return_Node : Node_Id;
      Scope_Id    : Entity_Id)
   is
      Form : Entity_Id;

   begin
      --  Ignore if procedure or return statement does not come from source

      if not Comes_From_Source (Scope_Id)
        or else not Comes_From_Source (Return_Node)
      then
         return;
      end if;

      --  Before we issue the warning, add an ad hoc defence against the most
      --  common case of false positives with this warning which is the case
      --  where there is a Boolean OUT parameter that has been set, and whose
      --  meaning is "ignore the values of the other parameters". We can't of
      --  course reliably tell this case at compile time, but the following
      --  test kills a lot of false positives, without generating a significant
      --  number of false negatives (missed real warnings).

      Form := First_Formal (Scope_Id);
      while Present (Form) loop
         if Ekind (Form) = E_Out_Parameter
           and then Root_Type (Etype (Form)) = Standard_Boolean
           and then not Never_Set_In_Source_Check_Spec (Form)
         then
            return;
         end if;

         Next_Formal (Form);
      end loop;

      --  Loop through formals

      Form := First_Formal (Scope_Id);
      while Present (Form) loop

         --  We are only interested in OUT parameters that come from source
         --  and are never set in the source, and furthermore only in scalars
         --  since non-scalars generate too many false positives.

         if Ekind (Form) = E_Out_Parameter
           and then Never_Set_In_Source_Check_Spec (Form)
           and then Is_Scalar_Type (Etype (Form))
           and then not Present (Unset_Reference (Form))
         then
            --  Here all conditions are met, record possible unset reference

            Set_Unset_Reference (Form, Return_Node);
         end if;

         Next_Formal (Form);
      end loop;
   end Warn_On_Unassigned_Out_Parameter;

   ---------------------------------
   -- Warn_On_Unreferenced_Entity --
   ---------------------------------

   procedure Warn_On_Unreferenced_Entity
     (Spec_E : Entity_Id;
      Body_E : Entity_Id := Empty)
   is
      E : Entity_Id := Spec_E;

   begin
      if not Referenced_Check_Spec (E)
        and then not Has_Pragma_Unreferenced_Check_Spec (E)
        and then not Warnings_Off_Check_Spec (E)
        and then not Has_Junk_Name (Spec_E)
        and then not Is_Exported (Spec_E)
      then
         case Ekind (E) is
            when E_Variable =>

               --  Case of variable that is assigned but not read. We suppress
               --  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) 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))
                  then
                     if not Has_Pragma_Unmodified_Check_Spec (E) then
                        Error_Msg_N -- CODEFIX
                          ("?m?variable & is assigned but never read!", E);
                     end if;

                     Set_Last_Assignment (E, Empty);
                  end if;

               --  Normal case of neither assigned nor read (exclude variables
               --  referenced as out parameters, since we already generated
               --  appropriate warnings at the call point in this case).

               elsif not Referenced_As_Out_Parameter (E) then

                  --  We suppress the message for types for which a valid
                  --  pragma Unreferenced_Objects has been given, otherwise
                  --  we go ahead and give the message.

                  if not Has_Pragma_Unreferenced_Objects (Etype (E)) then

                     --  Distinguish renamed case in message

                     if Present (Renamed_Object (E))
                       and then Comes_From_Source (Renamed_Object (E))
                     then
                        Error_Msg_N -- CODEFIX
                          ("?u?renamed variable & is not referenced!", E);
                     else
                        Error_Msg_N -- CODEFIX
                          ("?u?variable & is not referenced!", E);
                     end if;
                  end if;
               end if;

            when E_Constant =>
               if not Has_Pragma_Unreferenced_Objects (Etype (E)) then
                  if Present (Renamed_Object (E))
                    and then Comes_From_Source (Renamed_Object (E))
                  then
                     Error_Msg_N -- CODEFIX
                       ("?u?renamed constant & is not referenced!", E);
                  else
                     Error_Msg_N -- CODEFIX
                       ("?u?constant & is not referenced!", E);
                  end if;
               end if;

            when E_In_Out_Parameter
               | E_In_Parameter
            =>
               --  Do not emit message for formals of a renaming, because they
               --  are never referenced explicitly.

               if Nkind (Original_Node (Unit_Declaration_Node (Scope (E)))) /=
                                          N_Subprogram_Renaming_Declaration
               then
                  --  Suppress this message for an IN OUT parameter of a
                  --  non-scalar type, since it is normal to have only an
                  --  assignment in such a case.

                  if Ekind (E) = E_In_Parameter
                    or else not Referenced_As_LHS_Check_Spec (E)
                    or else Is_Scalar_Type (Etype (E))
                  then
                     if Present (Body_E) then
                        E := Body_E;
                     end if;

                     declare
                        S : Node_Id := Scope (E);
                     begin
                        if Ekind (S) = E_Subprogram_Body then
                           S := Parent (S);

                           while Nkind (S) not in
                             N_Expression_Function             |
                             N_Subprogram_Body                 |
                             N_Subprogram_Renaming_Declaration |
                             N_Empty
                           loop
                              S := Parent (S);
                           end loop;

                           if Present (S) then
                              S := Corresponding_Spec (S);
                           end if;
                        end if;

                        --  Do not warn for dispatching operations, because
                        --  that causes too much noise. Also do not warn for
                        --  trivial subprograms (e.g. stubs).

                        if (No (S) or else not Is_Dispatching_Operation (S))
                          and then not Is_Trivial_Subprogram (Scope (E))
                          and then Check_Unreferenced_Formals
                        then
                           Error_Msg_NE -- CODEFIX
                             ("?f?formal parameter & is not referenced!",
                              E, Spec_E);
                        end if;
                     end;
                  end if;
               end if;

            when E_Out_Parameter =>
               null;

            when E_Discriminant =>
               Error_Msg_N ("?u?discriminant & is not referenced!", E);

            when E_Named_Integer
               | E_Named_Real
            =>
               Error_Msg_N -- CODEFIX
                 ("?u?named number & is not referenced!", E);

            when Formal_Object_Kind =>
               Error_Msg_N -- CODEFIX
                 ("?u?formal object & is not referenced!", E);

            when E_Enumeration_Literal =>
               Error_Msg_N -- CODEFIX
                 ("?u?literal & is not referenced!", E);

            when E_Function =>
               Error_Msg_N -- CODEFIX
                 ("?u?function & is not referenced!", E);

            when E_Procedure =>
               Error_Msg_N -- CODEFIX
                 ("?u?procedure & is not referenced!", E);

            when E_Package =>
               Error_Msg_N -- CODEFIX
                 ("?u?package & is not referenced!", E);

            when E_Exception =>
               Error_Msg_N -- CODEFIX
                 ("?u?exception & is not referenced!", E);

            when E_Label =>
               Error_Msg_N -- CODEFIX
                 ("?u?label & is not referenced!", E);

            when E_Generic_Procedure =>
               Error_Msg_N -- CODEFIX
                 ("?u?generic procedure & is never instantiated!", E);

            when E_Generic_Function =>
               Error_Msg_N -- CODEFIX
                 ("?u?generic function & is never instantiated!", E);

            when Type_Kind =>
               Error_Msg_N -- CODEFIX
                 ("?u?type & is not referenced!", E);

            when others =>
               Error_Msg_N -- CODEFIX
                 ("?u?& is not referenced!", E);
         end case;

         --  Kill warnings on the entity on which the message has been posted
         --  (nothing is posted on out parameters because back end might be
         --  able to uncover an uninitialized path, and warn accordingly).

         if Ekind (E) /= E_Out_Parameter then
            Set_Warnings_Off (E);
         end if;
      end if;
   end Warn_On_Unreferenced_Entity;

   --------------------------------
   -- Warn_On_Useless_Assignment --
   --------------------------------

   procedure Warn_On_Useless_Assignment
     (Ent : Entity_Id;
      N   : Node_Id := Empty)
   is
      P    : Node_Id;
      X    : Node_Id;

      function Check_Ref (N : Node_Id) return Traverse_Result;
      --  Used to instantiate Traverse_Func. Returns Abandon if a reference to
      --  the entity in question is found.

      function Test_No_Refs is new Traverse_Func (Check_Ref);

      ---------------
      -- Check_Ref --
      ---------------

      function Check_Ref (N : Node_Id) return Traverse_Result is
      begin
         --  Check reference to our identifier. We use name equality here
         --  because the exception handlers have not yet been analyzed. This
         --  is not quite right, but it really does not matter that we fail
         --  to output the warning in some obscure cases of name clashes.

         if Nkind (N) = N_Identifier and then Chars (N) = Chars (Ent) then
            return Abandon;
         else
            return OK;
         end if;
      end Check_Ref;

   --  Start of processing for Warn_On_Useless_Assignment

   begin
      --  Check if this is a case we want to warn on, a scalar or access
      --  variable with the last assignment field set, with warnings enabled,
      --  and which is not imported or exported. We also check that it is OK
      --  to capture the value. We are not going to capture any value, but
      --  the warning message depends on the same kind of conditions.

      --  If the assignment appears as an out-parameter in a call within an
      --  expression function it may be detected twice: once when expression
      --  itself is analyzed, and once when the constructed body is analyzed.
      --  We don't want to emit a spurious warning in this case.

      if Is_Assignable (Ent)
        and then not Is_Return_Object (Ent)
        and then Present (Last_Assignment (Ent))
        and then Last_Assignment (Ent) /= N
        and then not Is_Imported (Ent)
        and then not Is_Exported (Ent)
        and then Safe_To_Capture_Value (N, Ent)
        and then not Has_Pragma_Unreferenced_Check_Spec (Ent)
        and then not Has_Junk_Name (Ent)
      then
         --  Before we issue the message, check covering exception handlers.
         --  Search up tree for enclosing statement sequences and handlers.

         P := Parent (Last_Assignment (Ent));
         while Present (P) loop

            --  Something is really wrong if we don't find a handled statement
            --  sequence, so just suppress the warning.

            if No (P) then
               Set_Last_Assignment (Ent, Empty);
               return;

            --  When we hit a package/subprogram body, issue warning and exit

            elsif Nkind (P) in N_Entry_Body
                             | N_Package_Body
                             | N_Subprogram_Body
                             | N_Task_Body
            then
               --  Case of assigned value never referenced

               if No (N) then
                  declare
                     LA : constant Node_Id := Last_Assignment (Ent);

                  begin
                     --  Don't give this for OUT and IN OUT formals, since
                     --  clearly caller may reference the assigned value. Also
                     --  never give such warnings for internal variables. In
                     --  either case, word the warning in a conditional way,
                     --  because in the case of a component of a controlled
                     --  type, the assigned value might be referenced in the
                     --  Finalize operation, so we can't make a definitive
                     --  statement that it's never referenced.

                     if Ekind (Ent) = E_Variable
                       and then not Is_Internal_Name (Chars (Ent))
                     then
                        --  Give appropriate message, distinguishing between
                        --  assignment statements and out parameters.

                        if Nkind (Parent (LA)) in N_Parameter_Association
                                                | N_Procedure_Call_Statement
                        then
                           if Warn_On_All_Unread_Out_Parameters then
                              Error_Msg_NE
                                ("?.o?& modified by call, but value might not "
                                 & "be referenced", LA, Ent);
                           end if;
                        else
                           Error_Msg_NE -- CODEFIX
                             ("?m?possibly useless assignment to&, value "
                              & "might not be referenced!", LA, Ent);
                        end if;
                     end if;
                  end;

               --  Case of assigned value overwritten

               else
                  declare
                     LA : constant Node_Id := Last_Assignment (Ent);

                  begin
                     Error_Msg_Sloc := Sloc (N);

                     --  Give appropriate message, distinguishing between
                     --  assignment statements and out parameters.

                     if Nkind (Parent (LA)) in N_Procedure_Call_Statement
                                             | N_Parameter_Association
                     then
                        Error_Msg_NE
                          ("?m?& modified by call, but value overwritten #!",
                           LA, Ent);
                     else
                        Error_Msg_NE -- CODEFIX
                          ("?m?useless assignment to&, value overwritten #!",
                           LA, Ent);
                     end if;
                  end;
               end if;

               --  Clear last assignment indication and we are done

               Set_Last_Assignment (Ent, Empty);
               return;

            --  Enclosing handled sequence of statements

            elsif Nkind (P) = N_Handled_Sequence_Of_Statements then

               --  Check exception handlers present

               if Present (Exception_Handlers (P)) then

                  --  If we are not at the top level, we regard an inner
                  --  exception handler as a decisive indicator that we should
                  --  not generate the warning, since the variable in question
                  --  may be accessed after an exception in the outer block.

                  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;

                     --  Otherwise we are at the outer level. An exception
                     --  handler is significant only if it references the
                     --  variable in question, or if the entity in question
                     --  is an OUT or IN OUT parameter, in which case
                     --  the caller can reference it after the exception
                     --  handler completes.

                  else
                     if Is_Formal (Ent) then
                        Set_Last_Assignment (Ent, Empty);
                        return;

                     else
                        X := First (Exception_Handlers (P));
                        while Present (X) loop
                           if Test_No_Refs (X) = Abandon then
                              Set_Last_Assignment (Ent, Empty);
                              return;
                           end if;

                           Next (X);
                        end loop;
                     end if;
                  end if;
               end if;
            end if;

            P := Parent (P);
         end loop;
      end if;
   end Warn_On_Useless_Assignment;

   ---------------------------------
   -- Warn_On_Useless_Assignments --
   ---------------------------------

   procedure Warn_On_Useless_Assignments (E : Entity_Id) is
      Ent : Entity_Id;

   begin
      if Warn_On_Modified_Unread
        and then In_Extended_Main_Source_Unit (E)
      then
         Ent := First_Entity (E);
         while Present (Ent) loop
            Warn_On_Useless_Assignment (Ent);
            Next_Entity (Ent);
         end loop;
      end if;
   end Warn_On_Useless_Assignments;

   -----------------------------
   -- Warnings_Off_Check_Spec --
   -----------------------------

   function Warnings_Off_Check_Spec (E : Entity_Id) return Boolean is
   begin
      if Is_Formal (E) and then Present (Spec_Entity (E)) then

         --  Note: use of OR here instead of OR ELSE is deliberate, we want
         --  to mess with flags on both entities.

         return Has_Warnings_Off (E)
                  or
                Has_Warnings_Off (Spec_Entity (E));

      else
         return Has_Warnings_Off (E);
      end if;
   end Warnings_Off_Check_Spec;

end Sem_Warn;
