------------------------------------------------------------------------------
--                                                                          --
--                         GNAT COMPILER COMPONENTS                         --
--                                                                          --
--                             S E M _ W A R N                              --
--                                                                          --
--                                 B o d y                                  --
--                                                                          --
--          Copyright (C) 1999-2008, 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 Errout;   use Errout;
with Exp_Code; use Exp_Code;
with Fname;    use Fname;
with Lib;      use Lib;
with Namet;    use Namet;
with Nlists;   use Nlists;
with Opt;      use Opt;
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_Util; use Sem_Util;
with Sinfo;    use Sinfo;
with Sinput;   use Sinput;
with Snames;   use Snames;
with Stand;    use Stand;
with Stringt;  use Stringt;
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 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;

      --  Check multiple code statements in a row

      if Is_List_Member (N)
        and then Present (Prev (N))
        and then Nkind (Prev (N)) = N_Code_Statement
      then
         Error_Msg_F
           ("?code statements in sequence should usually be Volatile!", N);
         Error_Msg_F
           ("\?(suggest using template with multiple instructions)!", N);
      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
      Iter : constant Node_Id := Iteration_Scheme (Loop_Statement);

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

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

      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_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 funny
      --  kludge, 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.

      function Find_Ref 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
         --  Condition is a direct variable reference

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

         --  Case of condition is a comparison with compile time known value

         elsif Nkind (N) in N_Op_Compare 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 condition is a negation, check its operand

         elsif Nkind (N) = N_Op_Not then
            Find_Var (Right_Opnd (N));

         --  Case of condition is function call

         elsif Nkind (N) = N_Function_Call then

            --  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 warnings are suppressed on function entity

            elsif Has_Warnings_Off (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_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_Descendent_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
         S : Entity_Id;

         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;

      --  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 iteration scheme

         if N = Iter 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 May_Be_Lvalue (N) then
               return Abandon;
            end if;

            --  If we appear in the context of a procedure call, then also
            --  abandon, since there may be issues of non-visible side
            --  effects going on in the call.

            declare
               P : Node_Id;

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

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

            --  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 May_Be_Lvalue (N)
         then
            return Abandon;

            --  Call to subprogram

         elsif Nkind (N) = N_Procedure_Call_Statement
           or else Nkind (N) = N_Function_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;
         end if;

         --  All OK, continue scan

         return OK;
      end Test_Ref;

   --  Start of processing for Check_Infinite_Loop_Warning

   begin
      --  We need a while iteration with no condition actions. Conditions
      --  actions just make things too complicated to get the warning right.

      if No (Iter)
        or else No (Condition (Iter))
        or else Present (Condition_Actions (Iter))
        or else Debug_Flag_Dot_W
      then
         return;
      end if;

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

      Find_Var (Condition (Iter));

      --  Nothing to do if local variable from source not found

      if No (Var)
        or else Ekind (Var) /= E_Variable
        or else Is_Library_Level_Entity (Var)
        or else not Comes_From_Source (Var)
      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).

      elsif 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) = N_Delay_Relative_Statement
           or else Nkind (Fstm) = N_Delay_Until_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 Find_Ref (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_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 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;

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

         if Is_Internal_Name (Chars (E1)) 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_Package_Body    |
                    N_Task_Body       |
                    N_Entry_Body      |
                    N_Protected_Body  |
                    N_Block_Statement |
                    N_Subunit         =>
                  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.

         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) = E_Out_Parameter
                    or else Ekind (E1) = E_In_Out_Parameter)
                  and then not Is_Protected_Type (Current_Scope))
            then
               --  Case of an unassigned variable

               --  First gather any Unset_Reference indication for E1. In the
               --  case of a 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.

               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 Address_Taken (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).

                  if (Is_Volatile (E1) or else Has_Volatile_Components (E1))
                    and then not Is_Imported (E1)
                  then
                     Error_Msg_N
                       ("?& is not modified, volatile has no effect!", 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 then
                              Error_Msg_N
                                ("?& 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 warning for this case turned off

                  and then Warn_On_No_Value_Assigned

                  --  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, of
                  --  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 containing any
                     --  access element component, since the logical effect
                     --  of modifying a parameter may be achieved by modifying
                     --  a referenced entity.

                     elsif Is_Composite_Type (E1T)
                       and then Has_Access_Values (E1T)
                     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.

                     else
                        In_Out_Warnings.Append (E1);
                     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
                           then
                              Output_Reference_Error
                                ("?formal parameter& is read but "
                                 & "never assigned!");
                           end if;

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

                  --  Case of variable

                  else
                     if Referenced (E1) then
                        if not Has_Unmodified (E1)
                          and then not Warnings_Off_E1
                        then
                           Output_Reference_Error
                             ("?variable& is read but never assigned!");
                        end if;

                     elsif not Has_Unreferenced (E1)
                       and then not Warnings_Off_E1
                     then
                        Output_Reference_Error
                          ("?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
                     then
                        Error_Msg_N
                          ("?for loop implicitly declares loop variable!",
                           Hiding_Loop_Variable (E1));

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

                  goto Continue;
               end if;

               --  Check for unset reference

               if Warn_On_No_Value_Assigned and then Present (UR) 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
                  --  or qualification, and in this case we want the object
                  --  entity inside.

                  UR := Original_Node (UR);
                  while Nkind (UR) = N_Type_Conversion
                    or else Nkind (UR) = N_Qualified_Expression
                  loop
                     UR := Expression (UR);
                  end loop;

                  --  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 then
                           Error_Msg_NE
                             ("?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
                        Error_Msg_Node_2 := Selector_Name (Parent (UR));

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

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

                                 Next_Entity (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 Is_Trivial_Subprogram (Scope (E1)) then
                           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;
                        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 error.

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

               --  Labels, and enumeration literals, and exceptions. The
               --  warnings are also placed on 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) = E_Exception
                           or else
                         Ekind (E1) = E_Named_Integer
                           or else
                         Ekind (E1) = 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)
                           or else not Is_Task_Type (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
                   Is_Internal_File_Name
                     (Unit_File_Name (Get_Source_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 then
                     Unreferenced_Entities.Append (E1);
                  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 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;
         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, certainly need 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 (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_Identifier | N_Expanded_Name =>
            declare
               E : constant Entity_Id := Entity (N);

            begin
               if (Ekind (E) = E_Variable
                     or else
                   Ekind (E) = 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
                                (Sloc (N),  Sloc (Unset_Reference (E))))
                 and then not Has_Pragma_Unmodified_Check_Spec (E)
                 and then not Warnings_Off_Check_Spec (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 via 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!

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

                  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 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 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) = N_If_Statement
                                     or else
                                   Nkind (P) = 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;

                     --  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 we set the Unset_Reference
                     --  field of 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;
               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;

         --  For type conversions or qualifications examine the expression

         when N_Type_Conversion | N_Qualified_Expression =>
            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
      Cnode : Node_Id;
      Item  : Node_Id;
      Lunit : Node_Id;
      Ent   : Entity_Id;

      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
         Is_Visible_Renaming : Boolean := False;
         Pack                : Entity_Id;

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

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

         procedure Check_Inner_Package (Pack : Entity_Id) is
            E  : Entity_Id;
            Un : constant Node_Id := Sinfo.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
               Nam  : Node_Id;

            begin
               if Nkind (N) = N_Use_Package_Clause then
                  Nam := First (Names (N));
                  while Present (Nam) loop
                     if Entity (Nam) = Pack then
                        Error_Msg_Qual_Level := 1;
                        Error_Msg_NE
                          ("?no entities of package& are referenced!",
                             Nam, Pack);
                        Error_Msg_Qual_Level := 0;
                     end if;

                     Next (Nam);
                  end loop;
               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 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_Object (E1) = L
               then
                  Is_Visible_Renaming := not Is_Hidden (E1);
                  return E1;

               elsif Ekind (E1) = E_Package
                 and then No (Renamed_Object (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;

      --  Start of processing for Check_One_Unit

      begin
         Cnode := Cunit (Unit);

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

         --  In configurable run time mode, we remove the bodies of non-inlined
         --  subprograms, which may lead to spurious warnings, which are
         --  clearly undesirable.

         elsif Configurable_Run_Time_Mode
           and then Is_Predefined_File_Name (Unit_File_Name (Unit))
         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)
            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_File_Name (Unit_File_Name (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

                     else
                        Error_Msg_N
                          ("?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 then
                              null;

                           --  Else give the warning

                           else
                              if not
                                Has_Unreferenced (Entity (Name (Item)))
                              then
                                 Error_Msg_N
                                   ("?no entities of & are referenced!",
                                    Name (Item));
                              end if;

                              --  Look for renamings of this package, and flag
                              --  them as well. If the original package has
                              --  warnings off, we suppress the warning on the
                              --  renaming as well.

                              Pack := Find_Package_Renaming (Munite, Lunit);

                              if Present (Pack)
                                and then not Has_Warnings_Off (Lunit)
                                and then not Has_Unreferenced (Pack)
                              then
                                 Error_Msg_NE
                                   ("?no entities of & are referenced!",
                                     Unit_Declaration_Node (Pack),
                                     Pack);
                              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_With_Type (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);
                           end if;

                           if Unreferenced_In_Spec (Item) then
                              Error_Msg_N
                                ("?unit& is not referenced in spec!",
                                 Name (Item));

                           elsif No_Entities_Ref_In_Spec (Item) then
                              Error_Msg_N
                                ("?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
                                ("\?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
                          ("?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
                       ("?unit& is not instantiated in spec!", Name (Item));
                     Error_Msg_N
                       ("\?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
      if not Opt.Check_Withs
        or else Operating_Mode = Check_Syntax
      then
         return;
      end if;

      --  Flag any unused with clauses, but skip this step if we are compiling
      --  a subunit on its own, since we do not have enough information to
      --  determine whether with's are used. We will get the relevant warnings
      --  when we compile the parent. This is the normal style of GNAT
      --  compilation in any case.

      if Nkind (Unit (Cunit (Main_Unit))) = N_Subunit then
         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_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.

         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;

   ------------------------------------
   -- 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 =>
         return False;
   end Operand_Has_Warnings_Suppressed;

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

   procedure Output_Non_Modifed_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
      --  modifies 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 -gnatwc is set then output message that we could be IN

               if not Is_Trivial_Subprogram (Scope (E1)) then
                  if Warn_On_Constant then
                     Error_Msg_N
                       ("?formal parameter & is not modified!", E1);
                     Error_Msg_N
                       ("\?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 ("?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_Modifed_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
              ("?with of obsolescent package& declared#", N, E);
         elsif Ekind (E) = E_Procedure then
            Error_Msg_NE
              ("?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) = E_Component
        or else Ekind (E) = 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
                 ("?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
                 ("?could use Unreferenced instead of "
                  & "Warnings Off for &", Pragma_Identifier (N), E);

            --  Not used at all

            else
               Error_Msg_NE
                 ("?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;

   ----------------------------
   -- Set_Dot_Warning_Switch --
   ----------------------------

   function Set_Dot_Warning_Switch (C : Character) return Boolean is
   begin
      case C is
         when 'a' =>
            Warn_On_Assertion_Failure           := True;

         when 'A' =>
            Warn_On_Assertion_Failure           := False;

         when 'b' =>
            Warn_On_Biased_Representation       := True;

         when 'B' =>
            Warn_On_Biased_Representation       := False;

         when 'c' =>
            Warn_On_Unrepped_Components         := True;

         when 'C' =>
            Warn_On_Unrepped_Components         := False;

         when 'e' =>
            Address_Clause_Overlay_Warnings     := True;
            Check_Unreferenced                  := True;
            Check_Unreferenced_Formals          := True;
            Check_Withs                         := True;
            Constant_Condition_Warnings         := True;
            Elab_Warnings                       := True;
            Implementation_Unit_Warnings        := True;
            Ineffective_Inline_Warnings         := True;
            Warn_On_Ada_2005_Compatibility      := True;
            Warn_On_All_Unread_Out_Parameters   := True;
            Warn_On_Assertion_Failure           := True;
            Warn_On_Assumed_Low_Bound           := True;
            Warn_On_Bad_Fixed_Value             := True;
            Warn_On_Biased_Representation       := True;
            Warn_On_Constant                    := True;
            Warn_On_Deleted_Code                := True;
            Warn_On_Dereference                 := True;
            Warn_On_Export_Import               := True;
            Warn_On_Hiding                      := True;
            Warn_On_Modified_Unread             := True;
            Warn_On_No_Value_Assigned           := True;
            Warn_On_Non_Local_Exception         := True;
            Warn_On_Object_Renames_Function     := True;
            Warn_On_Obsolescent_Feature         := True;
            Warn_On_Questionable_Missing_Parens := True;
            Warn_On_Redundant_Constructs        := True;
            Warn_On_Unchecked_Conversion        := True;
            Warn_On_Unrecognized_Pragma         := True;
            Warn_On_Unrepped_Components         := True;
            Warn_On_Warnings_Off                := True;

         when 'o' =>
            Warn_On_All_Unread_Out_Parameters   := True;

         when 'O' =>
            Warn_On_All_Unread_Out_Parameters   := False;

         when 'p' =>
            Warn_On_Parameter_Order             := True;

         when 'P' =>
            Warn_On_Parameter_Order             := False;

         when 'r' =>
            Warn_On_Object_Renames_Function     := True;

         when 'R' =>
            Warn_On_Object_Renames_Function     := False;

         when 'w' =>
            Warn_On_Warnings_Off                := True;

         when 'W' =>
            Warn_On_Warnings_Off                := False;

         when 'x' =>
            Warn_On_Non_Local_Exception         := True;

         when 'X' =>
            Warn_On_Non_Local_Exception         := False;

         when others =>
            return False;
      end case;

      return True;
   end Set_Dot_Warning_Switch;

   ------------------------
   -- Set_Warning_Switch --
   ------------------------

   function Set_Warning_Switch (C : Character) return Boolean is
   begin
      case C is
         when 'a' =>
            Check_Unreferenced                  := True;
            Check_Unreferenced_Formals          := True;
            Check_Withs                         := True;
            Constant_Condition_Warnings         := True;
            Implementation_Unit_Warnings        := True;
            Ineffective_Inline_Warnings         := True;
            Warn_On_Ada_2005_Compatibility      := True;
            Warn_On_Assertion_Failure           := True;
            Warn_On_Assumed_Low_Bound           := True;
            Warn_On_Bad_Fixed_Value             := True;
            Warn_On_Biased_Representation       := True;
            Warn_On_Constant                    := True;
            Warn_On_Export_Import               := True;
            Warn_On_Modified_Unread             := True;
            Warn_On_No_Value_Assigned           := True;
            Warn_On_Non_Local_Exception         := True;
            Warn_On_Object_Renames_Function     := True;
            Warn_On_Obsolescent_Feature         := True;
            Warn_On_Parameter_Order             := True;
            Warn_On_Questionable_Missing_Parens := True;
            Warn_On_Redundant_Constructs        := True;
            Warn_On_Unchecked_Conversion        := True;
            Warn_On_Unrecognized_Pragma         := True;
            Warn_On_Unrepped_Components         := True;

         when 'A' =>
            Check_Unreferenced                  := False;
            Check_Unreferenced_Formals          := False;
            Check_Withs                         := False;
            Constant_Condition_Warnings         := False;
            Elab_Warnings                       := False;
            Implementation_Unit_Warnings        := False;
            Ineffective_Inline_Warnings         := False;
            Warn_On_Ada_2005_Compatibility      := False;
            Warn_On_Assertion_Failure           := False;
            Warn_On_Assumed_Low_Bound           := False;
            Warn_On_Bad_Fixed_Value             := False;
            Warn_On_Biased_Representation       := False;
            Warn_On_Constant                    := False;
            Warn_On_Deleted_Code                := False;
            Warn_On_Dereference                 := False;
            Warn_On_Export_Import               := False;
            Warn_On_Hiding                      := False;
            Warn_On_Modified_Unread             := False;
            Warn_On_No_Value_Assigned           := False;
            Warn_On_Non_Local_Exception         := False;
            Warn_On_Obsolescent_Feature         := False;
            Warn_On_All_Unread_Out_Parameters   := False;
            Warn_On_Parameter_Order             := False;
            Warn_On_Questionable_Missing_Parens := False;
            Warn_On_Redundant_Constructs        := False;
            Warn_On_Object_Renames_Function     := False;
            Warn_On_Unchecked_Conversion        := False;
            Warn_On_Unrecognized_Pragma         := False;
            Warn_On_Unrepped_Components         := False;
            Warn_On_Warnings_Off                := False;

         when 'b' =>
            Warn_On_Bad_Fixed_Value             := True;

         when 'B' =>
            Warn_On_Bad_Fixed_Value             := False;

         when 'c' =>
            Constant_Condition_Warnings         := True;

         when 'C' =>
            Constant_Condition_Warnings         := False;

         when 'd' =>
            Warn_On_Dereference                 := True;

         when 'D' =>
            Warn_On_Dereference                 := False;

         when 'e' =>
            Warning_Mode                        := Treat_As_Error;

         when 'f' =>
            Check_Unreferenced_Formals          := True;

         when 'F' =>
            Check_Unreferenced_Formals          := False;

         when 'g' =>
            Warn_On_Unrecognized_Pragma         := True;

         when 'G' =>
            Warn_On_Unrecognized_Pragma         := False;

         when 'h' =>
            Warn_On_Hiding                      := True;

         when 'H' =>
            Warn_On_Hiding                      := False;

         when 'i' =>
            Implementation_Unit_Warnings        := True;

         when 'I' =>
            Implementation_Unit_Warnings        := False;

         when 'j' =>
            Warn_On_Obsolescent_Feature         := True;

         when 'J' =>
            Warn_On_Obsolescent_Feature         := False;

         when 'k' =>
            Warn_On_Constant                    := True;

         when 'K' =>
            Warn_On_Constant                    := False;

         when 'l' =>
            Elab_Warnings                       := True;

         when 'L' =>
            Elab_Warnings                       := False;

         when 'm' =>
            Warn_On_Modified_Unread             := True;

         when 'M' =>
            Warn_On_Modified_Unread             := False;

         when 'n' =>
            Warning_Mode                        := Normal;

         when 'o' =>
            Address_Clause_Overlay_Warnings     := True;

         when 'O' =>
            Address_Clause_Overlay_Warnings     := False;

         when 'p' =>
            Ineffective_Inline_Warnings         := True;

         when 'P' =>
            Ineffective_Inline_Warnings         := False;

         when 'q' =>
            Warn_On_Questionable_Missing_Parens := True;

         when 'Q' =>
            Warn_On_Questionable_Missing_Parens := False;

         when 'r' =>
            Warn_On_Redundant_Constructs        := True;

         when 'R' =>
            Warn_On_Redundant_Constructs        := False;

         when 's' =>
            Warning_Mode                        := Suppress;

         when 't' =>
            Warn_On_Deleted_Code                := True;

         when 'T' =>
            Warn_On_Deleted_Code                := False;

         when 'u' =>
            Check_Unreferenced                  := True;
            Check_Withs                         := True;
            Check_Unreferenced_Formals          := True;

         when 'U' =>
            Check_Unreferenced                  := False;
            Check_Withs                         := False;
            Check_Unreferenced_Formals          := False;

         when 'v' =>
            Warn_On_No_Value_Assigned           := True;

         when 'V' =>
            Warn_On_No_Value_Assigned           := False;

         when 'w' =>
            Warn_On_Assumed_Low_Bound           := True;

         when 'W' =>
            Warn_On_Assumed_Low_Bound           := False;

         when 'x' =>
            Warn_On_Export_Import               := True;

         when 'X' =>
            Warn_On_Export_Import               := False;

         when 'y' =>
            Warn_On_Ada_2005_Compatibility      := True;

         when 'Y' =>
            Warn_On_Ada_2005_Compatibility      := False;

         when 'z' =>
            Warn_On_Unchecked_Conversion        := True;

         when 'Z' =>
            Warn_On_Unchecked_Conversion        := False;

         when others =>
            return False;
      end case;

      return True;
   end Set_Warning_Switch;

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

   procedure Warn_On_Known_Condition (C : Node_Id) is
      P : Node_Id;

      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.

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

   --  Start of processing for Warn_On_Known_Condition

   begin
      --   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 Nkind (C) = N_Identifier
        and then
          (Entity (C) = Standard_False or else Entity (C) = Standard_True)
        and then Comes_From_Source (Original_Node (C))
        and then not In_Instance
      then
         --  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 (Original_Node (P)) = Name_Assert
                          or else
                        Pragma_Name (Original_Node (P)) = 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 := Entity (C) = Standard_True;
               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;

               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?", Cond, Original_Node (C));
                     Track (Original_Node (C), Cond);

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

               else
                  Error_Msg_N ("condition is always False?", Cond);
                  Track (Cond, Cond);
               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_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 (Root_Type (Typ) = Standard_String
                       or else
                     Root_Type (Typ) = Standard_Wide_String
                       or else
                     Root_Type (Typ) = Standard_Wide_Wide_String)
           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

         ----------------------
         -- 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 ("?index for& may assume lower bound of^", X, Ent);
         end Warn1;

      --  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
            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
                    ("\suggested replacement: `&''First`", X, Ent);
               else
                  Error_Msg_Uint_1 := Intval (X) - Low_Bound;
                  Error_Msg_FE
                    ("\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
                 ("\suggested replacement: `&~`", Original_Node (X), Ent);
            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
              ("\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
              ("\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_Known (Ent)
            then
               Test_Suspicious_Index;
            end if;
         end if;
      end if;
   end Warn_On_Suspicious_Index;

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

   procedure Warn_On_Unassigned_Out_Parameter
     (Return_Node : Node_Id;
      Scope_Id    : Entity_Id)
   is
      Form  : Entity_Id;
      Form2 : 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;

      --  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
            --  Before we issue the warning, an add 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).

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

               Next_Formal (Form2);
            end loop;

            --  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)
      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)
                 and then No (Address_Clause (E))
                 and then not Is_Volatile (E)
               then
                  if Warn_On_Modified_Unread
                    and then not Is_Imported (E)
                    and then not Is_Return_Object (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
                          ("?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
                          ("?renamed variable & is not referenced!", E);
                     else
                        Error_Msg_N
                          ("?variable & is not referenced!", E);
                     end if;
                  end if;
               end if;

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

            when E_In_Parameter     |
                 E_In_Out_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 (E)
                  then
                     if Present (Body_E) then
                        E := Body_E;
                     end if;

                     if not Is_Trivial_Subprogram (Scope (E)) then
                        Error_Msg_NE
                          ("?formal parameter & is not referenced!",
                           E, Spec_E);
                     end if;
                  end if;
               end if;

            when E_Out_Parameter    =>
               null;

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

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

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

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

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

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

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

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

         --  Kill warnings on the entity on which the message has been posted

         Set_Warnings_Off (E);
      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 messages depends on the same kind of conditions.

      if Is_Assignable (Ent)
        and then not Is_Return_Object (Ent)
        and then Present (Last_Assignment (Ent))
        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)
      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) = N_Subprogram_Body
              or else Nkind (P) = N_Package_Body
            then
               --  Case of assigned value never referenced

               if No (N) then

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

                  if Ekind (Ent) = E_Variable
                    and then not Is_Internal_Name (Chars (Ent))
                  then
                     if Referenced_As_Out_Parameter (Ent) then
                        Error_Msg_NE
                          ("?& modified by call, but value never referenced",
                           Last_Assignment (Ent), Ent);
                     else
                        Error_Msg_NE
                          ("?useless assignment to&, value never referenced!",
                           Last_Assignment (Ent), Ent);
                     end if;
                  end if;

               --  Case of assigned value overwritten

               else
                  Error_Msg_Sloc := Sloc (N);

                  if Referenced_As_Out_Parameter (Ent) then
                     Error_Msg_NE
                       ("?& modified by call, but value overwritten #!",
                        Last_Assignment (Ent), Ent);
                  else
                     Error_Msg_NE
                       ("?useless assignment to&, value overwritten #!",
                        Last_Assignment (Ent), Ent);
                  end if;
               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)) /= N_Subprogram_Body
                    and then Nkind (Parent (P)) /= N_Package_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.

                  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;

                        X := Next (X);
                     end loop;
                  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;
