1------------------------------------------------------------------------------
2--                                                                          --
3--                         GNAT COMPILER COMPONENTS                         --
4--                                                                          --
5--                             S E M _ W A R N                              --
6--                                                                          --
7--                                 B o d y                                  --
8--                                                                          --
9--          Copyright (C) 1999-2015, Free Software Foundation, Inc.         --
10--                                                                          --
11-- GNAT is free software;  you can  redistribute it  and/or modify it under --
12-- terms of the  GNU General Public License as published  by the Free Soft- --
13-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
14-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
15-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
16-- or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License --
17-- for  more details.  You should have  received  a copy of the GNU General --
18-- Public License  distributed with GNAT; see file COPYING3.  If not, go to --
19-- http://www.gnu.org/licenses for a complete copy of the license.          --
20--                                                                          --
21-- GNAT was originally developed  by the GNAT team at  New York University. --
22-- Extensive contributions were provided by Ada Core Technologies Inc.      --
23--                                                                          --
24------------------------------------------------------------------------------
25
26with Atree;    use Atree;
27with Debug;    use Debug;
28with Einfo;    use Einfo;
29with Errout;   use Errout;
30with Exp_Code; use Exp_Code;
31with Fname;    use Fname;
32with Lib;      use Lib;
33with Lib.Xref; use Lib.Xref;
34with Namet;    use Namet;
35with Nlists;   use Nlists;
36with Opt;      use Opt;
37with Par_SCO;  use Par_SCO;
38with Rtsfind;  use Rtsfind;
39with Sem;      use Sem;
40with Sem_Ch8;  use Sem_Ch8;
41with Sem_Aux;  use Sem_Aux;
42with Sem_Eval; use Sem_Eval;
43with Sem_Prag; use Sem_Prag;
44with Sem_Util; use Sem_Util;
45with Sinfo;    use Sinfo;
46with Sinput;   use Sinput;
47with Snames;   use Snames;
48with Stand;    use Stand;
49with Stringt;  use Stringt;
50with Uintp;    use Uintp;
51
52package body Sem_Warn is
53
54   --  The following table collects Id's of entities that are potentially
55   --  unreferenced. See Check_Unset_Reference for further details.
56   --  ??? Check_Unset_Reference has zero information about this table.
57
58   package Unreferenced_Entities is new Table.Table (
59     Table_Component_Type => Entity_Id,
60     Table_Index_Type     => Nat,
61     Table_Low_Bound      => 1,
62     Table_Initial        => Alloc.Unreferenced_Entities_Initial,
63     Table_Increment      => Alloc.Unreferenced_Entities_Increment,
64     Table_Name           => "Unreferenced_Entities");
65
66   --  The following table collects potential warnings for IN OUT parameters
67   --  that are referenced but not modified. These warnings are processed when
68   --  the front end calls the procedure Output_Non_Modified_In_Out_Warnings.
69   --  The reason that we defer output of these messages is that we want to
70   --  detect the case where the relevant procedure is used as a generic actual
71   --  in an instantiation, since we suppress the warnings in this case. The
72   --  flag Used_As_Generic_Actual will be set in this case, but only at the
73   --  point of usage. Similarly, we suppress the message if the address of the
74   --  procedure is taken, where the flag Address_Taken may be set later.
75
76   package In_Out_Warnings is new Table.Table (
77     Table_Component_Type => Entity_Id,
78     Table_Index_Type     => Nat,
79     Table_Low_Bound      => 1,
80     Table_Initial        => Alloc.In_Out_Warnings_Initial,
81     Table_Increment      => Alloc.In_Out_Warnings_Increment,
82     Table_Name           => "In_Out_Warnings");
83
84   --------------------------------------------------------
85   -- Handling of Warnings Off, Unmodified, Unreferenced --
86   --------------------------------------------------------
87
88   --  The functions Has_Warnings_Off, Has_Unmodified, Has_Unreferenced must
89   --  generally be used instead of Warnings_Off, Has_Pragma_Unmodified and
90   --  Has_Pragma_Unreferenced, as noted in the specs in Einfo.
91
92   --  In order to avoid losing warnings in -gnatw.w (warn on unnecessary
93   --  warnings off pragma) mode, i.e. to avoid false negatives, the code
94   --  must follow some important rules.
95
96   --  Call these functions as late as possible, after completing all other
97   --  tests, just before the warnings is given. For example, don't write:
98
99   --     if not Has_Warnings_Off (E)
100   --       and then some-other-predicate-on-E then ..
101
102   --  Instead the following is preferred
103
104   --     if some-other-predicate-on-E
105   --       and then Has_Warnings_Off (E)
106
107   --  This way if some-other-predicate is false, we avoid a false indication
108   --  that a Warnings (Off, E) pragma was useful in preventing a warning.
109
110   --  The second rule is that if both Has_Unmodified and Has_Warnings_Off, or
111   --  Has_Unreferenced and Has_Warnings_Off are called, make sure that the
112   --  call to Has_Unmodified/Has_Unreferenced comes first, this way we record
113   --  that the Warnings (Off) could have been Unreferenced or Unmodified. In
114   --  fact Has_Unmodified/Has_Unreferenced includes a test for Warnings Off,
115   --  and so a subsequent test is not needed anyway (though it is harmless).
116
117   -----------------------
118   -- Local Subprograms --
119   -----------------------
120
121   function Generic_Package_Spec_Entity (E : Entity_Id) return Boolean;
122   --  This returns true if the entity E is declared within a generic package.
123   --  The point of this is to detect variables which are not assigned within
124   --  the generic, but might be assigned outside the package for any given
125   --  instance. These are cases where we leave the warnings to be posted for
126   --  the instance, when we will know more.
127
128   function Goto_Spec_Entity (E : Entity_Id) return Entity_Id;
129   --  If E is a parameter entity for a subprogram body, then this function
130   --  returns the corresponding spec entity, if not, E is returned unchanged.
131
132   function Has_Pragma_Unmodified_Check_Spec (E : Entity_Id) return Boolean;
133   --  Tests Has_Pragma_Unmodified flag for entity E. If E is not a formal,
134   --  this is simply the setting of the flag Has_Pragma_Unmodified. If E is
135   --  a body formal, the setting of the flag in the corresponding spec is
136   --  also checked (and True returned if either flag is True).
137
138   function Has_Pragma_Unreferenced_Check_Spec (E : Entity_Id) return Boolean;
139   --  Tests Has_Pragma_Unreferenced flag for entity E. If E is not a formal,
140   --  this is simply the setting of the flag Has_Pragma_Unreferenced. If E is
141   --  a body formal, the setting of the flag in the corresponding spec is
142   --  also checked (and True returned if either flag is True).
143
144   function Never_Set_In_Source_Check_Spec (E : Entity_Id) return Boolean;
145   --  Tests Never_Set_In_Source status for entity E. If E is not a formal,
146   --  this is simply the setting of the flag Never_Set_In_Source. If E is
147   --  a body formal, the setting of the flag in the corresponding spec is
148   --  also checked (and False returned if either flag is False).
149
150   function Operand_Has_Warnings_Suppressed (N : Node_Id) return Boolean;
151   --  This function traverses the expression tree represented by the node N
152   --  and determines if any sub-operand is a reference to an entity for which
153   --  the Warnings_Off flag is set. True is returned if such an entity is
154   --  encountered, and False otherwise.
155
156   function Referenced_Check_Spec (E : Entity_Id) return Boolean;
157   --  Tests Referenced status for entity E. If E is not a formal, this is
158   --  simply the setting of the flag Referenced. If E is a body formal, the
159   --  setting of the flag in the corresponding spec is also checked (and True
160   --  returned if either flag is True).
161
162   function Referenced_As_LHS_Check_Spec (E : Entity_Id) return Boolean;
163   --  Tests Referenced_As_LHS status for entity E. If E is not a formal, this
164   --  is simply the setting of the flag Referenced_As_LHS. If E is a body
165   --  formal, the setting of the flag in the corresponding spec is also
166   --  checked (and True returned if either flag is True).
167
168   function Referenced_As_Out_Parameter_Check_Spec
169     (E : Entity_Id) return Boolean;
170   --  Tests Referenced_As_Out_Parameter status for entity E. If E is not a
171   --  formal, this is simply the setting of Referenced_As_Out_Parameter. If E
172   --  is a body formal, the setting of the flag in the corresponding spec is
173   --  also checked (and True returned if either flag is True).
174
175   procedure Warn_On_Unreferenced_Entity
176     (Spec_E : Entity_Id;
177      Body_E : Entity_Id := Empty);
178   --  Output warnings for unreferenced entity E. For the case of an entry
179   --  formal, Body_E is the corresponding body entity for a particular
180   --  accept statement, and the message is posted on Body_E. In all other
181   --  cases, Body_E is ignored and must be Empty.
182
183   function Warnings_Off_Check_Spec (E : Entity_Id) return Boolean;
184   --  Returns True if Warnings_Off is set for the entity E or (in the case
185   --  where there is a Spec_Entity), Warnings_Off is set for the Spec_Entity.
186
187   --------------------------
188   -- Check_Code_Statement --
189   --------------------------
190
191   procedure Check_Code_Statement (N : Node_Id) is
192   begin
193      --  If volatile, nothing to worry about
194
195      if Is_Asm_Volatile (N) then
196         return;
197      end if;
198
199      --  Warn if no input or no output
200
201      Setup_Asm_Inputs (N);
202
203      if No (Asm_Input_Value) then
204         Error_Msg_F
205           ("??code statement with no inputs should usually be Volatile!", N);
206         return;
207      end if;
208
209      Setup_Asm_Outputs (N);
210
211      if No (Asm_Output_Variable) then
212         Error_Msg_F
213           ("??code statement with no outputs should usually be Volatile!", N);
214         return;
215      end if;
216   end Check_Code_Statement;
217
218   ---------------------------------
219   -- Check_Infinite_Loop_Warning --
220   ---------------------------------
221
222   --  The case we look for is a while loop which tests a local variable, where
223   --  there is no obvious direct or possible indirect update of the variable
224   --  within the body of the loop.
225
226   procedure Check_Infinite_Loop_Warning (Loop_Statement : Node_Id) is
227      Expression : Node_Id := Empty;
228      --  Set to WHILE or EXIT WHEN condition to be tested
229
230      Ref : Node_Id := Empty;
231      --  Reference in Expression to variable that might not be modified
232      --  in loop, indicating a possible infinite loop.
233
234      Var : Entity_Id := Empty;
235      --  Corresponding entity (entity of Ref)
236
237      Function_Call_Found : Boolean := False;
238      --  True if Find_Var found a function call in the condition
239
240      procedure Find_Var (N : Node_Id);
241      --  Inspect condition to see if it depends on a single entity reference.
242      --  If so, Ref is set to point to the reference node, and Var is set to
243      --  the referenced Entity.
244
245      function Has_Indirection (T : Entity_Id) return Boolean;
246      --  If the controlling variable is an access type, or is a record type
247      --  with access components, assume that it is changed indirectly and
248      --  suppress the warning. As a concession to low-level programming, in
249      --  particular within Declib, we also suppress warnings on a record
250      --  type that contains components of type Address or Short_Address.
251
252      function Is_Suspicious_Function_Name (E : Entity_Id) return Boolean;
253      --  Given an entity name, see if the name appears to have something to
254      --  do with I/O or network stuff, and if so, return True. Used to kill
255      --  some false positives on a heuristic basis that such functions will
256      --  likely have some strange side effect dependencies. A rather strange
257      --  test, but warning messages are in the heuristics business.
258
259      function Test_Ref (N : Node_Id) return Traverse_Result;
260      --  Test for reference to variable in question. Returns Abandon if
261      --  matching reference found. Used in instantiation of No_Ref_Found.
262
263      function No_Ref_Found is new Traverse_Func (Test_Ref);
264      --  Function to traverse body of procedure. Returns Abandon if matching
265      --  reference found.
266
267      --------------
268      -- Find_Var --
269      --------------
270
271      procedure Find_Var (N : Node_Id) is
272      begin
273         --  Condition is a direct variable reference
274
275         if Is_Entity_Name (N) then
276            Ref := N;
277            Var := Entity (Ref);
278
279         --  Case of condition is a comparison with compile time known value
280
281         elsif Nkind (N) in N_Op_Compare then
282            if Compile_Time_Known_Value (Right_Opnd (N)) then
283               Find_Var (Left_Opnd (N));
284
285            elsif Compile_Time_Known_Value (Left_Opnd (N)) then
286               Find_Var (Right_Opnd (N));
287
288            --  Ignore any other comparison
289
290            else
291               return;
292            end if;
293
294         --  If condition is a negation, check its operand
295
296         elsif Nkind (N) = N_Op_Not then
297            Find_Var (Right_Opnd (N));
298
299         --  Case of condition is function call
300
301         elsif Nkind (N) = N_Function_Call then
302
303            Function_Call_Found := True;
304
305            --  Forget it if function name is not entity, who knows what
306            --  we might be calling?
307
308            if not Is_Entity_Name (Name (N)) then
309               return;
310
311            --  Forget it if function name is suspicious. A strange test
312            --  but warning generation is in the heuristics business.
313
314            elsif Is_Suspicious_Function_Name (Entity (Name (N))) then
315               return;
316
317            --  Forget it if warnings are suppressed on function entity
318
319            elsif Has_Warnings_Off (Entity (Name (N))) then
320               return;
321            end if;
322
323            --  OK, see if we have one argument
324
325            declare
326               PA : constant List_Id := Parameter_Associations (N);
327
328            begin
329               --  One argument, so check the argument
330
331               if Present (PA) and then List_Length (PA) = 1 then
332                  if Nkind (First (PA)) = N_Parameter_Association then
333                     Find_Var (Explicit_Actual_Parameter (First (PA)));
334                  else
335                     Find_Var (First (PA));
336                  end if;
337
338               --  Not one argument
339
340               else
341                  return;
342               end if;
343            end;
344
345         --  Any other kind of node is not something we warn for
346
347         else
348            return;
349         end if;
350      end Find_Var;
351
352      ---------------------
353      -- Has_Indirection --
354      ---------------------
355
356      function Has_Indirection (T : Entity_Id) return Boolean is
357         Comp : Entity_Id;
358         Rec  : Entity_Id;
359
360      begin
361         if Is_Access_Type (T) then
362            return True;
363
364         elsif Is_Private_Type (T)
365           and then Present (Full_View (T))
366           and then Is_Access_Type (Full_View (T))
367         then
368            return True;
369
370         elsif Is_Record_Type (T) then
371            Rec := T;
372
373         elsif Is_Private_Type (T)
374           and then Present (Full_View (T))
375           and then Is_Record_Type (Full_View (T))
376         then
377            Rec := Full_View (T);
378         else
379            return False;
380         end if;
381
382         Comp := First_Component (Rec);
383         while Present (Comp) loop
384            if Is_Access_Type (Etype (Comp))
385              or else Is_Descendent_Of_Address (Etype (Comp))
386            then
387               return True;
388            end if;
389
390            Next_Component (Comp);
391         end loop;
392
393         return False;
394      end Has_Indirection;
395
396      ---------------------------------
397      -- Is_Suspicious_Function_Name --
398      ---------------------------------
399
400      function Is_Suspicious_Function_Name (E : Entity_Id) return Boolean is
401         S : Entity_Id;
402
403         function Substring_Present (S : String) return Boolean;
404         --  Returns True if name buffer has given string delimited by non-
405         --  alphabetic characters or by end of string. S is lower case.
406
407         -----------------------
408         -- Substring_Present --
409         -----------------------
410
411         function Substring_Present (S : String) return Boolean is
412            Len : constant Natural := S'Length;
413
414         begin
415            for J in 1 .. Name_Len - (Len - 1) loop
416               if Name_Buffer (J .. J + (Len - 1)) = S
417                 and then (J = 1 or else Name_Buffer (J - 1) not in 'a' .. 'z')
418                 and then
419                   (J + Len > Name_Len
420                     or else Name_Buffer (J + Len) not in 'a' .. 'z')
421               then
422                  return True;
423               end if;
424            end loop;
425
426            return False;
427         end Substring_Present;
428
429      --  Start of processing for Is_Suspicious_Function_Name
430
431      begin
432         S := E;
433         while Present (S) and then S /= Standard_Standard loop
434            Get_Name_String (Chars (S));
435
436            if Substring_Present ("io")
437              or else Substring_Present ("file")
438              or else Substring_Present ("network")
439            then
440               return True;
441            else
442               S := Scope (S);
443            end if;
444         end loop;
445
446         return False;
447      end Is_Suspicious_Function_Name;
448
449      --------------
450      -- Test_Ref --
451      --------------
452
453      function Test_Ref (N : Node_Id) return Traverse_Result is
454      begin
455         --  Waste of time to look at the expression we are testing
456
457         if N = Expression then
458            return Skip;
459
460         --  Direct reference to variable in question
461
462         elsif Is_Entity_Name (N)
463           and then Present (Entity (N))
464           and then Entity (N) = Var
465         then
466            --  If this is an lvalue, then definitely abandon, since
467            --  this could be a direct modification of the variable.
468
469            if May_Be_Lvalue (N) then
470               return Abandon;
471            end if;
472
473            --  If the condition contains a function call, we consider it may
474            --  be modified by side-effects from a procedure call. Otherwise,
475            --  we consider the condition may not be modified, although that
476            --  might happen if Variable is itself a by-reference parameter,
477            --  and the procedure called modifies the global object referred to
478            --  by Variable, but we actually prefer to issue a warning in this
479            --  odd case. Note that the case where the procedure called has
480            --  visibility over Variable is treated in another case below.
481
482            if Function_Call_Found then
483               declare
484                  P : Node_Id;
485
486               begin
487                  P := N;
488                  loop
489                     P := Parent (P);
490                     exit when P = Loop_Statement;
491
492                     --  Abandon if at procedure call, or something strange is
493                     --  going on (perhaps a node with no parent that should
494                     --  have one but does not?) As always, for a warning we
495                     --  prefer to just abandon the warning than get into the
496                     --  business of complaining about the tree structure here.
497
498                     if No (P)
499                       or else Nkind (P) = N_Procedure_Call_Statement
500                     then
501                        return Abandon;
502                     end if;
503                  end loop;
504               end;
505            end if;
506
507         --  Reference to variable renaming variable in question
508
509         elsif Is_Entity_Name (N)
510           and then Present (Entity (N))
511           and then Ekind (Entity (N)) = E_Variable
512           and then Present (Renamed_Object (Entity (N)))
513           and then Is_Entity_Name (Renamed_Object (Entity (N)))
514           and then Entity (Renamed_Object (Entity (N))) = Var
515           and then May_Be_Lvalue (N)
516         then
517            return Abandon;
518
519         --  Call to subprogram
520
521         elsif Nkind (N) in N_Subprogram_Call then
522
523            --  If subprogram is within the scope of the entity we are dealing
524            --  with as the loop variable, then it could modify this parameter,
525            --  so we abandon in this case. In the case of a subprogram that is
526            --  not an entity we also abandon. The check for no entity being
527            --  present is a defense against previous errors.
528
529            if not Is_Entity_Name (Name (N))
530              or else No (Entity (Name (N)))
531              or else Scope_Within (Entity (Name (N)), Scope (Var))
532            then
533               return Abandon;
534            end if;
535
536            --  If any of the arguments are of type access to subprogram, then
537            --  we may have funny side effects, so no warning in this case.
538
539            declare
540               Actual : Node_Id;
541            begin
542               Actual := First_Actual (N);
543               while Present (Actual) loop
544                  if Is_Access_Subprogram_Type (Etype (Actual)) then
545                     return Abandon;
546                  else
547                     Next_Actual (Actual);
548                  end if;
549               end loop;
550            end;
551
552         --  Declaration of the variable in question
553
554         elsif Nkind (N) = N_Object_Declaration
555           and then Defining_Identifier (N) = Var
556         then
557            return Abandon;
558         end if;
559
560         --  All OK, continue scan
561
562         return OK;
563      end Test_Ref;
564
565   --  Start of processing for Check_Infinite_Loop_Warning
566
567   begin
568      --  Skip processing if debug flag gnatd.w is set
569
570      if Debug_Flag_Dot_W then
571         return;
572      end if;
573
574      --  Deal with Iteration scheme present
575
576      declare
577         Iter : constant Node_Id := Iteration_Scheme (Loop_Statement);
578
579      begin
580         if Present (Iter) then
581
582            --  While iteration
583
584            if Present (Condition (Iter)) then
585
586               --  Skip processing for while iteration with conditions actions,
587               --  since they make it too complicated to get the warning right.
588
589               if Present (Condition_Actions (Iter)) then
590                  return;
591               end if;
592
593               --  Capture WHILE condition
594
595               Expression := Condition (Iter);
596
597            --  For iteration, do not process, since loop will always terminate
598
599            elsif Present (Loop_Parameter_Specification (Iter)) then
600               return;
601            end if;
602         end if;
603      end;
604
605      --  Check chain of EXIT statements, we only process loops that have a
606      --  single exit condition (either a single EXIT WHEN statement, or a
607      --  WHILE loop not containing any EXIT WHEN statements).
608
609      declare
610         Ident     : constant Node_Id := Identifier (Loop_Statement);
611         Exit_Stmt : Node_Id;
612
613      begin
614         --  If we don't have a proper chain set, ignore call entirely. This
615         --  happens because of previous errors.
616
617         if No (Entity (Ident))
618           or else Ekind (Entity (Ident)) /= E_Loop
619         then
620            Check_Error_Detected;
621            return;
622         end if;
623
624         --  Otherwise prepare to scan list of EXIT statements
625
626         Exit_Stmt := First_Exit_Statement (Entity (Ident));
627         while Present (Exit_Stmt) loop
628
629            --  Check for EXIT WHEN
630
631            if Present (Condition (Exit_Stmt)) then
632
633               --  Quit processing if EXIT WHEN in WHILE loop, or more than
634               --  one EXIT WHEN statement present in the loop.
635
636               if Present (Expression) then
637                  return;
638
639               --  Otherwise capture condition from EXIT WHEN statement
640
641               else
642                  Expression := Condition (Exit_Stmt);
643               end if;
644
645            --  If an unconditional exit statement is the last statement in the
646            --  loop, assume that no warning is needed, without any attempt at
647            --  checking whether the exit is reachable.
648
649            elsif Exit_Stmt = Last (Statements (Loop_Statement)) then
650               return;
651            end if;
652
653            Exit_Stmt := Next_Exit_Statement (Exit_Stmt);
654         end loop;
655      end;
656
657      --  Return if no condition to test
658
659      if No (Expression) then
660         return;
661      end if;
662
663      --  Initial conditions met, see if condition is of right form
664
665      Find_Var (Expression);
666
667      --  Nothing to do if local variable from source not found. If it's a
668      --  renaming, it is probably renaming something too complicated to deal
669      --  with here.
670
671      if No (Var)
672        or else Ekind (Var) /= E_Variable
673        or else Is_Library_Level_Entity (Var)
674        or else not Comes_From_Source (Var)
675        or else Nkind (Parent (Var)) = N_Object_Renaming_Declaration
676      then
677         return;
678
679      --  Nothing to do if there is some indirection involved (assume that the
680      --  designated variable might be modified in some way we don't see).
681      --  However, if no function call was found, then we don't care about
682      --  indirections, because the condition must be something like "while X
683      --  /= null loop", so we don't care if X.all is modified in the loop.
684
685      elsif Function_Call_Found and then Has_Indirection (Etype (Var)) then
686         return;
687
688      --  Same sort of thing for volatile variable, might be modified by
689      --  some other task or by the operating system in some way.
690
691      elsif Is_Volatile (Var) then
692         return;
693      end if;
694
695      --  Filter out case of original statement sequence starting with delay.
696      --  We assume this is a multi-tasking program and that the condition
697      --  is affected by other threads (some kind of busy wait).
698
699      declare
700         Fstm : constant Node_Id :=
701                  Original_Node (First (Statements (Loop_Statement)));
702      begin
703         if Nkind (Fstm) = N_Delay_Relative_Statement
704           or else Nkind (Fstm) = N_Delay_Until_Statement
705         then
706            return;
707         end if;
708      end;
709
710      --  We have a variable reference of the right form, now we scan the loop
711      --  body to see if it looks like it might not be modified
712
713      if No_Ref_Found (Loop_Statement) = OK then
714         Error_Msg_NE
715           ("??variable& is not modified in loop body!", Ref, Var);
716         Error_Msg_N
717           ("\??possible infinite loop!", Ref);
718      end if;
719   end Check_Infinite_Loop_Warning;
720
721   ----------------------------
722   -- Check_Low_Bound_Tested --
723   ----------------------------
724
725   procedure Check_Low_Bound_Tested (Expr : Node_Id) is
726      procedure Check_Low_Bound_Tested_For (Opnd : Node_Id);
727      --  Determine whether operand Opnd denotes attribute 'First whose prefix
728      --  is a formal parameter. If this is the case, mark the entity of the
729      --  prefix as having its low bound tested.
730
731      --------------------------------
732      -- Check_Low_Bound_Tested_For --
733      --------------------------------
734
735      procedure Check_Low_Bound_Tested_For (Opnd : Node_Id) is
736      begin
737         if Nkind (Opnd) = N_Attribute_Reference
738           and then Attribute_Name (Opnd) = Name_First
739           and then Is_Entity_Name (Prefix (Opnd))
740           and then Present (Entity (Prefix (Opnd)))
741           and then Is_Formal (Entity (Prefix (Opnd)))
742         then
743            Set_Low_Bound_Tested (Entity (Prefix (Opnd)));
744         end if;
745      end Check_Low_Bound_Tested_For;
746
747   --  Start of processing for Check_Low_Bound_Tested
748
749   begin
750      if Comes_From_Source (Expr) then
751         Check_Low_Bound_Tested_For (Left_Opnd  (Expr));
752         Check_Low_Bound_Tested_For (Right_Opnd (Expr));
753      end if;
754   end Check_Low_Bound_Tested;
755
756   ----------------------
757   -- Check_References --
758   ----------------------
759
760   procedure Check_References (E : Entity_Id; Anod : Node_Id := Empty) is
761      E1  : Entity_Id;
762      E1T : Entity_Id;
763      UR  : Node_Id;
764
765      function Body_Formal
766        (E                : Entity_Id;
767         Accept_Statement : Node_Id) return Entity_Id;
768      --  For an entry formal entity from an entry declaration, find the
769      --  corresponding body formal from the given accept statement.
770
771      procedure May_Need_Initialized_Actual (Ent : Entity_Id);
772      --  If an entity of a generic type has default initialization, then the
773      --  corresponding actual type should be fully initialized, or else there
774      --  will be uninitialized components in the instantiation, that might go
775      --  unreported. This routine marks the type of the uninitialized variable
776      --  appropriately to allow the compiler to emit an appropriate warning
777      --  in the instance. In a sense, the use of a type that requires full
778      --  initialization is a weak part of the generic contract.
779
780      function Missing_Subunits return Boolean;
781      --  We suppress warnings when there are missing subunits, because this
782      --  may generate too many false positives: entities in a parent may only
783      --  be referenced in one of the subunits. We make an exception for
784      --  subunits that contain no other stubs.
785
786      procedure Output_Reference_Error (M : String);
787      --  Used to output an error message. Deals with posting the error on the
788      --  body formal in the accept case.
789
790      function Publicly_Referenceable (Ent : Entity_Id) return Boolean;
791      --  This is true if the entity in question is potentially referenceable
792      --  from another unit. This is true for entities in packages that are at
793      --  the library level.
794
795      function Warnings_Off_E1 return Boolean;
796      --  Return True if Warnings_Off is set for E1, or for its Etype (E1T),
797      --  or for the base type of E1T.
798
799      -----------------
800      -- Body_Formal --
801      -----------------
802
803      function Body_Formal
804        (E                : Entity_Id;
805         Accept_Statement : Node_Id) return Entity_Id
806      is
807         Body_Param : Node_Id;
808         Body_E     : Entity_Id;
809
810      begin
811         --  Loop to find matching parameter in accept statement
812
813         Body_Param := First (Parameter_Specifications (Accept_Statement));
814         while Present (Body_Param) loop
815            Body_E := Defining_Identifier (Body_Param);
816
817            if Chars (Body_E) = Chars (E) then
818               return Body_E;
819            end if;
820
821            Next (Body_Param);
822         end loop;
823
824         --  Should never fall through, should always find a match
825
826         raise Program_Error;
827      end Body_Formal;
828
829      ---------------------------------
830      -- May_Need_Initialized_Actual --
831      ---------------------------------
832
833      procedure May_Need_Initialized_Actual (Ent : Entity_Id) is
834         T   : constant Entity_Id := Etype (Ent);
835         Par : constant Node_Id   := Parent (T);
836
837      begin
838         if not Is_Generic_Type (T) then
839            null;
840
841         elsif (Nkind (Par)) = N_Private_Extension_Declaration then
842
843            --  We only indicate the first such variable in the generic.
844
845            if No (Uninitialized_Variable (Par)) then
846               Set_Uninitialized_Variable (Par, Ent);
847            end if;
848
849         elsif (Nkind (Par)) = N_Formal_Type_Declaration
850           and then Nkind (Formal_Type_Definition (Par)) =
851                                         N_Formal_Private_Type_Definition
852         then
853            if No (Uninitialized_Variable (Formal_Type_Definition (Par))) then
854               Set_Uninitialized_Variable (Formal_Type_Definition (Par), Ent);
855            end if;
856         end if;
857      end May_Need_Initialized_Actual;
858
859      ----------------------
860      -- Missing_Subunits --
861      ----------------------
862
863      function Missing_Subunits return Boolean is
864         D : Node_Id;
865
866      begin
867         if not Unloaded_Subunits then
868
869            --  Normal compilation, all subunits are present
870
871            return False;
872
873         elsif E /= Main_Unit_Entity then
874
875            --  No warnings on a stub that is not the main unit
876
877            return True;
878
879         elsif Nkind (Unit_Declaration_Node (E)) in N_Proper_Body then
880            D := First (Declarations (Unit_Declaration_Node (E)));
881            while Present (D) loop
882
883               --  No warnings if the proper body contains nested stubs
884
885               if Nkind (D) in N_Body_Stub then
886                  return True;
887               end if;
888
889               Next (D);
890            end loop;
891
892            return False;
893
894         else
895            --  Missing stubs elsewhere
896
897            return True;
898         end if;
899      end Missing_Subunits;
900
901      ----------------------------
902      -- Output_Reference_Error --
903      ----------------------------
904
905      procedure Output_Reference_Error (M : String) is
906      begin
907         --  Never issue messages for internal names or renamings
908
909         if Is_Internal_Name (Chars (E1))
910           or else Nkind (Parent (E1)) = N_Object_Renaming_Declaration
911         then
912            return;
913         end if;
914
915         --  Don't output message for IN OUT formal unless we have the warning
916         --  flag specifically set. It is a bit odd to distinguish IN OUT
917         --  formals from other cases. This distinction is historical in
918         --  nature. Warnings for IN OUT formals were added fairly late.
919
920         if Ekind (E1) = E_In_Out_Parameter
921           and then not Check_Unreferenced_Formals
922         then
923            return;
924         end if;
925
926         --  Other than accept case, post error on defining identifier
927
928         if No (Anod) then
929            Error_Msg_N (M, E1);
930
931         --  Accept case, find body formal to post the message
932
933         else
934            Error_Msg_NE (M, Body_Formal (E1, Accept_Statement => Anod), E1);
935
936         end if;
937      end Output_Reference_Error;
938
939      ----------------------------
940      -- Publicly_Referenceable --
941      ----------------------------
942
943      function Publicly_Referenceable (Ent : Entity_Id) return Boolean is
944         P    : Node_Id;
945         Prev : Node_Id;
946
947      begin
948         --  A formal parameter is never referenceable outside the body of its
949         --  subprogram or entry.
950
951         if Is_Formal (Ent) then
952            return False;
953         end if;
954
955         --  Examine parents to look for a library level package spec. But if
956         --  we find a body or block or other similar construct along the way,
957         --  we cannot be referenced.
958
959         Prev := Ent;
960         P    := Parent (Ent);
961         loop
962            case Nkind (P) is
963
964               --  If we get to top of tree, then publicly referenceable
965
966               when N_Empty =>
967                  return True;
968
969               --  If we reach a generic package declaration, then always
970               --  consider this referenceable, since any instantiation will
971               --  have access to the entities in the generic package. Note
972               --  that the package itself may not be instantiated, but then
973               --  we will get a warning for the package entity.
974
975               --  Note that generic formal parameters are themselves not
976               --  publicly referenceable in an instance, and warnings on them
977               --  are useful.
978
979               when N_Generic_Package_Declaration =>
980                  return
981                    not Is_List_Member (Prev)
982                      or else List_Containing (Prev) /=
983                                            Generic_Formal_Declarations (P);
984
985               --  Similarly, the generic formals of a generic subprogram are
986               --  not accessible.
987
988               when N_Generic_Subprogram_Declaration  =>
989                  if Is_List_Member (Prev)
990                    and then List_Containing (Prev) =
991                               Generic_Formal_Declarations (P)
992                  then
993                     return False;
994                  else
995                     P := Parent (P);
996                  end if;
997
998               --  If we reach a subprogram body, entity is not referenceable
999               --  unless it is the defining entity of the body. This will
1000               --  happen, e.g. when a function is an attribute renaming that
1001               --  is rewritten as a body.
1002
1003               when N_Subprogram_Body  =>
1004                  if Ent /= Defining_Entity (P) then
1005                     return False;
1006                  else
1007                     P := Parent (P);
1008                  end if;
1009
1010               --  If we reach any other body, definitely not referenceable
1011
1012               when N_Package_Body    |
1013                    N_Task_Body       |
1014                    N_Entry_Body      |
1015                    N_Protected_Body  |
1016                    N_Block_Statement |
1017                    N_Subunit         =>
1018                  return False;
1019
1020               --  For all other cases, keep looking up tree
1021
1022               when others =>
1023                  Prev := P;
1024                  P    := Parent (P);
1025            end case;
1026         end loop;
1027      end Publicly_Referenceable;
1028
1029      ---------------------
1030      -- Warnings_Off_E1 --
1031      ---------------------
1032
1033      function Warnings_Off_E1 return Boolean is
1034      begin
1035         return Has_Warnings_Off (E1T)
1036           or else Has_Warnings_Off (Base_Type (E1T))
1037           or else Warnings_Off_Check_Spec (E1);
1038      end Warnings_Off_E1;
1039
1040   --  Start of processing for Check_References
1041
1042   begin
1043      Process_Deferred_References;
1044
1045      --  No messages if warnings are suppressed, or if we have detected any
1046      --  real errors so far (this last check avoids junk messages resulting
1047      --  from errors, e.g. a subunit that is not loaded).
1048
1049      if Warning_Mode = Suppress or else Serious_Errors_Detected /= 0 then
1050         return;
1051      end if;
1052
1053      --  We also skip the messages if any subunits were not loaded (see
1054      --  comment in Sem_Ch10 to understand how this is set, and why it is
1055      --  necessary to suppress the warnings in this case).
1056
1057      if Missing_Subunits then
1058         return;
1059      end if;
1060
1061      --  Otherwise loop through entities, looking for suspicious stuff
1062
1063      E1 := First_Entity (E);
1064      while Present (E1) loop
1065         E1T := Etype (E1);
1066
1067         --  We are only interested in source entities. We also don't issue
1068         --  warnings within instances, since the proper place for such
1069         --  warnings is on the template when it is compiled, and we don't
1070         --  issue warnings for variables with names like Junk, Discard etc.
1071
1072         if Comes_From_Source (E1)
1073           and then Instantiation_Location (Sloc (E1)) = No_Location
1074         then
1075            --  We are interested in variables and out/in-out parameters, but
1076            --  we exclude protected types, too complicated to worry about.
1077
1078            if Ekind (E1) = E_Variable
1079              or else
1080                (Ekind_In (E1, E_Out_Parameter, E_In_Out_Parameter)
1081                  and then not Is_Protected_Type (Current_Scope))
1082            then
1083               --  If the formal has a class-wide type, retrieve its type
1084               --  because checks below depend on its private nature.
1085
1086               if Is_Class_Wide_Type (E1T) then
1087                  E1T := Etype (E1T);
1088               end if;
1089
1090               --  Case of an unassigned variable
1091
1092               --  First gather any Unset_Reference indication for E1. In the
1093               --  case of a parameter, it is the Spec_Entity that is relevant.
1094
1095               if Ekind (E1) = E_Out_Parameter
1096                 and then Present (Spec_Entity (E1))
1097               then
1098                  UR := Unset_Reference (Spec_Entity (E1));
1099               else
1100                  UR := Unset_Reference (E1);
1101               end if;
1102
1103               --  Special processing for access types
1104
1105               if Present (UR) and then Is_Access_Type (E1T) then
1106
1107                  --  For access types, the only time we made a UR entry was
1108                  --  for a dereference, and so we post the appropriate warning
1109                  --  here (note that the dereference may not be explicit in
1110                  --  the source, for example in the case of a dispatching call
1111                  --  with an anonymous access controlling formal, or of an
1112                  --  assignment of a pointer involving discriminant check on
1113                  --  the designated object).
1114
1115                  if not Warnings_Off_E1 then
1116                     Error_Msg_NE ("??& may be null!", UR, E1);
1117                  end if;
1118
1119                  goto Continue;
1120
1121               --  Case of variable that could be a constant. Note that we
1122               --  never signal such messages for generic package entities,
1123               --  since a given instance could have modifications outside
1124               --  the package.
1125
1126               --  Note that we used to check Address_Taken here, but we don't
1127               --  want to do that since it can be set for non-source cases,
1128               --  e.g. the Unrestricted_Access from a valid attribute, and
1129               --  the wanted effect is included in Never_Set_In_Source.
1130
1131               elsif Warn_On_Constant
1132                 and then (Ekind (E1) = E_Variable
1133                            and then Has_Initial_Value (E1))
1134                 and then Never_Set_In_Source_Check_Spec (E1)
1135                 and then not Generic_Package_Spec_Entity (E1)
1136               then
1137                  --  A special case, if this variable is volatile and not
1138                  --  imported, it is not helpful to tell the programmer
1139                  --  to mark the variable as constant, since this would be
1140                  --  illegal by virtue of RM C.6(13).
1141
1142                  if (Is_Volatile (E1) or else Has_Volatile_Components (E1))
1143                    and then not Is_Imported (E1)
1144                  then
1145                     Error_Msg_N
1146                       ("?k?& is not modified, volatile has no effect!", E1);
1147
1148                  --  Another special case, Exception_Occurrence, this catches
1149                  --  the case of exception choice (and a bit more too, but not
1150                  --  worth doing more investigation here).
1151
1152                  elsif Is_RTE (E1T, RE_Exception_Occurrence) then
1153                     null;
1154
1155                  --  Here we give the warning if referenced and no pragma
1156                  --  Unreferenced or Unmodified is present.
1157
1158                  else
1159                     --  Variable case
1160
1161                     if Ekind (E1) = E_Variable then
1162                        if Referenced_Check_Spec (E1)
1163                          and then not Has_Pragma_Unreferenced_Check_Spec (E1)
1164                          and then not Has_Pragma_Unmodified_Check_Spec (E1)
1165                        then
1166                           if not Warnings_Off_E1
1167                             and then not Has_Junk_Name (E1)
1168                           then
1169                              Error_Msg_N -- CODEFIX
1170                                ("?k?& is not modified, "
1171                                 & "could be declared constant!",
1172                                 E1);
1173                           end if;
1174                        end if;
1175                     end if;
1176                  end if;
1177
1178               --  Other cases of a variable or parameter never set in source
1179
1180               elsif Never_Set_In_Source_Check_Spec (E1)
1181
1182                 --  No warning if warning for this case turned off
1183
1184                 and then Warn_On_No_Value_Assigned
1185
1186                 --  No warning if address taken somewhere
1187
1188                 and then not Address_Taken (E1)
1189
1190                 --  No warning if explicit initial value
1191
1192                 and then not Has_Initial_Value (E1)
1193
1194                 --  No warning for generic package spec entities, since we
1195                 --  might set them in a child unit or something like that
1196
1197                 and then not Generic_Package_Spec_Entity (E1)
1198
1199                 --  No warning if fully initialized type, except that for
1200                 --  this purpose we do not consider access types to qualify
1201                 --  as fully initialized types (relying on an access type
1202                 --  variable being null when it is never set is a bit odd).
1203
1204                 --  Also we generate warning for an out parameter that is
1205                 --  never referenced, since again it seems odd to rely on
1206                 --  default initialization to set an out parameter value.
1207
1208                and then (Is_Access_Type (E1T)
1209                           or else Ekind (E1) = E_Out_Parameter
1210                           or else not Is_Fully_Initialized_Type (E1T))
1211               then
1212                  --  Do not output complaint about never being assigned a
1213                  --  value if a pragma Unmodified applies to the variable
1214                  --  we are examining, or if it is a parameter, if there is
1215                  --  a pragma Unreferenced for the corresponding spec, or
1216                  --  if the type is marked as having unreferenced objects.
1217                  --  The last is a little peculiar, but better too few than
1218                  --  too many warnings in this situation.
1219
1220                  if Has_Pragma_Unreferenced_Objects (E1T)
1221                    or else Has_Pragma_Unmodified_Check_Spec (E1)
1222                  then
1223                     null;
1224
1225                  --  IN OUT parameter case where parameter is referenced. We
1226                  --  separate this out, since this is the case where we delay
1227                  --  output of the warning until more information is available
1228                  --  (about use in an instantiation or address being taken).
1229
1230                  elsif Ekind (E1) = E_In_Out_Parameter
1231                    and then Referenced_Check_Spec (E1)
1232                  then
1233                     --  Suppress warning if private type, and the procedure
1234                     --  has a separate declaration in a different unit. This
1235                     --  is the case where the client of a package sees only
1236                     --  the private type, and it may be quite reasonable
1237                     --  for the logical view to be IN OUT, even if the
1238                     --  implementation ends up using access types or some
1239                     --  other method to achieve the local effect of a
1240                     --  modification. On the other hand if the spec and body
1241                     --  are in the same unit, we are in the package body and
1242                     --  there we have less excuse for a junk IN OUT parameter.
1243
1244                     if Has_Private_Declaration (E1T)
1245                       and then Present (Spec_Entity (E1))
1246                       and then not In_Same_Source_Unit (E1, Spec_Entity (E1))
1247                     then
1248                        null;
1249
1250                     --  Suppress warning for any parameter of a dispatching
1251                     --  operation, since it is quite reasonable to have an
1252                     --  operation that is overridden, and for some subclasses
1253                     --  needs the formal to be IN OUT and for others happens
1254                     --  not to assign it.
1255
1256                     elsif Is_Dispatching_Operation
1257                             (Scope (Goto_Spec_Entity (E1)))
1258                     then
1259                        null;
1260
1261                     --  Suppress warning if composite type contains any access
1262                     --  component, since the logical effect of modifying a
1263                     --  parameter may be achieved by modifying a referenced
1264                     --  object.
1265
1266                     elsif Is_Composite_Type (E1T)
1267                       and then Has_Access_Values (E1T)
1268                     then
1269                        null;
1270
1271                     --  Suppress warning on formals of an entry body. All
1272                     --  references are attached to the formal in the entry
1273                     --  declaration, which are marked Is_Entry_Formal.
1274
1275                     elsif Ekind (Scope (E1)) = E_Entry
1276                       and then not Is_Entry_Formal (E1)
1277                     then
1278                        null;
1279
1280                     --  OK, looks like warning for an IN OUT parameter that
1281                     --  could be IN makes sense, but we delay the output of
1282                     --  the warning, pending possibly finding out later on
1283                     --  that the associated subprogram is used as a generic
1284                     --  actual, or its address/access is taken. In these two
1285                     --  cases, we suppress the warning because the context may
1286                     --  force use of IN OUT, even if in this particular case
1287                     --  the formal is not modified.
1288
1289                     else
1290                        --  Suppress the warnings for a junk name
1291
1292                        if not Has_Junk_Name (E1) then
1293                           In_Out_Warnings.Append (E1);
1294                        end if;
1295                     end if;
1296
1297                  --  Other cases of formals
1298
1299                  elsif Is_Formal (E1) then
1300                     if not Is_Trivial_Subprogram (Scope (E1)) then
1301                        if Referenced_Check_Spec (E1) then
1302                           if not Has_Pragma_Unmodified_Check_Spec (E1)
1303                             and then not Warnings_Off_E1
1304                             and then not Has_Junk_Name (E1)
1305                           then
1306                              Output_Reference_Error
1307                                ("?f?formal parameter& is read but "
1308                                 & "never assigned!");
1309                           end if;
1310
1311                        elsif not Has_Pragma_Unreferenced_Check_Spec (E1)
1312                          and then not Warnings_Off_E1
1313                          and then not Has_Junk_Name (E1)
1314                        then
1315                           Output_Reference_Error
1316                             ("?f?formal parameter& is not referenced!");
1317                        end if;
1318                     end if;
1319
1320                  --  Case of variable
1321
1322                  else
1323                     if Referenced (E1) then
1324                        if not Has_Unmodified (E1)
1325                          and then not Warnings_Off_E1
1326                          and then not Has_Junk_Name (E1)
1327                        then
1328                           Output_Reference_Error
1329                             ("?v?variable& is read but never assigned!");
1330                           May_Need_Initialized_Actual (E1);
1331                        end if;
1332
1333                     elsif not Has_Unreferenced (E1)
1334                       and then not Warnings_Off_E1
1335                       and then not Has_Junk_Name (E1)
1336                     then
1337                        Output_Reference_Error -- CODEFIX
1338                          ("?v?variable& is never read and never assigned!");
1339                     end if;
1340
1341                     --  Deal with special case where this variable is hidden
1342                     --  by a loop variable.
1343
1344                     if Ekind (E1) = E_Variable
1345                       and then Present (Hiding_Loop_Variable (E1))
1346                       and then not Warnings_Off_E1
1347                     then
1348                        Error_Msg_N
1349                          ("?v?for loop implicitly declares loop variable!",
1350                           Hiding_Loop_Variable (E1));
1351
1352                        Error_Msg_Sloc := Sloc (E1);
1353                        Error_Msg_N
1354                          ("\?v?declaration hides & declared#!",
1355                           Hiding_Loop_Variable (E1));
1356                     end if;
1357                  end if;
1358
1359                  goto Continue;
1360               end if;
1361
1362               --  Check for unset reference
1363
1364               if Warn_On_No_Value_Assigned and then Present (UR) then
1365
1366                  --  For other than access type, go back to original node to
1367                  --  deal with case where original unset reference has been
1368                  --  rewritten during expansion.
1369
1370                  --  In some cases, the original node may be a type conversion
1371                  --  or qualification, and in this case we want the object
1372                  --  entity inside.
1373
1374                  UR := Original_Node (UR);
1375                  while Nkind (UR) = N_Type_Conversion
1376                    or else Nkind (UR) = N_Qualified_Expression
1377                    or else Nkind (UR) = N_Expression_With_Actions
1378                  loop
1379                     UR := Expression (UR);
1380                  end loop;
1381
1382                  --  Don't issue warning if appearing inside Initial_Condition
1383                  --  pragma or aspect, since that expression is not evaluated
1384                  --  at the point where it occurs in the source.
1385
1386                  if In_Pragma_Expression (UR, Name_Initial_Condition) then
1387                     goto Continue;
1388                  end if;
1389
1390                  --  Here we issue the warning, all checks completed
1391
1392                  --  If we have a return statement, this was a case of an OUT
1393                  --  parameter not being set at the time of the return. (Note:
1394                  --  it can't be N_Extended_Return_Statement, because those
1395                  --  are only for functions, and functions do not allow OUT
1396                  --  parameters.)
1397
1398                  if not Is_Trivial_Subprogram (Scope (E1)) then
1399                     if Nkind (UR) = N_Simple_Return_Statement
1400                       and then not Has_Pragma_Unmodified_Check_Spec (E1)
1401                     then
1402                        if not Warnings_Off_E1
1403                          and then not Has_Junk_Name (E1)
1404                        then
1405                           Error_Msg_NE
1406                             ("?v?OUT parameter& not set before return",
1407                              UR, E1);
1408                        end if;
1409
1410                        --  If the unset reference is a selected component
1411                        --  prefix from source, mention the component as well.
1412                        --  If the selected component comes from expansion, all
1413                        --  we know is that the entity is not fully initialized
1414                        --  at the point of the reference. Locate a random
1415                        --  uninitialized component to get a better message.
1416
1417                     elsif Nkind (Parent (UR)) = N_Selected_Component then
1418                        Error_Msg_Node_2 := Selector_Name (Parent (UR));
1419
1420                        if not Comes_From_Source (Parent (UR)) then
1421                           declare
1422                              Comp : Entity_Id;
1423
1424                           begin
1425                              Comp := First_Entity (E1T);
1426                              while Present (Comp) loop
1427                                 if Ekind (Comp) = E_Component
1428                                   and then Nkind (Parent (Comp)) =
1429                                              N_Component_Declaration
1430                                   and then No (Expression (Parent (Comp)))
1431                                 then
1432                                    Error_Msg_Node_2 := Comp;
1433                                    exit;
1434                                 end if;
1435
1436                                 Next_Entity (Comp);
1437                              end loop;
1438                           end;
1439                        end if;
1440
1441                        --  Issue proper warning. This is a case of referencing
1442                        --  a variable before it has been explicitly assigned.
1443                        --  For access types, UR was only set for dereferences,
1444                        --  so the issue is that the value may be null.
1445
1446                        if not Is_Trivial_Subprogram (Scope (E1)) then
1447                           if not Warnings_Off_E1 then
1448                              if Is_Access_Type (Etype (Parent (UR))) then
1449                                 Error_Msg_N ("??`&.&` may be null!", UR);
1450                              else
1451                                 Error_Msg_N
1452                                   ("??`&.&` may be referenced before "
1453                                    & "it has a value!", UR);
1454                              end if;
1455                           end if;
1456                        end if;
1457
1458                     --  All other cases of unset reference active
1459
1460                     elsif not Warnings_Off_E1 then
1461                        Error_Msg_N
1462                          ("??& may be referenced before it has a value!", UR);
1463                     end if;
1464                  end if;
1465
1466                  goto Continue;
1467
1468               end if;
1469            end if;
1470
1471            --  Then check for unreferenced entities. Note that we are only
1472            --  interested in entities whose Referenced flag is not set.
1473
1474            if not Referenced_Check_Spec (E1)
1475
1476              --  If Referenced_As_LHS is set, then that's still interesting
1477              --  (potential "assigned but never read" case), but not if we
1478              --  have pragma Unreferenced, which cancels this warning.
1479
1480              and then (not Referenced_As_LHS_Check_Spec (E1)
1481                         or else not Has_Unreferenced (E1))
1482
1483              --  Check that warnings on unreferenced entities are enabled
1484
1485              and then
1486                ((Check_Unreferenced and then not Is_Formal (E1))
1487
1488                  --  Case of warning on unreferenced formal
1489
1490                  or else (Check_Unreferenced_Formals and then Is_Formal (E1))
1491
1492                  --  Case of warning on unread variables modified by an
1493                  --  assignment, or an OUT parameter if it is the only one.
1494
1495                  or else (Warn_On_Modified_Unread
1496                            and then Referenced_As_LHS_Check_Spec (E1))
1497
1498                  --  Case of warning on any unread OUT parameter (note such
1499                  --  indications are only set if the appropriate warning
1500                  --  options were set, so no need to recheck here.)
1501
1502                  or else Referenced_As_Out_Parameter_Check_Spec (E1))
1503
1504              --  All other entities, including local packages that cannot be
1505              --  referenced from elsewhere, including those declared within a
1506              --  package body.
1507
1508              and then (Is_Object (E1)
1509                         or else Is_Type (E1)
1510                         or else Ekind (E1) = E_Label
1511                         or else Ekind_In (E1, E_Exception,
1512                                               E_Named_Integer,
1513                                               E_Named_Real)
1514                         or else Is_Overloadable (E1)
1515
1516                         --  Package case, if the main unit is a package spec
1517                         --  or generic package spec, then there may be a
1518                         --  corresponding body that references this package
1519                         --  in some other file. Otherwise we can be sure
1520                         --  that there is no other reference.
1521
1522                         or else
1523                           (Ekind (E1) = E_Package
1524                             and then
1525                               not Is_Package_Or_Generic_Package
1526                                     (Cunit_Entity (Current_Sem_Unit))))
1527
1528              --  Exclude instantiations, since there is no reason why every
1529              --  entity in an instantiation should be referenced.
1530
1531              and then Instantiation_Location (Sloc (E1)) = No_Location
1532
1533              --  Exclude formal parameters from bodies if the corresponding
1534              --  spec entity has been referenced in the case where there is
1535              --  a separate spec.
1536
1537              and then not (Is_Formal (E1)
1538                             and then Ekind (Scope (E1)) = E_Subprogram_Body
1539                             and then Present (Spec_Entity (E1))
1540                             and then Referenced (Spec_Entity (E1)))
1541
1542              --  Consider private type referenced if full view is referenced.
1543              --  If there is not full view, this is a generic type on which
1544              --  warnings are also useful.
1545
1546              and then
1547                not (Is_Private_Type (E1)
1548                      and then Present (Full_View (E1))
1549                      and then Referenced (Full_View (E1)))
1550
1551              --  Don't worry about full view, only about private type
1552
1553              and then not Has_Private_Declaration (E1)
1554
1555              --  Eliminate dispatching operations from consideration, we
1556              --  cannot tell if these are referenced or not in any easy
1557              --  manner (note this also catches Adjust/Finalize/Initialize).
1558
1559              and then not Is_Dispatching_Operation (E1)
1560
1561              --  Check entity that can be publicly referenced (we do not give
1562              --  messages for such entities, since there could be other
1563              --  units, not involved in this compilation, that contain
1564              --  relevant references.
1565
1566              and then not Publicly_Referenceable (E1)
1567
1568              --  Class wide types are marked as source entities, but they are
1569              --  not really source entities, and are always created, so we do
1570              --  not care if they are not referenced.
1571
1572              and then Ekind (E1) /= E_Class_Wide_Type
1573
1574              --  Objects other than parameters of task types are allowed to
1575              --  be non-referenced, since they start up tasks.
1576
1577              and then ((Ekind (E1) /= E_Variable
1578                          and then Ekind (E1) /= E_Constant
1579                          and then Ekind (E1) /= E_Component)
1580                         or else not Is_Task_Type (E1T))
1581
1582              --  For subunits, only place warnings on the main unit itself,
1583              --  since parent units are not completely compiled.
1584
1585              and then (Nkind (Unit (Cunit (Main_Unit))) /= N_Subunit
1586                         or else Get_Source_Unit (E1) = Main_Unit)
1587
1588              --  No warning on a return object, because these are often
1589              --  created with a single expression and an implicit return.
1590              --  If the object is a variable there will be a warning
1591              --  indicating that it could be declared constant.
1592
1593              and then not
1594                (Ekind (E1) = E_Constant and then Is_Return_Object (E1))
1595            then
1596               --  Suppress warnings in internal units if not in -gnatg mode
1597               --  (these would be junk warnings for an applications program,
1598               --  since they refer to problems in internal units).
1599
1600               if GNAT_Mode
1601                 or else not Is_Internal_File_Name
1602                               (Unit_File_Name (Get_Source_Unit (E1)))
1603               then
1604                  --  We do not immediately flag the error. This is because we
1605                  --  have not expanded generic bodies yet, and they may have
1606                  --  the missing reference. So instead we park the entity on a
1607                  --  list, for later processing. However for the case of an
1608                  --  accept statement we want to output messages now, since
1609                  --  we know we already have all information at hand, and we
1610                  --  also want to have separate warnings for each accept
1611                  --  statement for the same entry.
1612
1613                  if Present (Anod) then
1614                     pragma Assert (Is_Formal (E1));
1615
1616                     --  The unreferenced entity is E1, but post the warning
1617                     --  on the body entity for this accept statement.
1618
1619                     if not Warnings_Off_E1 then
1620                        Warn_On_Unreferenced_Entity
1621                          (E1, Body_Formal (E1, Accept_Statement => Anod));
1622                     end if;
1623
1624                  elsif not Warnings_Off_E1
1625                    and then not Has_Junk_Name (E1)
1626                  then
1627                     Unreferenced_Entities.Append (E1);
1628                  end if;
1629               end if;
1630
1631            --  Generic units are referenced in the generic body, but if they
1632            --  are not public and never instantiated we want to force a
1633            --  warning on them. We treat them as redundant constructs to
1634            --  minimize noise.
1635
1636            elsif Is_Generic_Subprogram (E1)
1637              and then not Is_Instantiated (E1)
1638              and then not Publicly_Referenceable (E1)
1639              and then Instantiation_Depth (Sloc (E1)) = 0
1640              and then Warn_On_Redundant_Constructs
1641            then
1642               if not Warnings_Off_E1 and then not Has_Junk_Name (E1) then
1643                  Unreferenced_Entities.Append (E1);
1644
1645                  --  Force warning on entity
1646
1647                  Set_Referenced (E1, False);
1648               end if;
1649            end if;
1650         end if;
1651
1652         --  Recurse into nested package or block. Do not recurse into a formal
1653         --  package, because the corresponding body is not analyzed.
1654
1655         <<Continue>>
1656            if (Is_Package_Or_Generic_Package (E1)
1657                 and then Nkind (Parent (E1)) = N_Package_Specification
1658                 and then
1659                   Nkind (Original_Node (Unit_Declaration_Node (E1))) /=
1660                                                N_Formal_Package_Declaration)
1661
1662              or else Ekind (E1) = E_Block
1663            then
1664               Check_References (E1);
1665            end if;
1666
1667            Next_Entity (E1);
1668      end loop;
1669   end Check_References;
1670
1671   ---------------------------
1672   -- Check_Unset_Reference --
1673   ---------------------------
1674
1675   procedure Check_Unset_Reference (N : Node_Id) is
1676      Typ : constant Entity_Id := Etype (N);
1677
1678      function Is_OK_Fully_Initialized return Boolean;
1679      --  This function returns true if the given node N is fully initialized
1680      --  so that the reference is safe as far as this routine is concerned.
1681      --  Safe generally means that the type of N is a fully initialized type.
1682      --  The one special case is that for access types, which are always fully
1683      --  initialized, we don't consider a dereference OK since it will surely
1684      --  be dereferencing a null value, which won't do.
1685
1686      function Prefix_Has_Dereference (Pref : Node_Id) return Boolean;
1687      --  Used to test indexed or selected component or slice to see if the
1688      --  evaluation of the prefix depends on a dereference, and if so, returns
1689      --  True, in which case we always check the prefix, even if we know that
1690      --  the referenced component is initialized. Pref is the prefix to test.
1691
1692      -----------------------------
1693      -- Is_OK_Fully_Initialized --
1694      -----------------------------
1695
1696      function Is_OK_Fully_Initialized return Boolean is
1697      begin
1698         if Is_Access_Type (Typ) and then Is_Dereferenced (N) then
1699            return False;
1700
1701         --  If a type has Default_Initial_Condition set, or it inherits it,
1702         --  DIC might be specified with a boolean value, meaning that the type
1703         --  is considered to be fully default initialized (SPARK RM 3.1 and
1704         --  SPARK RM 7.3.3). To avoid generating spurious warnings in this
1705         --  case, consider all types with DIC as fully initialized.
1706
1707         elsif Has_Default_Init_Cond (Typ)
1708           or else Has_Inherited_Default_Init_Cond (Typ)
1709         then
1710            return True;
1711
1712         else
1713            return Is_Fully_Initialized_Type (Typ);
1714         end if;
1715      end Is_OK_Fully_Initialized;
1716
1717      ----------------------------
1718      -- Prefix_Has_Dereference --
1719      ----------------------------
1720
1721      function Prefix_Has_Dereference (Pref : Node_Id) return Boolean is
1722      begin
1723         --  If prefix is of an access type, it certainly needs a dereference
1724
1725         if Is_Access_Type (Etype (Pref)) then
1726            return True;
1727
1728         --  If prefix is explicit dereference, that's a dereference for sure
1729
1730         elsif Nkind (Pref) = N_Explicit_Dereference then
1731            return True;
1732
1733            --  If prefix is itself a component reference or slice check prefix
1734
1735         elsif Nkind (Pref) = N_Slice
1736           or else Nkind (Pref) = N_Indexed_Component
1737           or else Nkind (Pref) = N_Selected_Component
1738         then
1739            return Prefix_Has_Dereference (Prefix (Pref));
1740
1741         --  All other cases do not involve a dereference
1742
1743         else
1744            return False;
1745         end if;
1746      end Prefix_Has_Dereference;
1747
1748   --  Start of processing for Check_Unset_Reference
1749
1750   begin
1751      --  Nothing to do if warnings suppressed
1752
1753      if Warning_Mode = Suppress then
1754         return;
1755      end if;
1756
1757      --  Nothing to do for numeric or string literal. Do this test early to
1758      --  save time in a common case (it does not matter that we do not include
1759      --  character literal here, since that will be caught later on in the
1760      --  when others branch of the case statement).
1761
1762      if Nkind (N) in N_Numeric_Or_String_Literal then
1763         return;
1764      end if;
1765
1766      --  Ignore reference unless it comes from source. Almost always if we
1767      --  have a reference from generated code, it is bogus (e.g. calls to init
1768      --  procs to set default discriminant values).
1769
1770      if not Comes_From_Source (N) then
1771         return;
1772      end if;
1773
1774      --  Otherwise see what kind of node we have. If the entity already has an
1775      --  unset reference, it is not necessarily the earliest in the text,
1776      --  because resolution of the prefix of selected components is completed
1777      --  before the resolution of the selected component itself. As a result,
1778      --  given (R /= null and then R.X > 0), the occurrences of R are examined
1779      --  in right-to-left order. If there is already an unset reference, we
1780      --  check whether N is earlier before proceeding.
1781
1782      case Nkind (N) is
1783
1784         --  For identifier or expanded name, examine the entity involved
1785
1786         when N_Identifier | N_Expanded_Name =>
1787            declare
1788               E : constant Entity_Id := Entity (N);
1789
1790            begin
1791               if Ekind_In (E, E_Variable, E_Out_Parameter)
1792                 and then Never_Set_In_Source_Check_Spec (E)
1793                 and then not Has_Initial_Value (E)
1794                 and then (No (Unset_Reference (E))
1795                            or else
1796                              Earlier_In_Extended_Unit
1797                                (Sloc (N), Sloc (Unset_Reference (E))))
1798                 and then not Has_Pragma_Unmodified_Check_Spec (E)
1799                 and then not Warnings_Off_Check_Spec (E)
1800                 and then not Has_Junk_Name (E)
1801               then
1802                  --  We may have an unset reference. The first test is whether
1803                  --  this is an access to a discriminant of a record or a
1804                  --  component with default initialization. Both of these
1805                  --  cases can be ignored, since the actual object that is
1806                  --  referenced is definitely initialized. Note that this
1807                  --  covers the case of reading discriminants of an OUT
1808                  --  parameter, which is OK even in Ada 83.
1809
1810                  --  Note that we are only interested in a direct reference to
1811                  --  a record component here. If the reference is through an
1812                  --  access type, then the access object is being referenced,
1813                  --  not the record, and still deserves an unset reference.
1814
1815                  if Nkind (Parent (N)) = N_Selected_Component
1816                    and not Is_Access_Type (Typ)
1817                  then
1818                     declare
1819                        ES : constant Entity_Id :=
1820                               Entity (Selector_Name (Parent (N)));
1821                     begin
1822                        if Ekind (ES) = E_Discriminant
1823                          or else
1824                            (Present (Declaration_Node (ES))
1825                               and then
1826                             Present (Expression (Declaration_Node (ES))))
1827                        then
1828                           return;
1829                        end if;
1830                     end;
1831                  end if;
1832
1833                  --  Exclude fully initialized types
1834
1835                  if Is_OK_Fully_Initialized then
1836                     return;
1837                  end if;
1838
1839                  --  Here we have a potential unset reference. But before we
1840                  --  get worried about it, we have to make sure that the
1841                  --  entity declaration is in the same procedure as the
1842                  --  reference, since if they are in separate procedures, then
1843                  --  we have no idea about sequential execution.
1844
1845                  --  The tests in the loop below catch all such cases, but do
1846                  --  allow the reference to appear in a loop, block, or
1847                  --  package spec that is nested within the declaring scope.
1848                  --  As always, it is possible to construct cases where the
1849                  --  warning is wrong, that is why it is a warning.
1850
1851                  Potential_Unset_Reference : declare
1852                     SR : Entity_Id;
1853                     SE : constant Entity_Id := Scope (E);
1854
1855                     function Within_Postcondition return Boolean;
1856                     --  Returns True if N is within a Postcondition, a
1857                     --  Refined_Post, an Ensures component in a Test_Case,
1858                     --  or a Contract_Cases.
1859
1860                     --------------------------
1861                     -- Within_Postcondition --
1862                     --------------------------
1863
1864                     function Within_Postcondition return Boolean is
1865                        Nod, P : Node_Id;
1866
1867                     begin
1868                        Nod := Parent (N);
1869                        while Present (Nod) loop
1870                           if Nkind (Nod) = N_Pragma
1871                             and then Nam_In (Pragma_Name (Nod),
1872                                              Name_Postcondition,
1873                                              Name_Refined_Post,
1874                                              Name_Contract_Cases)
1875                           then
1876                              return True;
1877
1878                           elsif Present (Parent (Nod)) then
1879                              P := Parent (Nod);
1880
1881                              if Nkind (P) = N_Pragma
1882                                and then Pragma_Name (P) = Name_Test_Case
1883                                and then Nod = Test_Case_Arg (P, Name_Ensures)
1884                              then
1885                                 return True;
1886                              end if;
1887                           end if;
1888
1889                           Nod := Parent (Nod);
1890                        end loop;
1891
1892                        return False;
1893                     end Within_Postcondition;
1894
1895                  --  Start of processing for Potential_Unset_Reference
1896
1897                  begin
1898                     SR := Current_Scope;
1899                     while SR /= SE loop
1900                        if SR = Standard_Standard
1901                          or else Is_Subprogram (SR)
1902                          or else Is_Concurrent_Body (SR)
1903                          or else Is_Concurrent_Type (SR)
1904                        then
1905                           return;
1906                        end if;
1907
1908                        SR := Scope (SR);
1909                     end loop;
1910
1911                     --  Case of reference has an access type. This is a
1912                     --  special case since access types are always set to null
1913                     --  so cannot be truly uninitialized, but we still want to
1914                     --  warn about cases of obvious null dereference.
1915
1916                     if Is_Access_Type (Typ) then
1917                        Access_Type_Case : declare
1918                           P : Node_Id;
1919
1920                           function Process
1921                             (N : Node_Id) return Traverse_Result;
1922                           --  Process function for instantiation of Traverse
1923                           --  below. Checks if N contains reference to E other
1924                           --  than a dereference.
1925
1926                           function Ref_In (Nod : Node_Id) return Boolean;
1927                           --  Determines whether Nod contains a reference to
1928                           --  the entity E that is not a dereference.
1929
1930                           -------------
1931                           -- Process --
1932                           -------------
1933
1934                           function Process
1935                             (N : Node_Id) return Traverse_Result
1936                           is
1937                           begin
1938                              if Is_Entity_Name (N)
1939                                and then Entity (N) = E
1940                                and then not Is_Dereferenced (N)
1941                              then
1942                                 return Abandon;
1943                              else
1944                                 return OK;
1945                              end if;
1946                           end Process;
1947
1948                           ------------
1949                           -- Ref_In --
1950                           ------------
1951
1952                           function Ref_In (Nod : Node_Id) return Boolean is
1953                              function Traverse is new Traverse_Func (Process);
1954                           begin
1955                              return Traverse (Nod) = Abandon;
1956                           end Ref_In;
1957
1958                        --  Start of processing for Access_Type_Case
1959
1960                        begin
1961                           --  Don't bother if we are inside an instance, since
1962                           --  the compilation of the generic template is where
1963                           --  the warning should be issued.
1964
1965                           if In_Instance then
1966                              return;
1967                           end if;
1968
1969                           --  Don't bother if this is not the main unit. If we
1970                           --  try to give this warning for with'ed units, we
1971                           --  get some false positives, since we do not record
1972                           --  references in other units.
1973
1974                           if not In_Extended_Main_Source_Unit (E)
1975                                or else
1976                              not In_Extended_Main_Source_Unit (N)
1977                           then
1978                              return;
1979                           end if;
1980
1981                           --  We are only interested in dereferences
1982
1983                           if not Is_Dereferenced (N) then
1984                              return;
1985                           end if;
1986
1987                           --  One more check, don't bother with references
1988                           --  that are inside conditional statements or WHILE
1989                           --  loops if the condition references the entity in
1990                           --  question. This avoids most false positives.
1991
1992                           P := Parent (N);
1993                           loop
1994                              P := Parent (P);
1995                              exit when No (P);
1996
1997                              if Nkind_In (P, N_If_Statement, N_Elsif_Part)
1998                                and then Ref_In (Condition (P))
1999                              then
2000                                 return;
2001
2002                              elsif Nkind (P) = N_Loop_Statement
2003                                and then Present (Iteration_Scheme (P))
2004                                and then
2005                                  Ref_In (Condition (Iteration_Scheme (P)))
2006                              then
2007                                 return;
2008                              end if;
2009                           end loop;
2010                        end Access_Type_Case;
2011                     end if;
2012
2013                     --  One more check, don't bother if we are within a
2014                     --  postcondition, since the expression occurs in a
2015                     --  place unrelated to the actual test.
2016
2017                     if not Within_Postcondition then
2018
2019                        --  Here we definitely have a case for giving a warning
2020                        --  for a reference to an unset value. But we don't
2021                        --  give the warning now. Instead set Unset_Reference
2022                        --  in the identifier involved. The reason for this is
2023                        --  that if we find the variable is never ever assigned
2024                        --  a value then that warning is more important and
2025                        --  there is no point in giving the reference warning.
2026
2027                        --  If this is an identifier, set the field directly
2028
2029                        if Nkind (N) = N_Identifier then
2030                           Set_Unset_Reference (E, N);
2031
2032                        --  Otherwise it is an expanded name, so set the field
2033                        --  of the actual identifier for the reference.
2034
2035                        else
2036                           Set_Unset_Reference (E, Selector_Name (N));
2037                        end if;
2038                     end if;
2039                  end Potential_Unset_Reference;
2040               end if;
2041            end;
2042
2043         --  Indexed component or slice
2044
2045         when N_Indexed_Component | N_Slice =>
2046
2047            --  If prefix does not involve dereferencing an access type, then
2048            --  we know we are OK if the component type is fully initialized,
2049            --  since the component will have been set as part of the default
2050            --  initialization.
2051
2052            if not Prefix_Has_Dereference (Prefix (N))
2053              and then Is_OK_Fully_Initialized
2054            then
2055               return;
2056
2057            --  Look at prefix in access type case, or if the component is not
2058            --  fully initialized.
2059
2060            else
2061               Check_Unset_Reference (Prefix (N));
2062            end if;
2063
2064         --  Record component
2065
2066         when N_Selected_Component =>
2067            declare
2068               Pref : constant Node_Id   := Prefix (N);
2069               Ent  : constant Entity_Id := Entity (Selector_Name (N));
2070
2071            begin
2072               --  If prefix involves dereferencing an access type, always
2073               --  check the prefix, since the issue then is whether this
2074               --  access value is null.
2075
2076               if Prefix_Has_Dereference (Pref) then
2077                  null;
2078
2079               --  Always go to prefix if no selector entity is set. Can this
2080               --  happen in the normal case? Not clear, but it definitely can
2081               --  happen in error cases.
2082
2083               elsif No (Ent) then
2084                  null;
2085
2086               --  For a record component, check some cases where we have
2087               --  reasonable cause to consider that the component is known to
2088               --  be or probably is initialized. In this case, we don't care
2089               --  if the prefix itself was explicitly initialized.
2090
2091               --  Discriminants are always considered initialized
2092
2093               elsif Ekind (Ent) = E_Discriminant then
2094                  return;
2095
2096               --  An explicitly initialized component is certainly initialized
2097
2098               elsif Nkind (Parent (Ent)) = N_Component_Declaration
2099                 and then Present (Expression (Parent (Ent)))
2100               then
2101                  return;
2102
2103               --  A fully initialized component is initialized
2104
2105               elsif Is_OK_Fully_Initialized then
2106                  return;
2107               end if;
2108
2109               --  If none of those cases apply, check the record type prefix
2110
2111               Check_Unset_Reference (Pref);
2112            end;
2113
2114         --  For type conversions, qualifications, or expressions with actions,
2115         --  examine the expression.
2116
2117         when N_Type_Conversion         |
2118              N_Qualified_Expression    |
2119              N_Expression_With_Actions =>
2120            Check_Unset_Reference (Expression (N));
2121
2122         --  For explicit dereference, always check prefix, which will generate
2123         --  an unset reference (since this is a case of dereferencing null).
2124
2125         when N_Explicit_Dereference =>
2126            Check_Unset_Reference (Prefix (N));
2127
2128         --  All other cases are not cases of an unset reference
2129
2130         when others =>
2131            null;
2132
2133      end case;
2134   end Check_Unset_Reference;
2135
2136   ------------------------
2137   -- Check_Unused_Withs --
2138   ------------------------
2139
2140   procedure Check_Unused_Withs (Spec_Unit : Unit_Number_Type := No_Unit) is
2141      Cnode : Node_Id;
2142      Item  : Node_Id;
2143      Lunit : Node_Id;
2144      Ent   : Entity_Id;
2145
2146      Munite : constant Entity_Id := Cunit_Entity (Main_Unit);
2147      --  This is needed for checking the special renaming case
2148
2149      procedure Check_One_Unit (Unit : Unit_Number_Type);
2150      --  Subsidiary procedure, performs checks for specified unit
2151
2152      --------------------
2153      -- Check_One_Unit --
2154      --------------------
2155
2156      procedure Check_One_Unit (Unit : Unit_Number_Type) is
2157         Is_Visible_Renaming : Boolean := False;
2158         Pack                : Entity_Id;
2159
2160         procedure Check_Inner_Package (Pack : Entity_Id);
2161         --  Pack is a package local to a unit in a with_clause. Both the unit
2162         --  and Pack are referenced. If none of the entities in Pack are
2163         --  referenced, then the only occurrence of Pack is in a USE clause
2164         --  or a pragma, and a warning is worthwhile as well.
2165
2166         function Check_System_Aux return Boolean;
2167         --  Before giving a warning on a with_clause for System, check whether
2168         --  a system extension is present.
2169
2170         function Find_Package_Renaming
2171           (P : Entity_Id;
2172            L : Entity_Id) return Entity_Id;
2173         --  The only reference to a context unit may be in a renaming
2174         --  declaration. If this renaming declares a visible entity, do not
2175         --  warn that the context clause could be moved to the body, because
2176         --  the renaming may be intended to re-export the unit.
2177
2178         function Has_Visible_Entities (P : Entity_Id) return Boolean;
2179         --  This function determines if a package has any visible entities.
2180         --  True is returned if there is at least one declared visible entity,
2181         --  otherwise False is returned (e.g. case of only pragmas present).
2182
2183         -------------------------
2184         -- Check_Inner_Package --
2185         -------------------------
2186
2187         procedure Check_Inner_Package (Pack : Entity_Id) is
2188            E  : Entity_Id;
2189            Un : constant Node_Id := Sinfo.Unit (Cnode);
2190
2191            function Check_Use_Clause (N : Node_Id) return Traverse_Result;
2192            --  If N is a use_clause for Pack, emit warning
2193
2194            procedure Check_Use_Clauses is new
2195              Traverse_Proc (Check_Use_Clause);
2196
2197            ----------------------
2198            -- Check_Use_Clause --
2199            ----------------------
2200
2201            function Check_Use_Clause (N : Node_Id) return Traverse_Result is
2202               Nam  : Node_Id;
2203
2204            begin
2205               if Nkind (N) = N_Use_Package_Clause then
2206                  Nam := First (Names (N));
2207                  while Present (Nam) loop
2208                     if Entity (Nam) = Pack then
2209
2210                        --  Suppress message if any serious errors detected
2211                        --  that turn off expansion, and thus result in false
2212                        --  positives for this warning.
2213
2214                        if Serious_Errors_Detected = 0 then
2215                           Error_Msg_Qual_Level := 1;
2216                           Error_Msg_NE -- CODEFIX
2217                             ("?u?no entities of package& are referenced!",
2218                                Nam, Pack);
2219                           Error_Msg_Qual_Level := 0;
2220                        end if;
2221                     end if;
2222
2223                     Next (Nam);
2224                  end loop;
2225               end if;
2226
2227               return OK;
2228            end Check_Use_Clause;
2229
2230         --  Start of processing for Check_Inner_Package
2231
2232         begin
2233            E := First_Entity (Pack);
2234            while Present (E) loop
2235               if Referenced_Check_Spec (E) then
2236                  return;
2237               end if;
2238
2239               Next_Entity (E);
2240            end loop;
2241
2242            --  No entities of the package are referenced. Check whether the
2243            --  reference to the package itself is a use clause, and if so
2244            --  place a warning on it.
2245
2246            Check_Use_Clauses (Un);
2247         end Check_Inner_Package;
2248
2249         ----------------------
2250         -- Check_System_Aux --
2251         ----------------------
2252
2253         function Check_System_Aux return Boolean is
2254            Ent : Entity_Id;
2255
2256         begin
2257            if Chars (Lunit) = Name_System
2258               and then Scope (Lunit) = Standard_Standard
2259               and then Present_System_Aux
2260            then
2261               Ent := First_Entity (System_Aux_Id);
2262               while Present (Ent) loop
2263                  if Referenced_Check_Spec (Ent) then
2264                     return True;
2265                  end if;
2266
2267                  Next_Entity (Ent);
2268               end loop;
2269            end if;
2270
2271            return False;
2272         end Check_System_Aux;
2273
2274         ---------------------------
2275         -- Find_Package_Renaming --
2276         ---------------------------
2277
2278         function Find_Package_Renaming
2279           (P : Entity_Id;
2280            L : Entity_Id) return Entity_Id
2281         is
2282            E1 : Entity_Id;
2283            R  : Entity_Id;
2284
2285         begin
2286            Is_Visible_Renaming := False;
2287
2288            E1 := First_Entity (P);
2289            while Present (E1) loop
2290               if Ekind (E1) = E_Package and then Renamed_Object (E1) = L then
2291                  Is_Visible_Renaming := not Is_Hidden (E1);
2292                  return E1;
2293
2294               elsif Ekind (E1) = E_Package
2295                 and then No (Renamed_Object (E1))
2296                 and then not Is_Generic_Instance (E1)
2297               then
2298                  R := Find_Package_Renaming (E1, L);
2299
2300                  if Present (R) then
2301                     Is_Visible_Renaming := not Is_Hidden (R);
2302                     return R;
2303                  end if;
2304               end if;
2305
2306               Next_Entity (E1);
2307            end loop;
2308
2309            return Empty;
2310         end Find_Package_Renaming;
2311
2312         --------------------------
2313         -- Has_Visible_Entities --
2314         --------------------------
2315
2316         function Has_Visible_Entities (P : Entity_Id) return Boolean is
2317            E : Entity_Id;
2318
2319         begin
2320            --  If unit in context is not a package, it is a subprogram that
2321            --  is not called or a generic unit that is not instantiated
2322            --  in the current unit, and warning is appropriate.
2323
2324            if Ekind (P) /= E_Package then
2325               return True;
2326            end if;
2327
2328            --  If unit comes from a limited_with clause, look for declaration
2329            --  of shadow entities.
2330
2331            if Present (Limited_View (P)) then
2332               E := First_Entity (Limited_View (P));
2333            else
2334               E := First_Entity (P);
2335            end if;
2336
2337            while Present (E) and then E /= First_Private_Entity (P) loop
2338               if Comes_From_Source (E) or else Present (Limited_View (P)) then
2339                  return True;
2340               end if;
2341
2342               Next_Entity (E);
2343            end loop;
2344
2345            return False;
2346         end Has_Visible_Entities;
2347
2348      --  Start of processing for Check_One_Unit
2349
2350      begin
2351         Cnode := Cunit (Unit);
2352
2353         --  Only do check in units that are part of the extended main unit.
2354         --  This is actually a necessary restriction, because in the case of
2355         --  subprogram acting as its own specification, there can be with's in
2356         --  subunits that we will not see.
2357
2358         if not In_Extended_Main_Source_Unit (Cnode) then
2359            return;
2360
2361         --  In configurable run time mode, we remove the bodies of non-inlined
2362         --  subprograms, which may lead to spurious warnings, which are
2363         --  clearly undesirable.
2364
2365         elsif Configurable_Run_Time_Mode
2366           and then Is_Predefined_File_Name (Unit_File_Name (Unit))
2367         then
2368            return;
2369         end if;
2370
2371         --  Loop through context items in this unit
2372
2373         Item := First (Context_Items (Cnode));
2374         while Present (Item) loop
2375            if Nkind (Item) = N_With_Clause
2376              and then not Implicit_With (Item)
2377              and then In_Extended_Main_Source_Unit (Item)
2378
2379              --  Guard for no entity present. Not clear under what conditions
2380              --  this happens, but it does occur, and since this is only a
2381              --  warning, we just suppress the warning in this case.
2382
2383              and then Nkind (Name (Item)) in N_Has_Entity
2384              and then Present (Entity (Name (Item)))
2385            then
2386               Lunit := Entity (Name (Item));
2387
2388               --  Check if this unit is referenced (skip the check if this
2389               --  is explicitly marked by a pragma Unreferenced).
2390
2391               if not Referenced (Lunit) and then not Has_Unreferenced (Lunit)
2392               then
2393                  --  Suppress warnings in internal units if not in -gnatg mode
2394                  --  (these would be junk warnings for an application program,
2395                  --  since they refer to problems in internal units).
2396
2397                  if GNAT_Mode
2398                    or else not Is_Internal_File_Name (Unit_File_Name (Unit))
2399                  then
2400                     --  Here we definitely have a non-referenced unit. If it
2401                     --  is the special call for a spec unit, then just set the
2402                     --  flag to be read later.
2403
2404                     if Unit = Spec_Unit then
2405                        Set_Unreferenced_In_Spec (Item);
2406
2407                     --  Otherwise simple unreferenced message, but skip this
2408                     --  if no visible entities, because that is most likely a
2409                     --  case where warning would be false positive (e.g. a
2410                     --  package with only a linker options pragma and nothing
2411                     --  else or a pragma elaborate with a body library task).
2412
2413                     elsif Has_Visible_Entities (Entity (Name (Item))) then
2414                        Error_Msg_N -- CODEFIX
2415                          ("?u?unit& is not referenced!", Name (Item));
2416                     end if;
2417                  end if;
2418
2419               --  If main unit is a renaming of this unit, then we consider
2420               --  the with to be OK (obviously it is needed in this case).
2421               --  This may be transitive: the unit in the with_clause may
2422               --  itself be a renaming, in which case both it and the main
2423               --  unit rename the same ultimate package.
2424
2425               elsif Present (Renamed_Entity (Munite))
2426                  and then
2427                    (Renamed_Entity (Munite) = Lunit
2428                      or else Renamed_Entity (Munite) = Renamed_Entity (Lunit))
2429               then
2430                  null;
2431
2432               --  If this unit is referenced, and it is a package, we do
2433               --  another test, to see if any of the entities in the package
2434               --  are referenced. If none of the entities are referenced, we
2435               --  still post a warning. This occurs if the only use of the
2436               --  package is in a use clause, or in a package renaming
2437               --  declaration. This check is skipped for packages that are
2438               --  renamed in a spec, since the entities in such a package are
2439               --  visible to clients via the renaming.
2440
2441               elsif Ekind (Lunit) = E_Package
2442                 and then not Renamed_In_Spec (Lunit)
2443               then
2444                  --  If Is_Instantiated is set, it means that the package is
2445                  --  implicitly instantiated (this is the case of parent
2446                  --  instance or an actual for a generic package formal), and
2447                  --  this counts as a reference.
2448
2449                  if Is_Instantiated (Lunit) then
2450                     null;
2451
2452                  --  If no entities in package, and there is a pragma
2453                  --  Elaborate_Body present, then assume that this with is
2454                  --  done for purposes of this elaboration.
2455
2456                  elsif No (First_Entity (Lunit))
2457                    and then Has_Pragma_Elaborate_Body (Lunit)
2458                  then
2459                     null;
2460
2461                  --  Otherwise see if any entities have been referenced
2462
2463                  else
2464                     if Limited_Present (Item) then
2465                        Ent := First_Entity (Limited_View (Lunit));
2466                     else
2467                        Ent := First_Entity (Lunit);
2468                     end if;
2469
2470                     loop
2471                        --  No more entities, and we did not find one that was
2472                        --  referenced. Means we have a definite case of a with
2473                        --  none of whose entities was referenced.
2474
2475                        if No (Ent) then
2476
2477                           --  If in spec, just set the flag
2478
2479                           if Unit = Spec_Unit then
2480                              Set_No_Entities_Ref_In_Spec (Item);
2481
2482                           elsif Check_System_Aux then
2483                              null;
2484
2485                           --  Else the warning may be needed
2486
2487                           else
2488                              declare
2489                                 Eitem : constant Entity_Id :=
2490                                           Entity (Name (Item));
2491
2492                              begin
2493                                 --  Warn if we unreferenced flag set and we
2494                                 --  have not had serious errors. The reason we
2495                                 --  inhibit the message if there are errors is
2496                                 --  to prevent false positives from disabling
2497                                 --  expansion.
2498
2499                                 if not Has_Unreferenced (Eitem)
2500                                   and then Serious_Errors_Detected = 0
2501                                 then
2502                                    --  Get possible package renaming
2503
2504                                    Pack :=
2505                                      Find_Package_Renaming (Munite, Lunit);
2506
2507                                    --  No warning if either the package or its
2508                                    --  renaming is used as a generic actual.
2509
2510                                    if Used_As_Generic_Actual (Eitem)
2511                                      or else
2512                                        (Present (Pack)
2513                                          and then
2514                                            Used_As_Generic_Actual (Pack))
2515                                    then
2516                                       exit;
2517                                    end if;
2518
2519                                    --  Here we give the warning
2520
2521                                    Error_Msg_N -- CODEFIX
2522                                      ("?u?no entities of & are referenced!",
2523                                       Name (Item));
2524
2525                                    --  Flag renaming of package as well. If
2526                                    --  the original package has warnings off,
2527                                    --  we suppress the warning on the renaming
2528                                    --  as well.
2529
2530                                    if Present (Pack)
2531                                      and then not Has_Warnings_Off (Lunit)
2532                                      and then not Has_Unreferenced (Pack)
2533                                    then
2534                                       Error_Msg_NE -- CODEFIX
2535                                         ("?u?no entities of& are referenced!",
2536                                          Unit_Declaration_Node (Pack), Pack);
2537                                    end if;
2538                                 end if;
2539                              end;
2540                           end if;
2541
2542                           exit;
2543
2544                        --  Case of entity being referenced. The reference may
2545                        --  come from a limited_with_clause, in which case the
2546                        --  limited view of the entity carries the flag.
2547
2548                        elsif Referenced_Check_Spec (Ent)
2549                          or else Referenced_As_LHS_Check_Spec (Ent)
2550                          or else Referenced_As_Out_Parameter_Check_Spec (Ent)
2551                          or else
2552                            (From_Limited_With (Ent)
2553                              and then Is_Incomplete_Type (Ent)
2554                              and then Present (Non_Limited_View (Ent))
2555                              and then Referenced (Non_Limited_View (Ent)))
2556                        then
2557                           --  This means that the with is indeed fine, in that
2558                           --  it is definitely needed somewhere, and we can
2559                           --  quit worrying about this one...
2560
2561                           --  Except for one little detail: if either of the
2562                           --  flags was set during spec processing, this is
2563                           --  where we complain that the with could be moved
2564                           --  from the spec. If the spec contains a visible
2565                           --  renaming of the package, inhibit warning to move
2566                           --  with_clause to body.
2567
2568                           if Ekind (Munite) = E_Package_Body then
2569                              Pack :=
2570                                Find_Package_Renaming
2571                                  (Spec_Entity (Munite), Lunit);
2572                           else
2573                              Pack := Empty;
2574                           end if;
2575
2576                           --  If a renaming is present in the spec do not warn
2577                           --  because the body or child unit may depend on it.
2578
2579                           if Present (Pack)
2580                             and then Renamed_Entity (Pack) = Lunit
2581                           then
2582                              exit;
2583
2584                           elsif Unreferenced_In_Spec (Item) then
2585                              Error_Msg_N -- CODEFIX
2586                                ("?u?unit& is not referenced in spec!",
2587                                 Name (Item));
2588
2589                           elsif No_Entities_Ref_In_Spec (Item) then
2590                              Error_Msg_N -- CODEFIX
2591                                ("?u?no entities of & are referenced in spec!",
2592                                 Name (Item));
2593
2594                           else
2595                              if Ekind (Ent) = E_Package then
2596                                 Check_Inner_Package (Ent);
2597                              end if;
2598
2599                              exit;
2600                           end if;
2601
2602                           if not Is_Visible_Renaming then
2603                              Error_Msg_N -- CODEFIX
2604                                ("\?u?with clause might be moved to body!",
2605                                 Name (Item));
2606                           end if;
2607
2608                           exit;
2609
2610                        --  Move to next entity to continue search
2611
2612                        else
2613                           Next_Entity (Ent);
2614                        end if;
2615                     end loop;
2616                  end if;
2617
2618               --  For a generic package, the only interesting kind of
2619               --  reference is an instantiation, since entities cannot be
2620               --  referenced directly.
2621
2622               elsif Is_Generic_Unit (Lunit) then
2623
2624                  --  Unit was never instantiated, set flag for case of spec
2625                  --  call, or give warning for normal call.
2626
2627                  if not Is_Instantiated (Lunit) then
2628                     if Unit = Spec_Unit then
2629                        Set_Unreferenced_In_Spec (Item);
2630                     else
2631                        Error_Msg_N -- CODEFIX
2632                          ("?u?unit& is never instantiated!", Name (Item));
2633                     end if;
2634
2635                  --  If unit was indeed instantiated, make sure that flag is
2636                  --  not set showing it was uninstantiated in the spec, and if
2637                  --  so, give warning.
2638
2639                  elsif Unreferenced_In_Spec (Item) then
2640                     Error_Msg_N
2641                       ("?u?unit& is not instantiated in spec!", Name (Item));
2642                     Error_Msg_N -- CODEFIX
2643                       ("\?u?with clause can be moved to body!", Name (Item));
2644                  end if;
2645               end if;
2646            end if;
2647
2648            Next (Item);
2649         end loop;
2650      end Check_One_Unit;
2651
2652   --  Start of processing for Check_Unused_Withs
2653
2654   begin
2655      --  Immediate return if no semantics or warning flag not set
2656
2657      if not Opt.Check_Withs or else Operating_Mode = Check_Syntax then
2658         return;
2659      end if;
2660
2661      Process_Deferred_References;
2662
2663      --  Flag any unused with clauses. For a subunit, check only the units
2664      --  in its context, not those of the parent, which may be needed by other
2665      --  subunits.  We will get the full warnings when we compile the parent,
2666      --  but the following is helpful when compiling a subunit by itself.
2667
2668      if Nkind (Unit (Cunit (Main_Unit))) = N_Subunit then
2669         if Current_Sem_Unit = Main_Unit then
2670            Check_One_Unit (Main_Unit);
2671         end if;
2672
2673         return;
2674      end if;
2675
2676      --  Process specified units
2677
2678      if Spec_Unit = No_Unit then
2679
2680         --  For main call, check all units
2681
2682         for Unit in Main_Unit .. Last_Unit loop
2683            Check_One_Unit (Unit);
2684         end loop;
2685
2686      else
2687         --  For call for spec, check only the spec
2688
2689         Check_One_Unit (Spec_Unit);
2690      end if;
2691   end Check_Unused_Withs;
2692
2693   ---------------------------------
2694   -- Generic_Package_Spec_Entity --
2695   ---------------------------------
2696
2697   function Generic_Package_Spec_Entity (E : Entity_Id) return Boolean is
2698      S : Entity_Id;
2699
2700   begin
2701      if Is_Package_Body_Entity (E) then
2702         return False;
2703
2704      else
2705         S := Scope (E);
2706         loop
2707            if S = Standard_Standard then
2708               return False;
2709
2710            elsif Ekind (S) = E_Generic_Package then
2711               return True;
2712
2713            elsif Ekind (S) = E_Package then
2714               S := Scope (S);
2715
2716            else
2717               return False;
2718            end if;
2719         end loop;
2720      end if;
2721   end Generic_Package_Spec_Entity;
2722
2723   ----------------------
2724   -- Goto_Spec_Entity --
2725   ----------------------
2726
2727   function Goto_Spec_Entity (E : Entity_Id) return Entity_Id is
2728   begin
2729      if Is_Formal (E) and then Present (Spec_Entity (E)) then
2730         return Spec_Entity (E);
2731      else
2732         return E;
2733      end if;
2734   end Goto_Spec_Entity;
2735
2736   -------------------
2737   -- Has_Junk_Name --
2738   -------------------
2739
2740   function Has_Junk_Name (E : Entity_Id) return Boolean is
2741      function Match (S : String) return Boolean;
2742      --  Return true if substring S is found in Name_Buffer (1 .. Name_Len)
2743
2744      -----------
2745      -- Match --
2746      -----------
2747
2748      function Match (S : String) return Boolean is
2749         Slen1 : constant Integer := S'Length - 1;
2750
2751      begin
2752         for J in 1 .. Name_Len - S'Length + 1 loop
2753            if Name_Buffer (J .. J + Slen1) = S then
2754               return True;
2755            end if;
2756         end loop;
2757
2758         return False;
2759      end Match;
2760
2761   --  Start of processing for Has_Junk_Name
2762
2763   begin
2764      Get_Unqualified_Decoded_Name_String (Chars (E));
2765
2766      return
2767        Match ("discard") or else
2768        Match ("dummy")   or else
2769        Match ("ignore")  or else
2770        Match ("junk")    or else
2771        Match ("unused");
2772   end Has_Junk_Name;
2773
2774   --------------------------------------
2775   -- Has_Pragma_Unmodified_Check_Spec --
2776   --------------------------------------
2777
2778   function Has_Pragma_Unmodified_Check_Spec
2779     (E : Entity_Id) return Boolean
2780   is
2781   begin
2782      if Is_Formal (E) and then Present (Spec_Entity (E)) then
2783
2784         --  Note: use of OR instead of OR ELSE here is deliberate, we want
2785         --  to mess with Unmodified flags on both body and spec entities.
2786
2787         return Has_Unmodified (E)
2788                  or
2789                Has_Unmodified (Spec_Entity (E));
2790
2791      else
2792         return Has_Unmodified (E);
2793      end if;
2794   end Has_Pragma_Unmodified_Check_Spec;
2795
2796   ----------------------------------------
2797   -- Has_Pragma_Unreferenced_Check_Spec --
2798   ----------------------------------------
2799
2800   function Has_Pragma_Unreferenced_Check_Spec
2801     (E : Entity_Id) return Boolean
2802   is
2803   begin
2804      if Is_Formal (E) and then Present (Spec_Entity (E)) then
2805
2806         --  Note: use of OR here instead of OR ELSE is deliberate, we want
2807         --  to mess with flags on both entities.
2808
2809         return Has_Unreferenced (E)
2810                  or
2811                Has_Unreferenced (Spec_Entity (E));
2812
2813      else
2814         return Has_Unreferenced (E);
2815      end if;
2816   end Has_Pragma_Unreferenced_Check_Spec;
2817
2818   ----------------
2819   -- Initialize --
2820   ----------------
2821
2822   procedure Initialize is
2823   begin
2824      Warnings_Off_Pragmas.Init;
2825      Unreferenced_Entities.Init;
2826      In_Out_Warnings.Init;
2827   end Initialize;
2828
2829   ------------------------------------
2830   -- Never_Set_In_Source_Check_Spec --
2831   ------------------------------------
2832
2833   function Never_Set_In_Source_Check_Spec (E : Entity_Id) return Boolean is
2834   begin
2835      if Is_Formal (E) and then Present (Spec_Entity (E)) then
2836         return Never_Set_In_Source (E)
2837                  and then
2838                Never_Set_In_Source (Spec_Entity (E));
2839      else
2840         return Never_Set_In_Source (E);
2841      end if;
2842   end Never_Set_In_Source_Check_Spec;
2843
2844   -------------------------------------
2845   -- Operand_Has_Warnings_Suppressed --
2846   -------------------------------------
2847
2848   function Operand_Has_Warnings_Suppressed (N : Node_Id) return Boolean is
2849
2850      function Check_For_Warnings (N : Node_Id) return Traverse_Result;
2851      --  Function used to check one node to see if it is or was originally
2852      --  a reference to an entity for which Warnings are off. If so, Abandon
2853      --  is returned, otherwise OK_Orig is returned to continue the traversal
2854      --  of the original expression.
2855
2856      function Traverse is new Traverse_Func (Check_For_Warnings);
2857      --  Function used to traverse tree looking for warnings
2858
2859      ------------------------
2860      -- Check_For_Warnings --
2861      ------------------------
2862
2863      function Check_For_Warnings (N : Node_Id) return Traverse_Result is
2864         R : constant Node_Id := Original_Node (N);
2865
2866      begin
2867         if Nkind (R) in N_Has_Entity
2868           and then Present (Entity (R))
2869           and then Has_Warnings_Off (Entity (R))
2870         then
2871            return Abandon;
2872         else
2873            return OK_Orig;
2874         end if;
2875      end Check_For_Warnings;
2876
2877   --  Start of processing for Operand_Has_Warnings_Suppressed
2878
2879   begin
2880      return Traverse (N) = Abandon;
2881
2882   --  If any exception occurs, then something has gone wrong, and this is
2883   --  only a minor aesthetic issue anyway, so just say we did not find what
2884   --  we are looking for, rather than blow up.
2885
2886   exception
2887      when others =>
2888         return False;
2889   end Operand_Has_Warnings_Suppressed;
2890
2891   -----------------------------------------
2892   -- Output_Non_Modified_In_Out_Warnings --
2893   -----------------------------------------
2894
2895   procedure Output_Non_Modified_In_Out_Warnings is
2896
2897      function No_Warn_On_In_Out (E : Entity_Id) return Boolean;
2898      --  Given a formal parameter entity E, determines if there is a reason to
2899      --  suppress IN OUT warnings (not modified, could be IN) for formals of
2900      --  the subprogram. We suppress these warnings if Warnings Off is set, or
2901      --  if we have seen the address of the subprogram being taken, or if the
2902      --  subprogram is used as a generic actual (in the latter cases the
2903      --  context may force use of IN OUT, even if the parameter is not
2904      --  modifies for this particular case.
2905
2906      -----------------------
2907      -- No_Warn_On_In_Out --
2908      -----------------------
2909
2910      function No_Warn_On_In_Out (E : Entity_Id) return Boolean is
2911         S  : constant Entity_Id := Scope (E);
2912         SE : constant Entity_Id := Spec_Entity (E);
2913
2914      begin
2915         --  Do not warn if address is taken, since funny business may be going
2916         --  on in treating the parameter indirectly as IN OUT.
2917
2918         if Address_Taken (S)
2919           or else (Present (SE) and then Address_Taken (Scope (SE)))
2920         then
2921            return True;
2922
2923         --  Do not warn if used as a generic actual, since the generic may be
2924         --  what is forcing the use of an "unnecessary" IN OUT.
2925
2926         elsif Used_As_Generic_Actual (S)
2927           or else (Present (SE) and then Used_As_Generic_Actual (Scope (SE)))
2928         then
2929            return True;
2930
2931         --  Else test warnings off
2932
2933         elsif Warnings_Off_Check_Spec (S) then
2934            return True;
2935
2936         --  All tests for suppressing warning failed
2937
2938         else
2939            return False;
2940         end if;
2941      end No_Warn_On_In_Out;
2942
2943   --  Start of processing for Output_Non_Modified_In_Out_Warnings
2944
2945   begin
2946      --  Loop through entities for which a warning may be needed
2947
2948      for J in In_Out_Warnings.First .. In_Out_Warnings.Last loop
2949         declare
2950            E1 : constant Entity_Id := In_Out_Warnings.Table (J);
2951
2952         begin
2953            --  Suppress warning in specific cases (see details in comments for
2954            --  No_Warn_On_In_Out), or if there is a pragma Unmodified.
2955
2956            if Has_Pragma_Unmodified_Check_Spec (E1)
2957              or else No_Warn_On_In_Out (E1)
2958            then
2959               null;
2960
2961            --  Here we generate the warning
2962
2963            else
2964               --  If -gnatwc is set then output message that we could be IN
2965
2966               if not Is_Trivial_Subprogram (Scope (E1)) then
2967                  if Warn_On_Constant then
2968                     Error_Msg_N
2969                       ("?u?formal parameter & is not modified!", E1);
2970                     Error_Msg_N
2971                       ("\?u?mode could be IN instead of `IN OUT`!", E1);
2972
2973                     --  We do not generate warnings for IN OUT parameters
2974                     --  unless we have at least -gnatwu. This is deliberately
2975                     --  inconsistent with the treatment of variables, but
2976                     --  otherwise we get too many unexpected warnings in
2977                     --  default mode.
2978
2979                  elsif Check_Unreferenced then
2980                     Error_Msg_N
2981                       ("?u?formal parameter& is read but "
2982                        & "never assigned!", E1);
2983                  end if;
2984               end if;
2985
2986               --  Kill any other warnings on this entity, since this is the
2987               --  one that should dominate any other unreferenced warning.
2988
2989               Set_Warnings_Off (E1);
2990            end if;
2991         end;
2992      end loop;
2993   end Output_Non_Modified_In_Out_Warnings;
2994
2995   ----------------------------------------
2996   -- Output_Obsolescent_Entity_Warnings --
2997   ----------------------------------------
2998
2999   procedure Output_Obsolescent_Entity_Warnings (N : Node_Id; E : Entity_Id) is
3000      P : constant Node_Id := Parent (N);
3001      S : Entity_Id;
3002
3003   begin
3004      S := Current_Scope;
3005
3006      --  Do not output message if we are the scope of standard. This means
3007      --  we have a reference from a context clause from when it is originally
3008      --  processed, and that's too early to tell whether it is an obsolescent
3009      --  unit doing the with'ing. In Sem_Ch10.Analyze_Compilation_Unit we make
3010      --  sure that we have a later call when the scope is available. This test
3011      --  also eliminates all messages for use clauses, which is fine (we do
3012      --  not want messages for use clauses, since they are always redundant
3013      --  with respect to the associated with clause).
3014
3015      if S = Standard_Standard then
3016         return;
3017      end if;
3018
3019      --  Do not output message if we are in scope of an obsolescent package
3020      --  or subprogram.
3021
3022      loop
3023         if Is_Obsolescent (S) then
3024            return;
3025         end if;
3026
3027         S := Scope (S);
3028         exit when S = Standard_Standard;
3029      end loop;
3030
3031      --  Here we will output the message
3032
3033      Error_Msg_Sloc := Sloc (E);
3034
3035      --  Case of with clause
3036
3037      if Nkind (P) = N_With_Clause then
3038         if Ekind (E) = E_Package then
3039            Error_Msg_NE
3040              ("?j?with of obsolescent package& declared#", N, E);
3041         elsif Ekind (E) = E_Procedure then
3042            Error_Msg_NE
3043              ("?j?with of obsolescent procedure& declared#", N, E);
3044         else
3045            Error_Msg_NE
3046              ("??with of obsolescent function& declared#", N, E);
3047         end if;
3048
3049      --  If we do not have a with clause, then ignore any reference to an
3050      --  obsolescent package name. We only want to give the one warning of
3051      --  withing the package, not one each time it is used to qualify.
3052
3053      elsif Ekind (E) = E_Package then
3054         return;
3055
3056      --  Procedure call statement
3057
3058      elsif Nkind (P) = N_Procedure_Call_Statement then
3059         Error_Msg_NE
3060           ("??call to obsolescent procedure& declared#", N, E);
3061
3062      --  Function call
3063
3064      elsif Nkind (P) = N_Function_Call then
3065         Error_Msg_NE
3066           ("??call to obsolescent function& declared#", N, E);
3067
3068      --  Reference to obsolescent type
3069
3070      elsif Is_Type (E) then
3071         Error_Msg_NE
3072           ("??reference to obsolescent type& declared#", N, E);
3073
3074      --  Reference to obsolescent component
3075
3076      elsif Ekind_In (E, E_Component, E_Discriminant) then
3077         Error_Msg_NE
3078           ("??reference to obsolescent component& declared#", N, E);
3079
3080      --  Reference to obsolescent variable
3081
3082      elsif Ekind (E) = E_Variable then
3083         Error_Msg_NE
3084           ("??reference to obsolescent variable& declared#", N, E);
3085
3086      --  Reference to obsolescent constant
3087
3088      elsif Ekind (E) = E_Constant or else Ekind (E) in Named_Kind then
3089         Error_Msg_NE
3090           ("??reference to obsolescent constant& declared#", N, E);
3091
3092      --  Reference to obsolescent enumeration literal
3093
3094      elsif Ekind (E) = E_Enumeration_Literal then
3095         Error_Msg_NE
3096           ("??reference to obsolescent enumeration literal& declared#", N, E);
3097
3098      --  Generic message for any other case we missed
3099
3100      else
3101         Error_Msg_NE
3102           ("??reference to obsolescent entity& declared#", N, E);
3103      end if;
3104
3105      --  Output additional warning if present
3106
3107      for J in Obsolescent_Warnings.First .. Obsolescent_Warnings.Last loop
3108         if Obsolescent_Warnings.Table (J).Ent = E then
3109            String_To_Name_Buffer (Obsolescent_Warnings.Table (J).Msg);
3110            Error_Msg_Strlen := Name_Len;
3111            Error_Msg_String (1 .. Name_Len) := Name_Buffer (1 .. Name_Len);
3112            Error_Msg_N ("\\??~", N);
3113            exit;
3114         end if;
3115      end loop;
3116   end Output_Obsolescent_Entity_Warnings;
3117
3118   ----------------------------------
3119   -- Output_Unreferenced_Messages --
3120   ----------------------------------
3121
3122   procedure Output_Unreferenced_Messages is
3123   begin
3124      for J in Unreferenced_Entities.First .. Unreferenced_Entities.Last loop
3125         Warn_On_Unreferenced_Entity (Unreferenced_Entities.Table (J));
3126      end loop;
3127   end Output_Unreferenced_Messages;
3128
3129   -----------------------------------------
3130   -- Output_Unused_Warnings_Off_Warnings --
3131   -----------------------------------------
3132
3133   procedure Output_Unused_Warnings_Off_Warnings is
3134   begin
3135      for J in Warnings_Off_Pragmas.First .. Warnings_Off_Pragmas.Last loop
3136         declare
3137            Wentry : Warnings_Off_Entry renames Warnings_Off_Pragmas.Table (J);
3138            N      : Node_Id renames Wentry.N;
3139            E      : Node_Id renames Wentry.E;
3140
3141         begin
3142            --  Turn off Warnings_Off, or we won't get the warning
3143
3144            Set_Warnings_Off (E, False);
3145
3146            --  Nothing to do if pragma was used to suppress a general warning
3147
3148            if Warnings_Off_Used (E) then
3149               null;
3150
3151            --  If pragma was used both in unmodified and unreferenced contexts
3152            --  then that's as good as the general case, no warning.
3153
3154            elsif Warnings_Off_Used_Unmodified (E)
3155                    and
3156                  Warnings_Off_Used_Unreferenced (E)
3157            then
3158               null;
3159
3160            --  Used only in context where Unmodified would have worked
3161
3162            elsif Warnings_Off_Used_Unmodified (E) then
3163               Error_Msg_NE
3164                 ("?W?could use Unmodified instead of "
3165                  & "Warnings Off for &", Pragma_Identifier (N), E);
3166
3167            --  Used only in context where Unreferenced would have worked
3168
3169            elsif Warnings_Off_Used_Unreferenced (E) then
3170               Error_Msg_NE
3171                 ("?W?could use Unreferenced instead of "
3172                  & "Warnings Off for &", Pragma_Identifier (N), E);
3173
3174            --  Not used at all
3175
3176            else
3177               Error_Msg_NE
3178                 ("?W?pragma Warnings Off for & unused, "
3179                  & "could be omitted", N, E);
3180            end if;
3181         end;
3182      end loop;
3183   end Output_Unused_Warnings_Off_Warnings;
3184
3185   ---------------------------
3186   -- Referenced_Check_Spec --
3187   ---------------------------
3188
3189   function Referenced_Check_Spec (E : Entity_Id) return Boolean is
3190   begin
3191      if Is_Formal (E) and then Present (Spec_Entity (E)) then
3192         return Referenced (E) or else Referenced (Spec_Entity (E));
3193      else
3194         return Referenced (E);
3195      end if;
3196   end Referenced_Check_Spec;
3197
3198   ----------------------------------
3199   -- Referenced_As_LHS_Check_Spec --
3200   ----------------------------------
3201
3202   function Referenced_As_LHS_Check_Spec (E : Entity_Id) return Boolean is
3203   begin
3204      if Is_Formal (E) and then Present (Spec_Entity (E)) then
3205         return Referenced_As_LHS (E)
3206           or else Referenced_As_LHS (Spec_Entity (E));
3207      else
3208         return Referenced_As_LHS (E);
3209      end if;
3210   end Referenced_As_LHS_Check_Spec;
3211
3212   --------------------------------------------
3213   -- Referenced_As_Out_Parameter_Check_Spec --
3214   --------------------------------------------
3215
3216   function Referenced_As_Out_Parameter_Check_Spec
3217     (E : Entity_Id) return Boolean
3218   is
3219   begin
3220      if Is_Formal (E) and then Present (Spec_Entity (E)) then
3221         return Referenced_As_Out_Parameter (E)
3222           or else Referenced_As_Out_Parameter (Spec_Entity (E));
3223      else
3224         return Referenced_As_Out_Parameter (E);
3225      end if;
3226   end Referenced_As_Out_Parameter_Check_Spec;
3227
3228   -----------------------------
3229   -- Warn_On_Known_Condition --
3230   -----------------------------
3231
3232   procedure Warn_On_Known_Condition (C : Node_Id) is
3233      P           : Node_Id;
3234      Orig        : constant Node_Id := Original_Node (C);
3235      Test_Result : Boolean;
3236
3237      function Is_Known_Branch return Boolean;
3238      --  If the type of the condition is Boolean, the constant value of the
3239      --  condition is a boolean literal. If the type is a derived boolean
3240      --  type, the constant is wrapped in a type conversion of the derived
3241      --  literal. If the value of the condition is not a literal, no warnings
3242      --  can be produced. This function returns True if the result can be
3243      --  determined, and Test_Result is set True/False accordingly. Otherwise
3244      --  False is returned, and Test_Result is unchanged.
3245
3246      procedure Track (N : Node_Id; Loc : Node_Id);
3247      --  Adds continuation warning(s) pointing to reason (assignment or test)
3248      --  for the operand of the conditional having a known value (or at least
3249      --  enough is known about the value to issue the warning). N is the node
3250      --  which is judged to have a known value. Loc is the warning location.
3251
3252      ---------------------
3253      -- Is_Known_Branch --
3254      ---------------------
3255
3256      function Is_Known_Branch return Boolean is
3257      begin
3258         if Etype (C) = Standard_Boolean
3259           and then Is_Entity_Name (C)
3260           and then
3261             (Entity (C) = Standard_False or else Entity (C) = Standard_True)
3262         then
3263            Test_Result := Entity (C) = Standard_True;
3264            return True;
3265
3266         elsif Is_Boolean_Type (Etype (C))
3267           and then Nkind (C) = N_Unchecked_Type_Conversion
3268           and then Is_Entity_Name (Expression (C))
3269           and then Ekind (Entity (Expression (C))) = E_Enumeration_Literal
3270         then
3271            Test_Result :=
3272              Chars (Entity (Expression (C))) = Chars (Standard_True);
3273            return True;
3274
3275         else
3276            return False;
3277         end if;
3278      end Is_Known_Branch;
3279
3280      -----------
3281      -- Track --
3282      -----------
3283
3284      procedure Track (N : Node_Id; Loc : Node_Id) is
3285         Nod : constant Node_Id := Original_Node (N);
3286
3287      begin
3288         if Nkind (Nod) in N_Op_Compare then
3289            Track (Left_Opnd (Nod), Loc);
3290            Track (Right_Opnd (Nod), Loc);
3291
3292         elsif Is_Entity_Name (Nod) and then Is_Object (Entity (Nod)) then
3293            declare
3294               CV : constant Node_Id := Current_Value (Entity (Nod));
3295
3296            begin
3297               if Present (CV) then
3298                  Error_Msg_Sloc := Sloc (CV);
3299
3300                  if Nkind (CV) not in N_Subexpr then
3301                     Error_Msg_N ("\\??(see test #)", Loc);
3302
3303                  elsif Nkind (Parent (CV)) =
3304                          N_Case_Statement_Alternative
3305                  then
3306                     Error_Msg_N ("\\??(see case alternative #)", Loc);
3307
3308                  else
3309                     Error_Msg_N ("\\??(see assignment #)", Loc);
3310                  end if;
3311               end if;
3312            end;
3313         end if;
3314      end Track;
3315
3316   --  Start of processing for Warn_On_Known_Condition
3317
3318   begin
3319      --  Adjust SCO condition if from source
3320
3321      if Generate_SCO
3322        and then Comes_From_Source (Orig)
3323        and then Is_Known_Branch
3324      then
3325         declare
3326            Atrue : Boolean;
3327
3328         begin
3329            Atrue := Test_Result;
3330
3331            if Present (Parent (C)) and then Nkind (Parent (C)) = N_Op_Not then
3332               Atrue := not Atrue;
3333            end if;
3334
3335            Set_SCO_Condition (Orig, Atrue);
3336         end;
3337      end if;
3338
3339      --  Argument replacement in an inlined body can make conditions static.
3340      --  Do not emit warnings in this case.
3341
3342      if In_Inlined_Body then
3343         return;
3344      end if;
3345
3346      if Constant_Condition_Warnings
3347        and then Is_Known_Branch
3348        and then Comes_From_Source (Orig)
3349        and then not In_Instance
3350      then
3351         --  Don't warn if comparison of result of attribute against a constant
3352         --  value, since this is likely legitimate conditional compilation.
3353
3354         if Nkind (Orig) in N_Op_Compare
3355           and then Compile_Time_Known_Value (Right_Opnd (Orig))
3356           and then Nkind (Original_Node (Left_Opnd (Orig))) =
3357                                                     N_Attribute_Reference
3358         then
3359            return;
3360         end if;
3361
3362         --  See if this is in a statement or a declaration
3363
3364         P := Parent (C);
3365         loop
3366            --  If tree is not attached, do not issue warning (this is very
3367            --  peculiar, and probably arises from some other error condition)
3368
3369            if No (P) then
3370               return;
3371
3372            --  If we are in a declaration, then no warning, since in practice
3373            --  conditionals in declarations are used for intended tests which
3374            --  may be known at compile time, e.g. things like
3375
3376            --    x : constant Integer := 2 + (Word'Size = 32);
3377
3378            --  And a warning is annoying in such cases
3379
3380            elsif Nkind (P) in N_Declaration
3381                    or else
3382                  Nkind (P) in N_Later_Decl_Item
3383            then
3384               return;
3385
3386            --  Don't warn in assert or check pragma, since presumably tests in
3387            --  such a context are very definitely intended, and might well be
3388            --  known at compile time. Note that we have to test the original
3389            --  node, since assert pragmas get rewritten at analysis time.
3390
3391            elsif Nkind (Original_Node (P)) = N_Pragma
3392              and then Nam_In (Pragma_Name (Original_Node (P)), Name_Assert,
3393                                                                Name_Check)
3394            then
3395               return;
3396            end if;
3397
3398            exit when Is_Statement (P);
3399            P := Parent (P);
3400         end loop;
3401
3402         --  Here we issue the warning unless some sub-operand has warnings
3403         --  set off, in which case we suppress the warning for the node. If
3404         --  the original expression is an inequality, it has been expanded
3405         --  into a negation, and the value of the original expression is the
3406         --  negation of the equality. If the expression is an entity that
3407         --  appears within a negation, it is clearer to flag the negation
3408         --  itself, and report on its constant value.
3409
3410         if not Operand_Has_Warnings_Suppressed (C) then
3411            declare
3412               True_Branch : Boolean := Test_Result;
3413               Cond        : Node_Id := C;
3414
3415            begin
3416               if Present (Parent (C))
3417                 and then Nkind (Parent (C)) = N_Op_Not
3418               then
3419                  True_Branch := not True_Branch;
3420                  Cond := Parent (C);
3421               end if;
3422
3423               --  Condition always True
3424
3425               if True_Branch then
3426                  if Is_Entity_Name (Original_Node (C))
3427                    and then Nkind (Cond) /= N_Op_Not
3428                  then
3429                     Error_Msg_NE
3430                       ("object & is always True at this point?c?",
3431                        Cond, Original_Node (C));
3432                     Track (Original_Node (C), Cond);
3433
3434                  else
3435                     Error_Msg_N ("condition is always True?c?", Cond);
3436                     Track (Cond, Cond);
3437                  end if;
3438
3439               --  Condition always False
3440
3441               else
3442                  if Is_Entity_Name (Original_Node (C))
3443                    and then Nkind (Cond) /= N_Op_Not
3444                  then
3445                     Error_Msg_NE
3446                       ("object & is always False at this point?c?",
3447                        Cond, Original_Node (C));
3448                     Track (Original_Node (C), Cond);
3449
3450                  else
3451                     Error_Msg_N ("condition is always False?c?", Cond);
3452                     Track (Cond, Cond);
3453                  end if;
3454               end if;
3455            end;
3456         end if;
3457      end if;
3458   end Warn_On_Known_Condition;
3459
3460   ---------------------------------------
3461   -- Warn_On_Modified_As_Out_Parameter --
3462   ---------------------------------------
3463
3464   function Warn_On_Modified_As_Out_Parameter (E : Entity_Id) return Boolean is
3465   begin
3466      return
3467        (Warn_On_Modified_Unread and then Is_Only_Out_Parameter (E))
3468          or else Warn_On_All_Unread_Out_Parameters;
3469   end Warn_On_Modified_As_Out_Parameter;
3470
3471   ---------------------------------
3472   -- Warn_On_Overlapping_Actuals --
3473   ---------------------------------
3474
3475   procedure Warn_On_Overlapping_Actuals (Subp : Entity_Id; N : Node_Id) is
3476      Act1, Act2   : Node_Id;
3477      Form1, Form2 : Entity_Id;
3478
3479      function Is_Covered_Formal (Formal : Node_Id) return Boolean;
3480      --  Return True if Formal is covered by the rule
3481
3482      function Refer_Same_Object (Act1, Act2 : Node_Id) return Boolean;
3483      --  Two names are known to refer to the same object if the two names
3484      --  are known to denote the same object; or one of the names is a
3485      --  selected_component, indexed_component, or slice and its prefix is
3486      --  known to refer to the same object as the other name; or one of the
3487      --  two names statically denotes a renaming declaration whose renamed
3488      --  object_name is known to refer to the same object as the other name
3489      --  (RM 6.4.1(6.11/3))
3490
3491      -----------------------
3492      -- Refer_Same_Object --
3493      -----------------------
3494
3495      function Refer_Same_Object (Act1, Act2 : Node_Id) return Boolean is
3496      begin
3497         return Denotes_Same_Object (Act1, Act2)
3498           or else Denotes_Same_Prefix (Act1, Act2);
3499      end Refer_Same_Object;
3500
3501      -----------------------
3502      -- Is_Covered_Formal --
3503      -----------------------
3504
3505      function Is_Covered_Formal (Formal : Node_Id) return Boolean is
3506      begin
3507         return
3508           Ekind_In (Formal, E_Out_Parameter, E_In_Out_Parameter)
3509             and then (Is_Elementary_Type (Etype (Formal))
3510                        or else Is_Record_Type (Etype (Formal))
3511                        or else Is_Array_Type (Etype (Formal)));
3512      end Is_Covered_Formal;
3513
3514   begin
3515      if Ada_Version < Ada_2012 and then not Warn_On_Overlap then
3516         return;
3517      end if;
3518
3519      --  Exclude calls rewritten as enumeration literals
3520
3521      if Nkind (N) not in N_Subprogram_Call
3522        and then Nkind (N) /= N_Entry_Call_Statement
3523      then
3524         return;
3525      end if;
3526
3527      --  If a call C has two or more parameters of mode in out or out that are
3528      --  of an elementary type, then the call is legal only if for each name
3529      --  N that is passed as a parameter of mode in out or out to the call C,
3530      --  there is no other name among the other parameters of mode in out or
3531      --  out to C that is known to denote the same object (RM 6.4.1(6.15/3))
3532
3533      --  If appropriate warning switch is set, we also report warnings on
3534      --  overlapping parameters that are record types or array types.
3535
3536      Form1 := First_Formal (Subp);
3537      Act1  := First_Actual (N);
3538      while Present (Form1) and then Present (Act1) loop
3539         if Is_Covered_Formal (Form1) then
3540            Form2 := First_Formal (Subp);
3541            Act2  := First_Actual (N);
3542            while Present (Form2) and then Present (Act2) loop
3543               if Form1 /= Form2
3544                 and then Is_Covered_Formal (Form2)
3545                 and then Refer_Same_Object (Act1, Act2)
3546               then
3547                  --  Guard against previous errors
3548
3549                  if Error_Posted (N)
3550                    or else No (Etype (Act1))
3551                    or else No (Etype (Act2))
3552                  then
3553                     null;
3554
3555                  --  If the actual is a function call in prefix notation,
3556                  --  there is no real overlap.
3557
3558                  elsif Nkind (Act2) = N_Function_Call then
3559                     null;
3560
3561                  --  If type is not by-copy, assume that aliasing is intended
3562
3563                  elsif
3564                    Present (Underlying_Type (Etype (Form1)))
3565                      and then
3566                        (Is_By_Reference_Type (Underlying_Type (Etype (Form1)))
3567                          or else
3568                            Convention (Underlying_Type (Etype (Form1))) =
3569                                              Convention_Ada_Pass_By_Reference)
3570                  then
3571                     null;
3572
3573                  --  Under Ada 2012 we only report warnings on overlapping
3574                  --  arrays and record types if switch is set.
3575
3576                  elsif Ada_Version >= Ada_2012
3577                    and then not Is_Elementary_Type (Etype (Form1))
3578                    and then not Warn_On_Overlap
3579                  then
3580                     null;
3581
3582                  --  Here we may need to issue overlap message
3583
3584                  else
3585                     Error_Msg_Warn :=
3586
3587                       --  Overlap checking is an error only in Ada 2012. For
3588                       --  earlier versions of Ada, this is a warning.
3589
3590                       Ada_Version < Ada_2012
3591
3592                       --  Overlap is only illegal in Ada 2012 in the case of
3593                       --  elementary types (passed by copy). For other types,
3594                       --  we always have a warning in all Ada versions.
3595
3596                       or else not Is_Elementary_Type (Etype (Form1))
3597
3598                       --  Finally, debug flag -gnatd.E changes the error to a
3599                       --  warning even in Ada 2012 mode.
3600
3601                       or else Error_To_Warning;
3602
3603                     declare
3604                        Act  : Node_Id;
3605                        Form : Entity_Id;
3606
3607                     begin
3608                        --  Find matching actual
3609
3610                        Act  := First_Actual (N);
3611                        Form := First_Formal (Subp);
3612                        while Act /= Act2 loop
3613                           Next_Formal (Form);
3614                           Next_Actual (Act);
3615                        end loop;
3616
3617                        if Is_Elementary_Type (Etype (Act1))
3618                          and then Ekind (Form2) = E_In_Parameter
3619                        then
3620                           null;  --  No real aliasing
3621
3622                        elsif Is_Elementary_Type (Etype (Act2))
3623                          and then Ekind (Form2) = E_In_Parameter
3624                        then
3625                           null;  --  Ditto
3626
3627                        --  If the call was written in prefix notation, and
3628                        --  thus its prefix before rewriting was a selected
3629                        --  component, count only visible actuals in the call.
3630
3631                        elsif Is_Entity_Name (First_Actual (N))
3632                          and then Nkind (Original_Node (N)) = Nkind (N)
3633                          and then Nkind (Name (Original_Node (N))) =
3634                                                         N_Selected_Component
3635                          and then
3636                            Is_Entity_Name (Prefix (Name (Original_Node (N))))
3637                          and then
3638                            Entity (Prefix (Name (Original_Node (N)))) =
3639                              Entity (First_Actual (N))
3640                        then
3641                           if Act1 = First_Actual (N) then
3642                              Error_Msg_FE
3643                                ("<<`IN OUT` prefix overlaps with "
3644                                 & "actual for&", Act1, Form);
3645
3646                           else
3647                              --  For greater clarity, give name of formal
3648
3649                              Error_Msg_Node_2 := Form;
3650                              Error_Msg_FE
3651                                ("<<writable actual for & overlaps with "
3652                                 & "actual for&", Act1, Form);
3653                           end if;
3654
3655                        else
3656                           --  For greater clarity, give name of formal
3657
3658                           Error_Msg_Node_2 := Form;
3659
3660                           --  This is one of the messages
3661
3662                           Error_Msg_FE
3663                             ("<<writable actual for & overlaps with "
3664                              & "actual for&", Act1, Form1);
3665                        end if;
3666                     end;
3667                  end if;
3668
3669                  return;
3670               end if;
3671
3672               Next_Formal (Form2);
3673               Next_Actual (Act2);
3674            end loop;
3675         end if;
3676
3677         Next_Formal (Form1);
3678         Next_Actual (Act1);
3679      end loop;
3680   end Warn_On_Overlapping_Actuals;
3681
3682   ------------------------------
3683   -- Warn_On_Suspicious_Index --
3684   ------------------------------
3685
3686   procedure Warn_On_Suspicious_Index (Name : Entity_Id; X : Node_Id) is
3687
3688      Low_Bound : Uint;
3689      --  Set to lower bound for a suspicious type
3690
3691      Ent : Entity_Id;
3692      --  Entity for array reference
3693
3694      Typ : Entity_Id;
3695      --  Array type
3696
3697      function Is_Suspicious_Type (Typ : Entity_Id) return Boolean;
3698      --  Tests to see if Typ is a type for which we may have a suspicious
3699      --  index, namely an unconstrained array type, whose lower bound is
3700      --  either zero or one. If so, True is returned, and Low_Bound is set
3701      --  to this lower bound. If not, False is returned, and Low_Bound is
3702      --  undefined on return.
3703      --
3704      --  For now, we limit this to standard string types, so any other
3705      --  unconstrained types return False. We may change our minds on this
3706      --  later on, but strings seem the most important case.
3707
3708      procedure Test_Suspicious_Index;
3709      --  Test if index is of suspicious type and if so, generate warning
3710
3711      ------------------------
3712      -- Is_Suspicious_Type --
3713      ------------------------
3714
3715      function Is_Suspicious_Type (Typ : Entity_Id) return Boolean is
3716         LB : Node_Id;
3717
3718      begin
3719         if Is_Array_Type (Typ)
3720           and then not Is_Constrained (Typ)
3721           and then Number_Dimensions (Typ) = 1
3722           and then Is_Standard_String_Type (Typ)
3723           and then not Has_Warnings_Off (Typ)
3724         then
3725            LB := Type_Low_Bound (Etype (First_Index (Typ)));
3726
3727            if Compile_Time_Known_Value (LB) then
3728               Low_Bound := Expr_Value (LB);
3729               return Low_Bound = Uint_0 or else Low_Bound = Uint_1;
3730            end if;
3731         end if;
3732
3733         return False;
3734      end Is_Suspicious_Type;
3735
3736      ---------------------------
3737      -- Test_Suspicious_Index --
3738      ---------------------------
3739
3740      procedure Test_Suspicious_Index is
3741
3742         function Length_Reference (N : Node_Id) return Boolean;
3743         --  Check if node N is of the form Name'Length
3744
3745         procedure Warn1;
3746         --  Generate first warning line
3747
3748         ----------------------
3749         -- Length_Reference --
3750         ----------------------
3751
3752         function Length_Reference (N : Node_Id) return Boolean is
3753            R : constant Node_Id := Original_Node (N);
3754         begin
3755            return
3756              Nkind (R) = N_Attribute_Reference
3757                and then Attribute_Name (R) = Name_Length
3758                and then Is_Entity_Name (Prefix (R))
3759                and then Entity (Prefix (R)) = Ent;
3760         end Length_Reference;
3761
3762         -----------
3763         -- Warn1 --
3764         -----------
3765
3766         procedure Warn1 is
3767         begin
3768            Error_Msg_Uint_1 := Low_Bound;
3769            Error_Msg_FE -- CODEFIX
3770              ("?w?index for& may assume lower bound of^", X, Ent);
3771         end Warn1;
3772
3773      --  Start of processing for Test_Suspicious_Index
3774
3775      begin
3776         --  Nothing to do if subscript does not come from source (we don't
3777         --  want to give garbage warnings on compiler expanded code, e.g. the
3778         --  loops generated for slice assignments. Such junk warnings would
3779         --  be placed on source constructs with no subscript in sight).
3780
3781         if not Comes_From_Source (Original_Node (X)) then
3782            return;
3783         end if;
3784
3785         --  Case where subscript is a constant integer
3786
3787         if Nkind (X) = N_Integer_Literal then
3788            Warn1;
3789
3790            --  Case where original form of subscript is an integer literal
3791
3792            if Nkind (Original_Node (X)) = N_Integer_Literal then
3793               if Intval (X) = Low_Bound then
3794                  Error_Msg_FE -- CODEFIX
3795                    ("\?w?suggested replacement: `&''First`", X, Ent);
3796               else
3797                  Error_Msg_Uint_1 := Intval (X) - Low_Bound;
3798                  Error_Msg_FE -- CODEFIX
3799                    ("\?w?suggested replacement: `&''First + ^`", X, Ent);
3800
3801               end if;
3802
3803            --  Case where original form of subscript is more complex
3804
3805            else
3806               --  Build string X'First - 1 + expression where the expression
3807               --  is the original subscript. If the expression starts with "1
3808               --  + ", then the "- 1 + 1" is elided.
3809
3810               Error_Msg_String (1 .. 13) := "'First - 1 + ";
3811               Error_Msg_Strlen := 13;
3812
3813               declare
3814                  Sref : Source_Ptr := Sloc (First_Node (Original_Node (X)));
3815                  Tref : constant Source_Buffer_Ptr :=
3816                           Source_Text (Get_Source_File_Index (Sref));
3817                  --  Tref (Sref) is used to scan the subscript
3818
3819                  Pctr : Natural;
3820                  --  Parentheses counter when scanning subscript
3821
3822               begin
3823                  --  Tref (Sref) points to start of subscript
3824
3825                  --  Elide - 1 if subscript starts with 1 +
3826
3827                  if Tref (Sref .. Sref + 2) = "1 +" then
3828                     Error_Msg_Strlen := Error_Msg_Strlen - 6;
3829                     Sref := Sref + 2;
3830
3831                  elsif Tref (Sref .. Sref + 1) = "1+" then
3832                     Error_Msg_Strlen := Error_Msg_Strlen - 6;
3833                     Sref := Sref + 1;
3834                  end if;
3835
3836                  --  Now we will copy the subscript to the string buffer
3837
3838                  Pctr := 0;
3839                  loop
3840                     --  Count parens, exit if terminating right paren. Note
3841                     --  check to ignore paren appearing as character literal.
3842
3843                     if Tref (Sref + 1) = '''
3844                          and then
3845                        Tref (Sref - 1) = '''
3846                     then
3847                        null;
3848                     else
3849                        if Tref (Sref) = '(' then
3850                           Pctr := Pctr + 1;
3851                        elsif Tref (Sref) = ')' then
3852                           exit when Pctr = 0;
3853                           Pctr := Pctr - 1;
3854                        end if;
3855                     end if;
3856
3857                     --  Done if terminating double dot (slice case)
3858
3859                     exit when Pctr = 0
3860                       and then (Tref (Sref .. Sref + 1) = ".."
3861                                   or else
3862                                 Tref (Sref .. Sref + 2) = " ..");
3863
3864                     --  Quit if we have hit EOF character, something wrong
3865
3866                     if Tref (Sref) = EOF then
3867                        return;
3868                     end if;
3869
3870                     --  String literals are too much of a pain to handle
3871
3872                     if Tref (Sref) = '"' or else Tref (Sref) = '%' then
3873                        return;
3874                     end if;
3875
3876                     --  If we have a 'Range reference, then this is a case
3877                     --  where we cannot easily give a replacement. Don't try.
3878
3879                     if Tref (Sref .. Sref + 4) = "range"
3880                       and then Tref (Sref - 1) < 'A'
3881                       and then Tref (Sref + 5) < 'A'
3882                     then
3883                        return;
3884                     end if;
3885
3886                     --  Else store next character
3887
3888                     Error_Msg_Strlen := Error_Msg_Strlen + 1;
3889                     Error_Msg_String (Error_Msg_Strlen) := Tref (Sref);
3890                     Sref := Sref + 1;
3891
3892                     --  If we get more than 40 characters then the expression
3893                     --  is too long to copy, or something has gone wrong. In
3894                     --  either case, just skip the attempt at a suggested fix.
3895
3896                     if Error_Msg_Strlen > 40 then
3897                        return;
3898                     end if;
3899                  end loop;
3900               end;
3901
3902               --  Replacement subscript is now in string buffer
3903
3904               Error_Msg_FE -- CODEFIX
3905                 ("\?w?suggested replacement: `&~`", Original_Node (X), Ent);
3906            end if;
3907
3908         --  Case where subscript is of the form X'Length
3909
3910         elsif Length_Reference (X) then
3911            Warn1;
3912            Error_Msg_Node_2 := Ent;
3913            Error_Msg_FE
3914              ("\?w?suggest replacement of `&''Length` by `&''Last`",
3915               X, Ent);
3916
3917         --  Case where subscript is of the form X'Length - expression
3918
3919         elsif Nkind (X) = N_Op_Subtract
3920           and then Length_Reference (Left_Opnd (X))
3921         then
3922            Warn1;
3923            Error_Msg_Node_2 := Ent;
3924            Error_Msg_FE
3925              ("\?w?suggest replacement of `&''Length` by `&''Last`",
3926               Left_Opnd (X), Ent);
3927         end if;
3928      end Test_Suspicious_Index;
3929
3930   --  Start of processing for Warn_On_Suspicious_Index
3931
3932   begin
3933      --  Only process if warnings activated
3934
3935      if Warn_On_Assumed_Low_Bound then
3936
3937         --  Test if array is simple entity name
3938
3939         if Is_Entity_Name (Name) then
3940
3941            --  Test if array is parameter of unconstrained string type
3942
3943            Ent := Entity (Name);
3944            Typ := Etype (Ent);
3945
3946            if Is_Formal (Ent)
3947              and then Is_Suspicious_Type (Typ)
3948              and then not Low_Bound_Tested (Ent)
3949            then
3950               Test_Suspicious_Index;
3951            end if;
3952         end if;
3953      end if;
3954   end Warn_On_Suspicious_Index;
3955
3956   -------------------------------
3957   -- Warn_On_Suspicious_Update --
3958   -------------------------------
3959
3960   procedure Warn_On_Suspicious_Update (N : Node_Id) is
3961      Par : constant Node_Id := Parent (N);
3962      Arg : Node_Id;
3963
3964   begin
3965      --  Only process if warnings activated
3966
3967      if Warn_On_Suspicious_Contract then
3968         if Nkind_In (Par, N_Op_Eq, N_Op_Ne) then
3969            if N = Left_Opnd (Par) then
3970               Arg := Right_Opnd (Par);
3971            else
3972               Arg := Left_Opnd (Par);
3973            end if;
3974
3975            if Same_Object (Prefix (N), Arg) then
3976               if Nkind (Par) = N_Op_Eq then
3977                  Error_Msg_N
3978                    ("suspicious equality test with modified version of "
3979                     & "same object?T?", Par);
3980               else
3981                  Error_Msg_N
3982                    ("suspicious inequality test with modified version of "
3983                     & "same object?T?", Par);
3984               end if;
3985            end if;
3986         end if;
3987      end if;
3988   end Warn_On_Suspicious_Update;
3989
3990   --------------------------------------
3991   -- Warn_On_Unassigned_Out_Parameter --
3992   --------------------------------------
3993
3994   procedure Warn_On_Unassigned_Out_Parameter
3995     (Return_Node : Node_Id;
3996      Scope_Id    : Entity_Id)
3997   is
3998      Form  : Entity_Id;
3999      Form2 : Entity_Id;
4000
4001   begin
4002      --  Ignore if procedure or return statement does not come from source
4003
4004      if not Comes_From_Source (Scope_Id)
4005        or else not Comes_From_Source (Return_Node)
4006      then
4007         return;
4008      end if;
4009
4010      --  Loop through formals
4011
4012      Form := First_Formal (Scope_Id);
4013      while Present (Form) loop
4014
4015         --  We are only interested in OUT parameters that come from source
4016         --  and are never set in the source, and furthermore only in scalars
4017         --  since non-scalars generate too many false positives.
4018
4019         if Ekind (Form) = E_Out_Parameter
4020           and then Never_Set_In_Source_Check_Spec (Form)
4021           and then Is_Scalar_Type (Etype (Form))
4022           and then not Present (Unset_Reference (Form))
4023         then
4024            --  Before we issue the warning, an add ad hoc defence against the
4025            --  most common case of false positives with this warning which is
4026            --  the case where there is a Boolean OUT parameter that has been
4027            --  set, and whose meaning is "ignore the values of the other
4028            --  parameters". We can't of course reliably tell this case at
4029            --  compile time, but the following test kills a lot of false
4030            --  positives, without generating a significant number of false
4031            --  negatives (missed real warnings).
4032
4033            Form2 := First_Formal (Scope_Id);
4034            while Present (Form2) loop
4035               if Ekind (Form2) = E_Out_Parameter
4036                 and then Root_Type (Etype (Form2)) = Standard_Boolean
4037                 and then not Never_Set_In_Source_Check_Spec (Form2)
4038               then
4039                  return;
4040               end if;
4041
4042               Next_Formal (Form2);
4043            end loop;
4044
4045            --  Here all conditions are met, record possible unset reference
4046
4047            Set_Unset_Reference (Form, Return_Node);
4048         end if;
4049
4050         Next_Formal (Form);
4051      end loop;
4052   end Warn_On_Unassigned_Out_Parameter;
4053
4054   ---------------------------------
4055   -- Warn_On_Unreferenced_Entity --
4056   ---------------------------------
4057
4058   procedure Warn_On_Unreferenced_Entity
4059     (Spec_E : Entity_Id;
4060      Body_E : Entity_Id := Empty)
4061   is
4062      E : Entity_Id := Spec_E;
4063
4064   begin
4065      if not Referenced_Check_Spec (E)
4066        and then not Has_Pragma_Unreferenced_Check_Spec (E)
4067        and then not Warnings_Off_Check_Spec (E)
4068        and then not Has_Junk_Name (Spec_E)
4069        and then not Is_Exported (Spec_E)
4070      then
4071         case Ekind (E) is
4072            when E_Variable =>
4073
4074               --  Case of variable that is assigned but not read. We suppress
4075               --  the message if the variable is volatile, has an address
4076               --  clause, is aliased, or is a renaming, or is imported.
4077
4078               if Referenced_As_LHS_Check_Spec (E)
4079                 and then No (Address_Clause (E))
4080                 and then not Is_Volatile (E)
4081               then
4082                  if Warn_On_Modified_Unread
4083                    and then not Is_Imported (E)
4084                    and then not Is_Aliased (E)
4085                    and then No (Renamed_Object (E))
4086                  then
4087                     if not Has_Pragma_Unmodified_Check_Spec (E) then
4088                        Error_Msg_N -- CODEFIX
4089                          ("?u?variable & is assigned but never read!", E);
4090                     end if;
4091
4092                     Set_Last_Assignment (E, Empty);
4093                  end if;
4094
4095               --  Normal case of neither assigned nor read (exclude variables
4096               --  referenced as out parameters, since we already generated
4097               --  appropriate warnings at the call point in this case).
4098
4099               elsif not Referenced_As_Out_Parameter (E) then
4100
4101                  --  We suppress the message for types for which a valid
4102                  --  pragma Unreferenced_Objects has been given, otherwise
4103                  --  we go ahead and give the message.
4104
4105                  if not Has_Pragma_Unreferenced_Objects (Etype (E)) then
4106
4107                     --  Distinguish renamed case in message
4108
4109                     if Present (Renamed_Object (E))
4110                       and then Comes_From_Source (Renamed_Object (E))
4111                     then
4112                        Error_Msg_N -- CODEFIX
4113                          ("?u?renamed variable & is not referenced!", E);
4114                     else
4115                        Error_Msg_N -- CODEFIX
4116                          ("?u?variable & is not referenced!", E);
4117                     end if;
4118                  end if;
4119               end if;
4120
4121            when E_Constant =>
4122               if not Has_Pragma_Unreferenced_Objects (Etype (E)) then
4123                  if Present (Renamed_Object (E))
4124                    and then Comes_From_Source (Renamed_Object (E))
4125                  then
4126                     Error_Msg_N -- CODEFIX
4127                       ("?u?renamed constant & is not referenced!", E);
4128                  else
4129                     Error_Msg_N -- CODEFIX
4130                       ("?u?constant & is not referenced!", E);
4131                  end if;
4132               end if;
4133
4134            when E_In_Parameter     |
4135                 E_In_Out_Parameter =>
4136
4137               --  Do not emit message for formals of a renaming, because
4138               --  they are never referenced explicitly.
4139
4140               if Nkind (Original_Node (Unit_Declaration_Node (Scope (E)))) /=
4141                                          N_Subprogram_Renaming_Declaration
4142               then
4143                  --  Suppress this message for an IN OUT parameter of a
4144                  --  non-scalar type, since it is normal to have only an
4145                  --  assignment in such a case.
4146
4147                  if Ekind (E) = E_In_Parameter
4148                    or else not Referenced_As_LHS_Check_Spec (E)
4149                    or else Is_Scalar_Type (Etype (E))
4150                  then
4151                     if Present (Body_E) then
4152                        E := Body_E;
4153                     end if;
4154
4155                     if not Is_Trivial_Subprogram (Scope (E)) then
4156                        Error_Msg_NE -- CODEFIX
4157                          ("?u?formal parameter & is not referenced!",
4158                           E, Spec_E);
4159                     end if;
4160                  end if;
4161               end if;
4162
4163            when E_Out_Parameter =>
4164               null;
4165
4166            when E_Discriminant =>
4167               Error_Msg_N ("?u?discriminant & is not referenced!", E);
4168
4169            when E_Named_Integer |
4170                 E_Named_Real    =>
4171               Error_Msg_N -- CODEFIX
4172                 ("?u?named number & is not referenced!", E);
4173
4174            when Formal_Object_Kind =>
4175               Error_Msg_N -- CODEFIX
4176                 ("?u?formal object & is not referenced!", E);
4177
4178            when E_Enumeration_Literal =>
4179               Error_Msg_N -- CODEFIX
4180                 ("?u?literal & is not referenced!", E);
4181
4182            when E_Function =>
4183               Error_Msg_N -- CODEFIX
4184                 ("?u?function & is not referenced!", E);
4185
4186            when E_Procedure =>
4187               Error_Msg_N -- CODEFIX
4188                 ("?u?procedure & is not referenced!", E);
4189
4190            when E_Package =>
4191               Error_Msg_N -- CODEFIX
4192                 ("?u?package & is not referenced!", E);
4193
4194            when E_Exception =>
4195               Error_Msg_N -- CODEFIX
4196                 ("?u?exception & is not referenced!", E);
4197
4198            when E_Label =>
4199               Error_Msg_N -- CODEFIX
4200                 ("?u?label & is not referenced!", E);
4201
4202            when E_Generic_Procedure =>
4203               Error_Msg_N -- CODEFIX
4204                 ("?u?generic procedure & is never instantiated!", E);
4205
4206            when E_Generic_Function =>
4207               Error_Msg_N -- CODEFIX
4208                 ("?u?generic function & is never instantiated!", E);
4209
4210            when Type_Kind =>
4211               Error_Msg_N -- CODEFIX
4212                 ("?u?type & is not referenced!", E);
4213
4214            when others =>
4215               Error_Msg_N -- CODEFIX
4216                 ("?u?& is not referenced!", E);
4217         end case;
4218
4219         --  Kill warnings on the entity on which the message has been posted
4220         --  (nothing is posted on out parameters because back end might be
4221         --  able to uncover an uninitialized path, and warn accordingly).
4222
4223         if Ekind (E) /= E_Out_Parameter then
4224            Set_Warnings_Off (E);
4225         end if;
4226      end if;
4227   end Warn_On_Unreferenced_Entity;
4228
4229   --------------------------------
4230   -- Warn_On_Useless_Assignment --
4231   --------------------------------
4232
4233   procedure Warn_On_Useless_Assignment
4234     (Ent : Entity_Id;
4235      N   : Node_Id := Empty)
4236   is
4237      P    : Node_Id;
4238      X    : Node_Id;
4239
4240      function Check_Ref (N : Node_Id) return Traverse_Result;
4241      --  Used to instantiate Traverse_Func. Returns Abandon if a reference to
4242      --  the entity in question is found.
4243
4244      function Test_No_Refs is new Traverse_Func (Check_Ref);
4245
4246      ---------------
4247      -- Check_Ref --
4248      ---------------
4249
4250      function Check_Ref (N : Node_Id) return Traverse_Result is
4251      begin
4252         --  Check reference to our identifier. We use name equality here
4253         --  because the exception handlers have not yet been analyzed. This
4254         --  is not quite right, but it really does not matter that we fail
4255         --  to output the warning in some obscure cases of name clashes.
4256
4257         if Nkind (N) = N_Identifier and then Chars (N) = Chars (Ent) then
4258            return Abandon;
4259         else
4260            return OK;
4261         end if;
4262      end Check_Ref;
4263
4264   --  Start of processing for Warn_On_Useless_Assignment
4265
4266   begin
4267      --  Check if this is a case we want to warn on, a scalar or access
4268      --  variable with the last assignment field set, with warnings enabled,
4269      --  and which is not imported or exported. We also check that it is OK
4270      --  to capture the value. We are not going to capture any value, but
4271      --  the warning message depends on the same kind of conditions.
4272
4273      if Is_Assignable (Ent)
4274        and then not Is_Return_Object (Ent)
4275        and then Present (Last_Assignment (Ent))
4276        and then not Is_Imported (Ent)
4277        and then not Is_Exported (Ent)
4278        and then Safe_To_Capture_Value (N, Ent)
4279        and then not Has_Pragma_Unreferenced_Check_Spec (Ent)
4280        and then not Has_Junk_Name (Ent)
4281      then
4282         --  Before we issue the message, check covering exception handlers.
4283         --  Search up tree for enclosing statement sequences and handlers.
4284
4285         P := Parent (Last_Assignment (Ent));
4286         while Present (P) loop
4287
4288            --  Something is really wrong if we don't find a handled statement
4289            --  sequence, so just suppress the warning.
4290
4291            if No (P) then
4292               Set_Last_Assignment (Ent, Empty);
4293               return;
4294
4295            --  When we hit a package/subprogram body, issue warning and exit
4296
4297            elsif Nkind (P) = N_Subprogram_Body
4298              or else Nkind (P) = N_Package_Body
4299            then
4300               --  Case of assigned value never referenced
4301
4302               if No (N) then
4303                  declare
4304                     LA : constant Node_Id := Last_Assignment (Ent);
4305
4306                  begin
4307                     --  Don't give this for OUT and IN OUT formals, since
4308                     --  clearly caller may reference the assigned value. Also
4309                     --  never give such warnings for internal variables.
4310
4311                     if Ekind (Ent) = E_Variable
4312                       and then not Is_Internal_Name (Chars (Ent))
4313                     then
4314                        --  Give appropriate message, distinguishing between
4315                        --  assignment statements and out parameters.
4316
4317                        if Nkind_In (Parent (LA), N_Procedure_Call_Statement,
4318                                                  N_Parameter_Association)
4319                        then
4320                           Error_Msg_NE
4321                             ("?m?& modified by call, but value never "
4322                              & "referenced", LA, Ent);
4323
4324                        else
4325                           Error_Msg_NE -- CODEFIX
4326                             ("?m?useless assignment to&, value never "
4327                              & "referenced!", LA, Ent);
4328                        end if;
4329                     end if;
4330                  end;
4331
4332               --  Case of assigned value overwritten
4333
4334               else
4335                  declare
4336                     LA : constant Node_Id := Last_Assignment (Ent);
4337
4338                  begin
4339                     Error_Msg_Sloc := Sloc (N);
4340
4341                     --  Give appropriate message, distinguishing between
4342                     --  assignment statements and out parameters.
4343
4344                     if Nkind_In (Parent (LA), N_Procedure_Call_Statement,
4345                                               N_Parameter_Association)
4346                     then
4347                        Error_Msg_NE
4348                          ("?m?& modified by call, but value overwritten #!",
4349                           LA, Ent);
4350                     else
4351                        Error_Msg_NE -- CODEFIX
4352                          ("?m?useless assignment to&, value overwritten #!",
4353                           LA, Ent);
4354                     end if;
4355                  end;
4356               end if;
4357
4358               --  Clear last assignment indication and we are done
4359
4360               Set_Last_Assignment (Ent, Empty);
4361               return;
4362
4363            --  Enclosing handled sequence of statements
4364
4365            elsif Nkind (P) = N_Handled_Sequence_Of_Statements then
4366
4367               --  Check exception handlers present
4368
4369               if Present (Exception_Handlers (P)) then
4370
4371                  --  If we are not at the top level, we regard an inner
4372                  --  exception handler as a decisive indicator that we should
4373                  --  not generate the warning, since the variable in question
4374                  --  may be accessed after an exception in the outer block.
4375
4376                  if Nkind (Parent (P)) /= N_Subprogram_Body
4377                    and then Nkind (Parent (P)) /= N_Package_Body
4378                  then
4379                     Set_Last_Assignment (Ent, Empty);
4380                     return;
4381
4382                     --  Otherwise we are at the outer level. An exception
4383                     --  handler is significant only if it references the
4384                     --  variable in question, or if the entity in question
4385                     --  is an OUT or IN OUT parameter, in which case
4386                     --  the caller can reference it after the exception
4387                     --  handler completes.
4388
4389                  else
4390                     if Is_Formal (Ent) then
4391                        Set_Last_Assignment (Ent, Empty);
4392                        return;
4393
4394                     else
4395                        X := First (Exception_Handlers (P));
4396                        while Present (X) loop
4397                           if Test_No_Refs (X) = Abandon then
4398                              Set_Last_Assignment (Ent, Empty);
4399                              return;
4400                           end if;
4401
4402                           X := Next (X);
4403                        end loop;
4404                     end if;
4405                  end if;
4406               end if;
4407            end if;
4408
4409            P := Parent (P);
4410         end loop;
4411      end if;
4412   end Warn_On_Useless_Assignment;
4413
4414   ---------------------------------
4415   -- Warn_On_Useless_Assignments --
4416   ---------------------------------
4417
4418   procedure Warn_On_Useless_Assignments (E : Entity_Id) is
4419      Ent : Entity_Id;
4420
4421   begin
4422      Process_Deferred_References;
4423
4424      if Warn_On_Modified_Unread
4425        and then In_Extended_Main_Source_Unit (E)
4426      then
4427         Ent := First_Entity (E);
4428         while Present (Ent) loop
4429            Warn_On_Useless_Assignment (Ent);
4430            Next_Entity (Ent);
4431         end loop;
4432      end if;
4433   end Warn_On_Useless_Assignments;
4434
4435   -----------------------------
4436   -- Warnings_Off_Check_Spec --
4437   -----------------------------
4438
4439   function Warnings_Off_Check_Spec (E : Entity_Id) return Boolean is
4440   begin
4441      if Is_Formal (E) and then Present (Spec_Entity (E)) then
4442
4443         --  Note: use of OR here instead of OR ELSE is deliberate, we want
4444         --  to mess with flags on both entities.
4445
4446         return Has_Warnings_Off (E)
4447                  or
4448                Has_Warnings_Off (Spec_Entity (E));
4449
4450      else
4451         return Has_Warnings_Off (E);
4452      end if;
4453   end Warnings_Off_Check_Spec;
4454
4455end Sem_Warn;
4456