[multiple changes]
[platform/upstream/gcc.git] / gcc / ada / sem_warn.adb
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
26 with Atree;    use Atree;
27 with Debug;    use Debug;
28 with Einfo;    use Einfo;
29 with Errout;   use Errout;
30 with Exp_Code; use Exp_Code;
31 with Fname;    use Fname;
32 with Lib;      use Lib;
33 with Lib.Xref; use Lib.Xref;
34 with Namet;    use Namet;
35 with Nlists;   use Nlists;
36 with Opt;      use Opt;
37 with Par_SCO;  use Par_SCO;
38 with Rtsfind;  use Rtsfind;
39 with Sem;      use Sem;
40 with Sem_Ch8;  use Sem_Ch8;
41 with Sem_Aux;  use Sem_Aux;
42 with Sem_Eval; use Sem_Eval;
43 with Sem_Prag; use Sem_Prag;
44 with Sem_Util; use Sem_Util;
45 with Sinfo;    use Sinfo;
46 with Sinput;   use Sinput;
47 with Snames;   use Snames;
48 with Stand;    use Stand;
49 with Stringt;  use Stringt;
50 with Uintp;    use Uintp;
51
52 package 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
4455 end Sem_Warn;