[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_Descendant_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). Instead we suggest
1141                   --  using pragma Export (can't be Import because of the
1142                   --  initial value).
1143
1144                   if (Is_Volatile (E1) or else Has_Volatile_Components (E1))
1145                     and then not Is_Imported (E1)
1146                   then
1147                      Error_Msg_N
1148                        ("?k?& is not modified, " &
1149                           "consider pragma Export for volatile variable!",
1150                         E1);
1151
1152                   --  Another special case, Exception_Occurrence, this catches
1153                   --  the case of exception choice (and a bit more too, but not
1154                   --  worth doing more investigation here).
1155
1156                   elsif Is_RTE (E1T, RE_Exception_Occurrence) then
1157                      null;
1158
1159                   --  Here we give the warning if referenced and no pragma
1160                   --  Unreferenced or Unmodified is present.
1161
1162                   else
1163                      --  Variable case
1164
1165                      if Ekind (E1) = E_Variable then
1166                         if Referenced_Check_Spec (E1)
1167                           and then not Has_Pragma_Unreferenced_Check_Spec (E1)
1168                           and then not Has_Pragma_Unmodified_Check_Spec (E1)
1169                         then
1170                            if not Warnings_Off_E1
1171                              and then not Has_Junk_Name (E1)
1172                            then
1173                               Error_Msg_N -- CODEFIX
1174                                 ("?k?& is not modified, "
1175                                  & "could be declared constant!",
1176                                  E1);
1177                            end if;
1178                         end if;
1179                      end if;
1180                   end if;
1181
1182                --  Other cases of a variable or parameter never set in source
1183
1184                elsif Never_Set_In_Source_Check_Spec (E1)
1185
1186                  --  No warning if warning for this case turned off
1187
1188                  and then Warn_On_No_Value_Assigned
1189
1190                  --  No warning if address taken somewhere
1191
1192                  and then not Address_Taken (E1)
1193
1194                  --  No warning if explicit initial value
1195
1196                  and then not Has_Initial_Value (E1)
1197
1198                  --  No warning for generic package spec entities, since we
1199                  --  might set them in a child unit or something like that
1200
1201                  and then not Generic_Package_Spec_Entity (E1)
1202
1203                  --  No warning if fully initialized type, except that for
1204                  --  this purpose we do not consider access types to qualify
1205                  --  as fully initialized types (relying on an access type
1206                  --  variable being null when it is never set is a bit odd).
1207
1208                  --  Also we generate warning for an out parameter that is
1209                  --  never referenced, since again it seems odd to rely on
1210                  --  default initialization to set an out parameter value.
1211
1212                 and then (Is_Access_Type (E1T)
1213                            or else Ekind (E1) = E_Out_Parameter
1214                            or else not Is_Fully_Initialized_Type (E1T))
1215                then
1216                   --  Do not output complaint about never being assigned a
1217                   --  value if a pragma Unmodified applies to the variable
1218                   --  we are examining, or if it is a parameter, if there is
1219                   --  a pragma Unreferenced for the corresponding spec, or
1220                   --  if the type is marked as having unreferenced objects.
1221                   --  The last is a little peculiar, but better too few than
1222                   --  too many warnings in this situation.
1223
1224                   if Has_Pragma_Unreferenced_Objects (E1T)
1225                     or else Has_Pragma_Unmodified_Check_Spec (E1)
1226                   then
1227                      null;
1228
1229                   --  IN OUT parameter case where parameter is referenced. We
1230                   --  separate this out, since this is the case where we delay
1231                   --  output of the warning until more information is available
1232                   --  (about use in an instantiation or address being taken).
1233
1234                   elsif Ekind (E1) = E_In_Out_Parameter
1235                     and then Referenced_Check_Spec (E1)
1236                   then
1237                      --  Suppress warning if private type, and the procedure
1238                      --  has a separate declaration in a different unit. This
1239                      --  is the case where the client of a package sees only
1240                      --  the private type, and it may be quite reasonable
1241                      --  for the logical view to be IN OUT, even if the
1242                      --  implementation ends up using access types or some
1243                      --  other method to achieve the local effect of a
1244                      --  modification. On the other hand if the spec and body
1245                      --  are in the same unit, we are in the package body and
1246                      --  there we have less excuse for a junk IN OUT parameter.
1247
1248                      if Has_Private_Declaration (E1T)
1249                        and then Present (Spec_Entity (E1))
1250                        and then not In_Same_Source_Unit (E1, Spec_Entity (E1))
1251                      then
1252                         null;
1253
1254                      --  Suppress warning for any parameter of a dispatching
1255                      --  operation, since it is quite reasonable to have an
1256                      --  operation that is overridden, and for some subclasses
1257                      --  needs the formal to be IN OUT and for others happens
1258                      --  not to assign it.
1259
1260                      elsif Is_Dispatching_Operation
1261                              (Scope (Goto_Spec_Entity (E1)))
1262                      then
1263                         null;
1264
1265                      --  Suppress warning if composite type contains any access
1266                      --  component, since the logical effect of modifying a
1267                      --  parameter may be achieved by modifying a referenced
1268                      --  object.
1269
1270                      elsif Is_Composite_Type (E1T)
1271                        and then Has_Access_Values (E1T)
1272                      then
1273                         null;
1274
1275                      --  Suppress warning on formals of an entry body. All
1276                      --  references are attached to the formal in the entry
1277                      --  declaration, which are marked Is_Entry_Formal.
1278
1279                      elsif Ekind (Scope (E1)) = E_Entry
1280                        and then not Is_Entry_Formal (E1)
1281                      then
1282                         null;
1283
1284                      --  OK, looks like warning for an IN OUT parameter that
1285                      --  could be IN makes sense, but we delay the output of
1286                      --  the warning, pending possibly finding out later on
1287                      --  that the associated subprogram is used as a generic
1288                      --  actual, or its address/access is taken. In these two
1289                      --  cases, we suppress the warning because the context may
1290                      --  force use of IN OUT, even if in this particular case
1291                      --  the formal is not modified.
1292
1293                      else
1294                         --  Suppress the warnings for a junk name
1295
1296                         if not Has_Junk_Name (E1) then
1297                            In_Out_Warnings.Append (E1);
1298                         end if;
1299                      end if;
1300
1301                   --  Other cases of formals
1302
1303                   elsif Is_Formal (E1) then
1304                      if not Is_Trivial_Subprogram (Scope (E1)) then
1305                         if Referenced_Check_Spec (E1) then
1306                            if not Has_Pragma_Unmodified_Check_Spec (E1)
1307                              and then not Warnings_Off_E1
1308                              and then not Has_Junk_Name (E1)
1309                            then
1310                               Output_Reference_Error
1311                                 ("?f?formal parameter& is read but "
1312                                  & "never assigned!");
1313                            end if;
1314
1315                         elsif not Has_Pragma_Unreferenced_Check_Spec (E1)
1316                           and then not Warnings_Off_E1
1317                           and then not Has_Junk_Name (E1)
1318                         then
1319                            Output_Reference_Error
1320                              ("?f?formal parameter& is not referenced!");
1321                         end if;
1322                      end if;
1323
1324                   --  Case of variable
1325
1326                   else
1327                      if Referenced (E1) then
1328                         if not Has_Unmodified (E1)
1329                           and then not Warnings_Off_E1
1330                           and then not Has_Junk_Name (E1)
1331                         then
1332                            Output_Reference_Error
1333                              ("?v?variable& is read but never assigned!");
1334                            May_Need_Initialized_Actual (E1);
1335                         end if;
1336
1337                      elsif not Has_Unreferenced (E1)
1338                        and then not Warnings_Off_E1
1339                        and then not Has_Junk_Name (E1)
1340                      then
1341                         Output_Reference_Error -- CODEFIX
1342                           ("?v?variable& is never read and never assigned!");
1343                      end if;
1344
1345                      --  Deal with special case where this variable is hidden
1346                      --  by a loop variable.
1347
1348                      if Ekind (E1) = E_Variable
1349                        and then Present (Hiding_Loop_Variable (E1))
1350                        and then not Warnings_Off_E1
1351                      then
1352                         Error_Msg_N
1353                           ("?v?for loop implicitly declares loop variable!",
1354                            Hiding_Loop_Variable (E1));
1355
1356                         Error_Msg_Sloc := Sloc (E1);
1357                         Error_Msg_N
1358                           ("\?v?declaration hides & declared#!",
1359                            Hiding_Loop_Variable (E1));
1360                      end if;
1361                   end if;
1362
1363                   goto Continue;
1364                end if;
1365
1366                --  Check for unset reference
1367
1368                if Warn_On_No_Value_Assigned and then Present (UR) then
1369
1370                   --  For other than access type, go back to original node to
1371                   --  deal with case where original unset reference has been
1372                   --  rewritten during expansion.
1373
1374                   --  In some cases, the original node may be a type conversion
1375                   --  or qualification, and in this case we want the object
1376                   --  entity inside.
1377
1378                   UR := Original_Node (UR);
1379                   while Nkind (UR) = N_Type_Conversion
1380                     or else Nkind (UR) = N_Qualified_Expression
1381                     or else Nkind (UR) = N_Expression_With_Actions
1382                   loop
1383                      UR := Expression (UR);
1384                   end loop;
1385
1386                   --  Don't issue warning if appearing inside Initial_Condition
1387                   --  pragma or aspect, since that expression is not evaluated
1388                   --  at the point where it occurs in the source.
1389
1390                   if In_Pragma_Expression (UR, Name_Initial_Condition) then
1391                      goto Continue;
1392                   end if;
1393
1394                   --  Here we issue the warning, all checks completed
1395
1396                   --  If we have a return statement, this was a case of an OUT
1397                   --  parameter not being set at the time of the return. (Note:
1398                   --  it can't be N_Extended_Return_Statement, because those
1399                   --  are only for functions, and functions do not allow OUT
1400                   --  parameters.)
1401
1402                   if not Is_Trivial_Subprogram (Scope (E1)) then
1403                      if Nkind (UR) = N_Simple_Return_Statement
1404                        and then not Has_Pragma_Unmodified_Check_Spec (E1)
1405                      then
1406                         if not Warnings_Off_E1
1407                           and then not Has_Junk_Name (E1)
1408                         then
1409                            Error_Msg_NE
1410                              ("?v?OUT parameter& not set before return",
1411                               UR, E1);
1412                         end if;
1413
1414                         --  If the unset reference is a selected component
1415                         --  prefix from source, mention the component as well.
1416                         --  If the selected component comes from expansion, all
1417                         --  we know is that the entity is not fully initialized
1418                         --  at the point of the reference. Locate a random
1419                         --  uninitialized component to get a better message.
1420
1421                      elsif Nkind (Parent (UR)) = N_Selected_Component then
1422                         Error_Msg_Node_2 := Selector_Name (Parent (UR));
1423
1424                         if not Comes_From_Source (Parent (UR)) then
1425                            declare
1426                               Comp : Entity_Id;
1427
1428                            begin
1429                               Comp := First_Entity (E1T);
1430                               while Present (Comp) loop
1431                                  if Ekind (Comp) = E_Component
1432                                    and then Nkind (Parent (Comp)) =
1433                                               N_Component_Declaration
1434                                    and then No (Expression (Parent (Comp)))
1435                                  then
1436                                     Error_Msg_Node_2 := Comp;
1437                                     exit;
1438                                  end if;
1439
1440                                  Next_Entity (Comp);
1441                               end loop;
1442                            end;
1443                         end if;
1444
1445                         --  Issue proper warning. This is a case of referencing
1446                         --  a variable before it has been explicitly assigned.
1447                         --  For access types, UR was only set for dereferences,
1448                         --  so the issue is that the value may be null.
1449
1450                         if not Is_Trivial_Subprogram (Scope (E1)) then
1451                            if not Warnings_Off_E1 then
1452                               if Is_Access_Type (Etype (Parent (UR))) then
1453                                  Error_Msg_N ("??`&.&` may be null!", UR);
1454                               else
1455                                  Error_Msg_N
1456                                    ("??`&.&` may be referenced before "
1457                                     & "it has a value!", UR);
1458                               end if;
1459                            end if;
1460                         end if;
1461
1462                      --  All other cases of unset reference active
1463
1464                      elsif not Warnings_Off_E1 then
1465                         Error_Msg_N
1466                           ("??& may be referenced before it has a value!", UR);
1467                      end if;
1468                   end if;
1469
1470                   goto Continue;
1471
1472                end if;
1473             end if;
1474
1475             --  Then check for unreferenced entities. Note that we are only
1476             --  interested in entities whose Referenced flag is not set.
1477
1478             if not Referenced_Check_Spec (E1)
1479
1480               --  If Referenced_As_LHS is set, then that's still interesting
1481               --  (potential "assigned but never read" case), but not if we
1482               --  have pragma Unreferenced, which cancels this warning.
1483
1484               and then (not Referenced_As_LHS_Check_Spec (E1)
1485                          or else not Has_Unreferenced (E1))
1486
1487               --  Check that warnings on unreferenced entities are enabled
1488
1489               and then
1490                 ((Check_Unreferenced and then not Is_Formal (E1))
1491
1492                   --  Case of warning on unreferenced formal
1493
1494                   or else (Check_Unreferenced_Formals and then Is_Formal (E1))
1495
1496                   --  Case of warning on unread variables modified by an
1497                   --  assignment, or an OUT parameter if it is the only one.
1498
1499                   or else (Warn_On_Modified_Unread
1500                             and then Referenced_As_LHS_Check_Spec (E1))
1501
1502                   --  Case of warning on any unread OUT parameter (note such
1503                   --  indications are only set if the appropriate warning
1504                   --  options were set, so no need to recheck here.)
1505
1506                   or else Referenced_As_Out_Parameter_Check_Spec (E1))
1507
1508               --  All other entities, including local packages that cannot be
1509               --  referenced from elsewhere, including those declared within a
1510               --  package body.
1511
1512               and then (Is_Object (E1)
1513                          or else Is_Type (E1)
1514                          or else Ekind (E1) = E_Label
1515                          or else Ekind_In (E1, E_Exception,
1516                                                E_Named_Integer,
1517                                                E_Named_Real)
1518                          or else Is_Overloadable (E1)
1519
1520                          --  Package case, if the main unit is a package spec
1521                          --  or generic package spec, then there may be a
1522                          --  corresponding body that references this package
1523                          --  in some other file. Otherwise we can be sure
1524                          --  that there is no other reference.
1525
1526                          or else
1527                            (Ekind (E1) = E_Package
1528                              and then
1529                                not Is_Package_Or_Generic_Package
1530                                      (Cunit_Entity (Current_Sem_Unit))))
1531
1532               --  Exclude instantiations, since there is no reason why every
1533               --  entity in an instantiation should be referenced.
1534
1535               and then Instantiation_Location (Sloc (E1)) = No_Location
1536
1537               --  Exclude formal parameters from bodies if the corresponding
1538               --  spec entity has been referenced in the case where there is
1539               --  a separate spec.
1540
1541               and then not (Is_Formal (E1)
1542                              and then Ekind (Scope (E1)) = E_Subprogram_Body
1543                              and then Present (Spec_Entity (E1))
1544                              and then Referenced (Spec_Entity (E1)))
1545
1546               --  Consider private type referenced if full view is referenced.
1547               --  If there is not full view, this is a generic type on which
1548               --  warnings are also useful.
1549
1550               and then
1551                 not (Is_Private_Type (E1)
1552                       and then Present (Full_View (E1))
1553                       and then Referenced (Full_View (E1)))
1554
1555               --  Don't worry about full view, only about private type
1556
1557               and then not Has_Private_Declaration (E1)
1558
1559               --  Eliminate dispatching operations from consideration, we
1560               --  cannot tell if these are referenced or not in any easy
1561               --  manner (note this also catches Adjust/Finalize/Initialize).
1562
1563               and then not Is_Dispatching_Operation (E1)
1564
1565               --  Check entity that can be publicly referenced (we do not give
1566               --  messages for such entities, since there could be other
1567               --  units, not involved in this compilation, that contain
1568               --  relevant references.
1569
1570               and then not Publicly_Referenceable (E1)
1571
1572               --  Class wide types are marked as source entities, but they are
1573               --  not really source entities, and are always created, so we do
1574               --  not care if they are not referenced.
1575
1576               and then Ekind (E1) /= E_Class_Wide_Type
1577
1578               --  Objects other than parameters of task types are allowed to
1579               --  be non-referenced, since they start up tasks.
1580
1581               and then ((Ekind (E1) /= E_Variable
1582                           and then Ekind (E1) /= E_Constant
1583                           and then Ekind (E1) /= E_Component)
1584                          or else not Is_Task_Type (E1T))
1585
1586               --  For subunits, only place warnings on the main unit itself,
1587               --  since parent units are not completely compiled.
1588
1589               and then (Nkind (Unit (Cunit (Main_Unit))) /= N_Subunit
1590                          or else Get_Source_Unit (E1) = Main_Unit)
1591
1592               --  No warning on a return object, because these are often
1593               --  created with a single expression and an implicit return.
1594               --  If the object is a variable there will be a warning
1595               --  indicating that it could be declared constant.
1596
1597               and then not
1598                 (Ekind (E1) = E_Constant and then Is_Return_Object (E1))
1599             then
1600                --  Suppress warnings in internal units if not in -gnatg mode
1601                --  (these would be junk warnings for an applications program,
1602                --  since they refer to problems in internal units).
1603
1604                if GNAT_Mode
1605                  or else not Is_Internal_File_Name
1606                                (Unit_File_Name (Get_Source_Unit (E1)))
1607                then
1608                   --  We do not immediately flag the error. This is because we
1609                   --  have not expanded generic bodies yet, and they may have
1610                   --  the missing reference. So instead we park the entity on a
1611                   --  list, for later processing. However for the case of an
1612                   --  accept statement we want to output messages now, since
1613                   --  we know we already have all information at hand, and we
1614                   --  also want to have separate warnings for each accept
1615                   --  statement for the same entry.
1616
1617                   if Present (Anod) then
1618                      pragma Assert (Is_Formal (E1));
1619
1620                      --  The unreferenced entity is E1, but post the warning
1621                      --  on the body entity for this accept statement.
1622
1623                      if not Warnings_Off_E1 then
1624                         Warn_On_Unreferenced_Entity
1625                           (E1, Body_Formal (E1, Accept_Statement => Anod));
1626                      end if;
1627
1628                   elsif not Warnings_Off_E1
1629                     and then not Has_Junk_Name (E1)
1630                   then
1631                      Unreferenced_Entities.Append (E1);
1632                   end if;
1633                end if;
1634
1635             --  Generic units are referenced in the generic body, but if they
1636             --  are not public and never instantiated we want to force a
1637             --  warning on them. We treat them as redundant constructs to
1638             --  minimize noise.
1639
1640             elsif Is_Generic_Subprogram (E1)
1641               and then not Is_Instantiated (E1)
1642               and then not Publicly_Referenceable (E1)
1643               and then Instantiation_Depth (Sloc (E1)) = 0
1644               and then Warn_On_Redundant_Constructs
1645             then
1646                if not Warnings_Off_E1 and then not Has_Junk_Name (E1) then
1647                   Unreferenced_Entities.Append (E1);
1648
1649                   --  Force warning on entity
1650
1651                   Set_Referenced (E1, False);
1652                end if;
1653             end if;
1654          end if;
1655
1656          --  Recurse into nested package or block. Do not recurse into a formal
1657          --  package, because the corresponding body is not analyzed.
1658
1659          <<Continue>>
1660             if (Is_Package_Or_Generic_Package (E1)
1661                  and then Nkind (Parent (E1)) = N_Package_Specification
1662                  and then
1663                    Nkind (Original_Node (Unit_Declaration_Node (E1))) /=
1664                                                 N_Formal_Package_Declaration)
1665
1666               or else Ekind (E1) = E_Block
1667             then
1668                Check_References (E1);
1669             end if;
1670
1671             Next_Entity (E1);
1672       end loop;
1673    end Check_References;
1674
1675    ---------------------------
1676    -- Check_Unset_Reference --
1677    ---------------------------
1678
1679    procedure Check_Unset_Reference (N : Node_Id) is
1680       Typ : constant Entity_Id := Etype (N);
1681
1682       function Is_OK_Fully_Initialized return Boolean;
1683       --  This function returns true if the given node N is fully initialized
1684       --  so that the reference is safe as far as this routine is concerned.
1685       --  Safe generally means that the type of N is a fully initialized type.
1686       --  The one special case is that for access types, which are always fully
1687       --  initialized, we don't consider a dereference OK since it will surely
1688       --  be dereferencing a null value, which won't do.
1689
1690       function Prefix_Has_Dereference (Pref : Node_Id) return Boolean;
1691       --  Used to test indexed or selected component or slice to see if the
1692       --  evaluation of the prefix depends on a dereference, and if so, returns
1693       --  True, in which case we always check the prefix, even if we know that
1694       --  the referenced component is initialized. Pref is the prefix to test.
1695
1696       -----------------------------
1697       -- Is_OK_Fully_Initialized --
1698       -----------------------------
1699
1700       function Is_OK_Fully_Initialized return Boolean is
1701       begin
1702          if Is_Access_Type (Typ) and then Is_Dereferenced (N) then
1703             return False;
1704
1705          --  If a type has Default_Initial_Condition set, or it inherits it,
1706          --  DIC might be specified with a boolean value, meaning that the type
1707          --  is considered to be fully default initialized (SPARK RM 3.1 and
1708          --  SPARK RM 7.3.3). To avoid generating spurious warnings in this
1709          --  case, consider all types with DIC as fully initialized.
1710
1711          elsif Has_Default_Init_Cond (Typ)
1712            or else Has_Inherited_Default_Init_Cond (Typ)
1713          then
1714             return True;
1715
1716          else
1717             return Is_Fully_Initialized_Type (Typ);
1718          end if;
1719       end Is_OK_Fully_Initialized;
1720
1721       ----------------------------
1722       -- Prefix_Has_Dereference --
1723       ----------------------------
1724
1725       function Prefix_Has_Dereference (Pref : Node_Id) return Boolean is
1726       begin
1727          --  If prefix is of an access type, it certainly needs a dereference
1728
1729          if Is_Access_Type (Etype (Pref)) then
1730             return True;
1731
1732          --  If prefix is explicit dereference, that's a dereference for sure
1733
1734          elsif Nkind (Pref) = N_Explicit_Dereference then
1735             return True;
1736
1737             --  If prefix is itself a component reference or slice check prefix
1738
1739          elsif Nkind (Pref) = N_Slice
1740            or else Nkind (Pref) = N_Indexed_Component
1741            or else Nkind (Pref) = N_Selected_Component
1742          then
1743             return Prefix_Has_Dereference (Prefix (Pref));
1744
1745          --  All other cases do not involve a dereference
1746
1747          else
1748             return False;
1749          end if;
1750       end Prefix_Has_Dereference;
1751
1752    --  Start of processing for Check_Unset_Reference
1753
1754    begin
1755       --  Nothing to do if warnings suppressed
1756
1757       if Warning_Mode = Suppress then
1758          return;
1759       end if;
1760
1761       --  Nothing to do for numeric or string literal. Do this test early to
1762       --  save time in a common case (it does not matter that we do not include
1763       --  character literal here, since that will be caught later on in the
1764       --  when others branch of the case statement).
1765
1766       if Nkind (N) in N_Numeric_Or_String_Literal then
1767          return;
1768       end if;
1769
1770       --  Ignore reference unless it comes from source. Almost always if we
1771       --  have a reference from generated code, it is bogus (e.g. calls to init
1772       --  procs to set default discriminant values).
1773
1774       if not Comes_From_Source (N) then
1775          return;
1776       end if;
1777
1778       --  Otherwise see what kind of node we have. If the entity already has an
1779       --  unset reference, it is not necessarily the earliest in the text,
1780       --  because resolution of the prefix of selected components is completed
1781       --  before the resolution of the selected component itself. As a result,
1782       --  given (R /= null and then R.X > 0), the occurrences of R are examined
1783       --  in right-to-left order. If there is already an unset reference, we
1784       --  check whether N is earlier before proceeding.
1785
1786       case Nkind (N) is
1787
1788          --  For identifier or expanded name, examine the entity involved
1789
1790          when N_Identifier | N_Expanded_Name =>
1791             declare
1792                E : constant Entity_Id := Entity (N);
1793
1794             begin
1795                if Ekind_In (E, E_Variable, E_Out_Parameter)
1796                  and then Never_Set_In_Source_Check_Spec (E)
1797                  and then not Has_Initial_Value (E)
1798                  and then (No (Unset_Reference (E))
1799                             or else
1800                               Earlier_In_Extended_Unit
1801                                 (Sloc (N), Sloc (Unset_Reference (E))))
1802                  and then not Has_Pragma_Unmodified_Check_Spec (E)
1803                  and then not Warnings_Off_Check_Spec (E)
1804                  and then not Has_Junk_Name (E)
1805                then
1806                   --  We may have an unset reference. The first test is whether
1807                   --  this is an access to a discriminant of a record or a
1808                   --  component with default initialization. Both of these
1809                   --  cases can be ignored, since the actual object that is
1810                   --  referenced is definitely initialized. Note that this
1811                   --  covers the case of reading discriminants of an OUT
1812                   --  parameter, which is OK even in Ada 83.
1813
1814                   --  Note that we are only interested in a direct reference to
1815                   --  a record component here. If the reference is through an
1816                   --  access type, then the access object is being referenced,
1817                   --  not the record, and still deserves an unset reference.
1818
1819                   if Nkind (Parent (N)) = N_Selected_Component
1820                     and not Is_Access_Type (Typ)
1821                   then
1822                      declare
1823                         ES : constant Entity_Id :=
1824                                Entity (Selector_Name (Parent (N)));
1825                      begin
1826                         if Ekind (ES) = E_Discriminant
1827                           or else
1828                             (Present (Declaration_Node (ES))
1829                                and then
1830                              Present (Expression (Declaration_Node (ES))))
1831                         then
1832                            return;
1833                         end if;
1834                      end;
1835                   end if;
1836
1837                   --  Exclude fully initialized types
1838
1839                   if Is_OK_Fully_Initialized then
1840                      return;
1841                   end if;
1842
1843                   --  Here we have a potential unset reference. But before we
1844                   --  get worried about it, we have to make sure that the
1845                   --  entity declaration is in the same procedure as the
1846                   --  reference, since if they are in separate procedures, then
1847                   --  we have no idea about sequential execution.
1848
1849                   --  The tests in the loop below catch all such cases, but do
1850                   --  allow the reference to appear in a loop, block, or
1851                   --  package spec that is nested within the declaring scope.
1852                   --  As always, it is possible to construct cases where the
1853                   --  warning is wrong, that is why it is a warning.
1854
1855                   Potential_Unset_Reference : declare
1856                      SR : Entity_Id;
1857                      SE : constant Entity_Id := Scope (E);
1858
1859                      function Within_Postcondition return Boolean;
1860                      --  Returns True if N is within a Postcondition, a
1861                      --  Refined_Post, an Ensures component in a Test_Case,
1862                      --  or a Contract_Cases.
1863
1864                      --------------------------
1865                      -- Within_Postcondition --
1866                      --------------------------
1867
1868                      function Within_Postcondition return Boolean is
1869                         Nod, P : Node_Id;
1870
1871                      begin
1872                         Nod := Parent (N);
1873                         while Present (Nod) loop
1874                            if Nkind (Nod) = N_Pragma
1875                              and then Nam_In (Pragma_Name (Nod),
1876                                               Name_Postcondition,
1877                                               Name_Refined_Post,
1878                                               Name_Contract_Cases)
1879                            then
1880                               return True;
1881
1882                            elsif Present (Parent (Nod)) then
1883                               P := Parent (Nod);
1884
1885                               if Nkind (P) = N_Pragma
1886                                 and then Pragma_Name (P) = Name_Test_Case
1887                                 and then Nod = Test_Case_Arg (P, Name_Ensures)
1888                               then
1889                                  return True;
1890                               end if;
1891                            end if;
1892
1893                            Nod := Parent (Nod);
1894                         end loop;
1895
1896                         return False;
1897                      end Within_Postcondition;
1898
1899                   --  Start of processing for Potential_Unset_Reference
1900
1901                   begin
1902                      SR := Current_Scope;
1903                      while SR /= SE loop
1904                         if SR = Standard_Standard
1905                           or else Is_Subprogram (SR)
1906                           or else Is_Concurrent_Body (SR)
1907                           or else Is_Concurrent_Type (SR)
1908                         then
1909                            return;
1910                         end if;
1911
1912                         SR := Scope (SR);
1913                      end loop;
1914
1915                      --  Case of reference has an access type. This is a
1916                      --  special case since access types are always set to null
1917                      --  so cannot be truly uninitialized, but we still want to
1918                      --  warn about cases of obvious null dereference.
1919
1920                      if Is_Access_Type (Typ) then
1921                         Access_Type_Case : declare
1922                            P : Node_Id;
1923
1924                            function Process
1925                              (N : Node_Id) return Traverse_Result;
1926                            --  Process function for instantiation of Traverse
1927                            --  below. Checks if N contains reference to E other
1928                            --  than a dereference.
1929
1930                            function Ref_In (Nod : Node_Id) return Boolean;
1931                            --  Determines whether Nod contains a reference to
1932                            --  the entity E that is not a dereference.
1933
1934                            -------------
1935                            -- Process --
1936                            -------------
1937
1938                            function Process
1939                              (N : Node_Id) return Traverse_Result
1940                            is
1941                            begin
1942                               if Is_Entity_Name (N)
1943                                 and then Entity (N) = E
1944                                 and then not Is_Dereferenced (N)
1945                               then
1946                                  return Abandon;
1947                               else
1948                                  return OK;
1949                               end if;
1950                            end Process;
1951
1952                            ------------
1953                            -- Ref_In --
1954                            ------------
1955
1956                            function Ref_In (Nod : Node_Id) return Boolean is
1957                               function Traverse is new Traverse_Func (Process);
1958                            begin
1959                               return Traverse (Nod) = Abandon;
1960                            end Ref_In;
1961
1962                         --  Start of processing for Access_Type_Case
1963
1964                         begin
1965                            --  Don't bother if we are inside an instance, since
1966                            --  the compilation of the generic template is where
1967                            --  the warning should be issued.
1968
1969                            if In_Instance then
1970                               return;
1971                            end if;
1972
1973                            --  Don't bother if this is not the main unit. If we
1974                            --  try to give this warning for with'ed units, we
1975                            --  get some false positives, since we do not record
1976                            --  references in other units.
1977
1978                            if not In_Extended_Main_Source_Unit (E)
1979                                 or else
1980                               not In_Extended_Main_Source_Unit (N)
1981                            then
1982                               return;
1983                            end if;
1984
1985                            --  We are only interested in dereferences
1986
1987                            if not Is_Dereferenced (N) then
1988                               return;
1989                            end if;
1990
1991                            --  One more check, don't bother with references
1992                            --  that are inside conditional statements or WHILE
1993                            --  loops if the condition references the entity in
1994                            --  question. This avoids most false positives.
1995
1996                            P := Parent (N);
1997                            loop
1998                               P := Parent (P);
1999                               exit when No (P);
2000
2001                               if Nkind_In (P, N_If_Statement, N_Elsif_Part)
2002                                 and then Ref_In (Condition (P))
2003                               then
2004                                  return;
2005
2006                               elsif Nkind (P) = N_Loop_Statement
2007                                 and then Present (Iteration_Scheme (P))
2008                                 and then
2009                                   Ref_In (Condition (Iteration_Scheme (P)))
2010                               then
2011                                  return;
2012                               end if;
2013                            end loop;
2014                         end Access_Type_Case;
2015                      end if;
2016
2017                      --  One more check, don't bother if we are within a
2018                      --  postcondition, since the expression occurs in a
2019                      --  place unrelated to the actual test.
2020
2021                      if not Within_Postcondition then
2022
2023                         --  Here we definitely have a case for giving a warning
2024                         --  for a reference to an unset value. But we don't
2025                         --  give the warning now. Instead set Unset_Reference
2026                         --  in the identifier involved. The reason for this is
2027                         --  that if we find the variable is never ever assigned
2028                         --  a value then that warning is more important and
2029                         --  there is no point in giving the reference warning.
2030
2031                         --  If this is an identifier, set the field directly
2032
2033                         if Nkind (N) = N_Identifier then
2034                            Set_Unset_Reference (E, N);
2035
2036                         --  Otherwise it is an expanded name, so set the field
2037                         --  of the actual identifier for the reference.
2038
2039                         else
2040                            Set_Unset_Reference (E, Selector_Name (N));
2041                         end if;
2042                      end if;
2043                   end Potential_Unset_Reference;
2044                end if;
2045             end;
2046
2047          --  Indexed component or slice
2048
2049          when N_Indexed_Component | N_Slice =>
2050
2051             --  If prefix does not involve dereferencing an access type, then
2052             --  we know we are OK if the component type is fully initialized,
2053             --  since the component will have been set as part of the default
2054             --  initialization.
2055
2056             if not Prefix_Has_Dereference (Prefix (N))
2057               and then Is_OK_Fully_Initialized
2058             then
2059                return;
2060
2061             --  Look at prefix in access type case, or if the component is not
2062             --  fully initialized.
2063
2064             else
2065                Check_Unset_Reference (Prefix (N));
2066             end if;
2067
2068          --  Record component
2069
2070          when N_Selected_Component =>
2071             declare
2072                Pref : constant Node_Id   := Prefix (N);
2073                Ent  : constant Entity_Id := Entity (Selector_Name (N));
2074
2075             begin
2076                --  If prefix involves dereferencing an access type, always
2077                --  check the prefix, since the issue then is whether this
2078                --  access value is null.
2079
2080                if Prefix_Has_Dereference (Pref) then
2081                   null;
2082
2083                --  Always go to prefix if no selector entity is set. Can this
2084                --  happen in the normal case? Not clear, but it definitely can
2085                --  happen in error cases.
2086
2087                elsif No (Ent) then
2088                   null;
2089
2090                --  For a record component, check some cases where we have
2091                --  reasonable cause to consider that the component is known to
2092                --  be or probably is initialized. In this case, we don't care
2093                --  if the prefix itself was explicitly initialized.
2094
2095                --  Discriminants are always considered initialized
2096
2097                elsif Ekind (Ent) = E_Discriminant then
2098                   return;
2099
2100                --  An explicitly initialized component is certainly initialized
2101
2102                elsif Nkind (Parent (Ent)) = N_Component_Declaration
2103                  and then Present (Expression (Parent (Ent)))
2104                then
2105                   return;
2106
2107                --  A fully initialized component is initialized
2108
2109                elsif Is_OK_Fully_Initialized then
2110                   return;
2111                end if;
2112
2113                --  If none of those cases apply, check the record type prefix
2114
2115                Check_Unset_Reference (Pref);
2116             end;
2117
2118          --  For type conversions, qualifications, or expressions with actions,
2119          --  examine the expression.
2120
2121          when N_Type_Conversion         |
2122               N_Qualified_Expression    |
2123               N_Expression_With_Actions =>
2124             Check_Unset_Reference (Expression (N));
2125
2126          --  For explicit dereference, always check prefix, which will generate
2127          --  an unset reference (since this is a case of dereferencing null).
2128
2129          when N_Explicit_Dereference =>
2130             Check_Unset_Reference (Prefix (N));
2131
2132          --  All other cases are not cases of an unset reference
2133
2134          when others =>
2135             null;
2136
2137       end case;
2138    end Check_Unset_Reference;
2139
2140    ------------------------
2141    -- Check_Unused_Withs --
2142    ------------------------
2143
2144    procedure Check_Unused_Withs (Spec_Unit : Unit_Number_Type := No_Unit) is
2145       Cnode : Node_Id;
2146       Item  : Node_Id;
2147       Lunit : Node_Id;
2148       Ent   : Entity_Id;
2149
2150       Munite : constant Entity_Id := Cunit_Entity (Main_Unit);
2151       --  This is needed for checking the special renaming case
2152
2153       procedure Check_One_Unit (Unit : Unit_Number_Type);
2154       --  Subsidiary procedure, performs checks for specified unit
2155
2156       --------------------
2157       -- Check_One_Unit --
2158       --------------------
2159
2160       procedure Check_One_Unit (Unit : Unit_Number_Type) is
2161          Is_Visible_Renaming : Boolean := False;
2162          Pack                : Entity_Id;
2163
2164          procedure Check_Inner_Package (Pack : Entity_Id);
2165          --  Pack is a package local to a unit in a with_clause. Both the unit
2166          --  and Pack are referenced. If none of the entities in Pack are
2167          --  referenced, then the only occurrence of Pack is in a USE clause
2168          --  or a pragma, and a warning is worthwhile as well.
2169
2170          function Check_System_Aux return Boolean;
2171          --  Before giving a warning on a with_clause for System, check whether
2172          --  a system extension is present.
2173
2174          function Find_Package_Renaming
2175            (P : Entity_Id;
2176             L : Entity_Id) return Entity_Id;
2177          --  The only reference to a context unit may be in a renaming
2178          --  declaration. If this renaming declares a visible entity, do not
2179          --  warn that the context clause could be moved to the body, because
2180          --  the renaming may be intended to re-export the unit.
2181
2182          function Has_Visible_Entities (P : Entity_Id) return Boolean;
2183          --  This function determines if a package has any visible entities.
2184          --  True is returned if there is at least one declared visible entity,
2185          --  otherwise False is returned (e.g. case of only pragmas present).
2186
2187          -------------------------
2188          -- Check_Inner_Package --
2189          -------------------------
2190
2191          procedure Check_Inner_Package (Pack : Entity_Id) is
2192             E  : Entity_Id;
2193             Un : constant Node_Id := Sinfo.Unit (Cnode);
2194
2195             function Check_Use_Clause (N : Node_Id) return Traverse_Result;
2196             --  If N is a use_clause for Pack, emit warning
2197
2198             procedure Check_Use_Clauses is new
2199               Traverse_Proc (Check_Use_Clause);
2200
2201             ----------------------
2202             -- Check_Use_Clause --
2203             ----------------------
2204
2205             function Check_Use_Clause (N : Node_Id) return Traverse_Result is
2206                Nam  : Node_Id;
2207
2208             begin
2209                if Nkind (N) = N_Use_Package_Clause then
2210                   Nam := First (Names (N));
2211                   while Present (Nam) loop
2212                      if Entity (Nam) = Pack then
2213
2214                         --  Suppress message if any serious errors detected
2215                         --  that turn off expansion, and thus result in false
2216                         --  positives for this warning.
2217
2218                         if Serious_Errors_Detected = 0 then
2219                            Error_Msg_Qual_Level := 1;
2220                            Error_Msg_NE -- CODEFIX
2221                              ("?u?no entities of package& are referenced!",
2222                                 Nam, Pack);
2223                            Error_Msg_Qual_Level := 0;
2224                         end if;
2225                      end if;
2226
2227                      Next (Nam);
2228                   end loop;
2229                end if;
2230
2231                return OK;
2232             end Check_Use_Clause;
2233
2234          --  Start of processing for Check_Inner_Package
2235
2236          begin
2237             E := First_Entity (Pack);
2238             while Present (E) loop
2239                if Referenced_Check_Spec (E) then
2240                   return;
2241                end if;
2242
2243                Next_Entity (E);
2244             end loop;
2245
2246             --  No entities of the package are referenced. Check whether the
2247             --  reference to the package itself is a use clause, and if so
2248             --  place a warning on it.
2249
2250             Check_Use_Clauses (Un);
2251          end Check_Inner_Package;
2252
2253          ----------------------
2254          -- Check_System_Aux --
2255          ----------------------
2256
2257          function Check_System_Aux return Boolean is
2258             Ent : Entity_Id;
2259
2260          begin
2261             if Chars (Lunit) = Name_System
2262                and then Scope (Lunit) = Standard_Standard
2263                and then Present_System_Aux
2264             then
2265                Ent := First_Entity (System_Aux_Id);
2266                while Present (Ent) loop
2267                   if Referenced_Check_Spec (Ent) then
2268                      return True;
2269                   end if;
2270
2271                   Next_Entity (Ent);
2272                end loop;
2273             end if;
2274
2275             return False;
2276          end Check_System_Aux;
2277
2278          ---------------------------
2279          -- Find_Package_Renaming --
2280          ---------------------------
2281
2282          function Find_Package_Renaming
2283            (P : Entity_Id;
2284             L : Entity_Id) return Entity_Id
2285          is
2286             E1 : Entity_Id;
2287             R  : Entity_Id;
2288
2289          begin
2290             Is_Visible_Renaming := False;
2291
2292             E1 := First_Entity (P);
2293             while Present (E1) loop
2294                if Ekind (E1) = E_Package and then Renamed_Object (E1) = L then
2295                   Is_Visible_Renaming := not Is_Hidden (E1);
2296                   return E1;
2297
2298                elsif Ekind (E1) = E_Package
2299                  and then No (Renamed_Object (E1))
2300                  and then not Is_Generic_Instance (E1)
2301                then
2302                   R := Find_Package_Renaming (E1, L);
2303
2304                   if Present (R) then
2305                      Is_Visible_Renaming := not Is_Hidden (R);
2306                      return R;
2307                   end if;
2308                end if;
2309
2310                Next_Entity (E1);
2311             end loop;
2312
2313             return Empty;
2314          end Find_Package_Renaming;
2315
2316          --------------------------
2317          -- Has_Visible_Entities --
2318          --------------------------
2319
2320          function Has_Visible_Entities (P : Entity_Id) return Boolean is
2321             E : Entity_Id;
2322
2323          begin
2324             --  If unit in context is not a package, it is a subprogram that
2325             --  is not called or a generic unit that is not instantiated
2326             --  in the current unit, and warning is appropriate.
2327
2328             if Ekind (P) /= E_Package then
2329                return True;
2330             end if;
2331
2332             --  If unit comes from a limited_with clause, look for declaration
2333             --  of shadow entities.
2334
2335             if Present (Limited_View (P)) then
2336                E := First_Entity (Limited_View (P));
2337             else
2338                E := First_Entity (P);
2339             end if;
2340
2341             while Present (E) and then E /= First_Private_Entity (P) loop
2342                if Comes_From_Source (E) or else Present (Limited_View (P)) then
2343                   return True;
2344                end if;
2345
2346                Next_Entity (E);
2347             end loop;
2348
2349             return False;
2350          end Has_Visible_Entities;
2351
2352       --  Start of processing for Check_One_Unit
2353
2354       begin
2355          Cnode := Cunit (Unit);
2356
2357          --  Only do check in units that are part of the extended main unit.
2358          --  This is actually a necessary restriction, because in the case of
2359          --  subprogram acting as its own specification, there can be with's in
2360          --  subunits that we will not see.
2361
2362          if not In_Extended_Main_Source_Unit (Cnode) then
2363             return;
2364
2365          --  In configurable run time mode, we remove the bodies of non-inlined
2366          --  subprograms, which may lead to spurious warnings, which are
2367          --  clearly undesirable.
2368
2369          elsif Configurable_Run_Time_Mode
2370            and then Is_Predefined_File_Name (Unit_File_Name (Unit))
2371          then
2372             return;
2373          end if;
2374
2375          --  Loop through context items in this unit
2376
2377          Item := First (Context_Items (Cnode));
2378          while Present (Item) loop
2379             if Nkind (Item) = N_With_Clause
2380               and then not Implicit_With (Item)
2381               and then In_Extended_Main_Source_Unit (Item)
2382
2383               --  Guard for no entity present. Not clear under what conditions
2384               --  this happens, but it does occur, and since this is only a
2385               --  warning, we just suppress the warning in this case.
2386
2387               and then Nkind (Name (Item)) in N_Has_Entity
2388               and then Present (Entity (Name (Item)))
2389             then
2390                Lunit := Entity (Name (Item));
2391
2392                --  Check if this unit is referenced (skip the check if this
2393                --  is explicitly marked by a pragma Unreferenced).
2394
2395                if not Referenced (Lunit) and then not Has_Unreferenced (Lunit)
2396                then
2397                   --  Suppress warnings in internal units if not in -gnatg mode
2398                   --  (these would be junk warnings for an application program,
2399                   --  since they refer to problems in internal units).
2400
2401                   if GNAT_Mode
2402                     or else not Is_Internal_File_Name (Unit_File_Name (Unit))
2403                   then
2404                      --  Here we definitely have a non-referenced unit. If it
2405                      --  is the special call for a spec unit, then just set the
2406                      --  flag to be read later.
2407
2408                      if Unit = Spec_Unit then
2409                         Set_Unreferenced_In_Spec (Item);
2410
2411                      --  Otherwise simple unreferenced message, but skip this
2412                      --  if no visible entities, because that is most likely a
2413                      --  case where warning would be false positive (e.g. a
2414                      --  package with only a linker options pragma and nothing
2415                      --  else or a pragma elaborate with a body library task).
2416
2417                      elsif Has_Visible_Entities (Entity (Name (Item))) then
2418                         Error_Msg_N -- CODEFIX
2419                           ("?u?unit& is not referenced!", Name (Item));
2420                      end if;
2421                   end if;
2422
2423                --  If main unit is a renaming of this unit, then we consider
2424                --  the with to be OK (obviously it is needed in this case).
2425                --  This may be transitive: the unit in the with_clause may
2426                --  itself be a renaming, in which case both it and the main
2427                --  unit rename the same ultimate package.
2428
2429                elsif Present (Renamed_Entity (Munite))
2430                   and then
2431                     (Renamed_Entity (Munite) = Lunit
2432                       or else Renamed_Entity (Munite) = Renamed_Entity (Lunit))
2433                then
2434                   null;
2435
2436                --  If this unit is referenced, and it is a package, we do
2437                --  another test, to see if any of the entities in the package
2438                --  are referenced. If none of the entities are referenced, we
2439                --  still post a warning. This occurs if the only use of the
2440                --  package is in a use clause, or in a package renaming
2441                --  declaration. This check is skipped for packages that are
2442                --  renamed in a spec, since the entities in such a package are
2443                --  visible to clients via the renaming.
2444
2445                elsif Ekind (Lunit) = E_Package
2446                  and then not Renamed_In_Spec (Lunit)
2447                then
2448                   --  If Is_Instantiated is set, it means that the package is
2449                   --  implicitly instantiated (this is the case of parent
2450                   --  instance or an actual for a generic package formal), and
2451                   --  this counts as a reference.
2452
2453                   if Is_Instantiated (Lunit) then
2454                      null;
2455
2456                   --  If no entities in package, and there is a pragma
2457                   --  Elaborate_Body present, then assume that this with is
2458                   --  done for purposes of this elaboration.
2459
2460                   elsif No (First_Entity (Lunit))
2461                     and then Has_Pragma_Elaborate_Body (Lunit)
2462                   then
2463                      null;
2464
2465                   --  Otherwise see if any entities have been referenced
2466
2467                   else
2468                      if Limited_Present (Item) then
2469                         Ent := First_Entity (Limited_View (Lunit));
2470                      else
2471                         Ent := First_Entity (Lunit);
2472                      end if;
2473
2474                      loop
2475                         --  No more entities, and we did not find one that was
2476                         --  referenced. Means we have a definite case of a with
2477                         --  none of whose entities was referenced.
2478
2479                         if No (Ent) then
2480
2481                            --  If in spec, just set the flag
2482
2483                            if Unit = Spec_Unit then
2484                               Set_No_Entities_Ref_In_Spec (Item);
2485
2486                            elsif Check_System_Aux then
2487                               null;
2488
2489                            --  Else the warning may be needed
2490
2491                            else
2492                               declare
2493                                  Eitem : constant Entity_Id :=
2494                                            Entity (Name (Item));
2495
2496                               begin
2497                                  --  Warn if we unreferenced flag set and we
2498                                  --  have not had serious errors. The reason we
2499                                  --  inhibit the message if there are errors is
2500                                  --  to prevent false positives from disabling
2501                                  --  expansion.
2502
2503                                  if not Has_Unreferenced (Eitem)
2504                                    and then Serious_Errors_Detected = 0
2505                                  then
2506                                     --  Get possible package renaming
2507
2508                                     Pack :=
2509                                       Find_Package_Renaming (Munite, Lunit);
2510
2511                                     --  No warning if either the package or its
2512                                     --  renaming is used as a generic actual.
2513
2514                                     if Used_As_Generic_Actual (Eitem)
2515                                       or else
2516                                         (Present (Pack)
2517                                           and then
2518                                             Used_As_Generic_Actual (Pack))
2519                                     then
2520                                        exit;
2521                                     end if;
2522
2523                                     --  Here we give the warning
2524
2525                                     Error_Msg_N -- CODEFIX
2526                                       ("?u?no entities of & are referenced!",
2527                                        Name (Item));
2528
2529                                     --  Flag renaming of package as well. If
2530                                     --  the original package has warnings off,
2531                                     --  we suppress the warning on the renaming
2532                                     --  as well.
2533
2534                                     if Present (Pack)
2535                                       and then not Has_Warnings_Off (Lunit)
2536                                       and then not Has_Unreferenced (Pack)
2537                                     then
2538                                        Error_Msg_NE -- CODEFIX
2539                                          ("?u?no entities of& are referenced!",
2540                                           Unit_Declaration_Node (Pack), Pack);
2541                                     end if;
2542                                  end if;
2543                               end;
2544                            end if;
2545
2546                            exit;
2547
2548                         --  Case of entity being referenced. The reference may
2549                         --  come from a limited_with_clause, in which case the
2550                         --  limited view of the entity carries the flag.
2551
2552                         elsif Referenced_Check_Spec (Ent)
2553                           or else Referenced_As_LHS_Check_Spec (Ent)
2554                           or else Referenced_As_Out_Parameter_Check_Spec (Ent)
2555                           or else
2556                             (From_Limited_With (Ent)
2557                               and then Is_Incomplete_Type (Ent)
2558                               and then Present (Non_Limited_View (Ent))
2559                               and then Referenced (Non_Limited_View (Ent)))
2560                         then
2561                            --  This means that the with is indeed fine, in that
2562                            --  it is definitely needed somewhere, and we can
2563                            --  quit worrying about this one...
2564
2565                            --  Except for one little detail: if either of the
2566                            --  flags was set during spec processing, this is
2567                            --  where we complain that the with could be moved
2568                            --  from the spec. If the spec contains a visible
2569                            --  renaming of the package, inhibit warning to move
2570                            --  with_clause to body.
2571
2572                            if Ekind (Munite) = E_Package_Body then
2573                               Pack :=
2574                                 Find_Package_Renaming
2575                                   (Spec_Entity (Munite), Lunit);
2576                            else
2577                               Pack := Empty;
2578                            end if;
2579
2580                            --  If a renaming is present in the spec do not warn
2581                            --  because the body or child unit may depend on it.
2582
2583                            if Present (Pack)
2584                              and then Renamed_Entity (Pack) = Lunit
2585                            then
2586                               exit;
2587
2588                            elsif Unreferenced_In_Spec (Item) then
2589                               Error_Msg_N -- CODEFIX
2590                                 ("?u?unit& is not referenced in spec!",
2591                                  Name (Item));
2592
2593                            elsif No_Entities_Ref_In_Spec (Item) then
2594                               Error_Msg_N -- CODEFIX
2595                                 ("?u?no entities of & are referenced in spec!",
2596                                  Name (Item));
2597
2598                            else
2599                               if Ekind (Ent) = E_Package then
2600                                  Check_Inner_Package (Ent);
2601                               end if;
2602
2603                               exit;
2604                            end if;
2605
2606                            if not Is_Visible_Renaming then
2607                               Error_Msg_N -- CODEFIX
2608                                 ("\?u?with clause might be moved to body!",
2609                                  Name (Item));
2610                            end if;
2611
2612                            exit;
2613
2614                         --  Move to next entity to continue search
2615
2616                         else
2617                            Next_Entity (Ent);
2618                         end if;
2619                      end loop;
2620                   end if;
2621
2622                --  For a generic package, the only interesting kind of
2623                --  reference is an instantiation, since entities cannot be
2624                --  referenced directly.
2625
2626                elsif Is_Generic_Unit (Lunit) then
2627
2628                   --  Unit was never instantiated, set flag for case of spec
2629                   --  call, or give warning for normal call.
2630
2631                   if not Is_Instantiated (Lunit) then
2632                      if Unit = Spec_Unit then
2633                         Set_Unreferenced_In_Spec (Item);
2634                      else
2635                         Error_Msg_N -- CODEFIX
2636                           ("?u?unit& is never instantiated!", Name (Item));
2637                      end if;
2638
2639                   --  If unit was indeed instantiated, make sure that flag is
2640                   --  not set showing it was uninstantiated in the spec, and if
2641                   --  so, give warning.
2642
2643                   elsif Unreferenced_In_Spec (Item) then
2644                      Error_Msg_N
2645                        ("?u?unit& is not instantiated in spec!", Name (Item));
2646                      Error_Msg_N -- CODEFIX
2647                        ("\?u?with clause can be moved to body!", Name (Item));
2648                   end if;
2649                end if;
2650             end if;
2651
2652             Next (Item);
2653          end loop;
2654       end Check_One_Unit;
2655
2656    --  Start of processing for Check_Unused_Withs
2657
2658    begin
2659       --  Immediate return if no semantics or warning flag not set
2660
2661       if not Opt.Check_Withs or else Operating_Mode = Check_Syntax then
2662          return;
2663       end if;
2664
2665       Process_Deferred_References;
2666
2667       --  Flag any unused with clauses. For a subunit, check only the units
2668       --  in its context, not those of the parent, which may be needed by other
2669       --  subunits.  We will get the full warnings when we compile the parent,
2670       --  but the following is helpful when compiling a subunit by itself.
2671
2672       if Nkind (Unit (Cunit (Main_Unit))) = N_Subunit then
2673          if Current_Sem_Unit = Main_Unit then
2674             Check_One_Unit (Main_Unit);
2675          end if;
2676
2677          return;
2678       end if;
2679
2680       --  Process specified units
2681
2682       if Spec_Unit = No_Unit then
2683
2684          --  For main call, check all units
2685
2686          for Unit in Main_Unit .. Last_Unit loop
2687             Check_One_Unit (Unit);
2688          end loop;
2689
2690       else
2691          --  For call for spec, check only the spec
2692
2693          Check_One_Unit (Spec_Unit);
2694       end if;
2695    end Check_Unused_Withs;
2696
2697    ---------------------------------
2698    -- Generic_Package_Spec_Entity --
2699    ---------------------------------
2700
2701    function Generic_Package_Spec_Entity (E : Entity_Id) return Boolean is
2702       S : Entity_Id;
2703
2704    begin
2705       if Is_Package_Body_Entity (E) then
2706          return False;
2707
2708       else
2709          S := Scope (E);
2710          loop
2711             if S = Standard_Standard then
2712                return False;
2713
2714             elsif Ekind (S) = E_Generic_Package then
2715                return True;
2716
2717             elsif Ekind (S) = E_Package then
2718                S := Scope (S);
2719
2720             else
2721                return False;
2722             end if;
2723          end loop;
2724       end if;
2725    end Generic_Package_Spec_Entity;
2726
2727    ----------------------
2728    -- Goto_Spec_Entity --
2729    ----------------------
2730
2731    function Goto_Spec_Entity (E : Entity_Id) return Entity_Id is
2732    begin
2733       if Is_Formal (E) and then Present (Spec_Entity (E)) then
2734          return Spec_Entity (E);
2735       else
2736          return E;
2737       end if;
2738    end Goto_Spec_Entity;
2739
2740    -------------------
2741    -- Has_Junk_Name --
2742    -------------------
2743
2744    function Has_Junk_Name (E : Entity_Id) return Boolean is
2745       function Match (S : String) return Boolean;
2746       --  Return true if substring S is found in Name_Buffer (1 .. Name_Len)
2747
2748       -----------
2749       -- Match --
2750       -----------
2751
2752       function Match (S : String) return Boolean is
2753          Slen1 : constant Integer := S'Length - 1;
2754
2755       begin
2756          for J in 1 .. Name_Len - S'Length + 1 loop
2757             if Name_Buffer (J .. J + Slen1) = S then
2758                return True;
2759             end if;
2760          end loop;
2761
2762          return False;
2763       end Match;
2764
2765    --  Start of processing for Has_Junk_Name
2766
2767    begin
2768       Get_Unqualified_Decoded_Name_String (Chars (E));
2769
2770       return
2771         Match ("discard") or else
2772         Match ("dummy")   or else
2773         Match ("ignore")  or else
2774         Match ("junk")    or else
2775         Match ("unused");
2776    end Has_Junk_Name;
2777
2778    --------------------------------------
2779    -- Has_Pragma_Unmodified_Check_Spec --
2780    --------------------------------------
2781
2782    function Has_Pragma_Unmodified_Check_Spec
2783      (E : Entity_Id) return Boolean
2784    is
2785    begin
2786       if Is_Formal (E) and then Present (Spec_Entity (E)) then
2787
2788          --  Note: use of OR instead of OR ELSE here is deliberate, we want
2789          --  to mess with Unmodified flags on both body and spec entities.
2790
2791          return Has_Unmodified (E)
2792                   or
2793                 Has_Unmodified (Spec_Entity (E));
2794
2795       else
2796          return Has_Unmodified (E);
2797       end if;
2798    end Has_Pragma_Unmodified_Check_Spec;
2799
2800    ----------------------------------------
2801    -- Has_Pragma_Unreferenced_Check_Spec --
2802    ----------------------------------------
2803
2804    function Has_Pragma_Unreferenced_Check_Spec
2805      (E : Entity_Id) return Boolean
2806    is
2807    begin
2808       if Is_Formal (E) and then Present (Spec_Entity (E)) then
2809
2810          --  Note: use of OR here instead of OR ELSE is deliberate, we want
2811          --  to mess with flags on both entities.
2812
2813          return Has_Unreferenced (E)
2814                   or
2815                 Has_Unreferenced (Spec_Entity (E));
2816
2817       else
2818          return Has_Unreferenced (E);
2819       end if;
2820    end Has_Pragma_Unreferenced_Check_Spec;
2821
2822    ----------------
2823    -- Initialize --
2824    ----------------
2825
2826    procedure Initialize is
2827    begin
2828       Warnings_Off_Pragmas.Init;
2829       Unreferenced_Entities.Init;
2830       In_Out_Warnings.Init;
2831    end Initialize;
2832
2833    ------------------------------------
2834    -- Never_Set_In_Source_Check_Spec --
2835    ------------------------------------
2836
2837    function Never_Set_In_Source_Check_Spec (E : Entity_Id) return Boolean is
2838    begin
2839       if Is_Formal (E) and then Present (Spec_Entity (E)) then
2840          return Never_Set_In_Source (E)
2841                   and then
2842                 Never_Set_In_Source (Spec_Entity (E));
2843       else
2844          return Never_Set_In_Source (E);
2845       end if;
2846    end Never_Set_In_Source_Check_Spec;
2847
2848    -------------------------------------
2849    -- Operand_Has_Warnings_Suppressed --
2850    -------------------------------------
2851
2852    function Operand_Has_Warnings_Suppressed (N : Node_Id) return Boolean is
2853
2854       function Check_For_Warnings (N : Node_Id) return Traverse_Result;
2855       --  Function used to check one node to see if it is or was originally
2856       --  a reference to an entity for which Warnings are off. If so, Abandon
2857       --  is returned, otherwise OK_Orig is returned to continue the traversal
2858       --  of the original expression.
2859
2860       function Traverse is new Traverse_Func (Check_For_Warnings);
2861       --  Function used to traverse tree looking for warnings
2862
2863       ------------------------
2864       -- Check_For_Warnings --
2865       ------------------------
2866
2867       function Check_For_Warnings (N : Node_Id) return Traverse_Result is
2868          R : constant Node_Id := Original_Node (N);
2869
2870       begin
2871          if Nkind (R) in N_Has_Entity
2872            and then Present (Entity (R))
2873            and then Has_Warnings_Off (Entity (R))
2874          then
2875             return Abandon;
2876          else
2877             return OK_Orig;
2878          end if;
2879       end Check_For_Warnings;
2880
2881    --  Start of processing for Operand_Has_Warnings_Suppressed
2882
2883    begin
2884       return Traverse (N) = Abandon;
2885
2886    --  If any exception occurs, then something has gone wrong, and this is
2887    --  only a minor aesthetic issue anyway, so just say we did not find what
2888    --  we are looking for, rather than blow up.
2889
2890    exception
2891       when others =>
2892          return False;
2893    end Operand_Has_Warnings_Suppressed;
2894
2895    -----------------------------------------
2896    -- Output_Non_Modified_In_Out_Warnings --
2897    -----------------------------------------
2898
2899    procedure Output_Non_Modified_In_Out_Warnings is
2900
2901       function No_Warn_On_In_Out (E : Entity_Id) return Boolean;
2902       --  Given a formal parameter entity E, determines if there is a reason to
2903       --  suppress IN OUT warnings (not modified, could be IN) for formals of
2904       --  the subprogram. We suppress these warnings if Warnings Off is set, or
2905       --  if we have seen the address of the subprogram being taken, or if the
2906       --  subprogram is used as a generic actual (in the latter cases the
2907       --  context may force use of IN OUT, even if the parameter is not
2908       --  modifies for this particular case.
2909
2910       -----------------------
2911       -- No_Warn_On_In_Out --
2912       -----------------------
2913
2914       function No_Warn_On_In_Out (E : Entity_Id) return Boolean is
2915          S  : constant Entity_Id := Scope (E);
2916          SE : constant Entity_Id := Spec_Entity (E);
2917
2918       begin
2919          --  Do not warn if address is taken, since funny business may be going
2920          --  on in treating the parameter indirectly as IN OUT.
2921
2922          if Address_Taken (S)
2923            or else (Present (SE) and then Address_Taken (Scope (SE)))
2924          then
2925             return True;
2926
2927          --  Do not warn if used as a generic actual, since the generic may be
2928          --  what is forcing the use of an "unnecessary" IN OUT.
2929
2930          elsif Used_As_Generic_Actual (S)
2931            or else (Present (SE) and then Used_As_Generic_Actual (Scope (SE)))
2932          then
2933             return True;
2934
2935          --  Else test warnings off
2936
2937          elsif Warnings_Off_Check_Spec (S) then
2938             return True;
2939
2940          --  All tests for suppressing warning failed
2941
2942          else
2943             return False;
2944          end if;
2945       end No_Warn_On_In_Out;
2946
2947    --  Start of processing for Output_Non_Modified_In_Out_Warnings
2948
2949    begin
2950       --  Loop through entities for which a warning may be needed
2951
2952       for J in In_Out_Warnings.First .. In_Out_Warnings.Last loop
2953          declare
2954             E1 : constant Entity_Id := In_Out_Warnings.Table (J);
2955
2956          begin
2957             --  Suppress warning in specific cases (see details in comments for
2958             --  No_Warn_On_In_Out), or if there is a pragma Unmodified.
2959
2960             if Has_Pragma_Unmodified_Check_Spec (E1)
2961               or else No_Warn_On_In_Out (E1)
2962             then
2963                null;
2964
2965             --  Here we generate the warning
2966
2967             else
2968                --  If -gnatwc is set then output message that we could be IN
2969
2970                if not Is_Trivial_Subprogram (Scope (E1)) then
2971                   if Warn_On_Constant then
2972                      Error_Msg_N
2973                        ("?u?formal parameter & is not modified!", E1);
2974                      Error_Msg_N
2975                        ("\?u?mode could be IN instead of `IN OUT`!", E1);
2976
2977                      --  We do not generate warnings for IN OUT parameters
2978                      --  unless we have at least -gnatwu. This is deliberately
2979                      --  inconsistent with the treatment of variables, but
2980                      --  otherwise we get too many unexpected warnings in
2981                      --  default mode.
2982
2983                   elsif Check_Unreferenced then
2984                      Error_Msg_N
2985                        ("?u?formal parameter& is read but "
2986                         & "never assigned!", E1);
2987                   end if;
2988                end if;
2989
2990                --  Kill any other warnings on this entity, since this is the
2991                --  one that should dominate any other unreferenced warning.
2992
2993                Set_Warnings_Off (E1);
2994             end if;
2995          end;
2996       end loop;
2997    end Output_Non_Modified_In_Out_Warnings;
2998
2999    ----------------------------------------
3000    -- Output_Obsolescent_Entity_Warnings --
3001    ----------------------------------------
3002
3003    procedure Output_Obsolescent_Entity_Warnings (N : Node_Id; E : Entity_Id) is
3004       P : constant Node_Id := Parent (N);
3005       S : Entity_Id;
3006
3007    begin
3008       S := Current_Scope;
3009
3010       --  Do not output message if we are the scope of standard. This means
3011       --  we have a reference from a context clause from when it is originally
3012       --  processed, and that's too early to tell whether it is an obsolescent
3013       --  unit doing the with'ing. In Sem_Ch10.Analyze_Compilation_Unit we make
3014       --  sure that we have a later call when the scope is available. This test
3015       --  also eliminates all messages for use clauses, which is fine (we do
3016       --  not want messages for use clauses, since they are always redundant
3017       --  with respect to the associated with clause).
3018
3019       if S = Standard_Standard then
3020          return;
3021       end if;
3022
3023       --  Do not output message if we are in scope of an obsolescent package
3024       --  or subprogram.
3025
3026       loop
3027          if Is_Obsolescent (S) then
3028             return;
3029          end if;
3030
3031          S := Scope (S);
3032          exit when S = Standard_Standard;
3033       end loop;
3034
3035       --  Here we will output the message
3036
3037       Error_Msg_Sloc := Sloc (E);
3038
3039       --  Case of with clause
3040
3041       if Nkind (P) = N_With_Clause then
3042          if Ekind (E) = E_Package then
3043             Error_Msg_NE
3044               ("?j?with of obsolescent package& declared#", N, E);
3045          elsif Ekind (E) = E_Procedure then
3046             Error_Msg_NE
3047               ("?j?with of obsolescent procedure& declared#", N, E);
3048          else
3049             Error_Msg_NE
3050               ("??with of obsolescent function& declared#", N, E);
3051          end if;
3052
3053       --  If we do not have a with clause, then ignore any reference to an
3054       --  obsolescent package name. We only want to give the one warning of
3055       --  withing the package, not one each time it is used to qualify.
3056
3057       elsif Ekind (E) = E_Package then
3058          return;
3059
3060       --  Procedure call statement
3061
3062       elsif Nkind (P) = N_Procedure_Call_Statement then
3063          Error_Msg_NE
3064            ("??call to obsolescent procedure& declared#", N, E);
3065
3066       --  Function call
3067
3068       elsif Nkind (P) = N_Function_Call then
3069          Error_Msg_NE
3070            ("??call to obsolescent function& declared#", N, E);
3071
3072       --  Reference to obsolescent type
3073
3074       elsif Is_Type (E) then
3075          Error_Msg_NE
3076            ("??reference to obsolescent type& declared#", N, E);
3077
3078       --  Reference to obsolescent component
3079
3080       elsif Ekind_In (E, E_Component, E_Discriminant) then
3081          Error_Msg_NE
3082            ("??reference to obsolescent component& declared#", N, E);
3083
3084       --  Reference to obsolescent variable
3085
3086       elsif Ekind (E) = E_Variable then
3087          Error_Msg_NE
3088            ("??reference to obsolescent variable& declared#", N, E);
3089
3090       --  Reference to obsolescent constant
3091
3092       elsif Ekind (E) = E_Constant or else Ekind (E) in Named_Kind then
3093          Error_Msg_NE
3094            ("??reference to obsolescent constant& declared#", N, E);
3095
3096       --  Reference to obsolescent enumeration literal
3097
3098       elsif Ekind (E) = E_Enumeration_Literal then
3099          Error_Msg_NE
3100            ("??reference to obsolescent enumeration literal& declared#", N, E);
3101
3102       --  Generic message for any other case we missed
3103
3104       else
3105          Error_Msg_NE
3106            ("??reference to obsolescent entity& declared#", N, E);
3107       end if;
3108
3109       --  Output additional warning if present
3110
3111       for J in Obsolescent_Warnings.First .. Obsolescent_Warnings.Last loop
3112          if Obsolescent_Warnings.Table (J).Ent = E then
3113             String_To_Name_Buffer (Obsolescent_Warnings.Table (J).Msg);
3114             Error_Msg_Strlen := Name_Len;
3115             Error_Msg_String (1 .. Name_Len) := Name_Buffer (1 .. Name_Len);
3116             Error_Msg_N ("\\??~", N);
3117             exit;
3118          end if;
3119       end loop;
3120    end Output_Obsolescent_Entity_Warnings;
3121
3122    ----------------------------------
3123    -- Output_Unreferenced_Messages --
3124    ----------------------------------
3125
3126    procedure Output_Unreferenced_Messages is
3127    begin
3128       for J in Unreferenced_Entities.First .. Unreferenced_Entities.Last loop
3129          Warn_On_Unreferenced_Entity (Unreferenced_Entities.Table (J));
3130       end loop;
3131    end Output_Unreferenced_Messages;
3132
3133    -----------------------------------------
3134    -- Output_Unused_Warnings_Off_Warnings --
3135    -----------------------------------------
3136
3137    procedure Output_Unused_Warnings_Off_Warnings is
3138    begin
3139       for J in Warnings_Off_Pragmas.First .. Warnings_Off_Pragmas.Last loop
3140          declare
3141             Wentry : Warnings_Off_Entry renames Warnings_Off_Pragmas.Table (J);
3142             N      : Node_Id renames Wentry.N;
3143             E      : Node_Id renames Wentry.E;
3144
3145          begin
3146             --  Turn off Warnings_Off, or we won't get the warning
3147
3148             Set_Warnings_Off (E, False);
3149
3150             --  Nothing to do if pragma was used to suppress a general warning
3151
3152             if Warnings_Off_Used (E) then
3153                null;
3154
3155             --  If pragma was used both in unmodified and unreferenced contexts
3156             --  then that's as good as the general case, no warning.
3157
3158             elsif Warnings_Off_Used_Unmodified (E)
3159                     and
3160                   Warnings_Off_Used_Unreferenced (E)
3161             then
3162                null;
3163
3164             --  Used only in context where Unmodified would have worked
3165
3166             elsif Warnings_Off_Used_Unmodified (E) then
3167                Error_Msg_NE
3168                  ("?W?could use Unmodified instead of "
3169                   & "Warnings Off for &", Pragma_Identifier (N), E);
3170
3171             --  Used only in context where Unreferenced would have worked
3172
3173             elsif Warnings_Off_Used_Unreferenced (E) then
3174                Error_Msg_NE
3175                  ("?W?could use Unreferenced instead of "
3176                   & "Warnings Off for &", Pragma_Identifier (N), E);
3177
3178             --  Not used at all
3179
3180             else
3181                Error_Msg_NE
3182                  ("?W?pragma Warnings Off for & unused, "
3183                   & "could be omitted", N, E);
3184             end if;
3185          end;
3186       end loop;
3187    end Output_Unused_Warnings_Off_Warnings;
3188
3189    ---------------------------
3190    -- Referenced_Check_Spec --
3191    ---------------------------
3192
3193    function Referenced_Check_Spec (E : Entity_Id) return Boolean is
3194    begin
3195       if Is_Formal (E) and then Present (Spec_Entity (E)) then
3196          return Referenced (E) or else Referenced (Spec_Entity (E));
3197       else
3198          return Referenced (E);
3199       end if;
3200    end Referenced_Check_Spec;
3201
3202    ----------------------------------
3203    -- Referenced_As_LHS_Check_Spec --
3204    ----------------------------------
3205
3206    function Referenced_As_LHS_Check_Spec (E : Entity_Id) return Boolean is
3207    begin
3208       if Is_Formal (E) and then Present (Spec_Entity (E)) then
3209          return Referenced_As_LHS (E)
3210            or else Referenced_As_LHS (Spec_Entity (E));
3211       else
3212          return Referenced_As_LHS (E);
3213       end if;
3214    end Referenced_As_LHS_Check_Spec;
3215
3216    --------------------------------------------
3217    -- Referenced_As_Out_Parameter_Check_Spec --
3218    --------------------------------------------
3219
3220    function Referenced_As_Out_Parameter_Check_Spec
3221      (E : Entity_Id) return Boolean
3222    is
3223    begin
3224       if Is_Formal (E) and then Present (Spec_Entity (E)) then
3225          return Referenced_As_Out_Parameter (E)
3226            or else Referenced_As_Out_Parameter (Spec_Entity (E));
3227       else
3228          return Referenced_As_Out_Parameter (E);
3229       end if;
3230    end Referenced_As_Out_Parameter_Check_Spec;
3231
3232    -----------------------------
3233    -- Warn_On_Known_Condition --
3234    -----------------------------
3235
3236    procedure Warn_On_Known_Condition (C : Node_Id) is
3237       P           : Node_Id;
3238       Orig        : constant Node_Id := Original_Node (C);
3239       Test_Result : Boolean;
3240
3241       function Is_Known_Branch return Boolean;
3242       --  If the type of the condition is Boolean, the constant value of the
3243       --  condition is a boolean literal. If the type is a derived boolean
3244       --  type, the constant is wrapped in a type conversion of the derived
3245       --  literal. If the value of the condition is not a literal, no warnings
3246       --  can be produced. This function returns True if the result can be
3247       --  determined, and Test_Result is set True/False accordingly. Otherwise
3248       --  False is returned, and Test_Result is unchanged.
3249
3250       procedure Track (N : Node_Id; Loc : Node_Id);
3251       --  Adds continuation warning(s) pointing to reason (assignment or test)
3252       --  for the operand of the conditional having a known value (or at least
3253       --  enough is known about the value to issue the warning). N is the node
3254       --  which is judged to have a known value. Loc is the warning location.
3255
3256       ---------------------
3257       -- Is_Known_Branch --
3258       ---------------------
3259
3260       function Is_Known_Branch return Boolean is
3261       begin
3262          if Etype (C) = Standard_Boolean
3263            and then Is_Entity_Name (C)
3264            and then
3265              (Entity (C) = Standard_False or else Entity (C) = Standard_True)
3266          then
3267             Test_Result := Entity (C) = Standard_True;
3268             return True;
3269
3270          elsif Is_Boolean_Type (Etype (C))
3271            and then Nkind (C) = N_Unchecked_Type_Conversion
3272            and then Is_Entity_Name (Expression (C))
3273            and then Ekind (Entity (Expression (C))) = E_Enumeration_Literal
3274          then
3275             Test_Result :=
3276               Chars (Entity (Expression (C))) = Chars (Standard_True);
3277             return True;
3278
3279          else
3280             return False;
3281          end if;
3282       end Is_Known_Branch;
3283
3284       -----------
3285       -- Track --
3286       -----------
3287
3288       procedure Track (N : Node_Id; Loc : Node_Id) is
3289          Nod : constant Node_Id := Original_Node (N);
3290
3291       begin
3292          if Nkind (Nod) in N_Op_Compare then
3293             Track (Left_Opnd (Nod), Loc);
3294             Track (Right_Opnd (Nod), Loc);
3295
3296          elsif Is_Entity_Name (Nod) and then Is_Object (Entity (Nod)) then
3297             declare
3298                CV : constant Node_Id := Current_Value (Entity (Nod));
3299
3300             begin
3301                if Present (CV) then
3302                   Error_Msg_Sloc := Sloc (CV);
3303
3304                   if Nkind (CV) not in N_Subexpr then
3305                      Error_Msg_N ("\\??(see test #)", Loc);
3306
3307                   elsif Nkind (Parent (CV)) =
3308                           N_Case_Statement_Alternative
3309                   then
3310                      Error_Msg_N ("\\??(see case alternative #)", Loc);
3311
3312                   else
3313                      Error_Msg_N ("\\??(see assignment #)", Loc);
3314                   end if;
3315                end if;
3316             end;
3317          end if;
3318       end Track;
3319
3320    --  Start of processing for Warn_On_Known_Condition
3321
3322    begin
3323       --  Adjust SCO condition if from source
3324
3325       if Generate_SCO
3326         and then Comes_From_Source (Orig)
3327         and then Is_Known_Branch
3328       then
3329          declare
3330             Atrue : Boolean;
3331
3332          begin
3333             Atrue := Test_Result;
3334
3335             if Present (Parent (C)) and then Nkind (Parent (C)) = N_Op_Not then
3336                Atrue := not Atrue;
3337             end if;
3338
3339             Set_SCO_Condition (Orig, Atrue);
3340          end;
3341       end if;
3342
3343       --  Argument replacement in an inlined body can make conditions static.
3344       --  Do not emit warnings in this case.
3345
3346       if In_Inlined_Body then
3347          return;
3348       end if;
3349
3350       if Constant_Condition_Warnings
3351         and then Is_Known_Branch
3352         and then Comes_From_Source (Orig)
3353         and then not In_Instance
3354       then
3355          --  Don't warn if comparison of result of attribute against a constant
3356          --  value, since this is likely legitimate conditional compilation.
3357
3358          if Nkind (Orig) in N_Op_Compare
3359            and then Compile_Time_Known_Value (Right_Opnd (Orig))
3360            and then Nkind (Original_Node (Left_Opnd (Orig))) =
3361                                                      N_Attribute_Reference
3362          then
3363             return;
3364          end if;
3365
3366          --  See if this is in a statement or a declaration
3367
3368          P := Parent (C);
3369          loop
3370             --  If tree is not attached, do not issue warning (this is very
3371             --  peculiar, and probably arises from some other error condition)
3372
3373             if No (P) then
3374                return;
3375
3376             --  If we are in a declaration, then no warning, since in practice
3377             --  conditionals in declarations are used for intended tests which
3378             --  may be known at compile time, e.g. things like
3379
3380             --    x : constant Integer := 2 + (Word'Size = 32);
3381
3382             --  And a warning is annoying in such cases
3383
3384             elsif Nkind (P) in N_Declaration
3385                     or else
3386                   Nkind (P) in N_Later_Decl_Item
3387             then
3388                return;
3389
3390             --  Don't warn in assert or check pragma, since presumably tests in
3391             --  such a context are very definitely intended, and might well be
3392             --  known at compile time. Note that we have to test the original
3393             --  node, since assert pragmas get rewritten at analysis time.
3394
3395             elsif Nkind (Original_Node (P)) = N_Pragma
3396               and then Nam_In (Pragma_Name (Original_Node (P)), Name_Assert,
3397                                                                 Name_Check)
3398             then
3399                return;
3400             end if;
3401
3402             exit when Is_Statement (P);
3403             P := Parent (P);
3404          end loop;
3405
3406          --  Here we issue the warning unless some sub-operand has warnings
3407          --  set off, in which case we suppress the warning for the node. If
3408          --  the original expression is an inequality, it has been expanded
3409          --  into a negation, and the value of the original expression is the
3410          --  negation of the equality. If the expression is an entity that
3411          --  appears within a negation, it is clearer to flag the negation
3412          --  itself, and report on its constant value.
3413
3414          if not Operand_Has_Warnings_Suppressed (C) then
3415             declare
3416                True_Branch : Boolean := Test_Result;
3417                Cond        : Node_Id := C;
3418
3419             begin
3420                if Present (Parent (C))
3421                  and then Nkind (Parent (C)) = N_Op_Not
3422                then
3423                   True_Branch := not True_Branch;
3424                   Cond := Parent (C);
3425                end if;
3426
3427                --  Condition always True
3428
3429                if True_Branch then
3430                   if Is_Entity_Name (Original_Node (C))
3431                     and then Nkind (Cond) /= N_Op_Not
3432                   then
3433                      Error_Msg_NE
3434                        ("object & is always True at this point?c?",
3435                         Cond, Original_Node (C));
3436                      Track (Original_Node (C), Cond);
3437
3438                   else
3439                      Error_Msg_N ("condition is always True?c?", Cond);
3440                      Track (Cond, Cond);
3441                   end if;
3442
3443                --  Condition always False
3444
3445                else
3446                   if Is_Entity_Name (Original_Node (C))
3447                     and then Nkind (Cond) /= N_Op_Not
3448                   then
3449                      Error_Msg_NE
3450                        ("object & is always False at this point?c?",
3451                         Cond, Original_Node (C));
3452                      Track (Original_Node (C), Cond);
3453
3454                   else
3455                      Error_Msg_N ("condition is always False?c?", Cond);
3456                      Track (Cond, Cond);
3457                   end if;
3458                end if;
3459             end;
3460          end if;
3461       end if;
3462    end Warn_On_Known_Condition;
3463
3464    ---------------------------------------
3465    -- Warn_On_Modified_As_Out_Parameter --
3466    ---------------------------------------
3467
3468    function Warn_On_Modified_As_Out_Parameter (E : Entity_Id) return Boolean is
3469    begin
3470       return
3471         (Warn_On_Modified_Unread and then Is_Only_Out_Parameter (E))
3472           or else Warn_On_All_Unread_Out_Parameters;
3473    end Warn_On_Modified_As_Out_Parameter;
3474
3475    ---------------------------------
3476    -- Warn_On_Overlapping_Actuals --
3477    ---------------------------------
3478
3479    procedure Warn_On_Overlapping_Actuals (Subp : Entity_Id; N : Node_Id) is
3480       Act1, Act2   : Node_Id;
3481       Form1, Form2 : Entity_Id;
3482
3483       function Is_Covered_Formal (Formal : Node_Id) return Boolean;
3484       --  Return True if Formal is covered by the rule
3485
3486       function Refer_Same_Object (Act1, Act2 : Node_Id) return Boolean;
3487       --  Two names are known to refer to the same object if the two names
3488       --  are known to denote the same object; or one of the names is a
3489       --  selected_component, indexed_component, or slice and its prefix is
3490       --  known to refer to the same object as the other name; or one of the
3491       --  two names statically denotes a renaming declaration whose renamed
3492       --  object_name is known to refer to the same object as the other name
3493       --  (RM 6.4.1(6.11/3))
3494
3495       -----------------------
3496       -- Refer_Same_Object --
3497       -----------------------
3498
3499       function Refer_Same_Object (Act1, Act2 : Node_Id) return Boolean is
3500       begin
3501          return Denotes_Same_Object (Act1, Act2)
3502            or else Denotes_Same_Prefix (Act1, Act2);
3503       end Refer_Same_Object;
3504
3505       -----------------------
3506       -- Is_Covered_Formal --
3507       -----------------------
3508
3509       function Is_Covered_Formal (Formal : Node_Id) return Boolean is
3510       begin
3511          return
3512            Ekind_In (Formal, E_Out_Parameter, E_In_Out_Parameter)
3513              and then (Is_Elementary_Type (Etype (Formal))
3514                         or else Is_Record_Type (Etype (Formal))
3515                         or else Is_Array_Type (Etype (Formal)));
3516       end Is_Covered_Formal;
3517
3518    begin
3519       if Ada_Version < Ada_2012 and then not Warn_On_Overlap then
3520          return;
3521       end if;
3522
3523       --  Exclude calls rewritten as enumeration literals
3524
3525       if Nkind (N) not in N_Subprogram_Call
3526         and then Nkind (N) /= N_Entry_Call_Statement
3527       then
3528          return;
3529       end if;
3530
3531       --  If a call C has two or more parameters of mode in out or out that are
3532       --  of an elementary type, then the call is legal only if for each name
3533       --  N that is passed as a parameter of mode in out or out to the call C,
3534       --  there is no other name among the other parameters of mode in out or
3535       --  out to C that is known to denote the same object (RM 6.4.1(6.15/3))
3536
3537       --  If appropriate warning switch is set, we also report warnings on
3538       --  overlapping parameters that are record types or array types.
3539
3540       Form1 := First_Formal (Subp);
3541       Act1  := First_Actual (N);
3542       while Present (Form1) and then Present (Act1) loop
3543          if Is_Covered_Formal (Form1) then
3544             Form2 := First_Formal (Subp);
3545             Act2  := First_Actual (N);
3546             while Present (Form2) and then Present (Act2) loop
3547                if Form1 /= Form2
3548                  and then Is_Covered_Formal (Form2)
3549                  and then Refer_Same_Object (Act1, Act2)
3550                then
3551                   --  Guard against previous errors
3552
3553                   if Error_Posted (N)
3554                     or else No (Etype (Act1))
3555                     or else No (Etype (Act2))
3556                   then
3557                      null;
3558
3559                   --  If the actual is a function call in prefix notation,
3560                   --  there is no real overlap.
3561
3562                   elsif Nkind (Act2) = N_Function_Call then
3563                      null;
3564
3565                   --  If type is not by-copy, assume that aliasing is intended
3566
3567                   elsif
3568                     Present (Underlying_Type (Etype (Form1)))
3569                       and then
3570                         (Is_By_Reference_Type (Underlying_Type (Etype (Form1)))
3571                           or else
3572                             Convention (Underlying_Type (Etype (Form1))) =
3573                                               Convention_Ada_Pass_By_Reference)
3574                   then
3575                      null;
3576
3577                   --  Under Ada 2012 we only report warnings on overlapping
3578                   --  arrays and record types if switch is set.
3579
3580                   elsif Ada_Version >= Ada_2012
3581                     and then not Is_Elementary_Type (Etype (Form1))
3582                     and then not Warn_On_Overlap
3583                   then
3584                      null;
3585
3586                   --  Here we may need to issue overlap message
3587
3588                   else
3589                      Error_Msg_Warn :=
3590
3591                        --  Overlap checking is an error only in Ada 2012. For
3592                        --  earlier versions of Ada, this is a warning.
3593
3594                        Ada_Version < Ada_2012
3595
3596                        --  Overlap is only illegal in Ada 2012 in the case of
3597                        --  elementary types (passed by copy). For other types,
3598                        --  we always have a warning in all Ada versions.
3599
3600                        or else not Is_Elementary_Type (Etype (Form1))
3601
3602                        --  Finally, debug flag -gnatd.E changes the error to a
3603                        --  warning even in Ada 2012 mode.
3604
3605                        or else Error_To_Warning;
3606
3607                      declare
3608                         Act  : Node_Id;
3609                         Form : Entity_Id;
3610
3611                      begin
3612                         --  Find matching actual
3613
3614                         Act  := First_Actual (N);
3615                         Form := First_Formal (Subp);
3616                         while Act /= Act2 loop
3617                            Next_Formal (Form);
3618                            Next_Actual (Act);
3619                         end loop;
3620
3621                         if Is_Elementary_Type (Etype (Act1))
3622                           and then Ekind (Form2) = E_In_Parameter
3623                         then
3624                            null;  --  No real aliasing
3625
3626                         elsif Is_Elementary_Type (Etype (Act2))
3627                           and then Ekind (Form2) = E_In_Parameter
3628                         then
3629                            null;  --  Ditto
3630
3631                         --  If the call was written in prefix notation, and
3632                         --  thus its prefix before rewriting was a selected
3633                         --  component, count only visible actuals in the call.
3634
3635                         elsif Is_Entity_Name (First_Actual (N))
3636                           and then Nkind (Original_Node (N)) = Nkind (N)
3637                           and then Nkind (Name (Original_Node (N))) =
3638                                                          N_Selected_Component
3639                           and then
3640                             Is_Entity_Name (Prefix (Name (Original_Node (N))))
3641                           and then
3642                             Entity (Prefix (Name (Original_Node (N)))) =
3643                               Entity (First_Actual (N))
3644                         then
3645                            if Act1 = First_Actual (N) then
3646                               Error_Msg_FE
3647                                 ("<<`IN OUT` prefix overlaps with "
3648                                  & "actual for&", Act1, Form);
3649
3650                            else
3651                               --  For greater clarity, give name of formal
3652
3653                               Error_Msg_Node_2 := Form;
3654                               Error_Msg_FE
3655                                 ("<<writable actual for & overlaps with "
3656                                  & "actual for&", Act1, Form);
3657                            end if;
3658
3659                         else
3660                            --  For greater clarity, give name of formal
3661
3662                            Error_Msg_Node_2 := Form;
3663
3664                            --  This is one of the messages
3665
3666                            Error_Msg_FE
3667                              ("<<writable actual for & overlaps with "
3668                               & "actual for&", Act1, Form1);
3669                         end if;
3670                      end;
3671                   end if;
3672
3673                   return;
3674                end if;
3675
3676                Next_Formal (Form2);
3677                Next_Actual (Act2);
3678             end loop;
3679          end if;
3680
3681          Next_Formal (Form1);
3682          Next_Actual (Act1);
3683       end loop;
3684    end Warn_On_Overlapping_Actuals;
3685
3686    ------------------------------
3687    -- Warn_On_Suspicious_Index --
3688    ------------------------------
3689
3690    procedure Warn_On_Suspicious_Index (Name : Entity_Id; X : Node_Id) is
3691
3692       Low_Bound : Uint;
3693       --  Set to lower bound for a suspicious type
3694
3695       Ent : Entity_Id;
3696       --  Entity for array reference
3697
3698       Typ : Entity_Id;
3699       --  Array type
3700
3701       function Is_Suspicious_Type (Typ : Entity_Id) return Boolean;
3702       --  Tests to see if Typ is a type for which we may have a suspicious
3703       --  index, namely an unconstrained array type, whose lower bound is
3704       --  either zero or one. If so, True is returned, and Low_Bound is set
3705       --  to this lower bound. If not, False is returned, and Low_Bound is
3706       --  undefined on return.
3707       --
3708       --  For now, we limit this to standard string types, so any other
3709       --  unconstrained types return False. We may change our minds on this
3710       --  later on, but strings seem the most important case.
3711
3712       procedure Test_Suspicious_Index;
3713       --  Test if index is of suspicious type and if so, generate warning
3714
3715       ------------------------
3716       -- Is_Suspicious_Type --
3717       ------------------------
3718
3719       function Is_Suspicious_Type (Typ : Entity_Id) return Boolean is
3720          LB : Node_Id;
3721
3722       begin
3723          if Is_Array_Type (Typ)
3724            and then not Is_Constrained (Typ)
3725            and then Number_Dimensions (Typ) = 1
3726            and then Is_Standard_String_Type (Typ)
3727            and then not Has_Warnings_Off (Typ)
3728          then
3729             LB := Type_Low_Bound (Etype (First_Index (Typ)));
3730
3731             if Compile_Time_Known_Value (LB) then
3732                Low_Bound := Expr_Value (LB);
3733                return Low_Bound = Uint_0 or else Low_Bound = Uint_1;
3734             end if;
3735          end if;
3736
3737          return False;
3738       end Is_Suspicious_Type;
3739
3740       ---------------------------
3741       -- Test_Suspicious_Index --
3742       ---------------------------
3743
3744       procedure Test_Suspicious_Index is
3745
3746          function Length_Reference (N : Node_Id) return Boolean;
3747          --  Check if node N is of the form Name'Length
3748
3749          procedure Warn1;
3750          --  Generate first warning line
3751
3752          ----------------------
3753          -- Length_Reference --
3754          ----------------------
3755
3756          function Length_Reference (N : Node_Id) return Boolean is
3757             R : constant Node_Id := Original_Node (N);
3758          begin
3759             return
3760               Nkind (R) = N_Attribute_Reference
3761                 and then Attribute_Name (R) = Name_Length
3762                 and then Is_Entity_Name (Prefix (R))
3763                 and then Entity (Prefix (R)) = Ent;
3764          end Length_Reference;
3765
3766          -----------
3767          -- Warn1 --
3768          -----------
3769
3770          procedure Warn1 is
3771          begin
3772             Error_Msg_Uint_1 := Low_Bound;
3773             Error_Msg_FE -- CODEFIX
3774               ("?w?index for& may assume lower bound of^", X, Ent);
3775          end Warn1;
3776
3777       --  Start of processing for Test_Suspicious_Index
3778
3779       begin
3780          --  Nothing to do if subscript does not come from source (we don't
3781          --  want to give garbage warnings on compiler expanded code, e.g. the
3782          --  loops generated for slice assignments. Such junk warnings would
3783          --  be placed on source constructs with no subscript in sight).
3784
3785          if not Comes_From_Source (Original_Node (X)) then
3786             return;
3787          end if;
3788
3789          --  Case where subscript is a constant integer
3790
3791          if Nkind (X) = N_Integer_Literal then
3792             Warn1;
3793
3794             --  Case where original form of subscript is an integer literal
3795
3796             if Nkind (Original_Node (X)) = N_Integer_Literal then
3797                if Intval (X) = Low_Bound then
3798                   Error_Msg_FE -- CODEFIX
3799                     ("\?w?suggested replacement: `&''First`", X, Ent);
3800                else
3801                   Error_Msg_Uint_1 := Intval (X) - Low_Bound;
3802                   Error_Msg_FE -- CODEFIX
3803                     ("\?w?suggested replacement: `&''First + ^`", X, Ent);
3804
3805                end if;
3806
3807             --  Case where original form of subscript is more complex
3808
3809             else
3810                --  Build string X'First - 1 + expression where the expression
3811                --  is the original subscript. If the expression starts with "1
3812                --  + ", then the "- 1 + 1" is elided.
3813
3814                Error_Msg_String (1 .. 13) := "'First - 1 + ";
3815                Error_Msg_Strlen := 13;
3816
3817                declare
3818                   Sref : Source_Ptr := Sloc (First_Node (Original_Node (X)));
3819                   Tref : constant Source_Buffer_Ptr :=
3820                            Source_Text (Get_Source_File_Index (Sref));
3821                   --  Tref (Sref) is used to scan the subscript
3822
3823                   Pctr : Natural;
3824                   --  Parentheses counter when scanning subscript
3825
3826                begin
3827                   --  Tref (Sref) points to start of subscript
3828
3829                   --  Elide - 1 if subscript starts with 1 +
3830
3831                   if Tref (Sref .. Sref + 2) = "1 +" then
3832                      Error_Msg_Strlen := Error_Msg_Strlen - 6;
3833                      Sref := Sref + 2;
3834
3835                   elsif Tref (Sref .. Sref + 1) = "1+" then
3836                      Error_Msg_Strlen := Error_Msg_Strlen - 6;
3837                      Sref := Sref + 1;
3838                   end if;
3839
3840                   --  Now we will copy the subscript to the string buffer
3841
3842                   Pctr := 0;
3843                   loop
3844                      --  Count parens, exit if terminating right paren. Note
3845                      --  check to ignore paren appearing as character literal.
3846
3847                      if Tref (Sref + 1) = '''
3848                           and then
3849                         Tref (Sref - 1) = '''
3850                      then
3851                         null;
3852                      else
3853                         if Tref (Sref) = '(' then
3854                            Pctr := Pctr + 1;
3855                         elsif Tref (Sref) = ')' then
3856                            exit when Pctr = 0;
3857                            Pctr := Pctr - 1;
3858                         end if;
3859                      end if;
3860
3861                      --  Done if terminating double dot (slice case)
3862
3863                      exit when Pctr = 0
3864                        and then (Tref (Sref .. Sref + 1) = ".."
3865                                    or else
3866                                  Tref (Sref .. Sref + 2) = " ..");
3867
3868                      --  Quit if we have hit EOF character, something wrong
3869
3870                      if Tref (Sref) = EOF then
3871                         return;
3872                      end if;
3873
3874                      --  String literals are too much of a pain to handle
3875
3876                      if Tref (Sref) = '"' or else Tref (Sref) = '%' then
3877                         return;
3878                      end if;
3879
3880                      --  If we have a 'Range reference, then this is a case
3881                      --  where we cannot easily give a replacement. Don't try.
3882
3883                      if Tref (Sref .. Sref + 4) = "range"
3884                        and then Tref (Sref - 1) < 'A'
3885                        and then Tref (Sref + 5) < 'A'
3886                      then
3887                         return;
3888                      end if;
3889
3890                      --  Else store next character
3891
3892                      Error_Msg_Strlen := Error_Msg_Strlen + 1;
3893                      Error_Msg_String (Error_Msg_Strlen) := Tref (Sref);
3894                      Sref := Sref + 1;
3895
3896                      --  If we get more than 40 characters then the expression
3897                      --  is too long to copy, or something has gone wrong. In
3898                      --  either case, just skip the attempt at a suggested fix.
3899
3900                      if Error_Msg_Strlen > 40 then
3901                         return;
3902                      end if;
3903                   end loop;
3904                end;
3905
3906                --  Replacement subscript is now in string buffer
3907
3908                Error_Msg_FE -- CODEFIX
3909                  ("\?w?suggested replacement: `&~`", Original_Node (X), Ent);
3910             end if;
3911
3912          --  Case where subscript is of the form X'Length
3913
3914          elsif Length_Reference (X) then
3915             Warn1;
3916             Error_Msg_Node_2 := Ent;
3917             Error_Msg_FE
3918               ("\?w?suggest replacement of `&''Length` by `&''Last`",
3919                X, Ent);
3920
3921          --  Case where subscript is of the form X'Length - expression
3922
3923          elsif Nkind (X) = N_Op_Subtract
3924            and then Length_Reference (Left_Opnd (X))
3925          then
3926             Warn1;
3927             Error_Msg_Node_2 := Ent;
3928             Error_Msg_FE
3929               ("\?w?suggest replacement of `&''Length` by `&''Last`",
3930                Left_Opnd (X), Ent);
3931          end if;
3932       end Test_Suspicious_Index;
3933
3934    --  Start of processing for Warn_On_Suspicious_Index
3935
3936    begin
3937       --  Only process if warnings activated
3938
3939       if Warn_On_Assumed_Low_Bound then
3940
3941          --  Test if array is simple entity name
3942
3943          if Is_Entity_Name (Name) then
3944
3945             --  Test if array is parameter of unconstrained string type
3946
3947             Ent := Entity (Name);
3948             Typ := Etype (Ent);
3949
3950             if Is_Formal (Ent)
3951               and then Is_Suspicious_Type (Typ)
3952               and then not Low_Bound_Tested (Ent)
3953             then
3954                Test_Suspicious_Index;
3955             end if;
3956          end if;
3957       end if;
3958    end Warn_On_Suspicious_Index;
3959
3960    -------------------------------
3961    -- Warn_On_Suspicious_Update --
3962    -------------------------------
3963
3964    procedure Warn_On_Suspicious_Update (N : Node_Id) is
3965       Par : constant Node_Id := Parent (N);
3966       Arg : Node_Id;
3967
3968    begin
3969       --  Only process if warnings activated
3970
3971       if Warn_On_Suspicious_Contract then
3972          if Nkind_In (Par, N_Op_Eq, N_Op_Ne) then
3973             if N = Left_Opnd (Par) then
3974                Arg := Right_Opnd (Par);
3975             else
3976                Arg := Left_Opnd (Par);
3977             end if;
3978
3979             if Same_Object (Prefix (N), Arg) then
3980                if Nkind (Par) = N_Op_Eq then
3981                   Error_Msg_N
3982                     ("suspicious equality test with modified version of "
3983                      & "same object?T?", Par);
3984                else
3985                   Error_Msg_N
3986                     ("suspicious inequality test with modified version of "
3987                      & "same object?T?", Par);
3988                end if;
3989             end if;
3990          end if;
3991       end if;
3992    end Warn_On_Suspicious_Update;
3993
3994    --------------------------------------
3995    -- Warn_On_Unassigned_Out_Parameter --
3996    --------------------------------------
3997
3998    procedure Warn_On_Unassigned_Out_Parameter
3999      (Return_Node : Node_Id;
4000       Scope_Id    : Entity_Id)
4001    is
4002       Form  : Entity_Id;
4003       Form2 : Entity_Id;
4004
4005    begin
4006       --  Ignore if procedure or return statement does not come from source
4007
4008       if not Comes_From_Source (Scope_Id)
4009         or else not Comes_From_Source (Return_Node)
4010       then
4011          return;
4012       end if;
4013
4014       --  Loop through formals
4015
4016       Form := First_Formal (Scope_Id);
4017       while Present (Form) loop
4018
4019          --  We are only interested in OUT parameters that come from source
4020          --  and are never set in the source, and furthermore only in scalars
4021          --  since non-scalars generate too many false positives.
4022
4023          if Ekind (Form) = E_Out_Parameter
4024            and then Never_Set_In_Source_Check_Spec (Form)
4025            and then Is_Scalar_Type (Etype (Form))
4026            and then not Present (Unset_Reference (Form))
4027          then
4028             --  Before we issue the warning, an add ad hoc defence against the
4029             --  most common case of false positives with this warning which is
4030             --  the case where there is a Boolean OUT parameter that has been
4031             --  set, and whose meaning is "ignore the values of the other
4032             --  parameters". We can't of course reliably tell this case at
4033             --  compile time, but the following test kills a lot of false
4034             --  positives, without generating a significant number of false
4035             --  negatives (missed real warnings).
4036
4037             Form2 := First_Formal (Scope_Id);
4038             while Present (Form2) loop
4039                if Ekind (Form2) = E_Out_Parameter
4040                  and then Root_Type (Etype (Form2)) = Standard_Boolean
4041                  and then not Never_Set_In_Source_Check_Spec (Form2)
4042                then
4043                   return;
4044                end if;
4045
4046                Next_Formal (Form2);
4047             end loop;
4048
4049             --  Here all conditions are met, record possible unset reference
4050
4051             Set_Unset_Reference (Form, Return_Node);
4052          end if;
4053
4054          Next_Formal (Form);
4055       end loop;
4056    end Warn_On_Unassigned_Out_Parameter;
4057
4058    ---------------------------------
4059    -- Warn_On_Unreferenced_Entity --
4060    ---------------------------------
4061
4062    procedure Warn_On_Unreferenced_Entity
4063      (Spec_E : Entity_Id;
4064       Body_E : Entity_Id := Empty)
4065    is
4066       E : Entity_Id := Spec_E;
4067
4068    begin
4069       if not Referenced_Check_Spec (E)
4070         and then not Has_Pragma_Unreferenced_Check_Spec (E)
4071         and then not Warnings_Off_Check_Spec (E)
4072         and then not Has_Junk_Name (Spec_E)
4073         and then not Is_Exported (Spec_E)
4074       then
4075          case Ekind (E) is
4076             when E_Variable =>
4077
4078                --  Case of variable that is assigned but not read. We suppress
4079                --  the message if the variable is volatile, has an address
4080                --  clause, is aliased, or is a renaming, or is imported.
4081
4082                if Referenced_As_LHS_Check_Spec (E)
4083                  and then No (Address_Clause (E))
4084                  and then not Is_Volatile (E)
4085                then
4086                   if Warn_On_Modified_Unread
4087                     and then not Is_Imported (E)
4088                     and then not Is_Aliased (E)
4089                     and then No (Renamed_Object (E))
4090                   then
4091                      if not Has_Pragma_Unmodified_Check_Spec (E) then
4092                         Error_Msg_N -- CODEFIX
4093                           ("?u?variable & is assigned but never read!", E);
4094                      end if;
4095
4096                      Set_Last_Assignment (E, Empty);
4097                   end if;
4098
4099                --  Normal case of neither assigned nor read (exclude variables
4100                --  referenced as out parameters, since we already generated
4101                --  appropriate warnings at the call point in this case).
4102
4103                elsif not Referenced_As_Out_Parameter (E) then
4104
4105                   --  We suppress the message for types for which a valid
4106                   --  pragma Unreferenced_Objects has been given, otherwise
4107                   --  we go ahead and give the message.
4108
4109                   if not Has_Pragma_Unreferenced_Objects (Etype (E)) then
4110
4111                      --  Distinguish renamed case in message
4112
4113                      if Present (Renamed_Object (E))
4114                        and then Comes_From_Source (Renamed_Object (E))
4115                      then
4116                         Error_Msg_N -- CODEFIX
4117                           ("?u?renamed variable & is not referenced!", E);
4118                      else
4119                         Error_Msg_N -- CODEFIX
4120                           ("?u?variable & is not referenced!", E);
4121                      end if;
4122                   end if;
4123                end if;
4124
4125             when E_Constant =>
4126                if not Has_Pragma_Unreferenced_Objects (Etype (E)) then
4127                   if Present (Renamed_Object (E))
4128                     and then Comes_From_Source (Renamed_Object (E))
4129                   then
4130                      Error_Msg_N -- CODEFIX
4131                        ("?u?renamed constant & is not referenced!", E);
4132                   else
4133                      Error_Msg_N -- CODEFIX
4134                        ("?u?constant & is not referenced!", E);
4135                   end if;
4136                end if;
4137
4138             when E_In_Parameter     |
4139                  E_In_Out_Parameter =>
4140
4141                --  Do not emit message for formals of a renaming, because
4142                --  they are never referenced explicitly.
4143
4144                if Nkind (Original_Node (Unit_Declaration_Node (Scope (E)))) /=
4145                                           N_Subprogram_Renaming_Declaration
4146                then
4147                   --  Suppress this message for an IN OUT parameter of a
4148                   --  non-scalar type, since it is normal to have only an
4149                   --  assignment in such a case.
4150
4151                   if Ekind (E) = E_In_Parameter
4152                     or else not Referenced_As_LHS_Check_Spec (E)
4153                     or else Is_Scalar_Type (Etype (E))
4154                   then
4155                      if Present (Body_E) then
4156                         E := Body_E;
4157                      end if;
4158
4159                      if not Is_Trivial_Subprogram (Scope (E)) then
4160                         Error_Msg_NE -- CODEFIX
4161                           ("?u?formal parameter & is not referenced!",
4162                            E, Spec_E);
4163                      end if;
4164                   end if;
4165                end if;
4166
4167             when E_Out_Parameter =>
4168                null;
4169
4170             when E_Discriminant =>
4171                Error_Msg_N ("?u?discriminant & is not referenced!", E);
4172
4173             when E_Named_Integer |
4174                  E_Named_Real    =>
4175                Error_Msg_N -- CODEFIX
4176                  ("?u?named number & is not referenced!", E);
4177
4178             when Formal_Object_Kind =>
4179                Error_Msg_N -- CODEFIX
4180                  ("?u?formal object & is not referenced!", E);
4181
4182             when E_Enumeration_Literal =>
4183                Error_Msg_N -- CODEFIX
4184                  ("?u?literal & is not referenced!", E);
4185
4186             when E_Function =>
4187                Error_Msg_N -- CODEFIX
4188                  ("?u?function & is not referenced!", E);
4189
4190             when E_Procedure =>
4191                Error_Msg_N -- CODEFIX
4192                  ("?u?procedure & is not referenced!", E);
4193
4194             when E_Package =>
4195                Error_Msg_N -- CODEFIX
4196                  ("?u?package & is not referenced!", E);
4197
4198             when E_Exception =>
4199                Error_Msg_N -- CODEFIX
4200                  ("?u?exception & is not referenced!", E);
4201
4202             when E_Label =>
4203                Error_Msg_N -- CODEFIX
4204                  ("?u?label & is not referenced!", E);
4205
4206             when E_Generic_Procedure =>
4207                Error_Msg_N -- CODEFIX
4208                  ("?u?generic procedure & is never instantiated!", E);
4209
4210             when E_Generic_Function =>
4211                Error_Msg_N -- CODEFIX
4212                  ("?u?generic function & is never instantiated!", E);
4213
4214             when Type_Kind =>
4215                Error_Msg_N -- CODEFIX
4216                  ("?u?type & is not referenced!", E);
4217
4218             when others =>
4219                Error_Msg_N -- CODEFIX
4220                  ("?u?& is not referenced!", E);
4221          end case;
4222
4223          --  Kill warnings on the entity on which the message has been posted
4224          --  (nothing is posted on out parameters because back end might be
4225          --  able to uncover an uninitialized path, and warn accordingly).
4226
4227          if Ekind (E) /= E_Out_Parameter then
4228             Set_Warnings_Off (E);
4229          end if;
4230       end if;
4231    end Warn_On_Unreferenced_Entity;
4232
4233    --------------------------------
4234    -- Warn_On_Useless_Assignment --
4235    --------------------------------
4236
4237    procedure Warn_On_Useless_Assignment
4238      (Ent : Entity_Id;
4239       N   : Node_Id := Empty)
4240    is
4241       P    : Node_Id;
4242       X    : Node_Id;
4243
4244       function Check_Ref (N : Node_Id) return Traverse_Result;
4245       --  Used to instantiate Traverse_Func. Returns Abandon if a reference to
4246       --  the entity in question is found.
4247
4248       function Test_No_Refs is new Traverse_Func (Check_Ref);
4249
4250       ---------------
4251       -- Check_Ref --
4252       ---------------
4253
4254       function Check_Ref (N : Node_Id) return Traverse_Result is
4255       begin
4256          --  Check reference to our identifier. We use name equality here
4257          --  because the exception handlers have not yet been analyzed. This
4258          --  is not quite right, but it really does not matter that we fail
4259          --  to output the warning in some obscure cases of name clashes.
4260
4261          if Nkind (N) = N_Identifier and then Chars (N) = Chars (Ent) then
4262             return Abandon;
4263          else
4264             return OK;
4265          end if;
4266       end Check_Ref;
4267
4268    --  Start of processing for Warn_On_Useless_Assignment
4269
4270    begin
4271       --  Check if this is a case we want to warn on, a scalar or access
4272       --  variable with the last assignment field set, with warnings enabled,
4273       --  and which is not imported or exported. We also check that it is OK
4274       --  to capture the value. We are not going to capture any value, but
4275       --  the warning message depends on the same kind of conditions.
4276
4277       if Is_Assignable (Ent)
4278         and then not Is_Return_Object (Ent)
4279         and then Present (Last_Assignment (Ent))
4280         and then not Is_Imported (Ent)
4281         and then not Is_Exported (Ent)
4282         and then Safe_To_Capture_Value (N, Ent)
4283         and then not Has_Pragma_Unreferenced_Check_Spec (Ent)
4284         and then not Has_Junk_Name (Ent)
4285       then
4286          --  Before we issue the message, check covering exception handlers.
4287          --  Search up tree for enclosing statement sequences and handlers.
4288
4289          P := Parent (Last_Assignment (Ent));
4290          while Present (P) loop
4291
4292             --  Something is really wrong if we don't find a handled statement
4293             --  sequence, so just suppress the warning.
4294
4295             if No (P) then
4296                Set_Last_Assignment (Ent, Empty);
4297                return;
4298
4299             --  When we hit a package/subprogram body, issue warning and exit
4300
4301             elsif Nkind (P) = N_Subprogram_Body
4302               or else Nkind (P) = N_Package_Body
4303             then
4304                --  Case of assigned value never referenced
4305
4306                if No (N) then
4307                   declare
4308                      LA : constant Node_Id := Last_Assignment (Ent);
4309
4310                   begin
4311                      --  Don't give this for OUT and IN OUT formals, since
4312                      --  clearly caller may reference the assigned value. Also
4313                      --  never give such warnings for internal variables.
4314
4315                      if Ekind (Ent) = E_Variable
4316                        and then not Is_Internal_Name (Chars (Ent))
4317                      then
4318                         --  Give appropriate message, distinguishing between
4319                         --  assignment statements and out parameters.
4320
4321                         if Nkind_In (Parent (LA), N_Procedure_Call_Statement,
4322                                                   N_Parameter_Association)
4323                         then
4324                            Error_Msg_NE
4325                              ("?m?& modified by call, but value never "
4326                               & "referenced", LA, Ent);
4327
4328                         else
4329                            Error_Msg_NE -- CODEFIX
4330                              ("?m?useless assignment to&, value never "
4331                               & "referenced!", LA, Ent);
4332                         end if;
4333                      end if;
4334                   end;
4335
4336                --  Case of assigned value overwritten
4337
4338                else
4339                   declare
4340                      LA : constant Node_Id := Last_Assignment (Ent);
4341
4342                   begin
4343                      Error_Msg_Sloc := Sloc (N);
4344
4345                      --  Give appropriate message, distinguishing between
4346                      --  assignment statements and out parameters.
4347
4348                      if Nkind_In (Parent (LA), N_Procedure_Call_Statement,
4349                                                N_Parameter_Association)
4350                      then
4351                         Error_Msg_NE
4352                           ("?m?& modified by call, but value overwritten #!",
4353                            LA, Ent);
4354                      else
4355                         Error_Msg_NE -- CODEFIX
4356                           ("?m?useless assignment to&, value overwritten #!",
4357                            LA, Ent);
4358                      end if;
4359                   end;
4360                end if;
4361
4362                --  Clear last assignment indication and we are done
4363
4364                Set_Last_Assignment (Ent, Empty);
4365                return;
4366
4367             --  Enclosing handled sequence of statements
4368
4369             elsif Nkind (P) = N_Handled_Sequence_Of_Statements then
4370
4371                --  Check exception handlers present
4372
4373                if Present (Exception_Handlers (P)) then
4374
4375                   --  If we are not at the top level, we regard an inner
4376                   --  exception handler as a decisive indicator that we should
4377                   --  not generate the warning, since the variable in question
4378                   --  may be accessed after an exception in the outer block.
4379
4380                   if Nkind (Parent (P)) /= N_Subprogram_Body
4381                     and then Nkind (Parent (P)) /= N_Package_Body
4382                   then
4383                      Set_Last_Assignment (Ent, Empty);
4384                      return;
4385
4386                      --  Otherwise we are at the outer level. An exception
4387                      --  handler is significant only if it references the
4388                      --  variable in question, or if the entity in question
4389                      --  is an OUT or IN OUT parameter, in which case
4390                      --  the caller can reference it after the exception
4391                      --  handler completes.
4392
4393                   else
4394                      if Is_Formal (Ent) then
4395                         Set_Last_Assignment (Ent, Empty);
4396                         return;
4397
4398                      else
4399                         X := First (Exception_Handlers (P));
4400                         while Present (X) loop
4401                            if Test_No_Refs (X) = Abandon then
4402                               Set_Last_Assignment (Ent, Empty);
4403                               return;
4404                            end if;
4405
4406                            X := Next (X);
4407                         end loop;
4408                      end if;
4409                   end if;
4410                end if;
4411             end if;
4412
4413             P := Parent (P);
4414          end loop;
4415       end if;
4416    end Warn_On_Useless_Assignment;
4417
4418    ---------------------------------
4419    -- Warn_On_Useless_Assignments --
4420    ---------------------------------
4421
4422    procedure Warn_On_Useless_Assignments (E : Entity_Id) is
4423       Ent : Entity_Id;
4424
4425    begin
4426       Process_Deferred_References;
4427
4428       if Warn_On_Modified_Unread
4429         and then In_Extended_Main_Source_Unit (E)
4430       then
4431          Ent := First_Entity (E);
4432          while Present (Ent) loop
4433             Warn_On_Useless_Assignment (Ent);
4434             Next_Entity (Ent);
4435          end loop;
4436       end if;
4437    end Warn_On_Useless_Assignments;
4438
4439    -----------------------------
4440    -- Warnings_Off_Check_Spec --
4441    -----------------------------
4442
4443    function Warnings_Off_Check_Spec (E : Entity_Id) return Boolean is
4444    begin
4445       if Is_Formal (E) and then Present (Spec_Entity (E)) then
4446
4447          --  Note: use of OR here instead of OR ELSE is deliberate, we want
4448          --  to mess with flags on both entities.
4449
4450          return Has_Warnings_Off (E)
4451                   or
4452                 Has_Warnings_Off (Spec_Entity (E));
4453
4454       else
4455          return Has_Warnings_Off (E);
4456       end if;
4457    end Warnings_Off_Check_Spec;
4458
4459 end Sem_Warn;