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