1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
|
------------------------------------------------------------------------------
-- --
-- GNAT COMPILER COMPONENTS --
-- --
-- S E M _ W A R N --
-- --
-- S p e c --
-- --
-- Copyright (C) 1999-2010, Free Software Foundation, Inc. --
-- --
-- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
-- ware Foundation; either version 3, or (at your option) any later ver- --
-- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
-- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
-- for more details. You should have received a copy of the GNU General --
-- Public License distributed with GNAT; see file COPYING3. If not, go to --
-- http://www.gnu.org/licenses for a complete copy of the license. --
-- --
-- GNAT was originally developed by the GNAT team at New York University. --
-- Extensive contributions were provided by Ada Core Technologies Inc. --
-- --
------------------------------------------------------------------------------
-- This package contains the routines used to deal with issuing warnings
-- about uses of uninitialized variables and unused with's. It also has
-- some unrelated routines related to the generation of warnings.
with Alloc; use Alloc;
with Table;
with Types; use Types;
package Sem_Warn is
-------------------
-- Warning Flags --
-------------------
-- These flags are activated or deactivated by -gnatw switches and control
-- whether warnings of a given class will be generated or not.
-- Note: most of these flags are still in opt, but the plan is to move them
-- here as time goes by.
Warn_On_Record_Holes : Boolean := False;
-- Warn when explicit record component clauses leave uncovered holes (gaps)
-- in a record layout. Off by default, set by -gnatw.h (but not -gnatwa).
Warn_On_Overridden_Size : Boolean := False;
-- Warn when explicit record component clause or array component_size
-- clause specifies a size that overrides a size for the type which was
-- set with an explicit size clause. Off by default, set by -gnatw.s (but
-- not -gnatwa).
------------------------
-- Warnings Off Table --
------------------------
type Warnings_Off_Entry is record
N : Node_Id;
-- A pragma Warnings (Off, ent) node
E : Entity_Id;
-- The entity involved
end record;
-- An entry is made in the following table for any valid Pragma Warnings
-- (Off, entity) encountered while Opt.Warn_On_Warnings_Off is True. It
-- is used to generate warnings on any of these pragmas that turn out not
-- to be needed, or that could be replaced by Unmodified/Unreferenced.
package Warnings_Off_Pragmas is new Table.Table (
Table_Component_Type => Warnings_Off_Entry,
Table_Index_Type => Int,
Table_Low_Bound => 0,
Table_Initial => Alloc.Warnings_Off_Pragmas_Initial,
Table_Increment => Alloc.Warnings_Off_Pragmas_Increment,
Table_Name => "Name_Warnings_Off_Pragmas");
--------------------
-- Initialization --
--------------------
procedure Initialize;
-- Initialize this package for new compilation
function Set_Warning_Switch (C : Character) return Boolean;
-- This function sets the warning switch or switches corresponding to the
-- given character. It is used to process a -gnatw switch on the command
-- line, or a character in a string literal in pragma Warnings. Returns
-- True for valid warning character C, False for invalid character.
function Set_Dot_Warning_Switch (C : Character) return Boolean;
-- This function sets the warning switch or switches corresponding to the
-- given character preceded by a dot. Used to process a -gnatw. switch on
-- the command line or .C in a string literal in pragma Warnings. Returns
-- True for valid warning character C, False for invalid character.
procedure Set_GNAT_Mode_Warnings;
-- This is called in -gnatg mode to set the warnings for gnat mode. It is
-- also used to set the proper warning statuses for -gnatw.g.
------------------------------------------
-- Routines to Handle Unused References --
------------------------------------------
procedure Check_References (E : Entity_Id; Anod : Node_Id := Empty);
-- Called at the end of processing a declarative region. The entity E
-- is the entity for the scope. All entities declared in the region,
-- as indicated by First_Entity and the entity chain, are checked to
-- see if they are variables for which warnings need to be posted for
-- either no assignments, or a use before an assignment or no references
-- at all. The Anod node is present for the case of an accept statement,
-- and references the accept statement. This is used to place the warning
-- messages in the right place.
procedure Check_Unset_Reference (N : Node_Id);
-- N is the node for an expression which occurs in a reference position,
-- e.g. as the right side of an assignment. This procedure checks to see
-- if the node is a reference to a variable entity where the entity has
-- Not_Assigned set. If so, the Unset_Reference field is set if it is not
-- the first occurrence. No warning is posted, instead warnings will be
-- posted later by Check_References. The reason we do things that
-- way is that if there are no assignments anywhere, we prefer to flag
-- the entity, rather than a reference to it. Note that for the purposes
-- of this routine, a type conversion or qualified expression whose
-- expression is an entity is also processed. The reason that we do not
-- process these at the point of occurrence is that both these constructs
-- can occur in non-reference positions (e.g. as out parameters).
procedure Check_Unused_Withs (Spec_Unit : Unit_Number_Type := No_Unit);
-- This routine performs two kinds of checks. It checks that all with'ed
-- units are referenced, and that at least one entity of each with'ed
-- unit is referenced (the latter check catches units that are only
-- referenced in a use or package renaming statement). Appropriate
-- warning messages are generated if either of these situations is
-- detected.
--
-- A special case arises when a package body or a subprogram body with
-- a separate spec is being compiled. In this case, a with may appear
-- on the spec, but be needed only by the body. This still generates
-- a warning, but the text is different (the with is not redundant,
-- it is misplaced).
--
-- This special case is implemented by making an initial call to this
-- procedure with Spec_Unit set to the unit number of the separate spec.
-- This call does not generate any warning messages, but instead may
-- result in flags being set in the N_With_Clause node that record that
-- there was no use in the spec.
--
-- The main call (made after all units have been analyzed, with Spec_Unit
-- set to the default value of No_Unit) generates the required warnings
-- using the flags set by the initial call where appropriate to specialize
-- the text of the warning messages.
---------------------
-- Output Routines --
---------------------
procedure Output_Non_Modified_In_Out_Warnings;
-- Warnings about IN OUT parameters that could be IN are collected till
-- the end of the compilation process (see body of this routine for a
-- discussion of why this is done). This procedure outputs the warnings.
-- Note: this should be called before Output_Unreferenced_Messages, since
-- if we have an IN OUT warning, that's the one we want to see!
procedure Output_Obsolescent_Entity_Warnings (N : Node_Id; E : Entity_Id);
-- N is a reference to obsolescent entity E, for which appropriate warning
-- messages are to be generated (caller has already checked that warnings
-- are active and appropriate for this entity).
procedure Output_Unreferenced_Messages;
-- Warnings about unreferenced entities are collected till the end of
-- the compilation process (see Check_Unset_Reference for further
-- details). This procedure outputs waiting warnings, if any.
procedure Output_Unused_Warnings_Off_Warnings;
-- Warnings about pragma Warnings (Off, ent) statements that are unused,
-- or could be replaced by Unmodified/Unreferenced pragmas, are collected
-- till the end of the compilation process. This procedure outputs waiting
-- warnings if any.
----------------------------
-- Other Warning Routines --
----------------------------
procedure Check_Code_Statement (N : Node_Id);
-- Perform warning checks on a code statement node
procedure Check_Infinite_Loop_Warning (Loop_Statement : Node_Id);
-- N is the node for a loop statement. This procedure checks if a warning
-- for a possible infinite loop should be given for a suspicious WHILE or
-- EXIT WHEN condition.
procedure Check_Low_Bound_Tested (Expr : Node_Id);
-- Expr is the node for a comparison operation. This procedure checks if
-- the comparison is a source comparison of P'First with some other value
-- and if so, sets the Low_Bound_Tested flag on entity P to suppress
-- warnings about improper low bound assumptions (we assume that if the
-- code has a test that explicitly checks P'First, then it is not operating
-- in blind assumption mode).
procedure Warn_On_Known_Condition (C : Node_Id);
-- C is a node for a boolean expression resulting from a relational
-- or membership operation. If the expression has a compile time known
-- value, then a warning is output if all the following conditions hold:
--
-- 1. Original expression comes from source. We don't want to generate
-- warnings for internally generated conditionals.
--
-- 2. As noted above, the expression is a relational or membership
-- test, we don't want to generate warnings for boolean variables
-- since this is typical of conditional compilation in Ada.
--
-- 3. The expression appears in a statement, rather than a declaration.
-- In practice, most occurrences in declarations are legitimate
-- conditionalizations, but occurrences in statements are often
-- errors for which the warning is useful.
--
-- 4. The expression does not occur within an instantiation. A non-
-- static expression in a generic may become constant because of
-- the attributes of the actuals, and we do not want to warn on
-- these legitimate constant foldings.
--
-- If all these conditions are met, the warning is issued noting that
-- the result of the test is always false or always true as appropriate.
function Warn_On_Modified_As_Out_Parameter (E : Entity_Id) return Boolean;
-- Returns True if we should activate warnings for entity E being modified
-- as an out parameter. True if either Warn_On_Modified_Unread is set for
-- an only OUT parameter, or if Warn_On_All_Unread_Out_Parameters is set.
procedure Warn_On_Overlapping_Actuals (Subp : Entity_Id; N : Node_Id);
-- Called on a subprogram call. Checks whether an IN OUT actual that is
-- not by-copy may overlap with another actual, thus leading to aliasing
-- in the body of the called subprogram.
procedure Warn_On_Suspicious_Index (Name : Entity_Id; X : Node_Id);
-- This is called after resolving an indexed component or a slice. Name
-- is the entity for the name of the indexed array, and X is the subscript
-- for the indexed component case, or one of the bounds in the slice case.
-- If Name is an unconstrained parameter of a standard string type, and
-- the index is of the form of a literal or Name'Length [- literal], then
-- a warning is generated that the subscripting operation is possibly
-- incorrectly assuming a lower bound of 1.
procedure Warn_On_Unassigned_Out_Parameter
(Return_Node : Node_Id;
Scope_Id : Entity_Id);
-- Called when processing a return statement given by Return_Node. Scope_Id
-- is the Entity_Id for the procedure in which the return statement lives.
-- A check is made for the case of a procedure with out parameters that
-- have not yet been assigned, and appropriate warnings are given.
procedure Warn_On_Useless_Assignment
(Ent : Entity_Id;
N : Node_Id := Empty);
-- Called to check if we have a case of a useless assignment to the given
-- entity Ent, as indicated by a non-empty Last_Assignment field. This call
-- should only be made if at least one of the flags Warn_On_Modified_Unread
-- or Warn_On_All_Unread_Out_Parameters is True, and if Ent is in the
-- extended main source unit. N is Empty for the end of block call
-- (warning message says value unreferenced), or the it is the node for
-- an overwriting assignment (warning message points to this assignment).
procedure Warn_On_Useless_Assignments (E : Entity_Id);
pragma Inline (Warn_On_Useless_Assignments);
-- Called at the end of a block or subprogram. Scans the entities of the
-- block or subprogram to see if there are any variables for which useless
-- assignments were made (assignments whose values were never read).
end Sem_Warn;
|