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