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