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