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