]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/ada/checks.adb
doc: @var fixes.
[thirdparty/gcc.git] / gcc / ada / checks.adb
CommitLineData
ee6ba406 1------------------------------------------------------------------------------
2-- --
3-- GNAT COMPILER COMPONENTS --
4-- --
5-- C H E C K S --
6-- --
7-- B o d y --
8-- --
e977c0cf 9-- Copyright (C) 1992-2010, Free Software Foundation, Inc. --
ee6ba406 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- --
80df182a 13-- ware Foundation; either version 3, or (at your option) any later ver- --
ee6ba406 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 --
80df182a 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. --
ee6ba406 20-- --
21-- GNAT was originally developed by the GNAT team at New York University. --
e78e8c8e 22-- Extensive contributions were provided by Ada Core Technologies Inc. --
ee6ba406 23-- --
24------------------------------------------------------------------------------
25
26with Atree; use Atree;
27with Debug; use Debug;
28with Einfo; use Einfo;
29with Errout; use Errout;
30with Exp_Ch2; use Exp_Ch2;
df40eeb0 31with Exp_Ch4; use Exp_Ch4;
00c403ee 32with Exp_Ch11; use Exp_Ch11;
05fcfafb 33with Exp_Pakd; use Exp_Pakd;
ee6ba406 34with Exp_Util; use Exp_Util;
35with Elists; use Elists;
5329ca64 36with Eval_Fat; use Eval_Fat;
ee6ba406 37with Freeze; use Freeze;
9dfe12ae 38with Lib; use Lib;
ee6ba406 39with Nlists; use Nlists;
40with Nmake; use Nmake;
41with Opt; use Opt;
9dfe12ae 42with Output; use Output;
c2b56224 43with Restrict; use Restrict;
1e16c51c 44with Rident; use Rident;
ee6ba406 45with Rtsfind; use Rtsfind;
46with Sem; use Sem;
d60c9ff7 47with Sem_Aux; use Sem_Aux;
ee6ba406 48with Sem_Eval; use Sem_Eval;
00f91aef 49with Sem_Ch3; use Sem_Ch3;
9dfe12ae 50with Sem_Ch8; use Sem_Ch8;
ee6ba406 51with Sem_Res; use Sem_Res;
52with Sem_Util; use Sem_Util;
53with Sem_Warn; use Sem_Warn;
54with Sinfo; use Sinfo;
9dfe12ae 55with Sinput; use Sinput;
ee6ba406 56with Snames; use Snames;
9dfe12ae 57with Sprint; use Sprint;
ee6ba406 58with Stand; use Stand;
f15731c4 59with Targparm; use Targparm;
ee6ba406 60with Tbuild; use Tbuild;
61with Ttypes; use Ttypes;
62with Urealp; use Urealp;
63with Validsw; use Validsw;
64
65package body Checks is
66
67 -- General note: many of these routines are concerned with generating
68 -- checking code to make sure that constraint error is raised at runtime.
69 -- Clearly this code is only needed if the expander is active, since
70 -- otherwise we will not be generating code or going into the runtime
71 -- execution anyway.
72
73 -- We therefore disconnect most of these checks if the expander is
74 -- inactive. This has the additional benefit that we do not need to
75 -- worry about the tree being messed up by previous errors (since errors
76 -- turn off expansion anyway).
77
78 -- There are a few exceptions to the above rule. For instance routines
79 -- such as Apply_Scalar_Range_Check that do not insert any code can be
80 -- safely called even when the Expander is inactive (but Errors_Detected
81 -- is 0). The benefit of executing this code when expansion is off, is
82 -- the ability to emit constraint error warning for static expressions
83 -- even when we are not generating code.
84
9dfe12ae 85 -------------------------------------
86 -- Suppression of Redundant Checks --
87 -------------------------------------
88
89 -- This unit implements a limited circuit for removal of redundant
90 -- checks. The processing is based on a tracing of simple sequential
91 -- flow. For any sequence of statements, we save expressions that are
92 -- marked to be checked, and then if the same expression appears later
93 -- with the same check, then under certain circumstances, the second
94 -- check can be suppressed.
95
96 -- Basically, we can suppress the check if we know for certain that
97 -- the previous expression has been elaborated (together with its
98 -- check), and we know that the exception frame is the same, and that
99 -- nothing has happened to change the result of the exception.
100
101 -- Let us examine each of these three conditions in turn to describe
102 -- how we ensure that this condition is met.
103
104 -- First, we need to know for certain that the previous expression has
105 -- been executed. This is done principly by the mechanism of calling
106 -- Conditional_Statements_Begin at the start of any statement sequence
107 -- and Conditional_Statements_End at the end. The End call causes all
108 -- checks remembered since the Begin call to be discarded. This does
109 -- miss a few cases, notably the case of a nested BEGIN-END block with
110 -- no exception handlers. But the important thing is to be conservative.
111 -- The other protection is that all checks are discarded if a label
112 -- is encountered, since then the assumption of sequential execution
113 -- is violated, and we don't know enough about the flow.
114
115 -- Second, we need to know that the exception frame is the same. We
116 -- do this by killing all remembered checks when we enter a new frame.
117 -- Again, that's over-conservative, but generally the cases we can help
118 -- with are pretty local anyway (like the body of a loop for example).
119
120 -- Third, we must be sure to forget any checks which are no longer valid.
121 -- This is done by two mechanisms, first the Kill_Checks_Variable call is
122 -- used to note any changes to local variables. We only attempt to deal
123 -- with checks involving local variables, so we do not need to worry
124 -- about global variables. Second, a call to any non-global procedure
125 -- causes us to abandon all stored checks, since such a all may affect
126 -- the values of any local variables.
127
128 -- The following define the data structures used to deal with remembering
129 -- checks so that redundant checks can be eliminated as described above.
130
131 -- Right now, the only expressions that we deal with are of the form of
132 -- simple local objects (either declared locally, or IN parameters) or
133 -- such objects plus/minus a compile time known constant. We can do
134 -- more later on if it seems worthwhile, but this catches many simple
135 -- cases in practice.
136
137 -- The following record type reflects a single saved check. An entry
138 -- is made in the stack of saved checks if and only if the expression
139 -- has been elaborated with the indicated checks.
140
141 type Saved_Check is record
142 Killed : Boolean;
143 -- Set True if entry is killed by Kill_Checks
144
145 Entity : Entity_Id;
146 -- The entity involved in the expression that is checked
147
148 Offset : Uint;
149 -- A compile time value indicating the result of adding or
150 -- subtracting a compile time value. This value is to be
151 -- added to the value of the Entity. A value of zero is
152 -- used for the case of a simple entity reference.
153
154 Check_Type : Character;
155 -- This is set to 'R' for a range check (in which case Target_Type
156 -- is set to the target type for the range check) or to 'O' for an
157 -- overflow check (in which case Target_Type is set to Empty).
158
159 Target_Type : Entity_Id;
160 -- Used only if Do_Range_Check is set. Records the target type for
161 -- the check. We need this, because a check is a duplicate only if
162 -- it has a the same target type (or more accurately one with a
163 -- range that is smaller or equal to the stored target type of a
164 -- saved check).
165 end record;
166
167 -- The following table keeps track of saved checks. Rather than use an
168 -- extensible table. We just use a table of fixed size, and we discard
169 -- any saved checks that do not fit. That's very unlikely to happen and
170 -- this is only an optimization in any case.
171
172 Saved_Checks : array (Int range 1 .. 200) of Saved_Check;
173 -- Array of saved checks
174
175 Num_Saved_Checks : Nat := 0;
176 -- Number of saved checks
177
178 -- The following stack keeps track of statement ranges. It is treated
179 -- as a stack. When Conditional_Statements_Begin is called, an entry
180 -- is pushed onto this stack containing the value of Num_Saved_Checks
181 -- at the time of the call. Then when Conditional_Statements_End is
182 -- called, this value is popped off and used to reset Num_Saved_Checks.
183
184 -- Note: again, this is a fixed length stack with a size that should
185 -- always be fine. If the value of the stack pointer goes above the
186 -- limit, then we just forget all saved checks.
187
188 Saved_Checks_Stack : array (Int range 1 .. 100) of Nat;
189 Saved_Checks_TOS : Nat := 0;
190
191 -----------------------
192 -- Local Subprograms --
193 -----------------------
ee6ba406 194
5329ca64 195 procedure Apply_Float_Conversion_Check
196 (Ck_Node : Node_Id;
197 Target_Typ : Entity_Id);
198 -- The checks on a conversion from a floating-point type to an integer
199 -- type are delicate. They have to be performed before conversion, they
200 -- have to raise an exception when the operand is a NaN, and rounding must
201 -- be taken into account to determine the safe bounds of the operand.
202
ee6ba406 203 procedure Apply_Selected_Length_Checks
204 (Ck_Node : Node_Id;
205 Target_Typ : Entity_Id;
206 Source_Typ : Entity_Id;
207 Do_Static : Boolean);
208 -- This is the subprogram that does all the work for Apply_Length_Check
209 -- and Apply_Static_Length_Check. Expr, Target_Typ and Source_Typ are as
210 -- described for the above routines. The Do_Static flag indicates that
211 -- only a static check is to be done.
212
213 procedure Apply_Selected_Range_Checks
214 (Ck_Node : Node_Id;
215 Target_Typ : Entity_Id;
216 Source_Typ : Entity_Id;
217 Do_Static : Boolean);
218 -- This is the subprogram that does all the work for Apply_Range_Check.
219 -- Expr, Target_Typ and Source_Typ are as described for the above
220 -- routine. The Do_Static flag indicates that only a static check is
221 -- to be done.
222
2af58f67 223 type Check_Type is new Check_Id range Access_Check .. Division_Check;
13dbf220 224 function Check_Needed (Nod : Node_Id; Check : Check_Type) return Boolean;
225 -- This function is used to see if an access or division by zero check is
226 -- needed. The check is to be applied to a single variable appearing in the
227 -- source, and N is the node for the reference. If N is not of this form,
228 -- True is returned with no further processing. If N is of the right form,
229 -- then further processing determines if the given Check is needed.
230 --
231 -- The particular circuit is to see if we have the case of a check that is
232 -- not needed because it appears in the right operand of a short circuited
233 -- conditional where the left operand guards the check. For example:
234 --
235 -- if Var = 0 or else Q / Var > 12 then
236 -- ...
237 -- end if;
238 --
239 -- In this example, the division check is not required. At the same time
240 -- we can issue warnings for suspicious use of non-short-circuited forms,
241 -- such as:
242 --
243 -- if Var = 0 or Q / Var > 12 then
244 -- ...
245 -- end if;
246
9dfe12ae 247 procedure Find_Check
248 (Expr : Node_Id;
249 Check_Type : Character;
250 Target_Type : Entity_Id;
251 Entry_OK : out Boolean;
252 Check_Num : out Nat;
253 Ent : out Entity_Id;
254 Ofs : out Uint);
255 -- This routine is used by Enable_Range_Check and Enable_Overflow_Check
256 -- to see if a check is of the form for optimization, and if so, to see
257 -- if it has already been performed. Expr is the expression to check,
258 -- and Check_Type is 'R' for a range check, 'O' for an overflow check.
259 -- Target_Type is the target type for a range check, and Empty for an
260 -- overflow check. If the entry is not of the form for optimization,
261 -- then Entry_OK is set to False, and the remaining out parameters
262 -- are undefined. If the entry is OK, then Ent/Ofs are set to the
263 -- entity and offset from the expression. Check_Num is the number of
264 -- a matching saved entry in Saved_Checks, or zero if no such entry
265 -- is located.
266
ee6ba406 267 function Get_Discriminal (E : Entity_Id; Bound : Node_Id) return Node_Id;
268 -- If a discriminal is used in constraining a prival, Return reference
269 -- to the discriminal of the protected body (which renames the parameter
270 -- of the enclosing protected operation). This clumsy transformation is
271 -- needed because privals are created too late and their actual subtypes
272 -- are not available when analysing the bodies of the protected operations.
0577b0b1 273 -- This function is called whenever the bound is an entity and the scope
274 -- indicates a protected operation. If the bound is an in-parameter of
275 -- a protected operation that is not a prival, the function returns the
276 -- bound itself.
ee6ba406 277 -- To be cleaned up???
278
279 function Guard_Access
280 (Cond : Node_Id;
281 Loc : Source_Ptr;
314a23b6 282 Ck_Node : Node_Id) return Node_Id;
ee6ba406 283 -- In the access type case, guard the test with a test to ensure
284 -- that the access value is non-null, since the checks do not
285 -- not apply to null access values.
286
287 procedure Install_Static_Check (R_Cno : Node_Id; Loc : Source_Ptr);
288 -- Called by Apply_{Length,Range}_Checks to rewrite the tree with the
289 -- Constraint_Error node.
290
0577b0b1 291 function Range_Or_Validity_Checks_Suppressed
292 (Expr : Node_Id) return Boolean;
293 -- Returns True if either range or validity checks or both are suppressed
294 -- for the type of the given expression, or, if the expression is the name
295 -- of an entity, if these checks are suppressed for the entity.
296
ee6ba406 297 function Selected_Length_Checks
298 (Ck_Node : Node_Id;
299 Target_Typ : Entity_Id;
300 Source_Typ : Entity_Id;
314a23b6 301 Warn_Node : Node_Id) return Check_Result;
ee6ba406 302 -- Like Apply_Selected_Length_Checks, except it doesn't modify
303 -- anything, just returns a list of nodes as described in the spec of
304 -- this package for the Range_Check function.
305
306 function Selected_Range_Checks
307 (Ck_Node : Node_Id;
308 Target_Typ : Entity_Id;
309 Source_Typ : Entity_Id;
314a23b6 310 Warn_Node : Node_Id) return Check_Result;
ee6ba406 311 -- Like Apply_Selected_Range_Checks, except it doesn't modify anything,
312 -- just returns a list of nodes as described in the spec of this package
313 -- for the Range_Check function.
314
315 ------------------------------
316 -- Access_Checks_Suppressed --
317 ------------------------------
318
319 function Access_Checks_Suppressed (E : Entity_Id) return Boolean is
320 begin
9dfe12ae 321 if Present (E) and then Checks_May_Be_Suppressed (E) then
322 return Is_Check_Suppressed (E, Access_Check);
323 else
324 return Scope_Suppress (Access_Check);
325 end if;
ee6ba406 326 end Access_Checks_Suppressed;
327
328 -------------------------------------
329 -- Accessibility_Checks_Suppressed --
330 -------------------------------------
331
332 function Accessibility_Checks_Suppressed (E : Entity_Id) return Boolean is
333 begin
9dfe12ae 334 if Present (E) and then Checks_May_Be_Suppressed (E) then
335 return Is_Check_Suppressed (E, Accessibility_Check);
336 else
337 return Scope_Suppress (Accessibility_Check);
338 end if;
ee6ba406 339 end Accessibility_Checks_Suppressed;
340
00c403ee 341 -----------------------------
342 -- Activate_Division_Check --
343 -----------------------------
344
345 procedure Activate_Division_Check (N : Node_Id) is
346 begin
347 Set_Do_Division_Check (N, True);
348 Possible_Local_Raise (N, Standard_Constraint_Error);
349 end Activate_Division_Check;
350
351 -----------------------------
352 -- Activate_Overflow_Check --
353 -----------------------------
354
355 procedure Activate_Overflow_Check (N : Node_Id) is
356 begin
357 Set_Do_Overflow_Check (N, True);
358 Possible_Local_Raise (N, Standard_Constraint_Error);
359 end Activate_Overflow_Check;
360
361 --------------------------
362 -- Activate_Range_Check --
363 --------------------------
364
365 procedure Activate_Range_Check (N : Node_Id) is
366 begin
367 Set_Do_Range_Check (N, True);
368 Possible_Local_Raise (N, Standard_Constraint_Error);
369 end Activate_Range_Check;
370
0577b0b1 371 ---------------------------------
372 -- Alignment_Checks_Suppressed --
373 ---------------------------------
374
375 function Alignment_Checks_Suppressed (E : Entity_Id) return Boolean is
376 begin
377 if Present (E) and then Checks_May_Be_Suppressed (E) then
378 return Is_Check_Suppressed (E, Alignment_Check);
379 else
380 return Scope_Suppress (Alignment_Check);
381 end if;
382 end Alignment_Checks_Suppressed;
383
ee6ba406 384 -------------------------
385 -- Append_Range_Checks --
386 -------------------------
387
388 procedure Append_Range_Checks
389 (Checks : Check_Result;
390 Stmts : List_Id;
391 Suppress_Typ : Entity_Id;
392 Static_Sloc : Source_Ptr;
393 Flag_Node : Node_Id)
394 is
9dfe12ae 395 Internal_Flag_Node : constant Node_Id := Flag_Node;
396 Internal_Static_Sloc : constant Source_Ptr := Static_Sloc;
397
ee6ba406 398 Checks_On : constant Boolean :=
399 (not Index_Checks_Suppressed (Suppress_Typ))
400 or else
401 (not Range_Checks_Suppressed (Suppress_Typ));
402
403 begin
404 -- For now we just return if Checks_On is false, however this should
405 -- be enhanced to check for an always True value in the condition
406 -- and to generate a compilation warning???
407
408 if not Checks_On then
409 return;
410 end if;
411
412 for J in 1 .. 2 loop
413 exit when No (Checks (J));
414
415 if Nkind (Checks (J)) = N_Raise_Constraint_Error
416 and then Present (Condition (Checks (J)))
417 then
418 if not Has_Dynamic_Range_Check (Internal_Flag_Node) then
419 Append_To (Stmts, Checks (J));
420 Set_Has_Dynamic_Range_Check (Internal_Flag_Node);
421 end if;
422
423 else
424 Append_To
f15731c4 425 (Stmts,
426 Make_Raise_Constraint_Error (Internal_Static_Sloc,
427 Reason => CE_Range_Check_Failed));
ee6ba406 428 end if;
429 end loop;
430 end Append_Range_Checks;
431
432 ------------------------
433 -- Apply_Access_Check --
434 ------------------------
435
436 procedure Apply_Access_Check (N : Node_Id) is
437 P : constant Node_Id := Prefix (N);
438
439 begin
13dbf220 440 -- We do not need checks if we are not generating code (i.e. the
441 -- expander is not active). This is not just an optimization, there
442 -- are cases (e.g. with pragma Debug) where generating the checks
443 -- can cause real trouble).
284faf8b 444
84d0d4a5 445 if not Expander_Active then
13dbf220 446 return;
9dfe12ae 447 end if;
ee6ba406 448
84d0d4a5 449 -- No check if short circuiting makes check unnecessary
9dfe12ae 450
84d0d4a5 451 if not Check_Needed (P, Access_Check) then
452 return;
ee6ba406 453 end if;
9dfe12ae 454
cc60bd16 455 -- No check if accessing the Offset_To_Top component of a dispatch
456 -- table. They are safe by construction.
457
040277b1 458 if Tagged_Type_Expansion
459 and then Present (Etype (P))
cc60bd16 460 and then RTU_Loaded (Ada_Tags)
461 and then RTE_Available (RE_Offset_To_Top_Ptr)
462 and then Etype (P) = RTE (RE_Offset_To_Top_Ptr)
463 then
464 return;
465 end if;
466
84d0d4a5 467 -- Otherwise go ahead and install the check
9dfe12ae 468
fa7497e8 469 Install_Null_Excluding_Check (P);
ee6ba406 470 end Apply_Access_Check;
471
472 -------------------------------
473 -- Apply_Accessibility_Check --
474 -------------------------------
475
55dc6dc2 476 procedure Apply_Accessibility_Check
477 (N : Node_Id;
478 Typ : Entity_Id;
479 Insert_Node : Node_Id)
480 is
ee6ba406 481 Loc : constant Source_Ptr := Sloc (N);
482 Param_Ent : constant Entity_Id := Param_Entity (N);
483 Param_Level : Node_Id;
484 Type_Level : Node_Id;
485
486 begin
487 if Inside_A_Generic then
488 return;
489
6ffc64fc 490 -- Only apply the run-time check if the access parameter has an
491 -- associated extra access level parameter and when the level of the
492 -- type is less deep than the level of the access parameter, and
493 -- accessibility checks are not suppressed.
ee6ba406 494
495 elsif Present (Param_Ent)
496 and then Present (Extra_Accessibility (Param_Ent))
6ffc64fc 497 and then UI_Gt (Object_Access_Level (N), Type_Access_Level (Typ))
ee6ba406 498 and then not Accessibility_Checks_Suppressed (Param_Ent)
499 and then not Accessibility_Checks_Suppressed (Typ)
500 then
501 Param_Level :=
502 New_Occurrence_Of (Extra_Accessibility (Param_Ent), Loc);
503
504 Type_Level :=
505 Make_Integer_Literal (Loc, Type_Access_Level (Typ));
506
bf3e1520 507 -- Raise Program_Error if the accessibility level of the access
84d0d4a5 508 -- parameter is deeper than the level of the target access type.
ee6ba406 509
55dc6dc2 510 Insert_Action (Insert_Node,
ee6ba406 511 Make_Raise_Program_Error (Loc,
512 Condition =>
513 Make_Op_Gt (Loc,
514 Left_Opnd => Param_Level,
f15731c4 515 Right_Opnd => Type_Level),
516 Reason => PE_Accessibility_Check_Failed));
ee6ba406 517
518 Analyze_And_Resolve (N);
519 end if;
520 end Apply_Accessibility_Check;
521
0577b0b1 522 --------------------------------
523 -- Apply_Address_Clause_Check --
524 --------------------------------
525
526 procedure Apply_Address_Clause_Check (E : Entity_Id; N : Node_Id) is
527 AC : constant Node_Id := Address_Clause (E);
528 Loc : constant Source_Ptr := Sloc (AC);
529 Typ : constant Entity_Id := Etype (E);
530 Aexp : constant Node_Id := Expression (AC);
c2b56224 531
c2b56224 532 Expr : Node_Id;
0577b0b1 533 -- Address expression (not necessarily the same as Aexp, for example
534 -- when Aexp is a reference to a constant, in which case Expr gets
535 -- reset to reference the value expression of the constant.
536
0577b0b1 537 procedure Compile_Time_Bad_Alignment;
538 -- Post error warnings when alignment is known to be incompatible. Note
539 -- that we do not go as far as inserting a raise of Program_Error since
540 -- this is an erroneous case, and it may happen that we are lucky and an
d6da7448 541 -- underaligned address turns out to be OK after all.
0577b0b1 542
543 --------------------------------
544 -- Compile_Time_Bad_Alignment --
545 --------------------------------
546
547 procedure Compile_Time_Bad_Alignment is
548 begin
d6da7448 549 if Address_Clause_Overlay_Warnings then
0577b0b1 550 Error_Msg_FE
551 ("?specified address for& may be inconsistent with alignment ",
552 Aexp, E);
553 Error_Msg_FE
2af58f67 554 ("\?program execution may be erroneous (RM 13.3(27))",
0577b0b1 555 Aexp, E);
83f8f0a6 556 Set_Address_Warning_Posted (AC);
0577b0b1 557 end if;
558 end Compile_Time_Bad_Alignment;
c2b56224 559
2af58f67 560 -- Start of processing for Apply_Address_Clause_Check
5c61a0ff 561
c2b56224 562 begin
d6da7448 563 -- See if alignment check needed. Note that we never need a check if the
564 -- maximum alignment is one, since the check will always succeed.
565
566 -- Note: we do not check for checks suppressed here, since that check
567 -- was done in Sem_Ch13 when the address clause was processed. We are
568 -- only called if checks were not suppressed. The reason for this is
569 -- that we have to delay the call to Apply_Alignment_Check till freeze
570 -- time (so that all types etc are elaborated), but we have to check
571 -- the status of check suppressing at the point of the address clause.
572
573 if No (AC)
574 or else not Check_Address_Alignment (AC)
575 or else Maximum_Alignment = 1
576 then
577 return;
578 end if;
579
580 -- Obtain expression from address clause
9dfe12ae 581
0577b0b1 582 Expr := Expression (AC);
583
584 -- The following loop digs for the real expression to use in the check
585
586 loop
587 -- For constant, get constant expression
588
589 if Is_Entity_Name (Expr)
590 and then Ekind (Entity (Expr)) = E_Constant
591 then
592 Expr := Constant_Value (Entity (Expr));
593
594 -- For unchecked conversion, get result to convert
595
596 elsif Nkind (Expr) = N_Unchecked_Type_Conversion then
597 Expr := Expression (Expr);
598
599 -- For (common case) of To_Address call, get argument
600
601 elsif Nkind (Expr) = N_Function_Call
602 and then Is_Entity_Name (Name (Expr))
603 and then Is_RTE (Entity (Name (Expr)), RE_To_Address)
604 then
605 Expr := First (Parameter_Associations (Expr));
606
607 if Nkind (Expr) = N_Parameter_Association then
608 Expr := Explicit_Actual_Parameter (Expr);
609 end if;
610
611 -- We finally have the real expression
612
613 else
614 exit;
615 end if;
616 end loop;
617
d6da7448 618 -- See if we know that Expr has a bad alignment at compile time
c2b56224 619
620 if Compile_Time_Known_Value (Expr)
f2a06be9 621 and then (Known_Alignment (E) or else Known_Alignment (Typ))
c2b56224 622 then
f2a06be9 623 declare
624 AL : Uint := Alignment (Typ);
625
626 begin
627 -- The object alignment might be more restrictive than the
628 -- type alignment.
629
630 if Known_Alignment (E) then
631 AL := Alignment (E);
632 end if;
633
634 if Expr_Value (Expr) mod AL /= 0 then
0577b0b1 635 Compile_Time_Bad_Alignment;
636 else
637 return;
f2a06be9 638 end if;
639 end;
c2b56224 640
0577b0b1 641 -- If the expression has the form X'Address, then we can find out if
642 -- the object X has an alignment that is compatible with the object E.
d6da7448 643 -- If it hasn't or we don't know, we defer issuing the warning until
644 -- the end of the compilation to take into account back end annotations.
c2b56224 645
0577b0b1 646 elsif Nkind (Expr) = N_Attribute_Reference
647 and then Attribute_Name (Expr) = Name_Address
d6da7448 648 and then Has_Compatible_Alignment (E, Prefix (Expr)) = Known_Compatible
0577b0b1 649 then
d6da7448 650 return;
0577b0b1 651 end if;
c2b56224 652
0577b0b1 653 -- Here we do not know if the value is acceptable. Stricly we don't have
654 -- to do anything, since if the alignment is bad, we have an erroneous
655 -- program. However we are allowed to check for erroneous conditions and
656 -- we decide to do this by default if the check is not suppressed.
657
658 -- However, don't do the check if elaboration code is unwanted
659
660 if Restriction_Active (No_Elaboration_Code) then
661 return;
662
663 -- Generate a check to raise PE if alignment may be inappropriate
664
665 else
666 -- If the original expression is a non-static constant, use the
667 -- name of the constant itself rather than duplicating its
00c403ee 668 -- defining expression, which was extracted above.
0577b0b1 669
00c403ee 670 -- Note: Expr is empty if the address-clause is applied to in-mode
671 -- actuals (allowed by 13.1(22)).
672
673 if not Present (Expr)
674 or else
675 (Is_Entity_Name (Expression (AC))
676 and then Ekind (Entity (Expression (AC))) = E_Constant
677 and then Nkind (Parent (Entity (Expression (AC))))
678 = N_Object_Declaration)
0577b0b1 679 then
680 Expr := New_Copy_Tree (Expression (AC));
681 else
682 Remove_Side_Effects (Expr);
c2b56224 683 end if;
c2b56224 684
0577b0b1 685 Insert_After_And_Analyze (N,
686 Make_Raise_Program_Error (Loc,
687 Condition =>
688 Make_Op_Ne (Loc,
689 Left_Opnd =>
690 Make_Op_Mod (Loc,
691 Left_Opnd =>
692 Unchecked_Convert_To
693 (RTE (RE_Integer_Address), Expr),
694 Right_Opnd =>
695 Make_Attribute_Reference (Loc,
696 Prefix => New_Occurrence_Of (E, Loc),
697 Attribute_Name => Name_Alignment)),
698 Right_Opnd => Make_Integer_Literal (Loc, Uint_0)),
699 Reason => PE_Misaligned_Address_Value),
700 Suppress => All_Checks);
701 return;
702 end if;
9dfe12ae 703
704 exception
0577b0b1 705 -- If we have some missing run time component in configurable run time
706 -- mode then just skip the check (it is not required in any case).
707
9dfe12ae 708 when RE_Not_Available =>
709 return;
0577b0b1 710 end Apply_Address_Clause_Check;
c2b56224 711
ee6ba406 712 -------------------------------------
713 -- Apply_Arithmetic_Overflow_Check --
714 -------------------------------------
715
f40f9731 716 -- This routine is called only if the type is an integer type, and a
717 -- software arithmetic overflow check may be needed for op (add, subtract,
718 -- or multiply). This check is performed only if Software_Overflow_Checking
719 -- is enabled and Do_Overflow_Check is set. In this case we expand the
720 -- operation into a more complex sequence of tests that ensures that
721 -- overflow is properly caught.
ee6ba406 722
723 procedure Apply_Arithmetic_Overflow_Check (N : Node_Id) is
724 Loc : constant Source_Ptr := Sloc (N);
780bfb21 725 Typ : constant Entity_Id := Etype (N);
726 Rtyp : constant Entity_Id := Root_Type (Typ);
ee6ba406 727
728 begin
f40f9731 729 -- An interesting special case. If the arithmetic operation appears as
730 -- the operand of a type conversion:
731
732 -- type1 (x op y)
733
734 -- and all the following conditions apply:
735
736 -- arithmetic operation is for a signed integer type
737 -- target type type1 is a static integer subtype
738 -- range of x and y are both included in the range of type1
739 -- range of x op y is included in the range of type1
740 -- size of type1 is at least twice the result size of op
741
742 -- then we don't do an overflow check in any case, instead we transform
743 -- the operation so that we end up with:
744
745 -- type1 (type1 (x) op type1 (y))
746
747 -- This avoids intermediate overflow before the conversion. It is
748 -- explicitly permitted by RM 3.5.4(24):
749
750 -- For the execution of a predefined operation of a signed integer
751 -- type, the implementation need not raise Constraint_Error if the
752 -- result is outside the base range of the type, so long as the
753 -- correct result is produced.
754
755 -- It's hard to imagine that any programmer counts on the exception
756 -- being raised in this case, and in any case it's wrong coding to
757 -- have this expectation, given the RM permission. Furthermore, other
758 -- Ada compilers do allow such out of range results.
759
760 -- Note that we do this transformation even if overflow checking is
761 -- off, since this is precisely about giving the "right" result and
762 -- avoiding the need for an overflow check.
763
8eb4a5eb 764 -- Note: this circuit is partially redundant with respect to the similar
765 -- processing in Exp_Ch4.Expand_N_Type_Conversion, but the latter deals
766 -- with cases that do not come through here. We still need the following
767 -- processing even with the Exp_Ch4 code in place, since we want to be
768 -- sure not to generate the arithmetic overflow check in these cases
769 -- (Exp_Ch4 would have a hard time removing them once generated).
770
f40f9731 771 if Is_Signed_Integer_Type (Typ)
772 and then Nkind (Parent (N)) = N_Type_Conversion
ee6ba406 773 then
f40f9731 774 declare
775 Target_Type : constant Entity_Id :=
776 Base_Type (Entity (Subtype_Mark (Parent (N))));
777
778 Llo, Lhi : Uint;
779 Rlo, Rhi : Uint;
780 LOK, ROK : Boolean;
781
782 Vlo : Uint;
783 Vhi : Uint;
784 VOK : Boolean;
785
786 Tlo : Uint;
787 Thi : Uint;
788
789 begin
790 if Is_Integer_Type (Target_Type)
791 and then RM_Size (Root_Type (Target_Type)) >= 2 * RM_Size (Rtyp)
792 then
793 Tlo := Expr_Value (Type_Low_Bound (Target_Type));
794 Thi := Expr_Value (Type_High_Bound (Target_Type));
795
9c486805 796 Determine_Range
797 (Left_Opnd (N), LOK, Llo, Lhi, Assume_Valid => True);
798 Determine_Range
799 (Right_Opnd (N), ROK, Rlo, Rhi, Assume_Valid => True);
f40f9731 800
801 if (LOK and ROK)
802 and then Tlo <= Llo and then Lhi <= Thi
803 and then Tlo <= Rlo and then Rhi <= Thi
804 then
9c486805 805 Determine_Range (N, VOK, Vlo, Vhi, Assume_Valid => True);
f40f9731 806
807 if VOK and then Tlo <= Vlo and then Vhi <= Thi then
808 Rewrite (Left_Opnd (N),
809 Make_Type_Conversion (Loc,
810 Subtype_Mark => New_Occurrence_Of (Target_Type, Loc),
811 Expression => Relocate_Node (Left_Opnd (N))));
812
813 Rewrite (Right_Opnd (N),
814 Make_Type_Conversion (Loc,
815 Subtype_Mark => New_Occurrence_Of (Target_Type, Loc),
816 Expression => Relocate_Node (Right_Opnd (N))));
817
780bfb21 818 -- Rewrite the conversion operand so that the original
819 -- node is retained, in order to avoid the warning for
820 -- redundant conversions in Resolve_Type_Conversion.
821
822 Rewrite (N, Relocate_Node (N));
823
f40f9731 824 Set_Etype (N, Target_Type);
780bfb21 825
f40f9731 826 Analyze_And_Resolve (Left_Opnd (N), Target_Type);
827 Analyze_And_Resolve (Right_Opnd (N), Target_Type);
828
829 -- Given that the target type is twice the size of the
830 -- source type, overflow is now impossible, so we can
831 -- safely kill the overflow check and return.
832
833 Set_Do_Overflow_Check (N, False);
834 return;
835 end if;
836 end if;
837 end if;
838 end;
ee6ba406 839 end if;
840
f40f9731 841 -- Now see if an overflow check is required
842
843 declare
844 Siz : constant Int := UI_To_Int (Esize (Rtyp));
845 Dsiz : constant Int := Siz * 2;
846 Opnod : Node_Id;
847 Ctyp : Entity_Id;
848 Opnd : Node_Id;
849 Cent : RE_Id;
ee6ba406 850
f40f9731 851 begin
852 -- Skip check if back end does overflow checks, or the overflow flag
df40eeb0 853 -- is not set anyway, or we are not doing code expansion, or the
854 -- parent node is a type conversion whose operand is an arithmetic
855 -- operation on signed integers on which the expander can promote
bbbed24b 856 -- later the operands to type Integer (see Expand_N_Type_Conversion).
ee6ba406 857
f40f9731 858 -- Special case CLI target, where arithmetic overflow checks can be
859 -- performed for integer and long_integer
ee6ba406 860
f40f9731 861 if Backend_Overflow_Checks_On_Target
862 or else not Do_Overflow_Check (N)
863 or else not Expander_Active
df40eeb0 864 or else (Present (Parent (N))
865 and then Nkind (Parent (N)) = N_Type_Conversion
866 and then Integer_Promotion_Possible (Parent (N)))
f40f9731 867 or else
868 (VM_Target = CLI_Target and then Siz >= Standard_Integer_Size)
869 then
870 return;
871 end if;
ee6ba406 872
f40f9731 873 -- Otherwise, generate the full general code for front end overflow
874 -- detection, which works by doing arithmetic in a larger type:
ee6ba406 875
f40f9731 876 -- x op y
ee6ba406 877
f40f9731 878 -- is expanded into
ee6ba406 879
f40f9731 880 -- Typ (Checktyp (x) op Checktyp (y));
ee6ba406 881
f40f9731 882 -- where Typ is the type of the original expression, and Checktyp is
883 -- an integer type of sufficient length to hold the largest possible
884 -- result.
ee6ba406 885
f40f9731 886 -- If the size of check type exceeds the size of Long_Long_Integer,
887 -- we use a different approach, expanding to:
ee6ba406 888
f40f9731 889 -- typ (xxx_With_Ovflo_Check (Integer_64 (x), Integer (y)))
ee6ba406 890
f40f9731 891 -- where xxx is Add, Multiply or Subtract as appropriate
ee6ba406 892
f40f9731 893 -- Find check type if one exists
894
895 if Dsiz <= Standard_Integer_Size then
896 Ctyp := Standard_Integer;
ee6ba406 897
f40f9731 898 elsif Dsiz <= Standard_Long_Long_Integer_Size then
899 Ctyp := Standard_Long_Long_Integer;
900
901 -- No check type exists, use runtime call
ee6ba406 902
903 else
f40f9731 904 if Nkind (N) = N_Op_Add then
905 Cent := RE_Add_With_Ovflo_Check;
ee6ba406 906
f40f9731 907 elsif Nkind (N) = N_Op_Multiply then
908 Cent := RE_Multiply_With_Ovflo_Check;
ee6ba406 909
f40f9731 910 else
911 pragma Assert (Nkind (N) = N_Op_Subtract);
912 Cent := RE_Subtract_With_Ovflo_Check;
913 end if;
914
915 Rewrite (N,
916 OK_Convert_To (Typ,
917 Make_Function_Call (Loc,
918 Name => New_Reference_To (RTE (Cent), Loc),
919 Parameter_Associations => New_List (
920 OK_Convert_To (RTE (RE_Integer_64), Left_Opnd (N)),
921 OK_Convert_To (RTE (RE_Integer_64), Right_Opnd (N))))));
ee6ba406 922
f40f9731 923 Analyze_And_Resolve (N, Typ);
924 return;
925 end if;
ee6ba406 926
f40f9731 927 -- If we fall through, we have the case where we do the arithmetic
928 -- in the next higher type and get the check by conversion. In these
929 -- cases Ctyp is set to the type to be used as the check type.
ee6ba406 930
f40f9731 931 Opnod := Relocate_Node (N);
ee6ba406 932
f40f9731 933 Opnd := OK_Convert_To (Ctyp, Left_Opnd (Opnod));
ee6ba406 934
f40f9731 935 Analyze (Opnd);
936 Set_Etype (Opnd, Ctyp);
937 Set_Analyzed (Opnd, True);
938 Set_Left_Opnd (Opnod, Opnd);
ee6ba406 939
f40f9731 940 Opnd := OK_Convert_To (Ctyp, Right_Opnd (Opnod));
ee6ba406 941
f40f9731 942 Analyze (Opnd);
943 Set_Etype (Opnd, Ctyp);
944 Set_Analyzed (Opnd, True);
945 Set_Right_Opnd (Opnod, Opnd);
ee6ba406 946
f40f9731 947 -- The type of the operation changes to the base type of the check
948 -- type, and we reset the overflow check indication, since clearly no
949 -- overflow is possible now that we are using a double length type.
950 -- We also set the Analyzed flag to avoid a recursive attempt to
951 -- expand the node.
ee6ba406 952
f40f9731 953 Set_Etype (Opnod, Base_Type (Ctyp));
954 Set_Do_Overflow_Check (Opnod, False);
955 Set_Analyzed (Opnod, True);
ee6ba406 956
f40f9731 957 -- Now build the outer conversion
ee6ba406 958
f40f9731 959 Opnd := OK_Convert_To (Typ, Opnod);
960 Analyze (Opnd);
961 Set_Etype (Opnd, Typ);
9dfe12ae 962
f40f9731 963 -- In the discrete type case, we directly generate the range check
964 -- for the outer operand. This range check will implement the
965 -- required overflow check.
9dfe12ae 966
f40f9731 967 if Is_Discrete_Type (Typ) then
968 Rewrite (N, Opnd);
969 Generate_Range_Check
970 (Expression (N), Typ, CE_Overflow_Check_Failed);
9dfe12ae 971
f40f9731 972 -- For other types, we enable overflow checking on the conversion,
973 -- after setting the node as analyzed to prevent recursive attempts
974 -- to expand the conversion node.
9dfe12ae 975
f40f9731 976 else
977 Set_Analyzed (Opnd, True);
978 Enable_Overflow_Check (Opnd);
979 Rewrite (N, Opnd);
980 end if;
981
982 exception
983 when RE_Not_Available =>
984 return;
985 end;
ee6ba406 986 end Apply_Arithmetic_Overflow_Check;
987
ee6ba406 988 ----------------------------
989 -- Apply_Constraint_Check --
990 ----------------------------
991
992 procedure Apply_Constraint_Check
993 (N : Node_Id;
994 Typ : Entity_Id;
995 No_Sliding : Boolean := False)
996 is
997 Desig_Typ : Entity_Id;
998
999 begin
7aafae1c 1000 -- No checks inside a generic (check the instantiations)
1001
ee6ba406 1002 if Inside_A_Generic then
1003 return;
7aafae1c 1004 end if;
ee6ba406 1005
7aafae1c 1006 -- Apply required constaint checks
1007
1008 if Is_Scalar_Type (Typ) then
ee6ba406 1009 Apply_Scalar_Range_Check (N, Typ);
1010
1011 elsif Is_Array_Type (Typ) then
1012
05fcfafb 1013 -- A useful optimization: an aggregate with only an others clause
5f260d20 1014 -- always has the right bounds.
1015
1016 if Nkind (N) = N_Aggregate
1017 and then No (Expressions (N))
1018 and then Nkind
1019 (First (Choices (First (Component_Associations (N)))))
1020 = N_Others_Choice
1021 then
1022 return;
1023 end if;
1024
ee6ba406 1025 if Is_Constrained (Typ) then
1026 Apply_Length_Check (N, Typ);
1027
1028 if No_Sliding then
1029 Apply_Range_Check (N, Typ);
1030 end if;
1031 else
1032 Apply_Range_Check (N, Typ);
1033 end if;
1034
1035 elsif (Is_Record_Type (Typ)
1036 or else Is_Private_Type (Typ))
1037 and then Has_Discriminants (Base_Type (Typ))
1038 and then Is_Constrained (Typ)
1039 then
1040 Apply_Discriminant_Check (N, Typ);
1041
1042 elsif Is_Access_Type (Typ) then
1043
1044 Desig_Typ := Designated_Type (Typ);
1045
1046 -- No checks necessary if expression statically null
1047
2af58f67 1048 if Known_Null (N) then
00c403ee 1049 if Can_Never_Be_Null (Typ) then
1050 Install_Null_Excluding_Check (N);
1051 end if;
ee6ba406 1052
1053 -- No sliding possible on access to arrays
1054
1055 elsif Is_Array_Type (Desig_Typ) then
1056 if Is_Constrained (Desig_Typ) then
1057 Apply_Length_Check (N, Typ);
1058 end if;
1059
1060 Apply_Range_Check (N, Typ);
1061
1062 elsif Has_Discriminants (Base_Type (Desig_Typ))
1063 and then Is_Constrained (Desig_Typ)
1064 then
1065 Apply_Discriminant_Check (N, Typ);
1066 end if;
fa7497e8 1067
bf3e1520 1068 -- Apply the 2005 Null_Excluding check. Note that we do not apply
00c403ee 1069 -- this check if the constraint node is illegal, as shown by having
1070 -- an error posted. This additional guard prevents cascaded errors
1071 -- and compiler aborts on illegal programs involving Ada 2005 checks.
1072
fa7497e8 1073 if Can_Never_Be_Null (Typ)
1074 and then not Can_Never_Be_Null (Etype (N))
00c403ee 1075 and then not Error_Posted (N)
fa7497e8 1076 then
1077 Install_Null_Excluding_Check (N);
1078 end if;
ee6ba406 1079 end if;
1080 end Apply_Constraint_Check;
1081
1082 ------------------------------
1083 -- Apply_Discriminant_Check --
1084 ------------------------------
1085
1086 procedure Apply_Discriminant_Check
1087 (N : Node_Id;
1088 Typ : Entity_Id;
1089 Lhs : Node_Id := Empty)
1090 is
1091 Loc : constant Source_Ptr := Sloc (N);
1092 Do_Access : constant Boolean := Is_Access_Type (Typ);
1093 S_Typ : Entity_Id := Etype (N);
1094 Cond : Node_Id;
1095 T_Typ : Entity_Id;
1096
7be5088a 1097 function Denotes_Explicit_Dereference (Obj : Node_Id) return Boolean;
1098 -- A heap object with an indefinite subtype is constrained by its
1099 -- initial value, and assigning to it requires a constraint_check.
1100 -- The target may be an explicit dereference, or a renaming of one.
1101
ee6ba406 1102 function Is_Aliased_Unconstrained_Component return Boolean;
1103 -- It is possible for an aliased component to have a nominal
1104 -- unconstrained subtype (through instantiation). If this is a
1105 -- discriminated component assigned in the expansion of an aggregate
1106 -- in an initialization, the check must be suppressed. This unusual
2af58f67 1107 -- situation requires a predicate of its own.
ee6ba406 1108
7be5088a 1109 ----------------------------------
1110 -- Denotes_Explicit_Dereference --
1111 ----------------------------------
1112
1113 function Denotes_Explicit_Dereference (Obj : Node_Id) return Boolean is
1114 begin
1115 return
1116 Nkind (Obj) = N_Explicit_Dereference
1117 or else
1118 (Is_Entity_Name (Obj)
1119 and then Present (Renamed_Object (Entity (Obj)))
9474aa9c 1120 and then Nkind (Renamed_Object (Entity (Obj))) =
1121 N_Explicit_Dereference);
7be5088a 1122 end Denotes_Explicit_Dereference;
1123
ee6ba406 1124 ----------------------------------------
1125 -- Is_Aliased_Unconstrained_Component --
1126 ----------------------------------------
1127
1128 function Is_Aliased_Unconstrained_Component return Boolean is
1129 Comp : Entity_Id;
1130 Pref : Node_Id;
1131
1132 begin
1133 if Nkind (Lhs) /= N_Selected_Component then
1134 return False;
1135 else
1136 Comp := Entity (Selector_Name (Lhs));
1137 Pref := Prefix (Lhs);
1138 end if;
1139
1140 if Ekind (Comp) /= E_Component
1141 or else not Is_Aliased (Comp)
1142 then
1143 return False;
1144 end if;
1145
1146 return not Comes_From_Source (Pref)
1147 and then In_Instance
1148 and then not Is_Constrained (Etype (Comp));
1149 end Is_Aliased_Unconstrained_Component;
1150
1151 -- Start of processing for Apply_Discriminant_Check
1152
1153 begin
1154 if Do_Access then
1155 T_Typ := Designated_Type (Typ);
1156 else
1157 T_Typ := Typ;
1158 end if;
1159
1160 -- Nothing to do if discriminant checks are suppressed or else no code
1161 -- is to be generated
1162
1163 if not Expander_Active
1164 or else Discriminant_Checks_Suppressed (T_Typ)
1165 then
1166 return;
1167 end if;
1168
feff2f05 1169 -- No discriminant checks necessary for an access when expression is
1170 -- statically Null. This is not only an optimization, it is fundamental
1171 -- because otherwise discriminant checks may be generated in init procs
1172 -- for types containing an access to a not-yet-frozen record, causing a
1173 -- deadly forward reference.
ee6ba406 1174
feff2f05 1175 -- Also, if the expression is of an access type whose designated type is
1176 -- incomplete, then the access value must be null and we suppress the
1177 -- check.
ee6ba406 1178
2af58f67 1179 if Known_Null (N) then
ee6ba406 1180 return;
1181
1182 elsif Is_Access_Type (S_Typ) then
1183 S_Typ := Designated_Type (S_Typ);
1184
1185 if Ekind (S_Typ) = E_Incomplete_Type then
1186 return;
1187 end if;
1188 end if;
1189
0577b0b1 1190 -- If an assignment target is present, then we need to generate the
1191 -- actual subtype if the target is a parameter or aliased object with
1192 -- an unconstrained nominal subtype.
1193
1194 -- Ada 2005 (AI-363): For Ada 2005, we limit the building of the actual
1195 -- subtype to the parameter and dereference cases, since other aliased
1196 -- objects are unconstrained (unless the nominal subtype is explicitly
7be5088a 1197 -- constrained).
ee6ba406 1198
1199 if Present (Lhs)
1200 and then (Present (Param_Entity (Lhs))
de54c5ab 1201 or else (Ada_Version < Ada_2005
0577b0b1 1202 and then not Is_Constrained (T_Typ)
ee6ba406 1203 and then Is_Aliased_View (Lhs)
0577b0b1 1204 and then not Is_Aliased_Unconstrained_Component)
de54c5ab 1205 or else (Ada_Version >= Ada_2005
0577b0b1 1206 and then not Is_Constrained (T_Typ)
7be5088a 1207 and then Denotes_Explicit_Dereference (Lhs)
0577b0b1 1208 and then Nkind (Original_Node (Lhs)) /=
1209 N_Function_Call))
ee6ba406 1210 then
1211 T_Typ := Get_Actual_Subtype (Lhs);
1212 end if;
1213
feff2f05 1214 -- Nothing to do if the type is unconstrained (this is the case where
1215 -- the actual subtype in the RM sense of N is unconstrained and no check
1216 -- is required).
ee6ba406 1217
1218 if not Is_Constrained (T_Typ) then
1219 return;
05fcfafb 1220
1221 -- Ada 2005: nothing to do if the type is one for which there is a
1222 -- partial view that is constrained.
1223
de54c5ab 1224 elsif Ada_Version >= Ada_2005
05fcfafb 1225 and then Has_Constrained_Partial_View (Base_Type (T_Typ))
1226 then
1227 return;
ee6ba406 1228 end if;
1229
00f91aef 1230 -- Nothing to do if the type is an Unchecked_Union
1231
1232 if Is_Unchecked_Union (Base_Type (T_Typ)) then
1233 return;
1234 end if;
1235
feff2f05 1236 -- Suppress checks if the subtypes are the same. the check must be
1237 -- preserved in an assignment to a formal, because the constraint is
1238 -- given by the actual.
ee6ba406 1239
1240 if Nkind (Original_Node (N)) /= N_Allocator
1241 and then (No (Lhs)
1242 or else not Is_Entity_Name (Lhs)
9dfe12ae 1243 or else No (Param_Entity (Lhs)))
ee6ba406 1244 then
1245 if (Etype (N) = Typ
1246 or else (Do_Access and then Designated_Type (Typ) = S_Typ))
1247 and then not Is_Aliased_View (Lhs)
1248 then
1249 return;
1250 end if;
1251
feff2f05 1252 -- We can also eliminate checks on allocators with a subtype mark that
1253 -- coincides with the context type. The context type may be a subtype
1254 -- without a constraint (common case, a generic actual).
ee6ba406 1255
1256 elsif Nkind (Original_Node (N)) = N_Allocator
1257 and then Is_Entity_Name (Expression (Original_Node (N)))
1258 then
1259 declare
9dfe12ae 1260 Alloc_Typ : constant Entity_Id :=
1261 Entity (Expression (Original_Node (N)));
ee6ba406 1262
1263 begin
1264 if Alloc_Typ = T_Typ
1265 or else (Nkind (Parent (T_Typ)) = N_Subtype_Declaration
1266 and then Is_Entity_Name (
1267 Subtype_Indication (Parent (T_Typ)))
1268 and then Alloc_Typ = Base_Type (T_Typ))
1269
1270 then
1271 return;
1272 end if;
1273 end;
1274 end if;
1275
feff2f05 1276 -- See if we have a case where the types are both constrained, and all
1277 -- the constraints are constants. In this case, we can do the check
1278 -- successfully at compile time.
ee6ba406 1279
9dfe12ae 1280 -- We skip this check for the case where the node is a rewritten`
ee6ba406 1281 -- allocator, because it already carries the context subtype, and
1282 -- extracting the discriminants from the aggregate is messy.
1283
1284 if Is_Constrained (S_Typ)
1285 and then Nkind (Original_Node (N)) /= N_Allocator
1286 then
1287 declare
1288 DconT : Elmt_Id;
1289 Discr : Entity_Id;
1290 DconS : Elmt_Id;
1291 ItemS : Node_Id;
1292 ItemT : Node_Id;
1293
1294 begin
1295 -- S_Typ may not have discriminants in the case where it is a
feff2f05 1296 -- private type completed by a default discriminated type. In that
1297 -- case, we need to get the constraints from the underlying_type.
1298 -- If the underlying type is unconstrained (i.e. has no default
1299 -- discriminants) no check is needed.
ee6ba406 1300
1301 if Has_Discriminants (S_Typ) then
1302 Discr := First_Discriminant (S_Typ);
1303 DconS := First_Elmt (Discriminant_Constraint (S_Typ));
1304
1305 else
1306 Discr := First_Discriminant (Underlying_Type (S_Typ));
1307 DconS :=
1308 First_Elmt
1309 (Discriminant_Constraint (Underlying_Type (S_Typ)));
1310
1311 if No (DconS) then
1312 return;
1313 end if;
fccb5da7 1314
1315 -- A further optimization: if T_Typ is derived from S_Typ
1316 -- without imposing a constraint, no check is needed.
1317
1318 if Nkind (Original_Node (Parent (T_Typ))) =
1319 N_Full_Type_Declaration
1320 then
1321 declare
5c61a0ff 1322 Type_Def : constant Node_Id :=
fccb5da7 1323 Type_Definition
1324 (Original_Node (Parent (T_Typ)));
1325 begin
1326 if Nkind (Type_Def) = N_Derived_Type_Definition
1327 and then Is_Entity_Name (Subtype_Indication (Type_Def))
1328 and then Entity (Subtype_Indication (Type_Def)) = S_Typ
1329 then
1330 return;
1331 end if;
1332 end;
1333 end if;
ee6ba406 1334 end if;
1335
1336 DconT := First_Elmt (Discriminant_Constraint (T_Typ));
1337
1338 while Present (Discr) loop
1339 ItemS := Node (DconS);
1340 ItemT := Node (DconT);
1341
00c403ee 1342 -- For a discriminated component type constrained by the
1343 -- current instance of an enclosing type, there is no
1344 -- applicable discriminant check.
1345
1346 if Nkind (ItemT) = N_Attribute_Reference
1347 and then Is_Access_Type (Etype (ItemT))
1348 and then Is_Entity_Name (Prefix (ItemT))
1349 and then Is_Type (Entity (Prefix (ItemT)))
1350 then
1351 return;
1352 end if;
1353
cc60bd16 1354 -- If the expressions for the discriminants are identical
1355 -- and it is side-effect free (for now just an entity),
1356 -- this may be a shared constraint, e.g. from a subtype
1357 -- without a constraint introduced as a generic actual.
1358 -- Examine other discriminants if any.
1359
1360 if ItemS = ItemT
1361 and then Is_Entity_Name (ItemS)
1362 then
1363 null;
1364
1365 elsif not Is_OK_Static_Expression (ItemS)
1366 or else not Is_OK_Static_Expression (ItemT)
1367 then
1368 exit;
ee6ba406 1369
cc60bd16 1370 elsif Expr_Value (ItemS) /= Expr_Value (ItemT) then
ee6ba406 1371 if Do_Access then -- needs run-time check.
1372 exit;
1373 else
1374 Apply_Compile_Time_Constraint_Error
f15731c4 1375 (N, "incorrect value for discriminant&?",
1376 CE_Discriminant_Check_Failed, Ent => Discr);
ee6ba406 1377 return;
1378 end if;
1379 end if;
1380
1381 Next_Elmt (DconS);
1382 Next_Elmt (DconT);
1383 Next_Discriminant (Discr);
1384 end loop;
1385
1386 if No (Discr) then
1387 return;
1388 end if;
1389 end;
1390 end if;
1391
1392 -- Here we need a discriminant check. First build the expression
1393 -- for the comparisons of the discriminants:
1394
1395 -- (n.disc1 /= typ.disc1) or else
1396 -- (n.disc2 /= typ.disc2) or else
1397 -- ...
1398 -- (n.discn /= typ.discn)
1399
1400 Cond := Build_Discriminant_Checks (N, T_Typ);
1401
1402 -- If Lhs is set and is a parameter, then the condition is
1403 -- guarded by: lhs'constrained and then (condition built above)
1404
1405 if Present (Param_Entity (Lhs)) then
1406 Cond :=
1407 Make_And_Then (Loc,
1408 Left_Opnd =>
1409 Make_Attribute_Reference (Loc,
1410 Prefix => New_Occurrence_Of (Param_Entity (Lhs), Loc),
1411 Attribute_Name => Name_Constrained),
1412 Right_Opnd => Cond);
1413 end if;
1414
1415 if Do_Access then
1416 Cond := Guard_Access (Cond, Loc, N);
1417 end if;
1418
1419 Insert_Action (N,
f15731c4 1420 Make_Raise_Constraint_Error (Loc,
1421 Condition => Cond,
1422 Reason => CE_Discriminant_Check_Failed));
ee6ba406 1423 end Apply_Discriminant_Check;
1424
1425 ------------------------
1426 -- Apply_Divide_Check --
1427 ------------------------
1428
1429 procedure Apply_Divide_Check (N : Node_Id) is
1430 Loc : constant Source_Ptr := Sloc (N);
1431 Typ : constant Entity_Id := Etype (N);
1432 Left : constant Node_Id := Left_Opnd (N);
1433 Right : constant Node_Id := Right_Opnd (N);
1434
1435 LLB : Uint;
1436 Llo : Uint;
1437 Lhi : Uint;
1438 LOK : Boolean;
1439 Rlo : Uint;
1440 Rhi : Uint;
96da3284 1441 ROK : Boolean;
1442
1443 pragma Warnings (Off, Lhi);
1444 -- Don't actually use this value
ee6ba406 1445
1446 begin
1447 if Expander_Active
13dbf220 1448 and then not Backend_Divide_Checks_On_Target
1449 and then Check_Needed (Right, Division_Check)
ee6ba406 1450 then
9c486805 1451 Determine_Range (Right, ROK, Rlo, Rhi, Assume_Valid => True);
ee6ba406 1452
1453 -- See if division by zero possible, and if so generate test. This
1454 -- part of the test is not controlled by the -gnato switch.
1455
1456 if Do_Division_Check (N) then
ee6ba406 1457 if (not ROK) or else (Rlo <= 0 and then 0 <= Rhi) then
1458 Insert_Action (N,
1459 Make_Raise_Constraint_Error (Loc,
1460 Condition =>
1461 Make_Op_Eq (Loc,
0577b0b1 1462 Left_Opnd => Duplicate_Subexpr_Move_Checks (Right),
f15731c4 1463 Right_Opnd => Make_Integer_Literal (Loc, 0)),
1464 Reason => CE_Divide_By_Zero));
ee6ba406 1465 end if;
1466 end if;
1467
1468 -- Test for extremely annoying case of xxx'First divided by -1
1469
1470 if Do_Overflow_Check (N) then
ee6ba406 1471 if Nkind (N) = N_Op_Divide
1472 and then Is_Signed_Integer_Type (Typ)
1473 then
9c486805 1474 Determine_Range (Left, LOK, Llo, Lhi, Assume_Valid => True);
ee6ba406 1475 LLB := Expr_Value (Type_Low_Bound (Base_Type (Typ)));
1476
1477 if ((not ROK) or else (Rlo <= (-1) and then (-1) <= Rhi))
1478 and then
1479 ((not LOK) or else (Llo = LLB))
1480 then
1481 Insert_Action (N,
1482 Make_Raise_Constraint_Error (Loc,
1483 Condition =>
1484 Make_And_Then (Loc,
1485
1486 Make_Op_Eq (Loc,
9dfe12ae 1487 Left_Opnd =>
1488 Duplicate_Subexpr_Move_Checks (Left),
ee6ba406 1489 Right_Opnd => Make_Integer_Literal (Loc, LLB)),
1490
1491 Make_Op_Eq (Loc,
9dfe12ae 1492 Left_Opnd =>
1493 Duplicate_Subexpr (Right),
ee6ba406 1494 Right_Opnd =>
f15731c4 1495 Make_Integer_Literal (Loc, -1))),
1496 Reason => CE_Overflow_Check_Failed));
ee6ba406 1497 end if;
1498 end if;
1499 end if;
1500 end if;
1501 end Apply_Divide_Check;
1502
5329ca64 1503 ----------------------------------
1504 -- Apply_Float_Conversion_Check --
1505 ----------------------------------
1506
feff2f05 1507 -- Let F and I be the source and target types of the conversion. The RM
1508 -- specifies that a floating-point value X is rounded to the nearest
1509 -- integer, with halfway cases being rounded away from zero. The rounded
1510 -- value of X is checked against I'Range.
1511
1512 -- The catch in the above paragraph is that there is no good way to know
1513 -- whether the round-to-integer operation resulted in overflow. A remedy is
1514 -- to perform a range check in the floating-point domain instead, however:
5329ca64 1515
5329ca64 1516 -- (1) The bounds may not be known at compile time
2af58f67 1517 -- (2) The check must take into account rounding or truncation.
5329ca64 1518 -- (3) The range of type I may not be exactly representable in F.
2af58f67 1519 -- (4) For the rounding case, The end-points I'First - 0.5 and
1520 -- I'Last + 0.5 may or may not be in range, depending on the
1521 -- sign of I'First and I'Last.
5329ca64 1522 -- (5) X may be a NaN, which will fail any comparison
1523
2af58f67 1524 -- The following steps correctly convert X with rounding:
feff2f05 1525
5329ca64 1526 -- (1) If either I'First or I'Last is not known at compile time, use
1527 -- I'Base instead of I in the next three steps and perform a
1528 -- regular range check against I'Range after conversion.
1529 -- (2) If I'First - 0.5 is representable in F then let Lo be that
1530 -- value and define Lo_OK as (I'First > 0). Otherwise, let Lo be
2af58f67 1531 -- F'Machine (I'First) and let Lo_OK be (Lo >= I'First).
1532 -- In other words, take one of the closest floating-point numbers
1533 -- (which is an integer value) to I'First, and see if it is in
1534 -- range or not.
5329ca64 1535 -- (3) If I'Last + 0.5 is representable in F then let Hi be that value
1536 -- and define Hi_OK as (I'Last < 0). Otherwise, let Hi be
2af58f67 1537 -- F'Machine (I'Last) and let Hi_OK be (Hi <= I'Last).
5329ca64 1538 -- (4) Raise CE when (Lo_OK and X < Lo) or (not Lo_OK and X <= Lo)
1539 -- or (Hi_OK and X > Hi) or (not Hi_OK and X >= Hi)
1540
2af58f67 1541 -- For the truncating case, replace steps (2) and (3) as follows:
1542 -- (2) If I'First > 0, then let Lo be F'Pred (I'First) and let Lo_OK
1543 -- be False. Otherwise, let Lo be F'Succ (I'First - 1) and let
1544 -- Lo_OK be True.
1545 -- (3) If I'Last < 0, then let Hi be F'Succ (I'Last) and let Hi_OK
1546 -- be False. Otherwise let Hi be F'Pred (I'Last + 1) and let
1547 -- Hi_OK be False
1548
5329ca64 1549 procedure Apply_Float_Conversion_Check
1550 (Ck_Node : Node_Id;
1551 Target_Typ : Entity_Id)
1552 is
feff2f05 1553 LB : constant Node_Id := Type_Low_Bound (Target_Typ);
1554 HB : constant Node_Id := Type_High_Bound (Target_Typ);
5329ca64 1555 Loc : constant Source_Ptr := Sloc (Ck_Node);
1556 Expr_Type : constant Entity_Id := Base_Type (Etype (Ck_Node));
feff2f05 1557 Target_Base : constant Entity_Id :=
1558 Implementation_Base_Type (Target_Typ);
1559
2af58f67 1560 Par : constant Node_Id := Parent (Ck_Node);
1561 pragma Assert (Nkind (Par) = N_Type_Conversion);
1562 -- Parent of check node, must be a type conversion
1563
1564 Truncate : constant Boolean := Float_Truncate (Par);
1565 Max_Bound : constant Uint :=
1566 UI_Expon
e8548746 1567 (Machine_Radix_Value (Expr_Type),
1568 Machine_Mantissa_Value (Expr_Type) - 1) - 1;
2af58f67 1569
5329ca64 1570 -- Largest bound, so bound plus or minus half is a machine number of F
1571
feff2f05 1572 Ifirst, Ilast : Uint;
1573 -- Bounds of integer type
1574
1575 Lo, Hi : Ureal;
1576 -- Bounds to check in floating-point domain
5329ca64 1577
feff2f05 1578 Lo_OK, Hi_OK : Boolean;
1579 -- True iff Lo resp. Hi belongs to I'Range
5329ca64 1580
feff2f05 1581 Lo_Chk, Hi_Chk : Node_Id;
1582 -- Expressions that are False iff check fails
1583
1584 Reason : RT_Exception_Code;
5329ca64 1585
1586 begin
1587 if not Compile_Time_Known_Value (LB)
1588 or not Compile_Time_Known_Value (HB)
1589 then
1590 declare
feff2f05 1591 -- First check that the value falls in the range of the base type,
1592 -- to prevent overflow during conversion and then perform a
1593 -- regular range check against the (dynamic) bounds.
5329ca64 1594
5329ca64 1595 pragma Assert (Target_Base /= Target_Typ);
5329ca64 1596
46eb6933 1597 Temp : constant Entity_Id := Make_Temporary (Loc, 'T', Par);
5329ca64 1598
1599 begin
1600 Apply_Float_Conversion_Check (Ck_Node, Target_Base);
1601 Set_Etype (Temp, Target_Base);
1602
1603 Insert_Action (Parent (Par),
1604 Make_Object_Declaration (Loc,
1605 Defining_Identifier => Temp,
1606 Object_Definition => New_Occurrence_Of (Target_Typ, Loc),
1607 Expression => New_Copy_Tree (Par)),
1608 Suppress => All_Checks);
1609
1610 Insert_Action (Par,
1611 Make_Raise_Constraint_Error (Loc,
1612 Condition =>
1613 Make_Not_In (Loc,
1614 Left_Opnd => New_Occurrence_Of (Temp, Loc),
1615 Right_Opnd => New_Occurrence_Of (Target_Typ, Loc)),
1616 Reason => CE_Range_Check_Failed));
1617 Rewrite (Par, New_Occurrence_Of (Temp, Loc));
1618
1619 return;
1620 end;
1621 end if;
1622
7d86aa98 1623 -- Get the (static) bounds of the target type
5329ca64 1624
1625 Ifirst := Expr_Value (LB);
1626 Ilast := Expr_Value (HB);
1627
7d86aa98 1628 -- A simple optimization: if the expression is a universal literal,
1629 -- we can do the comparison with the bounds and the conversion to
1630 -- an integer type statically. The range checks are unchanged.
1631
1632 if Nkind (Ck_Node) = N_Real_Literal
1633 and then Etype (Ck_Node) = Universal_Real
1634 and then Is_Integer_Type (Target_Typ)
1635 and then Nkind (Parent (Ck_Node)) = N_Type_Conversion
1636 then
1637 declare
1638 Int_Val : constant Uint := UR_To_Uint (Realval (Ck_Node));
1639
1640 begin
1641 if Int_Val <= Ilast and then Int_Val >= Ifirst then
1642
4309515d 1643 -- Conversion is safe
7d86aa98 1644
1645 Rewrite (Parent (Ck_Node),
1646 Make_Integer_Literal (Loc, UI_To_Int (Int_Val)));
1647 Analyze_And_Resolve (Parent (Ck_Node), Target_Typ);
1648 return;
1649 end if;
1650 end;
1651 end if;
1652
5329ca64 1653 -- Check against lower bound
1654
2af58f67 1655 if Truncate and then Ifirst > 0 then
1656 Lo := Pred (Expr_Type, UR_From_Uint (Ifirst));
1657 Lo_OK := False;
1658
1659 elsif Truncate then
1660 Lo := Succ (Expr_Type, UR_From_Uint (Ifirst - 1));
1661 Lo_OK := True;
1662
1663 elsif abs (Ifirst) < Max_Bound then
5329ca64 1664 Lo := UR_From_Uint (Ifirst) - Ureal_Half;
1665 Lo_OK := (Ifirst > 0);
2af58f67 1666
5329ca64 1667 else
1668 Lo := Machine (Expr_Type, UR_From_Uint (Ifirst), Round_Even, Ck_Node);
1669 Lo_OK := (Lo >= UR_From_Uint (Ifirst));
1670 end if;
1671
1672 if Lo_OK then
1673
1674 -- Lo_Chk := (X >= Lo)
1675
1676 Lo_Chk := Make_Op_Ge (Loc,
1677 Left_Opnd => Duplicate_Subexpr_No_Checks (Ck_Node),
1678 Right_Opnd => Make_Real_Literal (Loc, Lo));
1679
1680 else
1681 -- Lo_Chk := (X > Lo)
1682
1683 Lo_Chk := Make_Op_Gt (Loc,
1684 Left_Opnd => Duplicate_Subexpr_No_Checks (Ck_Node),
1685 Right_Opnd => Make_Real_Literal (Loc, Lo));
1686 end if;
1687
1688 -- Check against higher bound
1689
2af58f67 1690 if Truncate and then Ilast < 0 then
1691 Hi := Succ (Expr_Type, UR_From_Uint (Ilast));
1692 Lo_OK := False;
1693
1694 elsif Truncate then
1695 Hi := Pred (Expr_Type, UR_From_Uint (Ilast + 1));
1696 Hi_OK := True;
1697
1698 elsif abs (Ilast) < Max_Bound then
5329ca64 1699 Hi := UR_From_Uint (Ilast) + Ureal_Half;
1700 Hi_OK := (Ilast < 0);
1701 else
1702 Hi := Machine (Expr_Type, UR_From_Uint (Ilast), Round_Even, Ck_Node);
1703 Hi_OK := (Hi <= UR_From_Uint (Ilast));
1704 end if;
1705
1706 if Hi_OK then
1707
1708 -- Hi_Chk := (X <= Hi)
1709
1710 Hi_Chk := Make_Op_Le (Loc,
1711 Left_Opnd => Duplicate_Subexpr_No_Checks (Ck_Node),
1712 Right_Opnd => Make_Real_Literal (Loc, Hi));
1713
1714 else
1715 -- Hi_Chk := (X < Hi)
1716
1717 Hi_Chk := Make_Op_Lt (Loc,
1718 Left_Opnd => Duplicate_Subexpr_No_Checks (Ck_Node),
1719 Right_Opnd => Make_Real_Literal (Loc, Hi));
1720 end if;
1721
feff2f05 1722 -- If the bounds of the target type are the same as those of the base
1723 -- type, the check is an overflow check as a range check is not
1724 -- performed in these cases.
5329ca64 1725
1726 if Expr_Value (Type_Low_Bound (Target_Base)) = Ifirst
1727 and then Expr_Value (Type_High_Bound (Target_Base)) = Ilast
1728 then
1729 Reason := CE_Overflow_Check_Failed;
1730 else
1731 Reason := CE_Range_Check_Failed;
1732 end if;
1733
1734 -- Raise CE if either conditions does not hold
1735
1736 Insert_Action (Ck_Node,
1737 Make_Raise_Constraint_Error (Loc,
05fcfafb 1738 Condition => Make_Op_Not (Loc, Make_And_Then (Loc, Lo_Chk, Hi_Chk)),
5329ca64 1739 Reason => Reason));
1740 end Apply_Float_Conversion_Check;
1741
ee6ba406 1742 ------------------------
1743 -- Apply_Length_Check --
1744 ------------------------
1745
1746 procedure Apply_Length_Check
1747 (Ck_Node : Node_Id;
1748 Target_Typ : Entity_Id;
1749 Source_Typ : Entity_Id := Empty)
1750 is
1751 begin
1752 Apply_Selected_Length_Checks
1753 (Ck_Node, Target_Typ, Source_Typ, Do_Static => False);
1754 end Apply_Length_Check;
1755
7aafae1c 1756 ---------------------------
1757 -- Apply_Predicate_Check --
1758 ---------------------------
1759
1760 procedure Apply_Predicate_Check (N : Node_Id; Typ : Entity_Id) is
1761 begin
701d57a4 1762 if Present (Predicate_Function (Typ)) then
7aafae1c 1763 Insert_Action (N,
1764 Make_Predicate_Check (Typ, Duplicate_Subexpr (N)));
1765 end if;
1766 end Apply_Predicate_Check;
1767
ee6ba406 1768 -----------------------
1769 -- Apply_Range_Check --
1770 -----------------------
1771
1772 procedure Apply_Range_Check
1773 (Ck_Node : Node_Id;
1774 Target_Typ : Entity_Id;
1775 Source_Typ : Entity_Id := Empty)
1776 is
1777 begin
1778 Apply_Selected_Range_Checks
1779 (Ck_Node, Target_Typ, Source_Typ, Do_Static => False);
1780 end Apply_Range_Check;
1781
1782 ------------------------------
1783 -- Apply_Scalar_Range_Check --
1784 ------------------------------
1785
feff2f05 1786 -- Note that Apply_Scalar_Range_Check never turns the Do_Range_Check flag
1787 -- off if it is already set on.
ee6ba406 1788
1789 procedure Apply_Scalar_Range_Check
1790 (Expr : Node_Id;
1791 Target_Typ : Entity_Id;
1792 Source_Typ : Entity_Id := Empty;
1793 Fixed_Int : Boolean := False)
1794 is
1795 Parnt : constant Node_Id := Parent (Expr);
1796 S_Typ : Entity_Id;
1797 Arr : Node_Id := Empty; -- initialize to prevent warning
1798 Arr_Typ : Entity_Id := Empty; -- initialize to prevent warning
1799 OK : Boolean;
1800
1801 Is_Subscr_Ref : Boolean;
1802 -- Set true if Expr is a subscript
1803
1804 Is_Unconstrained_Subscr_Ref : Boolean;
1805 -- Set true if Expr is a subscript of an unconstrained array. In this
1806 -- case we do not attempt to do an analysis of the value against the
1807 -- range of the subscript, since we don't know the actual subtype.
1808
1809 Int_Real : Boolean;
feff2f05 1810 -- Set to True if Expr should be regarded as a real value even though
1811 -- the type of Expr might be discrete.
ee6ba406 1812
1813 procedure Bad_Value;
1814 -- Procedure called if value is determined to be out of range
1815
9dfe12ae 1816 ---------------
1817 -- Bad_Value --
1818 ---------------
1819
ee6ba406 1820 procedure Bad_Value is
1821 begin
1822 Apply_Compile_Time_Constraint_Error
f15731c4 1823 (Expr, "value not in range of}?", CE_Range_Check_Failed,
ee6ba406 1824 Ent => Target_Typ,
1825 Typ => Target_Typ);
1826 end Bad_Value;
1827
9dfe12ae 1828 -- Start of processing for Apply_Scalar_Range_Check
1829
ee6ba406 1830 begin
2af58f67 1831 -- Return if check obviously not needed
ee6ba406 1832
2af58f67 1833 if
1834 -- Not needed inside generic
ee6ba406 1835
2af58f67 1836 Inside_A_Generic
1837
1838 -- Not needed if previous error
1839
1840 or else Target_Typ = Any_Type
1841 or else Nkind (Expr) = N_Error
1842
1843 -- Not needed for non-scalar type
1844
1845 or else not Is_Scalar_Type (Target_Typ)
1846
1847 -- Not needed if we know node raises CE already
1848
1849 or else Raises_Constraint_Error (Expr)
ee6ba406 1850 then
1851 return;
1852 end if;
1853
1854 -- Now, see if checks are suppressed
1855
1856 Is_Subscr_Ref :=
1857 Is_List_Member (Expr) and then Nkind (Parnt) = N_Indexed_Component;
1858
1859 if Is_Subscr_Ref then
1860 Arr := Prefix (Parnt);
1861 Arr_Typ := Get_Actual_Subtype_If_Available (Arr);
1862 end if;
1863
1864 if not Do_Range_Check (Expr) then
1865
1866 -- Subscript reference. Check for Index_Checks suppressed
1867
1868 if Is_Subscr_Ref then
1869
1870 -- Check array type and its base type
1871
1872 if Index_Checks_Suppressed (Arr_Typ)
9dfe12ae 1873 or else Index_Checks_Suppressed (Base_Type (Arr_Typ))
ee6ba406 1874 then
1875 return;
1876
1877 -- Check array itself if it is an entity name
1878
1879 elsif Is_Entity_Name (Arr)
9dfe12ae 1880 and then Index_Checks_Suppressed (Entity (Arr))
ee6ba406 1881 then
1882 return;
1883
1884 -- Check expression itself if it is an entity name
1885
1886 elsif Is_Entity_Name (Expr)
9dfe12ae 1887 and then Index_Checks_Suppressed (Entity (Expr))
ee6ba406 1888 then
1889 return;
1890 end if;
1891
1892 -- All other cases, check for Range_Checks suppressed
1893
1894 else
1895 -- Check target type and its base type
1896
1897 if Range_Checks_Suppressed (Target_Typ)
9dfe12ae 1898 or else Range_Checks_Suppressed (Base_Type (Target_Typ))
ee6ba406 1899 then
1900 return;
1901
1902 -- Check expression itself if it is an entity name
1903
1904 elsif Is_Entity_Name (Expr)
9dfe12ae 1905 and then Range_Checks_Suppressed (Entity (Expr))
ee6ba406 1906 then
1907 return;
1908
feff2f05 1909 -- If Expr is part of an assignment statement, then check left
1910 -- side of assignment if it is an entity name.
ee6ba406 1911
1912 elsif Nkind (Parnt) = N_Assignment_Statement
1913 and then Is_Entity_Name (Name (Parnt))
9dfe12ae 1914 and then Range_Checks_Suppressed (Entity (Name (Parnt)))
ee6ba406 1915 then
1916 return;
1917 end if;
1918 end if;
1919 end if;
1920
9dfe12ae 1921 -- Do not set range checks if they are killed
1922
1923 if Nkind (Expr) = N_Unchecked_Type_Conversion
1924 and then Kill_Range_Check (Expr)
1925 then
1926 return;
1927 end if;
1928
1929 -- Do not set range checks for any values from System.Scalar_Values
1930 -- since the whole idea of such values is to avoid checking them!
1931
1932 if Is_Entity_Name (Expr)
1933 and then Is_RTU (Scope (Entity (Expr)), System_Scalar_Values)
1934 then
1935 return;
1936 end if;
1937
ee6ba406 1938 -- Now see if we need a check
1939
1940 if No (Source_Typ) then
1941 S_Typ := Etype (Expr);
1942 else
1943 S_Typ := Source_Typ;
1944 end if;
1945
1946 if not Is_Scalar_Type (S_Typ) or else S_Typ = Any_Type then
1947 return;
1948 end if;
1949
1950 Is_Unconstrained_Subscr_Ref :=
1951 Is_Subscr_Ref and then not Is_Constrained (Arr_Typ);
1952
feff2f05 1953 -- Always do a range check if the source type includes infinities and
1954 -- the target type does not include infinities. We do not do this if
1955 -- range checks are killed.
ee6ba406 1956
1957 if Is_Floating_Point_Type (S_Typ)
1958 and then Has_Infinities (S_Typ)
1959 and then not Has_Infinities (Target_Typ)
1960 then
1961 Enable_Range_Check (Expr);
1962 end if;
1963
feff2f05 1964 -- Return if we know expression is definitely in the range of the target
1965 -- type as determined by Determine_Range. Right now we only do this for
1966 -- discrete types, and not fixed-point or floating-point types.
ee6ba406 1967
f2a06be9 1968 -- The additional less-precise tests below catch these cases
ee6ba406 1969
feff2f05 1970 -- Note: skip this if we are given a source_typ, since the point of
1971 -- supplying a Source_Typ is to stop us looking at the expression.
1972 -- We could sharpen this test to be out parameters only ???
ee6ba406 1973
1974 if Is_Discrete_Type (Target_Typ)
1975 and then Is_Discrete_Type (Etype (Expr))
1976 and then not Is_Unconstrained_Subscr_Ref
1977 and then No (Source_Typ)
1978 then
1979 declare
1980 Tlo : constant Node_Id := Type_Low_Bound (Target_Typ);
1981 Thi : constant Node_Id := Type_High_Bound (Target_Typ);
1982 Lo : Uint;
1983 Hi : Uint;
1984
1985 begin
1986 if Compile_Time_Known_Value (Tlo)
1987 and then Compile_Time_Known_Value (Thi)
1988 then
9dfe12ae 1989 declare
1990 Lov : constant Uint := Expr_Value (Tlo);
1991 Hiv : constant Uint := Expr_Value (Thi);
ee6ba406 1992
9dfe12ae 1993 begin
1994 -- If range is null, we for sure have a constraint error
1995 -- (we don't even need to look at the value involved,
1996 -- since all possible values will raise CE).
1997
1998 if Lov > Hiv then
1999 Bad_Value;
2000 return;
2001 end if;
2002
2003 -- Otherwise determine range of value
2004
9c486805 2005 Determine_Range (Expr, OK, Lo, Hi, Assume_Valid => True);
9dfe12ae 2006
2007 if OK then
2008
2009 -- If definitely in range, all OK
ee6ba406 2010
ee6ba406 2011 if Lo >= Lov and then Hi <= Hiv then
2012 return;
2013
9dfe12ae 2014 -- If definitely not in range, warn
2015
ee6ba406 2016 elsif Lov > Hi or else Hiv < Lo then
2017 Bad_Value;
2018 return;
9dfe12ae 2019
2020 -- Otherwise we don't know
2021
2022 else
2023 null;
ee6ba406 2024 end if;
9dfe12ae 2025 end if;
2026 end;
ee6ba406 2027 end if;
2028 end;
2029 end if;
2030
2031 Int_Real :=
2032 Is_Floating_Point_Type (S_Typ)
2033 or else (Is_Fixed_Point_Type (S_Typ) and then not Fixed_Int);
2034
2035 -- Check if we can determine at compile time whether Expr is in the
9dfe12ae 2036 -- range of the target type. Note that if S_Typ is within the bounds
2037 -- of Target_Typ then this must be the case. This check is meaningful
2038 -- only if this is not a conversion between integer and real types.
ee6ba406 2039
2040 if not Is_Unconstrained_Subscr_Ref
2041 and then
2042 Is_Discrete_Type (S_Typ) = Is_Discrete_Type (Target_Typ)
2043 and then
7a1dabb3 2044 (In_Subrange_Of (S_Typ, Target_Typ, Fixed_Int)
ee6ba406 2045 or else
9c486805 2046 Is_In_Range (Expr, Target_Typ,
2047 Assume_Valid => True,
2048 Fixed_Int => Fixed_Int,
2049 Int_Real => Int_Real))
ee6ba406 2050 then
2051 return;
2052
9c486805 2053 elsif Is_Out_Of_Range (Expr, Target_Typ,
2054 Assume_Valid => True,
2055 Fixed_Int => Fixed_Int,
2056 Int_Real => Int_Real)
2057 then
ee6ba406 2058 Bad_Value;
2059 return;
2060
feff2f05 2061 -- In the floating-point case, we only do range checks if the type is
2062 -- constrained. We definitely do NOT want range checks for unconstrained
2063 -- types, since we want to have infinities
ee6ba406 2064
9dfe12ae 2065 elsif Is_Floating_Point_Type (S_Typ) then
2066 if Is_Constrained (S_Typ) then
2067 Enable_Range_Check (Expr);
2068 end if;
ee6ba406 2069
9dfe12ae 2070 -- For all other cases we enable a range check unconditionally
ee6ba406 2071
2072 else
2073 Enable_Range_Check (Expr);
2074 return;
2075 end if;
ee6ba406 2076 end Apply_Scalar_Range_Check;
2077
2078 ----------------------------------
2079 -- Apply_Selected_Length_Checks --
2080 ----------------------------------
2081
2082 procedure Apply_Selected_Length_Checks
2083 (Ck_Node : Node_Id;
2084 Target_Typ : Entity_Id;
2085 Source_Typ : Entity_Id;
2086 Do_Static : Boolean)
2087 is
2088 Cond : Node_Id;
2089 R_Result : Check_Result;
2090 R_Cno : Node_Id;
2091
2092 Loc : constant Source_Ptr := Sloc (Ck_Node);
2093 Checks_On : constant Boolean :=
2094 (not Index_Checks_Suppressed (Target_Typ))
2095 or else
2096 (not Length_Checks_Suppressed (Target_Typ));
2097
2098 begin
f15731c4 2099 if not Expander_Active then
ee6ba406 2100 return;
2101 end if;
2102
2103 R_Result :=
2104 Selected_Length_Checks (Ck_Node, Target_Typ, Source_Typ, Empty);
2105
2106 for J in 1 .. 2 loop
ee6ba406 2107 R_Cno := R_Result (J);
2108 exit when No (R_Cno);
2109
2110 -- A length check may mention an Itype which is attached to a
2111 -- subsequent node. At the top level in a package this can cause
2112 -- an order-of-elaboration problem, so we make sure that the itype
2113 -- is referenced now.
2114
2115 if Ekind (Current_Scope) = E_Package
2116 and then Is_Compilation_Unit (Current_Scope)
2117 then
2118 Ensure_Defined (Target_Typ, Ck_Node);
2119
2120 if Present (Source_Typ) then
2121 Ensure_Defined (Source_Typ, Ck_Node);
2122
2123 elsif Is_Itype (Etype (Ck_Node)) then
2124 Ensure_Defined (Etype (Ck_Node), Ck_Node);
2125 end if;
2126 end if;
2127
feff2f05 2128 -- If the item is a conditional raise of constraint error, then have
2129 -- a look at what check is being performed and ???
ee6ba406 2130
2131 if Nkind (R_Cno) = N_Raise_Constraint_Error
2132 and then Present (Condition (R_Cno))
2133 then
2134 Cond := Condition (R_Cno);
2135
0577b0b1 2136 -- Case where node does not now have a dynamic check
ee6ba406 2137
0577b0b1 2138 if not Has_Dynamic_Length_Check (Ck_Node) then
2139
2140 -- If checks are on, just insert the check
2141
2142 if Checks_On then
2143 Insert_Action (Ck_Node, R_Cno);
2144
2145 if not Do_Static then
2146 Set_Has_Dynamic_Length_Check (Ck_Node);
2147 end if;
2148
2149 -- If checks are off, then analyze the length check after
2150 -- temporarily attaching it to the tree in case the relevant
2151 -- condition can be evaluted at compile time. We still want a
2152 -- compile time warning in this case.
2153
2154 else
2155 Set_Parent (R_Cno, Ck_Node);
2156 Analyze (R_Cno);
ee6ba406 2157 end if;
ee6ba406 2158 end if;
2159
2160 -- Output a warning if the condition is known to be True
2161
2162 if Is_Entity_Name (Cond)
2163 and then Entity (Cond) = Standard_True
2164 then
2165 Apply_Compile_Time_Constraint_Error
2166 (Ck_Node, "wrong length for array of}?",
f15731c4 2167 CE_Length_Check_Failed,
ee6ba406 2168 Ent => Target_Typ,
2169 Typ => Target_Typ);
2170
2171 -- If we were only doing a static check, or if checks are not
2172 -- on, then we want to delete the check, since it is not needed.
2173 -- We do this by replacing the if statement by a null statement
2174
2175 elsif Do_Static or else not Checks_On then
00c403ee 2176 Remove_Warning_Messages (R_Cno);
ee6ba406 2177 Rewrite (R_Cno, Make_Null_Statement (Loc));
2178 end if;
2179
2180 else
2181 Install_Static_Check (R_Cno, Loc);
2182 end if;
ee6ba406 2183 end loop;
ee6ba406 2184 end Apply_Selected_Length_Checks;
2185
2186 ---------------------------------
2187 -- Apply_Selected_Range_Checks --
2188 ---------------------------------
2189
2190 procedure Apply_Selected_Range_Checks
2191 (Ck_Node : Node_Id;
2192 Target_Typ : Entity_Id;
2193 Source_Typ : Entity_Id;
2194 Do_Static : Boolean)
2195 is
2196 Cond : Node_Id;
2197 R_Result : Check_Result;
2198 R_Cno : Node_Id;
2199
2200 Loc : constant Source_Ptr := Sloc (Ck_Node);
2201 Checks_On : constant Boolean :=
2202 (not Index_Checks_Suppressed (Target_Typ))
2203 or else
2204 (not Range_Checks_Suppressed (Target_Typ));
2205
2206 begin
2207 if not Expander_Active or else not Checks_On then
2208 return;
2209 end if;
2210
2211 R_Result :=
2212 Selected_Range_Checks (Ck_Node, Target_Typ, Source_Typ, Empty);
2213
2214 for J in 1 .. 2 loop
2215
2216 R_Cno := R_Result (J);
2217 exit when No (R_Cno);
2218
feff2f05 2219 -- If the item is a conditional raise of constraint error, then have
2220 -- a look at what check is being performed and ???
ee6ba406 2221
2222 if Nkind (R_Cno) = N_Raise_Constraint_Error
2223 and then Present (Condition (R_Cno))
2224 then
2225 Cond := Condition (R_Cno);
2226
2227 if not Has_Dynamic_Range_Check (Ck_Node) then
2228 Insert_Action (Ck_Node, R_Cno);
2229
2230 if not Do_Static then
2231 Set_Has_Dynamic_Range_Check (Ck_Node);
2232 end if;
2233 end if;
2234
2235 -- Output a warning if the condition is known to be True
2236
2237 if Is_Entity_Name (Cond)
2238 and then Entity (Cond) = Standard_True
2239 then
feff2f05 2240 -- Since an N_Range is technically not an expression, we have
2241 -- to set one of the bounds to C_E and then just flag the
2242 -- N_Range. The warning message will point to the lower bound
2243 -- and complain about a range, which seems OK.
ee6ba406 2244
2245 if Nkind (Ck_Node) = N_Range then
2246 Apply_Compile_Time_Constraint_Error
2247 (Low_Bound (Ck_Node), "static range out of bounds of}?",
f15731c4 2248 CE_Range_Check_Failed,
ee6ba406 2249 Ent => Target_Typ,
2250 Typ => Target_Typ);
2251
2252 Set_Raises_Constraint_Error (Ck_Node);
2253
2254 else
2255 Apply_Compile_Time_Constraint_Error
2256 (Ck_Node, "static value out of range of}?",
f15731c4 2257 CE_Range_Check_Failed,
ee6ba406 2258 Ent => Target_Typ,
2259 Typ => Target_Typ);
2260 end if;
2261
2262 -- If we were only doing a static check, or if checks are not
2263 -- on, then we want to delete the check, since it is not needed.
2264 -- We do this by replacing the if statement by a null statement
2265
2266 elsif Do_Static or else not Checks_On then
00c403ee 2267 Remove_Warning_Messages (R_Cno);
ee6ba406 2268 Rewrite (R_Cno, Make_Null_Statement (Loc));
2269 end if;
2270
2271 else
2272 Install_Static_Check (R_Cno, Loc);
2273 end if;
ee6ba406 2274 end loop;
ee6ba406 2275 end Apply_Selected_Range_Checks;
2276
2277 -------------------------------
2278 -- Apply_Static_Length_Check --
2279 -------------------------------
2280
2281 procedure Apply_Static_Length_Check
2282 (Expr : Node_Id;
2283 Target_Typ : Entity_Id;
2284 Source_Typ : Entity_Id := Empty)
2285 is
2286 begin
2287 Apply_Selected_Length_Checks
2288 (Expr, Target_Typ, Source_Typ, Do_Static => True);
2289 end Apply_Static_Length_Check;
2290
2291 -------------------------------------
2292 -- Apply_Subscript_Validity_Checks --
2293 -------------------------------------
2294
2295 procedure Apply_Subscript_Validity_Checks (Expr : Node_Id) is
2296 Sub : Node_Id;
2297
2298 begin
2299 pragma Assert (Nkind (Expr) = N_Indexed_Component);
2300
2301 -- Loop through subscripts
2302
2303 Sub := First (Expressions (Expr));
2304 while Present (Sub) loop
2305
feff2f05 2306 -- Check one subscript. Note that we do not worry about enumeration
2307 -- type with holes, since we will convert the value to a Pos value
2308 -- for the subscript, and that convert will do the necessary validity
2309 -- check.
ee6ba406 2310
2311 Ensure_Valid (Sub, Holes_OK => True);
2312
2313 -- Move to next subscript
2314
2315 Sub := Next (Sub);
2316 end loop;
2317 end Apply_Subscript_Validity_Checks;
2318
2319 ----------------------------------
2320 -- Apply_Type_Conversion_Checks --
2321 ----------------------------------
2322
2323 procedure Apply_Type_Conversion_Checks (N : Node_Id) is
2324 Target_Type : constant Entity_Id := Etype (N);
2325 Target_Base : constant Entity_Id := Base_Type (Target_Type);
9dfe12ae 2326 Expr : constant Node_Id := Expression (N);
2327 Expr_Type : constant Entity_Id := Etype (Expr);
ee6ba406 2328
2329 begin
2330 if Inside_A_Generic then
2331 return;
2332
f15731c4 2333 -- Skip these checks if serious errors detected, there are some nasty
ee6ba406 2334 -- situations of incomplete trees that blow things up.
2335
f15731c4 2336 elsif Serious_Errors_Detected > 0 then
ee6ba406 2337 return;
2338
feff2f05 2339 -- Scalar type conversions of the form Target_Type (Expr) require a
2340 -- range check if we cannot be sure that Expr is in the base type of
2341 -- Target_Typ and also that Expr is in the range of Target_Typ. These
2342 -- are not quite the same condition from an implementation point of
2343 -- view, but clearly the second includes the first.
ee6ba406 2344
2345 elsif Is_Scalar_Type (Target_Type) then
2346 declare
2347 Conv_OK : constant Boolean := Conversion_OK (N);
feff2f05 2348 -- If the Conversion_OK flag on the type conversion is set and no
2349 -- floating point type is involved in the type conversion then
2350 -- fixed point values must be read as integral values.
ee6ba406 2351
5329ca64 2352 Float_To_Int : constant Boolean :=
2353 Is_Floating_Point_Type (Expr_Type)
2354 and then Is_Integer_Type (Target_Type);
2355
ee6ba406 2356 begin
ee6ba406 2357 if not Overflow_Checks_Suppressed (Target_Base)
e254d721 2358 and then not
7a1dabb3 2359 In_Subrange_Of (Expr_Type, Target_Base, Fixed_Int => Conv_OK)
5329ca64 2360 and then not Float_To_Int
ee6ba406 2361 then
00c403ee 2362 Activate_Overflow_Check (N);
ee6ba406 2363 end if;
2364
2365 if not Range_Checks_Suppressed (Target_Type)
2366 and then not Range_Checks_Suppressed (Expr_Type)
2367 then
5329ca64 2368 if Float_To_Int then
2369 Apply_Float_Conversion_Check (Expr, Target_Type);
2370 else
2371 Apply_Scalar_Range_Check
2372 (Expr, Target_Type, Fixed_Int => Conv_OK);
2373 end if;
ee6ba406 2374 end if;
2375 end;
2376
2377 elsif Comes_From_Source (N)
f40f9731 2378 and then not Discriminant_Checks_Suppressed (Target_Type)
ee6ba406 2379 and then Is_Record_Type (Target_Type)
2380 and then Is_Derived_Type (Target_Type)
2381 and then not Is_Tagged_Type (Target_Type)
2382 and then not Is_Constrained (Target_Type)
9dfe12ae 2383 and then Present (Stored_Constraint (Target_Type))
ee6ba406 2384 then
9dfe12ae 2385 -- An unconstrained derived type may have inherited discriminant
2386 -- Build an actual discriminant constraint list using the stored
ee6ba406 2387 -- constraint, to verify that the expression of the parent type
2388 -- satisfies the constraints imposed by the (unconstrained!)
2389 -- derived type. This applies to value conversions, not to view
2390 -- conversions of tagged types.
2391
2392 declare
9dfe12ae 2393 Loc : constant Source_Ptr := Sloc (N);
2394 Cond : Node_Id;
2395 Constraint : Elmt_Id;
2396 Discr_Value : Node_Id;
2397 Discr : Entity_Id;
2398
2399 New_Constraints : constant Elist_Id := New_Elmt_List;
2400 Old_Constraints : constant Elist_Id :=
2401 Discriminant_Constraint (Expr_Type);
ee6ba406 2402
2403 begin
9dfe12ae 2404 Constraint := First_Elmt (Stored_Constraint (Target_Type));
ee6ba406 2405 while Present (Constraint) loop
2406 Discr_Value := Node (Constraint);
2407
2408 if Is_Entity_Name (Discr_Value)
2409 and then Ekind (Entity (Discr_Value)) = E_Discriminant
2410 then
2411 Discr := Corresponding_Discriminant (Entity (Discr_Value));
2412
2413 if Present (Discr)
2414 and then Scope (Discr) = Base_Type (Expr_Type)
2415 then
2416 -- Parent is constrained by new discriminant. Obtain
feff2f05 2417 -- Value of original discriminant in expression. If the
2418 -- new discriminant has been used to constrain more than
2419 -- one of the stored discriminants, this will provide the
2420 -- required consistency check.
ee6ba406 2421
55868293 2422 Append_Elmt
2423 (Make_Selected_Component (Loc,
2424 Prefix =>
9dfe12ae 2425 Duplicate_Subexpr_No_Checks
2426 (Expr, Name_Req => True),
ee6ba406 2427 Selector_Name =>
2428 Make_Identifier (Loc, Chars (Discr))),
55868293 2429 New_Constraints);
ee6ba406 2430
2431 else
2432 -- Discriminant of more remote ancestor ???
2433
2434 return;
2435 end if;
2436
feff2f05 2437 -- Derived type definition has an explicit value for this
2438 -- stored discriminant.
ee6ba406 2439
2440 else
2441 Append_Elmt
9dfe12ae 2442 (Duplicate_Subexpr_No_Checks (Discr_Value),
2443 New_Constraints);
ee6ba406 2444 end if;
2445
2446 Next_Elmt (Constraint);
2447 end loop;
2448
2449 -- Use the unconstrained expression type to retrieve the
2450 -- discriminants of the parent, and apply momentarily the
2451 -- discriminant constraint synthesized above.
2452
2453 Set_Discriminant_Constraint (Expr_Type, New_Constraints);
2454 Cond := Build_Discriminant_Checks (Expr, Expr_Type);
2455 Set_Discriminant_Constraint (Expr_Type, Old_Constraints);
2456
2457 Insert_Action (N,
f15731c4 2458 Make_Raise_Constraint_Error (Loc,
2459 Condition => Cond,
2460 Reason => CE_Discriminant_Check_Failed));
ee6ba406 2461 end;
2462
feff2f05 2463 -- For arrays, conversions are applied during expansion, to take into
2464 -- accounts changes of representation. The checks become range checks on
2465 -- the base type or length checks on the subtype, depending on whether
2466 -- the target type is unconstrained or constrained.
ee6ba406 2467
2468 else
2469 null;
2470 end if;
ee6ba406 2471 end Apply_Type_Conversion_Checks;
2472
2473 ----------------------------------------------
2474 -- Apply_Universal_Integer_Attribute_Checks --
2475 ----------------------------------------------
2476
2477 procedure Apply_Universal_Integer_Attribute_Checks (N : Node_Id) is
2478 Loc : constant Source_Ptr := Sloc (N);
2479 Typ : constant Entity_Id := Etype (N);
2480
2481 begin
2482 if Inside_A_Generic then
2483 return;
2484
2485 -- Nothing to do if checks are suppressed
2486
2487 elsif Range_Checks_Suppressed (Typ)
2488 and then Overflow_Checks_Suppressed (Typ)
2489 then
2490 return;
2491
2492 -- Nothing to do if the attribute does not come from source. The
2493 -- internal attributes we generate of this type do not need checks,
2494 -- and furthermore the attempt to check them causes some circular
2495 -- elaboration orders when dealing with packed types.
2496
2497 elsif not Comes_From_Source (N) then
2498 return;
2499
9dfe12ae 2500 -- If the prefix is a selected component that depends on a discriminant
2501 -- the check may improperly expose a discriminant instead of using
2502 -- the bounds of the object itself. Set the type of the attribute to
2503 -- the base type of the context, so that a check will be imposed when
2504 -- needed (e.g. if the node appears as an index).
2505
2506 elsif Nkind (Prefix (N)) = N_Selected_Component
2507 and then Ekind (Typ) = E_Signed_Integer_Subtype
2508 and then Depends_On_Discriminant (Scalar_Range (Typ))
2509 then
2510 Set_Etype (N, Base_Type (Typ));
2511
feff2f05 2512 -- Otherwise, replace the attribute node with a type conversion node
2513 -- whose expression is the attribute, retyped to universal integer, and
2514 -- whose subtype mark is the target type. The call to analyze this
2515 -- conversion will set range and overflow checks as required for proper
2516 -- detection of an out of range value.
ee6ba406 2517
2518 else
2519 Set_Etype (N, Universal_Integer);
2520 Set_Analyzed (N, True);
2521
2522 Rewrite (N,
2523 Make_Type_Conversion (Loc,
2524 Subtype_Mark => New_Occurrence_Of (Typ, Loc),
2525 Expression => Relocate_Node (N)));
2526
2527 Analyze_And_Resolve (N, Typ);
2528 return;
2529 end if;
ee6ba406 2530 end Apply_Universal_Integer_Attribute_Checks;
2531
2532 -------------------------------
2533 -- Build_Discriminant_Checks --
2534 -------------------------------
2535
2536 function Build_Discriminant_Checks
2537 (N : Node_Id;
314a23b6 2538 T_Typ : Entity_Id) return Node_Id
ee6ba406 2539 is
2540 Loc : constant Source_Ptr := Sloc (N);
2541 Cond : Node_Id;
2542 Disc : Elmt_Id;
2543 Disc_Ent : Entity_Id;
9dfe12ae 2544 Dref : Node_Id;
ee6ba406 2545 Dval : Node_Id;
2546
84d0d4a5 2547 function Aggregate_Discriminant_Val (Disc : Entity_Id) return Node_Id;
2548
2549 ----------------------------------
2550 -- Aggregate_Discriminant_Value --
2551 ----------------------------------
2552
2553 function Aggregate_Discriminant_Val (Disc : Entity_Id) return Node_Id is
2554 Assoc : Node_Id;
2555
2556 begin
feff2f05 2557 -- The aggregate has been normalized with named associations. We use
2558 -- the Chars field to locate the discriminant to take into account
2559 -- discriminants in derived types, which carry the same name as those
2560 -- in the parent.
84d0d4a5 2561
2562 Assoc := First (Component_Associations (N));
2563 while Present (Assoc) loop
2564 if Chars (First (Choices (Assoc))) = Chars (Disc) then
2565 return Expression (Assoc);
2566 else
2567 Next (Assoc);
2568 end if;
2569 end loop;
2570
2571 -- Discriminant must have been found in the loop above
2572
2573 raise Program_Error;
2574 end Aggregate_Discriminant_Val;
2575
2576 -- Start of processing for Build_Discriminant_Checks
2577
ee6ba406 2578 begin
84d0d4a5 2579 -- Loop through discriminants evolving the condition
2580
ee6ba406 2581 Cond := Empty;
2582 Disc := First_Elmt (Discriminant_Constraint (T_Typ));
2583
9dfe12ae 2584 -- For a fully private type, use the discriminants of the parent type
ee6ba406 2585
2586 if Is_Private_Type (T_Typ)
2587 and then No (Full_View (T_Typ))
2588 then
2589 Disc_Ent := First_Discriminant (Etype (Base_Type (T_Typ)));
2590 else
2591 Disc_Ent := First_Discriminant (T_Typ);
2592 end if;
2593
2594 while Present (Disc) loop
ee6ba406 2595 Dval := Node (Disc);
2596
2597 if Nkind (Dval) = N_Identifier
2598 and then Ekind (Entity (Dval)) = E_Discriminant
2599 then
2600 Dval := New_Occurrence_Of (Discriminal (Entity (Dval)), Loc);
2601 else
9dfe12ae 2602 Dval := Duplicate_Subexpr_No_Checks (Dval);
ee6ba406 2603 end if;
2604
00f91aef 2605 -- If we have an Unchecked_Union node, we can infer the discriminants
2606 -- of the node.
9dfe12ae 2607
00f91aef 2608 if Is_Unchecked_Union (Base_Type (T_Typ)) then
2609 Dref := New_Copy (
2610 Get_Discriminant_Value (
2611 First_Discriminant (T_Typ),
2612 T_Typ,
2613 Stored_Constraint (T_Typ)));
2614
84d0d4a5 2615 elsif Nkind (N) = N_Aggregate then
2616 Dref :=
2617 Duplicate_Subexpr_No_Checks
2618 (Aggregate_Discriminant_Val (Disc_Ent));
2619
00f91aef 2620 else
2621 Dref :=
2622 Make_Selected_Component (Loc,
2623 Prefix =>
2624 Duplicate_Subexpr_No_Checks (N, Name_Req => True),
2625 Selector_Name =>
2626 Make_Identifier (Loc, Chars (Disc_Ent)));
2627
2628 Set_Is_In_Discriminant_Check (Dref);
2629 end if;
9dfe12ae 2630
ee6ba406 2631 Evolve_Or_Else (Cond,
2632 Make_Op_Ne (Loc,
9dfe12ae 2633 Left_Opnd => Dref,
ee6ba406 2634 Right_Opnd => Dval));
2635
2636 Next_Elmt (Disc);
2637 Next_Discriminant (Disc_Ent);
2638 end loop;
2639
2640 return Cond;
2641 end Build_Discriminant_Checks;
2642
13dbf220 2643 ------------------
2644 -- Check_Needed --
2645 ------------------
2646
2647 function Check_Needed (Nod : Node_Id; Check : Check_Type) return Boolean is
2648 N : Node_Id;
2649 P : Node_Id;
2650 K : Node_Kind;
2651 L : Node_Id;
2652 R : Node_Id;
2653
2654 begin
2655 -- Always check if not simple entity
2656
2657 if Nkind (Nod) not in N_Has_Entity
2658 or else not Comes_From_Source (Nod)
2659 then
2660 return True;
2661 end if;
2662
2663 -- Look up tree for short circuit
2664
2665 N := Nod;
2666 loop
2667 P := Parent (N);
2668 K := Nkind (P);
2669
7b17e51b 2670 -- Done if out of subexpression (note that we allow generated stuff
2671 -- such as itype declarations in this context, to keep the loop going
2672 -- since we may well have generated such stuff in complex situations.
2673 -- Also done if no parent (probably an error condition, but no point
2674 -- in behaving nasty if we find it!)
2675
2676 if No (P)
2677 or else (K not in N_Subexpr and then Comes_From_Source (P))
2678 then
13dbf220 2679 return True;
2680
7b17e51b 2681 -- Or/Or Else case, where test is part of the right operand, or is
2682 -- part of one of the actions associated with the right operand, and
2683 -- the left operand is an equality test.
13dbf220 2684
7b17e51b 2685 elsif K = N_Op_Or then
13dbf220 2686 exit when N = Right_Opnd (P)
2687 and then Nkind (Left_Opnd (P)) = N_Op_Eq;
2688
7b17e51b 2689 elsif K = N_Or_Else then
2690 exit when (N = Right_Opnd (P)
2691 or else
2692 (Is_List_Member (N)
2693 and then List_Containing (N) = Actions (P)))
2694 and then Nkind (Left_Opnd (P)) = N_Op_Eq;
13dbf220 2695
7b17e51b 2696 -- Similar test for the And/And then case, where the left operand
2697 -- is an inequality test.
2698
2699 elsif K = N_Op_And then
13dbf220 2700 exit when N = Right_Opnd (P)
38f5559f 2701 and then Nkind (Left_Opnd (P)) = N_Op_Ne;
7b17e51b 2702
2703 elsif K = N_And_Then then
2704 exit when (N = Right_Opnd (P)
2705 or else
2706 (Is_List_Member (N)
2707 and then List_Containing (N) = Actions (P)))
2708 and then Nkind (Left_Opnd (P)) = N_Op_Ne;
13dbf220 2709 end if;
2710
2711 N := P;
2712 end loop;
2713
2714 -- If we fall through the loop, then we have a conditional with an
2715 -- appropriate test as its left operand. So test further.
2716
2717 L := Left_Opnd (P);
13dbf220 2718 R := Right_Opnd (L);
2719 L := Left_Opnd (L);
2720
2721 -- Left operand of test must match original variable
2722
2723 if Nkind (L) not in N_Has_Entity
2724 or else Entity (L) /= Entity (Nod)
2725 then
2726 return True;
2727 end if;
2728
2af58f67 2729 -- Right operand of test must be key value (zero or null)
13dbf220 2730
2731 case Check is
2732 when Access_Check =>
2af58f67 2733 if not Known_Null (R) then
13dbf220 2734 return True;
2735 end if;
2736
2737 when Division_Check =>
2738 if not Compile_Time_Known_Value (R)
2739 or else Expr_Value (R) /= Uint_0
2740 then
2741 return True;
2742 end if;
2af58f67 2743
2744 when others =>
2745 raise Program_Error;
13dbf220 2746 end case;
2747
2748 -- Here we have the optimizable case, warn if not short-circuited
2749
2750 if K = N_Op_And or else K = N_Op_Or then
2751 case Check is
2752 when Access_Check =>
2753 Error_Msg_N
2754 ("Constraint_Error may be raised (access check)?",
2755 Parent (Nod));
2756 when Division_Check =>
2757 Error_Msg_N
2758 ("Constraint_Error may be raised (zero divide)?",
2759 Parent (Nod));
2af58f67 2760
2761 when others =>
2762 raise Program_Error;
13dbf220 2763 end case;
2764
2765 if K = N_Op_And then
e977c0cf 2766 Error_Msg_N -- CODEFIX
2767 ("use `AND THEN` instead of AND?", P);
13dbf220 2768 else
e977c0cf 2769 Error_Msg_N -- CODEFIX
2770 ("use `OR ELSE` instead of OR?", P);
13dbf220 2771 end if;
2772
2773 -- If not short-circuited, we need the ckeck
2774
2775 return True;
2776
2777 -- If short-circuited, we can omit the check
2778
2779 else
2780 return False;
2781 end if;
2782 end Check_Needed;
2783
ee6ba406 2784 -----------------------------------
2785 -- Check_Valid_Lvalue_Subscripts --
2786 -----------------------------------
2787
2788 procedure Check_Valid_Lvalue_Subscripts (Expr : Node_Id) is
2789 begin
2790 -- Skip this if range checks are suppressed
2791
2792 if Range_Checks_Suppressed (Etype (Expr)) then
2793 return;
2794
feff2f05 2795 -- Only do this check for expressions that come from source. We assume
2796 -- that expander generated assignments explicitly include any necessary
2797 -- checks. Note that this is not just an optimization, it avoids
2798 -- infinite recursions!
ee6ba406 2799
2800 elsif not Comes_From_Source (Expr) then
2801 return;
2802
2803 -- For a selected component, check the prefix
2804
2805 elsif Nkind (Expr) = N_Selected_Component then
2806 Check_Valid_Lvalue_Subscripts (Prefix (Expr));
2807 return;
2808
2809 -- Case of indexed component
2810
2811 elsif Nkind (Expr) = N_Indexed_Component then
2812 Apply_Subscript_Validity_Checks (Expr);
2813
feff2f05 2814 -- Prefix may itself be or contain an indexed component, and these
2815 -- subscripts need checking as well.
ee6ba406 2816
2817 Check_Valid_Lvalue_Subscripts (Prefix (Expr));
2818 end if;
2819 end Check_Valid_Lvalue_Subscripts;
2820
fa7497e8 2821 ----------------------------------
2822 -- Null_Exclusion_Static_Checks --
2823 ----------------------------------
2824
2825 procedure Null_Exclusion_Static_Checks (N : Node_Id) is
0577b0b1 2826 Error_Node : Node_Id;
2827 Expr : Node_Id;
2828 Has_Null : constant Boolean := Has_Null_Exclusion (N);
2829 K : constant Node_Kind := Nkind (N);
2830 Typ : Entity_Id;
fa7497e8 2831
13dbf220 2832 begin
0577b0b1 2833 pragma Assert
2834 (K = N_Component_Declaration
2835 or else K = N_Discriminant_Specification
2836 or else K = N_Function_Specification
2837 or else K = N_Object_Declaration
2838 or else K = N_Parameter_Specification);
2839
2840 if K = N_Function_Specification then
2841 Typ := Etype (Defining_Entity (N));
2842 else
2843 Typ := Etype (Defining_Identifier (N));
2844 end if;
fa7497e8 2845
13dbf220 2846 case K is
13dbf220 2847 when N_Component_Declaration =>
2848 if Present (Access_Definition (Component_Definition (N))) then
0577b0b1 2849 Error_Node := Component_Definition (N);
13dbf220 2850 else
0577b0b1 2851 Error_Node := Subtype_Indication (Component_Definition (N));
13dbf220 2852 end if;
5329ca64 2853
0577b0b1 2854 when N_Discriminant_Specification =>
2855 Error_Node := Discriminant_Type (N);
2856
2857 when N_Function_Specification =>
2858 Error_Node := Result_Definition (N);
2859
2860 when N_Object_Declaration =>
2861 Error_Node := Object_Definition (N);
2862
2863 when N_Parameter_Specification =>
2864 Error_Node := Parameter_Type (N);
2865
13dbf220 2866 when others =>
2867 raise Program_Error;
2868 end case;
5329ca64 2869
0577b0b1 2870 if Has_Null then
5329ca64 2871
0577b0b1 2872 -- Enforce legality rule 3.10 (13): A null exclusion can only be
2873 -- applied to an access [sub]type.
5329ca64 2874
0577b0b1 2875 if not Is_Access_Type (Typ) then
503f7fd3 2876 Error_Msg_N
00c403ee 2877 ("`NOT NULL` allowed only for an access type", Error_Node);
5329ca64 2878
feff2f05 2879 -- Enforce legality rule RM 3.10(14/1): A null exclusion can only
0577b0b1 2880 -- be applied to a [sub]type that does not exclude null already.
2881
2882 elsif Can_Never_Be_Null (Typ)
d16989f1 2883 and then Comes_From_Source (Typ)
0577b0b1 2884 then
503f7fd3 2885 Error_Msg_NE
00c403ee 2886 ("`NOT NULL` not allowed (& already excludes null)",
2887 Error_Node, Typ);
0577b0b1 2888 end if;
13dbf220 2889 end if;
5329ca64 2890
cc60bd16 2891 -- Check that null-excluding objects are always initialized, except for
2892 -- deferred constants, for which the expression will appear in the full
2893 -- declaration.
13dbf220 2894
2895 if K = N_Object_Declaration
84d0d4a5 2896 and then No (Expression (N))
cc60bd16 2897 and then not Constant_Present (N)
feff2f05 2898 and then not No_Initialization (N)
13dbf220 2899 then
feff2f05 2900 -- Add an expression that assigns null. This node is needed by
2901 -- Apply_Compile_Time_Constraint_Error, which will replace this with
2902 -- a Constraint_Error node.
13dbf220 2903
2904 Set_Expression (N, Make_Null (Sloc (N)));
2905 Set_Etype (Expression (N), Etype (Defining_Identifier (N)));
5329ca64 2906
13dbf220 2907 Apply_Compile_Time_Constraint_Error
2908 (N => Expression (N),
2909 Msg => "(Ada 2005) null-excluding objects must be initialized?",
2910 Reason => CE_Null_Not_Allowed);
2911 end if;
5329ca64 2912
cc60bd16 2913 -- Check that a null-excluding component, formal or object is not being
2914 -- assigned a null value. Otherwise generate a warning message and
2c145f84 2915 -- replace Expression (N) by an N_Constraint_Error node.
13dbf220 2916
0577b0b1 2917 if K /= N_Function_Specification then
2918 Expr := Expression (N);
5329ca64 2919
2af58f67 2920 if Present (Expr) and then Known_Null (Expr) then
13dbf220 2921 case K is
0577b0b1 2922 when N_Component_Declaration |
2923 N_Discriminant_Specification =>
7189d17f 2924 Apply_Compile_Time_Constraint_Error
0577b0b1 2925 (N => Expr,
2af58f67 2926 Msg => "(Ada 2005) null not allowed " &
0577b0b1 2927 "in null-excluding components?",
2928 Reason => CE_Null_Not_Allowed);
5329ca64 2929
0577b0b1 2930 when N_Object_Declaration =>
7189d17f 2931 Apply_Compile_Time_Constraint_Error
0577b0b1 2932 (N => Expr,
2af58f67 2933 Msg => "(Ada 2005) null not allowed " &
0577b0b1 2934 "in null-excluding objects?",
2935 Reason => CE_Null_Not_Allowed);
5329ca64 2936
0577b0b1 2937 when N_Parameter_Specification =>
7189d17f 2938 Apply_Compile_Time_Constraint_Error
0577b0b1 2939 (N => Expr,
2af58f67 2940 Msg => "(Ada 2005) null not allowed " &
0577b0b1 2941 "in null-excluding formals?",
2942 Reason => CE_Null_Not_Allowed);
13dbf220 2943
2944 when others =>
2945 null;
5329ca64 2946 end case;
2947 end if;
0577b0b1 2948 end if;
fa7497e8 2949 end Null_Exclusion_Static_Checks;
2950
9dfe12ae 2951 ----------------------------------
2952 -- Conditional_Statements_Begin --
2953 ----------------------------------
2954
2955 procedure Conditional_Statements_Begin is
2956 begin
2957 Saved_Checks_TOS := Saved_Checks_TOS + 1;
2958
feff2f05 2959 -- If stack overflows, kill all checks, that way we know to simply reset
2960 -- the number of saved checks to zero on return. This should never occur
2961 -- in practice.
9dfe12ae 2962
2963 if Saved_Checks_TOS > Saved_Checks_Stack'Last then
2964 Kill_All_Checks;
2965
feff2f05 2966 -- In the normal case, we just make a new stack entry saving the current
2967 -- number of saved checks for a later restore.
9dfe12ae 2968
2969 else
2970 Saved_Checks_Stack (Saved_Checks_TOS) := Num_Saved_Checks;
2971
2972 if Debug_Flag_CC then
2973 w ("Conditional_Statements_Begin: Num_Saved_Checks = ",
2974 Num_Saved_Checks);
2975 end if;
2976 end if;
2977 end Conditional_Statements_Begin;
2978
2979 --------------------------------
2980 -- Conditional_Statements_End --
2981 --------------------------------
2982
2983 procedure Conditional_Statements_End is
2984 begin
2985 pragma Assert (Saved_Checks_TOS > 0);
2986
feff2f05 2987 -- If the saved checks stack overflowed, then we killed all checks, so
2988 -- setting the number of saved checks back to zero is correct. This
2989 -- should never occur in practice.
9dfe12ae 2990
2991 if Saved_Checks_TOS > Saved_Checks_Stack'Last then
2992 Num_Saved_Checks := 0;
2993
feff2f05 2994 -- In the normal case, restore the number of saved checks from the top
2995 -- stack entry.
9dfe12ae 2996
2997 else
2998 Num_Saved_Checks := Saved_Checks_Stack (Saved_Checks_TOS);
2999 if Debug_Flag_CC then
3000 w ("Conditional_Statements_End: Num_Saved_Checks = ",
3001 Num_Saved_Checks);
3002 end if;
3003 end if;
3004
3005 Saved_Checks_TOS := Saved_Checks_TOS - 1;
3006 end Conditional_Statements_End;
3007
ee6ba406 3008 ---------------------
3009 -- Determine_Range --
3010 ---------------------
3011
6af1bdbc 3012 Cache_Size : constant := 2 ** 10;
ee6ba406 3013 type Cache_Index is range 0 .. Cache_Size - 1;
3014 -- Determine size of below cache (power of 2 is more efficient!)
3015
3016 Determine_Range_Cache_N : array (Cache_Index) of Node_Id;
9c486805 3017 Determine_Range_Cache_V : array (Cache_Index) of Boolean;
ee6ba406 3018 Determine_Range_Cache_Lo : array (Cache_Index) of Uint;
3019 Determine_Range_Cache_Hi : array (Cache_Index) of Uint;
feff2f05 3020 -- The above arrays are used to implement a small direct cache for
3021 -- Determine_Range calls. Because of the way Determine_Range recursively
3022 -- traces subexpressions, and because overflow checking calls the routine
3023 -- on the way up the tree, a quadratic behavior can otherwise be
3024 -- encountered in large expressions. The cache entry for node N is stored
3025 -- in the (N mod Cache_Size) entry, and can be validated by checking the
9c486805 3026 -- actual node value stored there. The Range_Cache_V array records the
3027 -- setting of Assume_Valid for the cache entry.
ee6ba406 3028
3029 procedure Determine_Range
9c486805 3030 (N : Node_Id;
3031 OK : out Boolean;
3032 Lo : out Uint;
3033 Hi : out Uint;
3034 Assume_Valid : Boolean := False)
ee6ba406 3035 is
e254d721 3036 Typ : Entity_Id := Etype (N);
3037 -- Type to use, may get reset to base type for possibly invalid entity
8880be85 3038
3039 Lo_Left : Uint;
3040 Hi_Left : Uint;
3041 -- Lo and Hi bounds of left operand
ee6ba406 3042
ee6ba406 3043 Lo_Right : Uint;
ee6ba406 3044 Hi_Right : Uint;
8880be85 3045 -- Lo and Hi bounds of right (or only) operand
3046
3047 Bound : Node_Id;
3048 -- Temp variable used to hold a bound node
3049
3050 Hbound : Uint;
3051 -- High bound of base type of expression
3052
3053 Lor : Uint;
3054 Hir : Uint;
3055 -- Refined values for low and high bounds, after tightening
3056
3057 OK1 : Boolean;
3058 -- Used in lower level calls to indicate if call succeeded
3059
3060 Cindex : Cache_Index;
3061 -- Used to search cache
ee6ba406 3062
3063 function OK_Operands return Boolean;
3064 -- Used for binary operators. Determines the ranges of the left and
3065 -- right operands, and if they are both OK, returns True, and puts
341bd953 3066 -- the results in Lo_Right, Hi_Right, Lo_Left, Hi_Left.
ee6ba406 3067
3068 -----------------
3069 -- OK_Operands --
3070 -----------------
3071
3072 function OK_Operands return Boolean is
3073 begin
9c486805 3074 Determine_Range
3075 (Left_Opnd (N), OK1, Lo_Left, Hi_Left, Assume_Valid);
ee6ba406 3076
3077 if not OK1 then
3078 return False;
3079 end if;
3080
9c486805 3081 Determine_Range
3082 (Right_Opnd (N), OK1, Lo_Right, Hi_Right, Assume_Valid);
ee6ba406 3083 return OK1;
3084 end OK_Operands;
3085
3086 -- Start of processing for Determine_Range
3087
3088 begin
3089 -- Prevent junk warnings by initializing range variables
3090
3091 Lo := No_Uint;
3092 Hi := No_Uint;
3093 Lor := No_Uint;
3094 Hir := No_Uint;
3095
a781c0fc 3096 -- If type is not defined, we can't determine its range
ee6ba406 3097
a781c0fc 3098 if No (Typ)
3099
3100 -- We don't deal with anything except discrete types
3101
3102 or else not Is_Discrete_Type (Typ)
3103
3104 -- Ignore type for which an error has been posted, since range in
3105 -- this case may well be a bogosity deriving from the error. Also
3106 -- ignore if error posted on the reference node.
3107
3108 or else Error_Posted (N) or else Error_Posted (Typ)
ee6ba406 3109 then
3110 OK := False;
3111 return;
3112 end if;
3113
3114 -- For all other cases, we can determine the range
3115
3116 OK := True;
3117
feff2f05 3118 -- If value is compile time known, then the possible range is the one
3119 -- value that we know this expression definitely has!
ee6ba406 3120
3121 if Compile_Time_Known_Value (N) then
3122 Lo := Expr_Value (N);
3123 Hi := Lo;
3124 return;
3125 end if;
3126
3127 -- Return if already in the cache
3128
3129 Cindex := Cache_Index (N mod Cache_Size);
3130
9c486805 3131 if Determine_Range_Cache_N (Cindex) = N
3132 and then
3133 Determine_Range_Cache_V (Cindex) = Assume_Valid
3134 then
ee6ba406 3135 Lo := Determine_Range_Cache_Lo (Cindex);
3136 Hi := Determine_Range_Cache_Hi (Cindex);
3137 return;
3138 end if;
3139
feff2f05 3140 -- Otherwise, start by finding the bounds of the type of the expression,
3141 -- the value cannot be outside this range (if it is, then we have an
3142 -- overflow situation, which is a separate check, we are talking here
3143 -- only about the expression value).
ee6ba406 3144
341bd953 3145 -- First a check, never try to find the bounds of a generic type, since
3146 -- these bounds are always junk values, and it is only valid to look at
3147 -- the bounds in an instance.
3148
3149 if Is_Generic_Type (Typ) then
3150 OK := False;
3151 return;
3152 end if;
3153
9c486805 3154 -- First step, change to use base type unless we know the value is valid
e254d721 3155
9c486805 3156 if (Is_Entity_Name (N) and then Is_Known_Valid (Entity (N)))
3157 or else Assume_No_Invalid_Values
3158 or else Assume_Valid
e254d721 3159 then
9c486805 3160 null;
3161 else
3162 Typ := Underlying_Type (Base_Type (Typ));
e254d721 3163 end if;
3164
feff2f05 3165 -- We use the actual bound unless it is dynamic, in which case use the
3166 -- corresponding base type bound if possible. If we can't get a bound
3167 -- then we figure we can't determine the range (a peculiar case, that
3168 -- perhaps cannot happen, but there is no point in bombing in this
3169 -- optimization circuit.
8880be85 3170
3171 -- First the low bound
ee6ba406 3172
3173 Bound := Type_Low_Bound (Typ);
3174
3175 if Compile_Time_Known_Value (Bound) then
3176 Lo := Expr_Value (Bound);
3177
3178 elsif Compile_Time_Known_Value (Type_Low_Bound (Base_Type (Typ))) then
3179 Lo := Expr_Value (Type_Low_Bound (Base_Type (Typ)));
3180
3181 else
3182 OK := False;
3183 return;
3184 end if;
3185
8880be85 3186 -- Now the high bound
3187
ee6ba406 3188 Bound := Type_High_Bound (Typ);
3189
8880be85 3190 -- We need the high bound of the base type later on, and this should
3191 -- always be compile time known. Again, it is not clear that this
3192 -- can ever be false, but no point in bombing.
ee6ba406 3193
8880be85 3194 if Compile_Time_Known_Value (Type_High_Bound (Base_Type (Typ))) then
ee6ba406 3195 Hbound := Expr_Value (Type_High_Bound (Base_Type (Typ)));
3196 Hi := Hbound;
3197
3198 else
3199 OK := False;
3200 return;
3201 end if;
3202
feff2f05 3203 -- If we have a static subtype, then that may have a tighter bound so
3204 -- use the upper bound of the subtype instead in this case.
8880be85 3205
3206 if Compile_Time_Known_Value (Bound) then
3207 Hi := Expr_Value (Bound);
3208 end if;
3209
feff2f05 3210 -- We may be able to refine this value in certain situations. If any
3211 -- refinement is possible, then Lor and Hir are set to possibly tighter
3212 -- bounds, and OK1 is set to True.
ee6ba406 3213
3214 case Nkind (N) is
3215
3216 -- For unary plus, result is limited by range of operand
3217
3218 when N_Op_Plus =>
9c486805 3219 Determine_Range
3220 (Right_Opnd (N), OK1, Lor, Hir, Assume_Valid);
ee6ba406 3221
3222 -- For unary minus, determine range of operand, and negate it
3223
3224 when N_Op_Minus =>
9c486805 3225 Determine_Range
3226 (Right_Opnd (N), OK1, Lo_Right, Hi_Right, Assume_Valid);
ee6ba406 3227
3228 if OK1 then
3229 Lor := -Hi_Right;
3230 Hir := -Lo_Right;
3231 end if;
3232
3233 -- For binary addition, get range of each operand and do the
3234 -- addition to get the result range.
3235
3236 when N_Op_Add =>
3237 if OK_Operands then
3238 Lor := Lo_Left + Lo_Right;
3239 Hir := Hi_Left + Hi_Right;
3240 end if;
3241
feff2f05 3242 -- Division is tricky. The only case we consider is where the right
3243 -- operand is a positive constant, and in this case we simply divide
3244 -- the bounds of the left operand
ee6ba406 3245
3246 when N_Op_Divide =>
3247 if OK_Operands then
3248 if Lo_Right = Hi_Right
3249 and then Lo_Right > 0
3250 then
3251 Lor := Lo_Left / Lo_Right;
3252 Hir := Hi_Left / Lo_Right;
3253
3254 else
3255 OK1 := False;
3256 end if;
3257 end if;
3258
feff2f05 3259 -- For binary subtraction, get range of each operand and do the worst
3260 -- case subtraction to get the result range.
ee6ba406 3261
3262 when N_Op_Subtract =>
3263 if OK_Operands then
3264 Lor := Lo_Left - Hi_Right;
3265 Hir := Hi_Left - Lo_Right;
3266 end if;
3267
feff2f05 3268 -- For MOD, if right operand is a positive constant, then result must
3269 -- be in the allowable range of mod results.
ee6ba406 3270
3271 when N_Op_Mod =>
3272 if OK_Operands then
9dfe12ae 3273 if Lo_Right = Hi_Right
3274 and then Lo_Right /= 0
3275 then
ee6ba406 3276 if Lo_Right > 0 then
3277 Lor := Uint_0;
3278 Hir := Lo_Right - 1;
3279
9dfe12ae 3280 else -- Lo_Right < 0
ee6ba406 3281 Lor := Lo_Right + 1;
3282 Hir := Uint_0;
3283 end if;
3284
3285 else
3286 OK1 := False;
3287 end if;
3288 end if;
3289
feff2f05 3290 -- For REM, if right operand is a positive constant, then result must
3291 -- be in the allowable range of mod results.
ee6ba406 3292
3293 when N_Op_Rem =>
3294 if OK_Operands then
9dfe12ae 3295 if Lo_Right = Hi_Right
3296 and then Lo_Right /= 0
3297 then
ee6ba406 3298 declare
3299 Dval : constant Uint := (abs Lo_Right) - 1;
3300
3301 begin
3302 -- The sign of the result depends on the sign of the
3303 -- dividend (but not on the sign of the divisor, hence
3304 -- the abs operation above).
3305
3306 if Lo_Left < 0 then
3307 Lor := -Dval;
3308 else
3309 Lor := Uint_0;
3310 end if;
3311
3312 if Hi_Left < 0 then
3313 Hir := Uint_0;
3314 else
3315 Hir := Dval;
3316 end if;
3317 end;
3318
3319 else
3320 OK1 := False;
3321 end if;
3322 end if;
3323
3324 -- Attribute reference cases
3325
3326 when N_Attribute_Reference =>
3327 case Attribute_Name (N) is
3328
3329 -- For Pos/Val attributes, we can refine the range using the
ddbf7f2e 3330 -- possible range of values of the attribute expression.
ee6ba406 3331
3332 when Name_Pos | Name_Val =>
9c486805 3333 Determine_Range
3334 (First (Expressions (N)), OK1, Lor, Hir, Assume_Valid);
ee6ba406 3335
3336 -- For Length attribute, use the bounds of the corresponding
3337 -- index type to refine the range.
3338
3339 when Name_Length =>
3340 declare
3341 Atyp : Entity_Id := Etype (Prefix (N));
3342 Inum : Nat;
3343 Indx : Node_Id;
3344
3345 LL, LU : Uint;
3346 UL, UU : Uint;
3347
3348 begin
3349 if Is_Access_Type (Atyp) then
3350 Atyp := Designated_Type (Atyp);
3351 end if;
3352
3353 -- For string literal, we know exact value
3354
3355 if Ekind (Atyp) = E_String_Literal_Subtype then
3356 OK := True;
3357 Lo := String_Literal_Length (Atyp);
3358 Hi := String_Literal_Length (Atyp);
3359 return;
3360 end if;
3361
3362 -- Otherwise check for expression given
3363
3364 if No (Expressions (N)) then
3365 Inum := 1;
3366 else
3367 Inum :=
3368 UI_To_Int (Expr_Value (First (Expressions (N))));
3369 end if;
3370
3371 Indx := First_Index (Atyp);
3372 for J in 2 .. Inum loop
3373 Indx := Next_Index (Indx);
3374 end loop;
3375
9116df93 3376 -- If the index type is a formal type or derived from
c8da6114 3377 -- one, the bounds are not static.
3378
3379 if Is_Generic_Type (Root_Type (Etype (Indx))) then
3380 OK := False;
3381 return;
3382 end if;
3383
ee6ba406 3384 Determine_Range
9c486805 3385 (Type_Low_Bound (Etype (Indx)), OK1, LL, LU,
3386 Assume_Valid);
ee6ba406 3387
3388 if OK1 then
3389 Determine_Range
9c486805 3390 (Type_High_Bound (Etype (Indx)), OK1, UL, UU,
3391 Assume_Valid);
ee6ba406 3392
3393 if OK1 then
3394
3395 -- The maximum value for Length is the biggest
3396 -- possible gap between the values of the bounds.
3397 -- But of course, this value cannot be negative.
3398
9c486805 3399 Hir := UI_Max (Uint_0, UU - LL + 1);
ee6ba406 3400
3401 -- For constrained arrays, the minimum value for
3402 -- Length is taken from the actual value of the
9116df93 3403 -- bounds, since the index will be exactly of this
3404 -- subtype.
ee6ba406 3405
3406 if Is_Constrained (Atyp) then
9c486805 3407 Lor := UI_Max (Uint_0, UL - LU + 1);
ee6ba406 3408
3409 -- For an unconstrained array, the minimum value
3410 -- for length is always zero.
3411
3412 else
3413 Lor := Uint_0;
3414 end if;
3415 end if;
3416 end if;
3417 end;
3418
3419 -- No special handling for other attributes
9116df93 3420 -- Probably more opportunities exist here???
ee6ba406 3421
3422 when others =>
3423 OK1 := False;
3424
3425 end case;
3426
feff2f05 3427 -- For type conversion from one discrete type to another, we can
3428 -- refine the range using the converted value.
ee6ba406 3429
3430 when N_Type_Conversion =>
9c486805 3431 Determine_Range (Expression (N), OK1, Lor, Hir, Assume_Valid);
ee6ba406 3432
3433 -- Nothing special to do for all other expression kinds
3434
3435 when others =>
3436 OK1 := False;
3437 Lor := No_Uint;
3438 Hir := No_Uint;
3439 end case;
3440
9116df93 3441 -- At this stage, if OK1 is true, then we know that the actual result of
3442 -- the computed expression is in the range Lor .. Hir. We can use this
3443 -- to restrict the possible range of results.
ee6ba406 3444
3445 if OK1 then
3446
9116df93 3447 -- If the refined value of the low bound is greater than the type
3448 -- high bound, then reset it to the more restrictive value. However,
3449 -- we do NOT do this for the case of a modular type where the
3450 -- possible upper bound on the value is above the base type high
3451 -- bound, because that means the result could wrap.
ee6ba406 3452
3453 if Lor > Lo
9116df93 3454 and then not (Is_Modular_Integer_Type (Typ) and then Hir > Hbound)
ee6ba406 3455 then
3456 Lo := Lor;
3457 end if;
3458
9116df93 3459 -- Similarly, if the refined value of the high bound is less than the
3460 -- value so far, then reset it to the more restrictive value. Again,
3461 -- we do not do this if the refined low bound is negative for a
3462 -- modular type, since this would wrap.
ee6ba406 3463
3464 if Hir < Hi
9116df93 3465 and then not (Is_Modular_Integer_Type (Typ) and then Lor < Uint_0)
ee6ba406 3466 then
3467 Hi := Hir;
3468 end if;
3469 end if;
3470
3471 -- Set cache entry for future call and we are all done
3472
3473 Determine_Range_Cache_N (Cindex) := N;
9c486805 3474 Determine_Range_Cache_V (Cindex) := Assume_Valid;
ee6ba406 3475 Determine_Range_Cache_Lo (Cindex) := Lo;
3476 Determine_Range_Cache_Hi (Cindex) := Hi;
3477 return;
3478
9116df93 3479 -- If any exception occurs, it means that we have some bug in the compiler,
3480 -- possibly triggered by a previous error, or by some unforeseen peculiar
ee6ba406 3481 -- occurrence. However, this is only an optimization attempt, so there is
3482 -- really no point in crashing the compiler. Instead we just decide, too
3483 -- bad, we can't figure out a range in this case after all.
3484
3485 exception
3486 when others =>
3487
3488 -- Debug flag K disables this behavior (useful for debugging)
3489
3490 if Debug_Flag_K then
3491 raise;
3492 else
3493 OK := False;
3494 Lo := No_Uint;
3495 Hi := No_Uint;
3496 return;
3497 end if;
ee6ba406 3498 end Determine_Range;
3499
3500 ------------------------------------
3501 -- Discriminant_Checks_Suppressed --
3502 ------------------------------------
3503
3504 function Discriminant_Checks_Suppressed (E : Entity_Id) return Boolean is
3505 begin
9dfe12ae 3506 if Present (E) then
3507 if Is_Unchecked_Union (E) then
3508 return True;
3509 elsif Checks_May_Be_Suppressed (E) then
3510 return Is_Check_Suppressed (E, Discriminant_Check);
3511 end if;
3512 end if;
3513
3514 return Scope_Suppress (Discriminant_Check);
ee6ba406 3515 end Discriminant_Checks_Suppressed;
3516
3517 --------------------------------
3518 -- Division_Checks_Suppressed --
3519 --------------------------------
3520
3521 function Division_Checks_Suppressed (E : Entity_Id) return Boolean is
3522 begin
9dfe12ae 3523 if Present (E) and then Checks_May_Be_Suppressed (E) then
3524 return Is_Check_Suppressed (E, Division_Check);
3525 else
3526 return Scope_Suppress (Division_Check);
3527 end if;
ee6ba406 3528 end Division_Checks_Suppressed;
3529
3530 -----------------------------------
3531 -- Elaboration_Checks_Suppressed --
3532 -----------------------------------
3533
3534 function Elaboration_Checks_Suppressed (E : Entity_Id) return Boolean is
3535 begin
38f5559f 3536 -- The complication in this routine is that if we are in the dynamic
3537 -- model of elaboration, we also check All_Checks, since All_Checks
3538 -- does not set Elaboration_Check explicitly.
3539
9dfe12ae 3540 if Present (E) then
3541 if Kill_Elaboration_Checks (E) then
3542 return True;
38f5559f 3543
9dfe12ae 3544 elsif Checks_May_Be_Suppressed (E) then
38f5559f 3545 if Is_Check_Suppressed (E, Elaboration_Check) then
3546 return True;
3547 elsif Dynamic_Elaboration_Checks then
3548 return Is_Check_Suppressed (E, All_Checks);
3549 else
3550 return False;
3551 end if;
9dfe12ae 3552 end if;
3553 end if;
3554
38f5559f 3555 if Scope_Suppress (Elaboration_Check) then
3556 return True;
3557 elsif Dynamic_Elaboration_Checks then
3558 return Scope_Suppress (All_Checks);
3559 else
3560 return False;
3561 end if;
ee6ba406 3562 end Elaboration_Checks_Suppressed;
3563
9dfe12ae 3564 ---------------------------
3565 -- Enable_Overflow_Check --
3566 ---------------------------
3567
3568 procedure Enable_Overflow_Check (N : Node_Id) is
3569 Typ : constant Entity_Id := Base_Type (Etype (N));
3570 Chk : Nat;
3571 OK : Boolean;
3572 Ent : Entity_Id;
3573 Ofs : Uint;
3574 Lo : Uint;
3575 Hi : Uint;
ee6ba406 3576
ee6ba406 3577 begin
9dfe12ae 3578 if Debug_Flag_CC then
3579 w ("Enable_Overflow_Check for node ", Int (N));
3580 Write_Str (" Source location = ");
3581 wl (Sloc (N));
00c403ee 3582 pg (Union_Id (N));
ee6ba406 3583 end if;
ee6ba406 3584
75209ec5 3585 -- No check if overflow checks suppressed for type of node
3586
3587 if Present (Etype (N))
3588 and then Overflow_Checks_Suppressed (Etype (N))
3589 then
3590 return;
3591
49260fa5 3592 -- Nothing to do for unsigned integer types, which do not overflow
3593
3594 elsif Is_Modular_Integer_Type (Typ) then
3595 return;
3596
feff2f05 3597 -- Nothing to do if the range of the result is known OK. We skip this
3598 -- for conversions, since the caller already did the check, and in any
3599 -- case the condition for deleting the check for a type conversion is
cc60bd16 3600 -- different.
ee6ba406 3601
75209ec5 3602 elsif Nkind (N) /= N_Type_Conversion then
9c486805 3603 Determine_Range (N, OK, Lo, Hi, Assume_Valid => True);
ee6ba406 3604
cc60bd16 3605 -- Note in the test below that we assume that the range is not OK
3606 -- if a bound of the range is equal to that of the type. That's not
3607 -- quite accurate but we do this for the following reasons:
ee6ba406 3608
9dfe12ae 3609 -- a) The way that Determine_Range works, it will typically report
3610 -- the bounds of the value as being equal to the bounds of the
3611 -- type, because it either can't tell anything more precise, or
3612 -- does not think it is worth the effort to be more precise.
ee6ba406 3613
9dfe12ae 3614 -- b) It is very unusual to have a situation in which this would
3615 -- generate an unnecessary overflow check (an example would be
3616 -- a subtype with a range 0 .. Integer'Last - 1 to which the
cc60bd16 3617 -- literal value one is added).
ee6ba406 3618
9dfe12ae 3619 -- c) The alternative is a lot of special casing in this routine
3620 -- which would partially duplicate Determine_Range processing.
ee6ba406 3621
9dfe12ae 3622 if OK
3623 and then Lo > Expr_Value (Type_Low_Bound (Typ))
3624 and then Hi < Expr_Value (Type_High_Bound (Typ))
3625 then
3626 if Debug_Flag_CC then
3627 w ("No overflow check required");
3628 end if;
3629
3630 return;
3631 end if;
3632 end if;
3633
feff2f05 3634 -- If not in optimizing mode, set flag and we are done. We are also done
3635 -- (and just set the flag) if the type is not a discrete type, since it
3636 -- is not worth the effort to eliminate checks for other than discrete
3637 -- types. In addition, we take this same path if we have stored the
3638 -- maximum number of checks possible already (a very unlikely situation,
3639 -- but we do not want to blow up!)
9dfe12ae 3640
3641 if Optimization_Level = 0
3642 or else not Is_Discrete_Type (Etype (N))
3643 or else Num_Saved_Checks = Saved_Checks'Last
ee6ba406 3644 then
00c403ee 3645 Activate_Overflow_Check (N);
9dfe12ae 3646
3647 if Debug_Flag_CC then
3648 w ("Optimization off");
3649 end if;
3650
ee6ba406 3651 return;
9dfe12ae 3652 end if;
ee6ba406 3653
9dfe12ae 3654 -- Otherwise evaluate and check the expression
3655
3656 Find_Check
3657 (Expr => N,
3658 Check_Type => 'O',
3659 Target_Type => Empty,
3660 Entry_OK => OK,
3661 Check_Num => Chk,
3662 Ent => Ent,
3663 Ofs => Ofs);
3664
3665 if Debug_Flag_CC then
3666 w ("Called Find_Check");
3667 w (" OK = ", OK);
3668
3669 if OK then
3670 w (" Check_Num = ", Chk);
3671 w (" Ent = ", Int (Ent));
3672 Write_Str (" Ofs = ");
3673 pid (Ofs);
3674 end if;
3675 end if;
ee6ba406 3676
9dfe12ae 3677 -- If check is not of form to optimize, then set flag and we are done
3678
3679 if not OK then
00c403ee 3680 Activate_Overflow_Check (N);
ee6ba406 3681 return;
9dfe12ae 3682 end if;
ee6ba406 3683
9dfe12ae 3684 -- If check is already performed, then return without setting flag
3685
3686 if Chk /= 0 then
3687 if Debug_Flag_CC then
3688 w ("Check suppressed!");
3689 end if;
ee6ba406 3690
ee6ba406 3691 return;
9dfe12ae 3692 end if;
ee6ba406 3693
9dfe12ae 3694 -- Here we will make a new entry for the new check
3695
00c403ee 3696 Activate_Overflow_Check (N);
9dfe12ae 3697 Num_Saved_Checks := Num_Saved_Checks + 1;
3698 Saved_Checks (Num_Saved_Checks) :=
3699 (Killed => False,
3700 Entity => Ent,
3701 Offset => Ofs,
3702 Check_Type => 'O',
3703 Target_Type => Empty);
3704
3705 if Debug_Flag_CC then
3706 w ("Make new entry, check number = ", Num_Saved_Checks);
3707 w (" Entity = ", Int (Ent));
3708 Write_Str (" Offset = ");
3709 pid (Ofs);
3710 w (" Check_Type = O");
3711 w (" Target_Type = Empty");
3712 end if;
ee6ba406 3713
feff2f05 3714 -- If we get an exception, then something went wrong, probably because of
3715 -- an error in the structure of the tree due to an incorrect program. Or it
3716 -- may be a bug in the optimization circuit. In either case the safest
3717 -- thing is simply to set the check flag unconditionally.
9dfe12ae 3718
3719 exception
3720 when others =>
00c403ee 3721 Activate_Overflow_Check (N);
9dfe12ae 3722
3723 if Debug_Flag_CC then
3724 w (" exception occurred, overflow flag set");
3725 end if;
3726
3727 return;
3728 end Enable_Overflow_Check;
3729
3730 ------------------------
3731 -- Enable_Range_Check --
3732 ------------------------
3733
3734 procedure Enable_Range_Check (N : Node_Id) is
3735 Chk : Nat;
3736 OK : Boolean;
3737 Ent : Entity_Id;
3738 Ofs : Uint;
3739 Ttyp : Entity_Id;
3740 P : Node_Id;
3741
3742 begin
feff2f05 3743 -- Return if unchecked type conversion with range check killed. In this
3744 -- case we never set the flag (that's what Kill_Range_Check is about!)
9dfe12ae 3745
3746 if Nkind (N) = N_Unchecked_Type_Conversion
3747 and then Kill_Range_Check (N)
ee6ba406 3748 then
3749 return;
9dfe12ae 3750 end if;
ee6ba406 3751
55e8372b 3752 -- Do not set range check flag if parent is assignment statement or
3753 -- object declaration with Suppress_Assignment_Checks flag set
3754
3755 if Nkind_In (Parent (N), N_Assignment_Statement, N_Object_Declaration)
3756 and then Suppress_Assignment_Checks (Parent (N))
3757 then
3758 return;
3759 end if;
3760
0577b0b1 3761 -- Check for various cases where we should suppress the range check
3762
3763 -- No check if range checks suppressed for type of node
3764
3765 if Present (Etype (N))
3766 and then Range_Checks_Suppressed (Etype (N))
3767 then
3768 return;
3769
3770 -- No check if node is an entity name, and range checks are suppressed
3771 -- for this entity, or for the type of this entity.
3772
3773 elsif Is_Entity_Name (N)
3774 and then (Range_Checks_Suppressed (Entity (N))
3775 or else Range_Checks_Suppressed (Etype (Entity (N))))
3776 then
3777 return;
3778
3779 -- No checks if index of array, and index checks are suppressed for
3780 -- the array object or the type of the array.
3781
3782 elsif Nkind (Parent (N)) = N_Indexed_Component then
3783 declare
3784 Pref : constant Node_Id := Prefix (Parent (N));
3785 begin
3786 if Is_Entity_Name (Pref)
3787 and then Index_Checks_Suppressed (Entity (Pref))
3788 then
3789 return;
3790 elsif Index_Checks_Suppressed (Etype (Pref)) then
3791 return;
3792 end if;
3793 end;
3794 end if;
3795
9dfe12ae 3796 -- Debug trace output
ee6ba406 3797
9dfe12ae 3798 if Debug_Flag_CC then
3799 w ("Enable_Range_Check for node ", Int (N));
3800 Write_Str (" Source location = ");
3801 wl (Sloc (N));
00c403ee 3802 pg (Union_Id (N));
9dfe12ae 3803 end if;
3804
feff2f05 3805 -- If not in optimizing mode, set flag and we are done. We are also done
3806 -- (and just set the flag) if the type is not a discrete type, since it
3807 -- is not worth the effort to eliminate checks for other than discrete
3808 -- types. In addition, we take this same path if we have stored the
3809 -- maximum number of checks possible already (a very unlikely situation,
3810 -- but we do not want to blow up!)
9dfe12ae 3811
3812 if Optimization_Level = 0
3813 or else No (Etype (N))
3814 or else not Is_Discrete_Type (Etype (N))
3815 or else Num_Saved_Checks = Saved_Checks'Last
ee6ba406 3816 then
00c403ee 3817 Activate_Range_Check (N);
9dfe12ae 3818
3819 if Debug_Flag_CC then
3820 w ("Optimization off");
3821 end if;
3822
ee6ba406 3823 return;
9dfe12ae 3824 end if;
ee6ba406 3825
9dfe12ae 3826 -- Otherwise find out the target type
ee6ba406 3827
9dfe12ae 3828 P := Parent (N);
ee6ba406 3829
9dfe12ae 3830 -- For assignment, use left side subtype
3831
3832 if Nkind (P) = N_Assignment_Statement
3833 and then Expression (P) = N
3834 then
3835 Ttyp := Etype (Name (P));
3836
3837 -- For indexed component, use subscript subtype
3838
3839 elsif Nkind (P) = N_Indexed_Component then
3840 declare
3841 Atyp : Entity_Id;
3842 Indx : Node_Id;
3843 Subs : Node_Id;
3844
3845 begin
3846 Atyp := Etype (Prefix (P));
3847
3848 if Is_Access_Type (Atyp) then
3849 Atyp := Designated_Type (Atyp);
f07ea091 3850
3851 -- If the prefix is an access to an unconstrained array,
feff2f05 3852 -- perform check unconditionally: it depends on the bounds of
3853 -- an object and we cannot currently recognize whether the test
3854 -- may be redundant.
f07ea091 3855
3856 if not Is_Constrained (Atyp) then
00c403ee 3857 Activate_Range_Check (N);
f07ea091 3858 return;
3859 end if;
7189d17f 3860
feff2f05 3861 -- Ditto if the prefix is an explicit dereference whose designated
3862 -- type is unconstrained.
7189d17f 3863
3864 elsif Nkind (Prefix (P)) = N_Explicit_Dereference
3865 and then not Is_Constrained (Atyp)
3866 then
00c403ee 3867 Activate_Range_Check (N);
7189d17f 3868 return;
9dfe12ae 3869 end if;
3870
3871 Indx := First_Index (Atyp);
3872 Subs := First (Expressions (P));
3873 loop
3874 if Subs = N then
3875 Ttyp := Etype (Indx);
3876 exit;
3877 end if;
3878
3879 Next_Index (Indx);
3880 Next (Subs);
3881 end loop;
3882 end;
3883
3884 -- For now, ignore all other cases, they are not so interesting
3885
3886 else
3887 if Debug_Flag_CC then
3888 w (" target type not found, flag set");
3889 end if;
3890
00c403ee 3891 Activate_Range_Check (N);
9dfe12ae 3892 return;
3893 end if;
3894
3895 -- Evaluate and check the expression
3896
3897 Find_Check
3898 (Expr => N,
3899 Check_Type => 'R',
3900 Target_Type => Ttyp,
3901 Entry_OK => OK,
3902 Check_Num => Chk,
3903 Ent => Ent,
3904 Ofs => Ofs);
3905
3906 if Debug_Flag_CC then
3907 w ("Called Find_Check");
3908 w ("Target_Typ = ", Int (Ttyp));
3909 w (" OK = ", OK);
3910
3911 if OK then
3912 w (" Check_Num = ", Chk);
3913 w (" Ent = ", Int (Ent));
3914 Write_Str (" Ofs = ");
3915 pid (Ofs);
3916 end if;
3917 end if;
3918
3919 -- If check is not of form to optimize, then set flag and we are done
3920
3921 if not OK then
3922 if Debug_Flag_CC then
3923 w (" expression not of optimizable type, flag set");
3924 end if;
3925
00c403ee 3926 Activate_Range_Check (N);
9dfe12ae 3927 return;
3928 end if;
3929
3930 -- If check is already performed, then return without setting flag
3931
3932 if Chk /= 0 then
3933 if Debug_Flag_CC then
3934 w ("Check suppressed!");
3935 end if;
3936
3937 return;
3938 end if;
3939
3940 -- Here we will make a new entry for the new check
3941
00c403ee 3942 Activate_Range_Check (N);
9dfe12ae 3943 Num_Saved_Checks := Num_Saved_Checks + 1;
3944 Saved_Checks (Num_Saved_Checks) :=
3945 (Killed => False,
3946 Entity => Ent,
3947 Offset => Ofs,
3948 Check_Type => 'R',
3949 Target_Type => Ttyp);
3950
3951 if Debug_Flag_CC then
3952 w ("Make new entry, check number = ", Num_Saved_Checks);
3953 w (" Entity = ", Int (Ent));
3954 Write_Str (" Offset = ");
3955 pid (Ofs);
3956 w (" Check_Type = R");
3957 w (" Target_Type = ", Int (Ttyp));
00c403ee 3958 pg (Union_Id (Ttyp));
9dfe12ae 3959 end if;
3960
feff2f05 3961 -- If we get an exception, then something went wrong, probably because of
3962 -- an error in the structure of the tree due to an incorrect program. Or
3963 -- it may be a bug in the optimization circuit. In either case the safest
3964 -- thing is simply to set the check flag unconditionally.
9dfe12ae 3965
3966 exception
3967 when others =>
00c403ee 3968 Activate_Range_Check (N);
9dfe12ae 3969
3970 if Debug_Flag_CC then
3971 w (" exception occurred, range flag set");
3972 end if;
3973
3974 return;
3975 end Enable_Range_Check;
3976
3977 ------------------
3978 -- Ensure_Valid --
3979 ------------------
3980
3981 procedure Ensure_Valid (Expr : Node_Id; Holes_OK : Boolean := False) is
3982 Typ : constant Entity_Id := Etype (Expr);
3983
3984 begin
3985 -- Ignore call if we are not doing any validity checking
3986
3987 if not Validity_Checks_On then
3988 return;
3989
0577b0b1 3990 -- Ignore call if range or validity checks suppressed on entity or type
9dfe12ae 3991
0577b0b1 3992 elsif Range_Or_Validity_Checks_Suppressed (Expr) then
9dfe12ae 3993 return;
3994
feff2f05 3995 -- No check required if expression is from the expander, we assume the
3996 -- expander will generate whatever checks are needed. Note that this is
3997 -- not just an optimization, it avoids infinite recursions!
9dfe12ae 3998
3999 -- Unchecked conversions must be checked, unless they are initialized
4000 -- scalar values, as in a component assignment in an init proc.
4001
4002 -- In addition, we force a check if Force_Validity_Checks is set
4003
4004 elsif not Comes_From_Source (Expr)
4005 and then not Force_Validity_Checks
4006 and then (Nkind (Expr) /= N_Unchecked_Type_Conversion
4007 or else Kill_Range_Check (Expr))
4008 then
4009 return;
4010
4011 -- No check required if expression is known to have valid value
4012
4013 elsif Expr_Known_Valid (Expr) then
4014 return;
4015
feff2f05 4016 -- Ignore case of enumeration with holes where the flag is set not to
4017 -- worry about holes, since no special validity check is needed
9dfe12ae 4018
4019 elsif Is_Enumeration_Type (Typ)
4020 and then Has_Non_Standard_Rep (Typ)
4021 and then Holes_OK
4022 then
4023 return;
4024
f2a06be9 4025 -- No check required on the left-hand side of an assignment
9dfe12ae 4026
4027 elsif Nkind (Parent (Expr)) = N_Assignment_Statement
4028 and then Expr = Name (Parent (Expr))
4029 then
4030 return;
4031
38f5559f 4032 -- No check on a univeral real constant. The context will eventually
4033 -- convert it to a machine number for some target type, or report an
4034 -- illegality.
4035
4036 elsif Nkind (Expr) = N_Real_Literal
4037 and then Etype (Expr) = Universal_Real
4038 then
4039 return;
4040
0577b0b1 4041 -- If the expression denotes a component of a packed boolean arrray,
4042 -- no possible check applies. We ignore the old ACATS chestnuts that
4043 -- involve Boolean range True..True.
4044
4045 -- Note: validity checks are generated for expressions that yield a
4046 -- scalar type, when it is possible to create a value that is outside of
4047 -- the type. If this is a one-bit boolean no such value exists. This is
4048 -- an optimization, and it also prevents compiler blowing up during the
4049 -- elaboration of improperly expanded packed array references.
4050
4051 elsif Nkind (Expr) = N_Indexed_Component
4052 and then Is_Bit_Packed_Array (Etype (Prefix (Expr)))
4053 and then Root_Type (Etype (Expr)) = Standard_Boolean
4054 then
4055 return;
4056
9dfe12ae 4057 -- An annoying special case. If this is an out parameter of a scalar
4058 -- type, then the value is not going to be accessed, therefore it is
4059 -- inappropriate to do any validity check at the call site.
4060
4061 else
4062 -- Only need to worry about scalar types
4063
4064 if Is_Scalar_Type (Typ) then
ee6ba406 4065 declare
4066 P : Node_Id;
4067 N : Node_Id;
4068 E : Entity_Id;
4069 F : Entity_Id;
4070 A : Node_Id;
4071 L : List_Id;
4072
4073 begin
4074 -- Find actual argument (which may be a parameter association)
4075 -- and the parent of the actual argument (the call statement)
4076
4077 N := Expr;
4078 P := Parent (Expr);
4079
4080 if Nkind (P) = N_Parameter_Association then
4081 N := P;
4082 P := Parent (N);
4083 end if;
4084
feff2f05 4085 -- Only need to worry if we are argument of a procedure call
4086 -- since functions don't have out parameters. If this is an
4087 -- indirect or dispatching call, get signature from the
4088 -- subprogram type.
ee6ba406 4089
4090 if Nkind (P) = N_Procedure_Call_Statement then
4091 L := Parameter_Associations (P);
9dfe12ae 4092
4093 if Is_Entity_Name (Name (P)) then
4094 E := Entity (Name (P));
4095 else
4096 pragma Assert (Nkind (Name (P)) = N_Explicit_Dereference);
4097 E := Etype (Name (P));
4098 end if;
ee6ba406 4099
feff2f05 4100 -- Only need to worry if there are indeed actuals, and if
4101 -- this could be a procedure call, otherwise we cannot get a
4102 -- match (either we are not an argument, or the mode of the
4103 -- formal is not OUT). This test also filters out the
4104 -- generic case.
ee6ba406 4105
4106 if Is_Non_Empty_List (L)
4107 and then Is_Subprogram (E)
4108 then
feff2f05 4109 -- This is the loop through parameters, looking for an
4110 -- OUT parameter for which we are the argument.
ee6ba406 4111
4112 F := First_Formal (E);
4113 A := First (L);
ee6ba406 4114 while Present (F) loop
4115 if Ekind (F) = E_Out_Parameter and then A = N then
4116 return;
4117 end if;
4118
4119 Next_Formal (F);
4120 Next (A);
4121 end loop;
4122 end if;
4123 end if;
4124 end;
4125 end if;
4126 end if;
4127
fa6a6949 4128 -- If this is a boolean expression, only its elementary operands need
90a07d4c 4129 -- checking: if they are valid, a boolean or short-circuit operation
4130 -- with them will be valid as well.
784d4230 4131
4132 if Base_Type (Typ) = Standard_Boolean
7af38999 4133 and then
fa6a6949 4134 (Nkind (Expr) in N_Op or else Nkind (Expr) in N_Short_Circuit)
784d4230 4135 then
4136 return;
4137 end if;
4138
0577b0b1 4139 -- If we fall through, a validity check is required
ee6ba406 4140
4141 Insert_Valid_Check (Expr);
ce7498d3 4142
4143 if Is_Entity_Name (Expr)
4144 and then Safe_To_Capture_Value (Expr, Entity (Expr))
4145 then
4146 Set_Is_Known_Valid (Entity (Expr));
4147 end if;
ee6ba406 4148 end Ensure_Valid;
4149
4150 ----------------------
4151 -- Expr_Known_Valid --
4152 ----------------------
4153
4154 function Expr_Known_Valid (Expr : Node_Id) return Boolean is
4155 Typ : constant Entity_Id := Etype (Expr);
4156
4157 begin
feff2f05 4158 -- Non-scalar types are always considered valid, since they never give
4159 -- rise to the issues of erroneous or bounded error behavior that are
4160 -- the concern. In formal reference manual terms the notion of validity
4161 -- only applies to scalar types. Note that even when packed arrays are
4162 -- represented using modular types, they are still arrays semantically,
4163 -- so they are also always valid (in particular, the unused bits can be
4164 -- random rubbish without affecting the validity of the array value).
ee6ba406 4165
fa814356 4166 if not Is_Scalar_Type (Typ) or else Is_Packed_Array_Type (Typ) then
ee6ba406 4167 return True;
4168
4169 -- If no validity checking, then everything is considered valid
4170
4171 elsif not Validity_Checks_On then
4172 return True;
4173
4174 -- Floating-point types are considered valid unless floating-point
4175 -- validity checks have been specifically turned on.
4176
4177 elsif Is_Floating_Point_Type (Typ)
4178 and then not Validity_Check_Floating_Point
4179 then
4180 return True;
4181
feff2f05 4182 -- If the expression is the value of an object that is known to be
4183 -- valid, then clearly the expression value itself is valid.
ee6ba406 4184
4185 elsif Is_Entity_Name (Expr)
4186 and then Is_Known_Valid (Entity (Expr))
4187 then
4188 return True;
4189
0577b0b1 4190 -- References to discriminants are always considered valid. The value
4191 -- of a discriminant gets checked when the object is built. Within the
4192 -- record, we consider it valid, and it is important to do so, since
4193 -- otherwise we can try to generate bogus validity checks which
feff2f05 4194 -- reference discriminants out of scope. Discriminants of concurrent
4195 -- types are excluded for the same reason.
0577b0b1 4196
4197 elsif Is_Entity_Name (Expr)
feff2f05 4198 and then Denotes_Discriminant (Expr, Check_Concurrent => True)
0577b0b1 4199 then
4200 return True;
4201
feff2f05 4202 -- If the type is one for which all values are known valid, then we are
4203 -- sure that the value is valid except in the slightly odd case where
4204 -- the expression is a reference to a variable whose size has been
4205 -- explicitly set to a value greater than the object size.
ee6ba406 4206
4207 elsif Is_Known_Valid (Typ) then
4208 if Is_Entity_Name (Expr)
4209 and then Ekind (Entity (Expr)) = E_Variable
4210 and then Esize (Entity (Expr)) > Esize (Typ)
4211 then
4212 return False;
4213 else
4214 return True;
4215 end if;
4216
4217 -- Integer and character literals always have valid values, where
4218 -- appropriate these will be range checked in any case.
4219
4220 elsif Nkind (Expr) = N_Integer_Literal
4221 or else
4222 Nkind (Expr) = N_Character_Literal
4223 then
4224 return True;
4225
4226 -- If we have a type conversion or a qualification of a known valid
4227 -- value, then the result will always be valid.
4228
4229 elsif Nkind (Expr) = N_Type_Conversion
4230 or else
4231 Nkind (Expr) = N_Qualified_Expression
4232 then
4233 return Expr_Known_Valid (Expression (Expr));
4234
38f5559f 4235 -- The result of any operator is always considered valid, since we
4236 -- assume the necessary checks are done by the operator. For operators
4237 -- on floating-point operations, we must also check when the operation
4238 -- is the right-hand side of an assignment, or is an actual in a call.
ee6ba406 4239
0577b0b1 4240 elsif Nkind (Expr) in N_Op then
1d90d657 4241 if Is_Floating_Point_Type (Typ)
4242 and then Validity_Check_Floating_Point
4243 and then
4244 (Nkind (Parent (Expr)) = N_Assignment_Statement
4245 or else Nkind (Parent (Expr)) = N_Function_Call
4246 or else Nkind (Parent (Expr)) = N_Parameter_Association)
4247 then
4248 return False;
4249 else
4250 return True;
4251 end if;
4252
feff2f05 4253 -- The result of a membership test is always valid, since it is true or
4254 -- false, there are no other possibilities.
0577b0b1 4255
4256 elsif Nkind (Expr) in N_Membership_Test then
4257 return True;
4258
ee6ba406 4259 -- For all other cases, we do not know the expression is valid
4260
4261 else
4262 return False;
4263 end if;
4264 end Expr_Known_Valid;
4265
9dfe12ae 4266 ----------------
4267 -- Find_Check --
4268 ----------------
4269
4270 procedure Find_Check
4271 (Expr : Node_Id;
4272 Check_Type : Character;
4273 Target_Type : Entity_Id;
4274 Entry_OK : out Boolean;
4275 Check_Num : out Nat;
4276 Ent : out Entity_Id;
4277 Ofs : out Uint)
4278 is
4279 function Within_Range_Of
4280 (Target_Type : Entity_Id;
314a23b6 4281 Check_Type : Entity_Id) return Boolean;
9dfe12ae 4282 -- Given a requirement for checking a range against Target_Type, and
4283 -- and a range Check_Type against which a check has already been made,
4284 -- determines if the check against check type is sufficient to ensure
4285 -- that no check against Target_Type is required.
4286
4287 ---------------------
4288 -- Within_Range_Of --
4289 ---------------------
4290
4291 function Within_Range_Of
4292 (Target_Type : Entity_Id;
314a23b6 4293 Check_Type : Entity_Id) return Boolean
9dfe12ae 4294 is
4295 begin
4296 if Target_Type = Check_Type then
4297 return True;
4298
4299 else
4300 declare
4301 Tlo : constant Node_Id := Type_Low_Bound (Target_Type);
4302 Thi : constant Node_Id := Type_High_Bound (Target_Type);
4303 Clo : constant Node_Id := Type_Low_Bound (Check_Type);
4304 Chi : constant Node_Id := Type_High_Bound (Check_Type);
4305
4306 begin
4307 if (Tlo = Clo
4308 or else (Compile_Time_Known_Value (Tlo)
4309 and then
4310 Compile_Time_Known_Value (Clo)
4311 and then
4312 Expr_Value (Clo) >= Expr_Value (Tlo)))
4313 and then
4314 (Thi = Chi
4315 or else (Compile_Time_Known_Value (Thi)
4316 and then
4317 Compile_Time_Known_Value (Chi)
4318 and then
4319 Expr_Value (Chi) <= Expr_Value (Clo)))
4320 then
4321 return True;
4322 else
4323 return False;
4324 end if;
4325 end;
4326 end if;
4327 end Within_Range_Of;
4328
4329 -- Start of processing for Find_Check
4330
4331 begin
ed195555 4332 -- Establish default, in case no entry is found
9dfe12ae 4333
4334 Check_Num := 0;
4335
4336 -- Case of expression is simple entity reference
4337
4338 if Is_Entity_Name (Expr) then
4339 Ent := Entity (Expr);
4340 Ofs := Uint_0;
4341
4342 -- Case of expression is entity + known constant
4343
4344 elsif Nkind (Expr) = N_Op_Add
4345 and then Compile_Time_Known_Value (Right_Opnd (Expr))
4346 and then Is_Entity_Name (Left_Opnd (Expr))
4347 then
4348 Ent := Entity (Left_Opnd (Expr));
4349 Ofs := Expr_Value (Right_Opnd (Expr));
4350
4351 -- Case of expression is entity - known constant
4352
4353 elsif Nkind (Expr) = N_Op_Subtract
4354 and then Compile_Time_Known_Value (Right_Opnd (Expr))
4355 and then Is_Entity_Name (Left_Opnd (Expr))
4356 then
4357 Ent := Entity (Left_Opnd (Expr));
4358 Ofs := UI_Negate (Expr_Value (Right_Opnd (Expr)));
4359
4360 -- Any other expression is not of the right form
4361
4362 else
4363 Ent := Empty;
4364 Ofs := Uint_0;
4365 Entry_OK := False;
4366 return;
4367 end if;
4368
feff2f05 4369 -- Come here with expression of appropriate form, check if entity is an
4370 -- appropriate one for our purposes.
9dfe12ae 4371
4372 if (Ekind (Ent) = E_Variable
cc60bd16 4373 or else Is_Constant_Object (Ent))
9dfe12ae 4374 and then not Is_Library_Level_Entity (Ent)
4375 then
4376 Entry_OK := True;
4377 else
4378 Entry_OK := False;
4379 return;
4380 end if;
4381
4382 -- See if there is matching check already
4383
4384 for J in reverse 1 .. Num_Saved_Checks loop
4385 declare
4386 SC : Saved_Check renames Saved_Checks (J);
4387
4388 begin
4389 if SC.Killed = False
4390 and then SC.Entity = Ent
4391 and then SC.Offset = Ofs
4392 and then SC.Check_Type = Check_Type
4393 and then Within_Range_Of (Target_Type, SC.Target_Type)
4394 then
4395 Check_Num := J;
4396 return;
4397 end if;
4398 end;
4399 end loop;
4400
4401 -- If we fall through entry was not found
4402
9dfe12ae 4403 return;
4404 end Find_Check;
4405
4406 ---------------------------------
4407 -- Generate_Discriminant_Check --
4408 ---------------------------------
4409
4410 -- Note: the code for this procedure is derived from the
feff2f05 4411 -- Emit_Discriminant_Check Routine in trans.c.
9dfe12ae 4412
4413 procedure Generate_Discriminant_Check (N : Node_Id) is
4414 Loc : constant Source_Ptr := Sloc (N);
4415 Pref : constant Node_Id := Prefix (N);
4416 Sel : constant Node_Id := Selector_Name (N);
4417
4418 Orig_Comp : constant Entity_Id :=
4419 Original_Record_Component (Entity (Sel));
4420 -- The original component to be checked
4421
4422 Discr_Fct : constant Entity_Id :=
4423 Discriminant_Checking_Func (Orig_Comp);
4424 -- The discriminant checking function
4425
4426 Discr : Entity_Id;
4427 -- One discriminant to be checked in the type
4428
4429 Real_Discr : Entity_Id;
4430 -- Actual discriminant in the call
4431
4432 Pref_Type : Entity_Id;
4433 -- Type of relevant prefix (ignoring private/access stuff)
4434
4435 Args : List_Id;
4436 -- List of arguments for function call
4437
4438 Formal : Entity_Id;
feff2f05 4439 -- Keep track of the formal corresponding to the actual we build for
4440 -- each discriminant, in order to be able to perform the necessary type
4441 -- conversions.
9dfe12ae 4442
4443 Scomp : Node_Id;
4444 -- Selected component reference for checking function argument
4445
4446 begin
4447 Pref_Type := Etype (Pref);
4448
4449 -- Force evaluation of the prefix, so that it does not get evaluated
4450 -- twice (once for the check, once for the actual reference). Such a
4451 -- double evaluation is always a potential source of inefficiency,
4452 -- and is functionally incorrect in the volatile case, or when the
4453 -- prefix may have side-effects. An entity or a component of an
4454 -- entity requires no evaluation.
4455
4456 if Is_Entity_Name (Pref) then
4457 if Treat_As_Volatile (Entity (Pref)) then
4458 Force_Evaluation (Pref, Name_Req => True);
4459 end if;
4460
4461 elsif Treat_As_Volatile (Etype (Pref)) then
4462 Force_Evaluation (Pref, Name_Req => True);
4463
4464 elsif Nkind (Pref) = N_Selected_Component
4465 and then Is_Entity_Name (Prefix (Pref))
4466 then
4467 null;
4468
4469 else
4470 Force_Evaluation (Pref, Name_Req => True);
4471 end if;
4472
4473 -- For a tagged type, use the scope of the original component to
4474 -- obtain the type, because ???
4475
4476 if Is_Tagged_Type (Scope (Orig_Comp)) then
4477 Pref_Type := Scope (Orig_Comp);
4478
feff2f05 4479 -- For an untagged derived type, use the discriminants of the parent
4480 -- which have been renamed in the derivation, possibly by a one-to-many
4481 -- discriminant constraint. For non-tagged type, initially get the Etype
4482 -- of the prefix
9dfe12ae 4483
4484 else
4485 if Is_Derived_Type (Pref_Type)
4486 and then Number_Discriminants (Pref_Type) /=
4487 Number_Discriminants (Etype (Base_Type (Pref_Type)))
4488 then
4489 Pref_Type := Etype (Base_Type (Pref_Type));
4490 end if;
4491 end if;
4492
4493 -- We definitely should have a checking function, This routine should
4494 -- not be called if no discriminant checking function is present.
4495
4496 pragma Assert (Present (Discr_Fct));
4497
4498 -- Create the list of the actual parameters for the call. This list
4499 -- is the list of the discriminant fields of the record expression to
4500 -- be discriminant checked.
4501
4502 Args := New_List;
4503 Formal := First_Formal (Discr_Fct);
4504 Discr := First_Discriminant (Pref_Type);
4505 while Present (Discr) loop
4506
4507 -- If we have a corresponding discriminant field, and a parent
4508 -- subtype is present, then we want to use the corresponding
4509 -- discriminant since this is the one with the useful value.
4510
4511 if Present (Corresponding_Discriminant (Discr))
4512 and then Ekind (Pref_Type) = E_Record_Type
4513 and then Present (Parent_Subtype (Pref_Type))
4514 then
4515 Real_Discr := Corresponding_Discriminant (Discr);
4516 else
4517 Real_Discr := Discr;
4518 end if;
4519
4520 -- Construct the reference to the discriminant
4521
4522 Scomp :=
4523 Make_Selected_Component (Loc,
4524 Prefix =>
4525 Unchecked_Convert_To (Pref_Type,
4526 Duplicate_Subexpr (Pref)),
4527 Selector_Name => New_Occurrence_Of (Real_Discr, Loc));
4528
4529 -- Manually analyze and resolve this selected component. We really
4530 -- want it just as it appears above, and do not want the expander
feff2f05 4531 -- playing discriminal games etc with this reference. Then we append
4532 -- the argument to the list we are gathering.
9dfe12ae 4533
4534 Set_Etype (Scomp, Etype (Real_Discr));
4535 Set_Analyzed (Scomp, True);
4536 Append_To (Args, Convert_To (Etype (Formal), Scomp));
4537
4538 Next_Formal_With_Extras (Formal);
4539 Next_Discriminant (Discr);
4540 end loop;
4541
4542 -- Now build and insert the call
4543
4544 Insert_Action (N,
4545 Make_Raise_Constraint_Error (Loc,
4546 Condition =>
4547 Make_Function_Call (Loc,
4548 Name => New_Occurrence_Of (Discr_Fct, Loc),
4549 Parameter_Associations => Args),
4550 Reason => CE_Discriminant_Check_Failed));
4551 end Generate_Discriminant_Check;
4552
5c99c290 4553 ---------------------------
4554 -- Generate_Index_Checks --
4555 ---------------------------
9dfe12ae 4556
4557 procedure Generate_Index_Checks (N : Node_Id) is
4558 Loc : constant Source_Ptr := Sloc (N);
4559 A : constant Node_Id := Prefix (N);
4560 Sub : Node_Id;
4561 Ind : Nat;
4562 Num : List_Id;
4563
4564 begin
0577b0b1 4565 -- Ignore call if index checks suppressed for array object or type
4566
4567 if (Is_Entity_Name (A) and then Index_Checks_Suppressed (Entity (A)))
4568 or else Index_Checks_Suppressed (Etype (A))
4569 then
4570 return;
4571 end if;
4572
4573 -- Generate the checks
4574
9dfe12ae 4575 Sub := First (Expressions (N));
4576 Ind := 1;
4577 while Present (Sub) loop
4578 if Do_Range_Check (Sub) then
4579 Set_Do_Range_Check (Sub, False);
4580
feff2f05 4581 -- Force evaluation except for the case of a simple name of a
4582 -- non-volatile entity.
9dfe12ae 4583
4584 if not Is_Entity_Name (Sub)
4585 or else Treat_As_Volatile (Entity (Sub))
4586 then
4587 Force_Evaluation (Sub);
4588 end if;
4589
4590 -- Generate a raise of constraint error with the appropriate
4591 -- reason and a condition of the form:
4592
4593 -- Base_Type(Sub) not in array'range (subscript)
4594
feff2f05 4595 -- Note that the reason we generate the conversion to the base
4596 -- type here is that we definitely want the range check to take
4597 -- place, even if it looks like the subtype is OK. Optimization
4598 -- considerations that allow us to omit the check have already
4599 -- been taken into account in the setting of the Do_Range_Check
4600 -- flag earlier on.
9dfe12ae 4601
4602 if Ind = 1 then
4603 Num := No_List;
4604 else
4605 Num := New_List (Make_Integer_Literal (Loc, Ind));
4606 end if;
4607
4608 Insert_Action (N,
4609 Make_Raise_Constraint_Error (Loc,
4610 Condition =>
4611 Make_Not_In (Loc,
4612 Left_Opnd =>
4613 Convert_To (Base_Type (Etype (Sub)),
4614 Duplicate_Subexpr_Move_Checks (Sub)),
4615 Right_Opnd =>
4616 Make_Attribute_Reference (Loc,
cc60bd16 4617 Prefix =>
4618 Duplicate_Subexpr_Move_Checks (A, Name_Req => True),
9dfe12ae 4619 Attribute_Name => Name_Range,
4620 Expressions => Num)),
4621 Reason => CE_Index_Check_Failed));
4622 end if;
4623
4624 Ind := Ind + 1;
4625 Next (Sub);
4626 end loop;
4627 end Generate_Index_Checks;
4628
4629 --------------------------
4630 -- Generate_Range_Check --
4631 --------------------------
4632
4633 procedure Generate_Range_Check
4634 (N : Node_Id;
4635 Target_Type : Entity_Id;
4636 Reason : RT_Exception_Code)
4637 is
4638 Loc : constant Source_Ptr := Sloc (N);
4639 Source_Type : constant Entity_Id := Etype (N);
4640 Source_Base_Type : constant Entity_Id := Base_Type (Source_Type);
4641 Target_Base_Type : constant Entity_Id := Base_Type (Target_Type);
4642
4643 begin
feff2f05 4644 -- First special case, if the source type is already within the range
4645 -- of the target type, then no check is needed (probably we should have
4646 -- stopped Do_Range_Check from being set in the first place, but better
4647 -- late than later in preventing junk code!
9dfe12ae 4648
feff2f05 4649 -- We do NOT apply this if the source node is a literal, since in this
4650 -- case the literal has already been labeled as having the subtype of
4651 -- the target.
9dfe12ae 4652
7a1dabb3 4653 if In_Subrange_Of (Source_Type, Target_Type)
9dfe12ae 4654 and then not
4655 (Nkind (N) = N_Integer_Literal
4656 or else
4657 Nkind (N) = N_Real_Literal
4658 or else
4659 Nkind (N) = N_Character_Literal
4660 or else
4661 (Is_Entity_Name (N)
4662 and then Ekind (Entity (N)) = E_Enumeration_Literal))
4663 then
4664 return;
4665 end if;
4666
4667 -- We need a check, so force evaluation of the node, so that it does
4668 -- not get evaluated twice (once for the check, once for the actual
4669 -- reference). Such a double evaluation is always a potential source
4670 -- of inefficiency, and is functionally incorrect in the volatile case.
4671
4672 if not Is_Entity_Name (N)
4673 or else Treat_As_Volatile (Entity (N))
4674 then
4675 Force_Evaluation (N);
4676 end if;
4677
feff2f05 4678 -- The easiest case is when Source_Base_Type and Target_Base_Type are
4679 -- the same since in this case we can simply do a direct check of the
4680 -- value of N against the bounds of Target_Type.
9dfe12ae 4681
4682 -- [constraint_error when N not in Target_Type]
4683
4684 -- Note: this is by far the most common case, for example all cases of
4685 -- checks on the RHS of assignments are in this category, but not all
4686 -- cases are like this. Notably conversions can involve two types.
4687
4688 if Source_Base_Type = Target_Base_Type then
4689 Insert_Action (N,
4690 Make_Raise_Constraint_Error (Loc,
4691 Condition =>
4692 Make_Not_In (Loc,
4693 Left_Opnd => Duplicate_Subexpr (N),
4694 Right_Opnd => New_Occurrence_Of (Target_Type, Loc)),
4695 Reason => Reason));
4696
4697 -- Next test for the case where the target type is within the bounds
4698 -- of the base type of the source type, since in this case we can
4699 -- simply convert these bounds to the base type of T to do the test.
4700
4701 -- [constraint_error when N not in
4702 -- Source_Base_Type (Target_Type'First)
4703 -- ..
4704 -- Source_Base_Type(Target_Type'Last))]
4705
f2a06be9 4706 -- The conversions will always work and need no check
9dfe12ae 4707
a9b57347 4708 -- Unchecked_Convert_To is used instead of Convert_To to handle the case
4709 -- of converting from an enumeration value to an integer type, such as
4710 -- occurs for the case of generating a range check on Enum'Val(Exp)
4711 -- (which used to be handled by gigi). This is OK, since the conversion
4712 -- itself does not require a check.
4713
7a1dabb3 4714 elsif In_Subrange_Of (Target_Type, Source_Base_Type) then
9dfe12ae 4715 Insert_Action (N,
4716 Make_Raise_Constraint_Error (Loc,
4717 Condition =>
4718 Make_Not_In (Loc,
4719 Left_Opnd => Duplicate_Subexpr (N),
4720
4721 Right_Opnd =>
4722 Make_Range (Loc,
4723 Low_Bound =>
a9b57347 4724 Unchecked_Convert_To (Source_Base_Type,
9dfe12ae 4725 Make_Attribute_Reference (Loc,
4726 Prefix =>
4727 New_Occurrence_Of (Target_Type, Loc),
4728 Attribute_Name => Name_First)),
4729
4730 High_Bound =>
a9b57347 4731 Unchecked_Convert_To (Source_Base_Type,
9dfe12ae 4732 Make_Attribute_Reference (Loc,
4733 Prefix =>
4734 New_Occurrence_Of (Target_Type, Loc),
4735 Attribute_Name => Name_Last)))),
4736 Reason => Reason));
4737
feff2f05 4738 -- Note that at this stage we now that the Target_Base_Type is not in
4739 -- the range of the Source_Base_Type (since even the Target_Type itself
4740 -- is not in this range). It could still be the case that Source_Type is
4741 -- in range of the target base type since we have not checked that case.
9dfe12ae 4742
feff2f05 4743 -- If that is the case, we can freely convert the source to the target,
4744 -- and then test the target result against the bounds.
9dfe12ae 4745
7a1dabb3 4746 elsif In_Subrange_Of (Source_Type, Target_Base_Type) then
9dfe12ae 4747
feff2f05 4748 -- We make a temporary to hold the value of the converted value
4749 -- (converted to the base type), and then we will do the test against
4750 -- this temporary.
9dfe12ae 4751
4752 -- Tnn : constant Target_Base_Type := Target_Base_Type (N);
4753 -- [constraint_error when Tnn not in Target_Type]
4754
4755 -- Then the conversion itself is replaced by an occurrence of Tnn
4756
4757 declare
46eb6933 4758 Tnn : constant Entity_Id := Make_Temporary (Loc, 'T', N);
9dfe12ae 4759
4760 begin
4761 Insert_Actions (N, New_List (
4762 Make_Object_Declaration (Loc,
4763 Defining_Identifier => Tnn,
4764 Object_Definition =>
4765 New_Occurrence_Of (Target_Base_Type, Loc),
4766 Constant_Present => True,
4767 Expression =>
4768 Make_Type_Conversion (Loc,
4769 Subtype_Mark => New_Occurrence_Of (Target_Base_Type, Loc),
4770 Expression => Duplicate_Subexpr (N))),
4771
4772 Make_Raise_Constraint_Error (Loc,
4773 Condition =>
4774 Make_Not_In (Loc,
4775 Left_Opnd => New_Occurrence_Of (Tnn, Loc),
4776 Right_Opnd => New_Occurrence_Of (Target_Type, Loc)),
4777
4778 Reason => Reason)));
4779
4780 Rewrite (N, New_Occurrence_Of (Tnn, Loc));
2af58f67 4781
4782 -- Set the type of N, because the declaration for Tnn might not
4783 -- be analyzed yet, as is the case if N appears within a record
4784 -- declaration, as a discriminant constraint or expression.
4785
4786 Set_Etype (N, Target_Base_Type);
9dfe12ae 4787 end;
4788
4789 -- At this stage, we know that we have two scalar types, which are
4790 -- directly convertible, and where neither scalar type has a base
4791 -- range that is in the range of the other scalar type.
4792
4793 -- The only way this can happen is with a signed and unsigned type.
4794 -- So test for these two cases:
4795
4796 else
4797 -- Case of the source is unsigned and the target is signed
4798
4799 if Is_Unsigned_Type (Source_Base_Type)
4800 and then not Is_Unsigned_Type (Target_Base_Type)
4801 then
4802 -- If the source is unsigned and the target is signed, then we
4803 -- know that the source is not shorter than the target (otherwise
4804 -- the source base type would be in the target base type range).
4805
feff2f05 4806 -- In other words, the unsigned type is either the same size as
4807 -- the target, or it is larger. It cannot be smaller.
9dfe12ae 4808
4809 pragma Assert
4810 (Esize (Source_Base_Type) >= Esize (Target_Base_Type));
4811
4812 -- We only need to check the low bound if the low bound of the
4813 -- target type is non-negative. If the low bound of the target
4814 -- type is negative, then we know that we will fit fine.
4815
4816 -- If the high bound of the target type is negative, then we
4817 -- know we have a constraint error, since we can't possibly
4818 -- have a negative source.
4819
4820 -- With these two checks out of the way, we can do the check
4821 -- using the source type safely
4822
4823 -- This is definitely the most annoying case!
4824
4825 -- [constraint_error
4826 -- when (Target_Type'First >= 0
4827 -- and then
4828 -- N < Source_Base_Type (Target_Type'First))
4829 -- or else Target_Type'Last < 0
4830 -- or else N > Source_Base_Type (Target_Type'Last)];
4831
4832 -- We turn off all checks since we know that the conversions
4833 -- will work fine, given the guards for negative values.
4834
4835 Insert_Action (N,
4836 Make_Raise_Constraint_Error (Loc,
4837 Condition =>
4838 Make_Or_Else (Loc,
4839 Make_Or_Else (Loc,
4840 Left_Opnd =>
4841 Make_And_Then (Loc,
4842 Left_Opnd => Make_Op_Ge (Loc,
4843 Left_Opnd =>
4844 Make_Attribute_Reference (Loc,
4845 Prefix =>
4846 New_Occurrence_Of (Target_Type, Loc),
4847 Attribute_Name => Name_First),
4848 Right_Opnd => Make_Integer_Literal (Loc, Uint_0)),
4849
4850 Right_Opnd =>
4851 Make_Op_Lt (Loc,
4852 Left_Opnd => Duplicate_Subexpr (N),
4853 Right_Opnd =>
4854 Convert_To (Source_Base_Type,
4855 Make_Attribute_Reference (Loc,
4856 Prefix =>
4857 New_Occurrence_Of (Target_Type, Loc),
4858 Attribute_Name => Name_First)))),
4859
4860 Right_Opnd =>
4861 Make_Op_Lt (Loc,
4862 Left_Opnd =>
4863 Make_Attribute_Reference (Loc,
4864 Prefix => New_Occurrence_Of (Target_Type, Loc),
4865 Attribute_Name => Name_Last),
4866 Right_Opnd => Make_Integer_Literal (Loc, Uint_0))),
4867
4868 Right_Opnd =>
4869 Make_Op_Gt (Loc,
4870 Left_Opnd => Duplicate_Subexpr (N),
4871 Right_Opnd =>
4872 Convert_To (Source_Base_Type,
4873 Make_Attribute_Reference (Loc,
4874 Prefix => New_Occurrence_Of (Target_Type, Loc),
4875 Attribute_Name => Name_Last)))),
4876
4877 Reason => Reason),
4878 Suppress => All_Checks);
4879
4880 -- Only remaining possibility is that the source is signed and
fc75802a 4881 -- the target is unsigned.
9dfe12ae 4882
4883 else
4884 pragma Assert (not Is_Unsigned_Type (Source_Base_Type)
4885 and then Is_Unsigned_Type (Target_Base_Type));
4886
feff2f05 4887 -- If the source is signed and the target is unsigned, then we
4888 -- know that the target is not shorter than the source (otherwise
4889 -- the target base type would be in the source base type range).
9dfe12ae 4890
feff2f05 4891 -- In other words, the unsigned type is either the same size as
4892 -- the target, or it is larger. It cannot be smaller.
9dfe12ae 4893
feff2f05 4894 -- Clearly we have an error if the source value is negative since
4895 -- no unsigned type can have negative values. If the source type
4896 -- is non-negative, then the check can be done using the target
4897 -- type.
9dfe12ae 4898
4899 -- Tnn : constant Target_Base_Type (N) := Target_Type;
4900
4901 -- [constraint_error
4902 -- when N < 0 or else Tnn not in Target_Type];
4903
feff2f05 4904 -- We turn off all checks for the conversion of N to the target
4905 -- base type, since we generate the explicit check to ensure that
4906 -- the value is non-negative
9dfe12ae 4907
4908 declare
46eb6933 4909 Tnn : constant Entity_Id := Make_Temporary (Loc, 'T', N);
9dfe12ae 4910
4911 begin
4912 Insert_Actions (N, New_List (
4913 Make_Object_Declaration (Loc,
4914 Defining_Identifier => Tnn,
4915 Object_Definition =>
4916 New_Occurrence_Of (Target_Base_Type, Loc),
4917 Constant_Present => True,
4918 Expression =>
a9b57347 4919 Make_Unchecked_Type_Conversion (Loc,
9dfe12ae 4920 Subtype_Mark =>
4921 New_Occurrence_Of (Target_Base_Type, Loc),
4922 Expression => Duplicate_Subexpr (N))),
4923
4924 Make_Raise_Constraint_Error (Loc,
4925 Condition =>
4926 Make_Or_Else (Loc,
4927 Left_Opnd =>
4928 Make_Op_Lt (Loc,
4929 Left_Opnd => Duplicate_Subexpr (N),
4930 Right_Opnd => Make_Integer_Literal (Loc, Uint_0)),
4931
4932 Right_Opnd =>
4933 Make_Not_In (Loc,
4934 Left_Opnd => New_Occurrence_Of (Tnn, Loc),
4935 Right_Opnd =>
4936 New_Occurrence_Of (Target_Type, Loc))),
4937
4938 Reason => Reason)),
4939 Suppress => All_Checks);
4940
feff2f05 4941 -- Set the Etype explicitly, because Insert_Actions may have
4942 -- placed the declaration in the freeze list for an enclosing
4943 -- construct, and thus it is not analyzed yet.
9dfe12ae 4944
4945 Set_Etype (Tnn, Target_Base_Type);
4946 Rewrite (N, New_Occurrence_Of (Tnn, Loc));
4947 end;
4948 end if;
4949 end if;
4950 end Generate_Range_Check;
4951
2af58f67 4952 ------------------
4953 -- Get_Check_Id --
4954 ------------------
4955
4956 function Get_Check_Id (N : Name_Id) return Check_Id is
4957 begin
4958 -- For standard check name, we can do a direct computation
4959
4960 if N in First_Check_Name .. Last_Check_Name then
4961 return Check_Id (N - (First_Check_Name - 1));
4962
4963 -- For non-standard names added by pragma Check_Name, search table
4964
4965 else
4966 for J in All_Checks + 1 .. Check_Names.Last loop
4967 if Check_Names.Table (J) = N then
4968 return J;
4969 end if;
4970 end loop;
4971 end if;
4972
4973 -- No matching name found
4974
4975 return No_Check_Id;
4976 end Get_Check_Id;
4977
ee6ba406 4978 ---------------------
4979 -- Get_Discriminal --
4980 ---------------------
4981
4982 function Get_Discriminal (E : Entity_Id; Bound : Node_Id) return Node_Id is
4983 Loc : constant Source_Ptr := Sloc (E);
4984 D : Entity_Id;
4985 Sc : Entity_Id;
4986
4987 begin
0577b0b1 4988 -- The bound can be a bona fide parameter of a protected operation,
4989 -- rather than a prival encoded as an in-parameter.
4990
4991 if No (Discriminal_Link (Entity (Bound))) then
4992 return Bound;
4993 end if;
4994
2af58f67 4995 -- Climb the scope stack looking for an enclosing protected type. If
4996 -- we run out of scopes, return the bound itself.
4997
4998 Sc := Scope (E);
4999 while Present (Sc) loop
5000 if Sc = Standard_Standard then
5001 return Bound;
5002
5003 elsif Ekind (Sc) = E_Protected_Type then
5004 exit;
5005 end if;
5006
5007 Sc := Scope (Sc);
5008 end loop;
5009
ee6ba406 5010 D := First_Discriminant (Sc);
2af58f67 5011 while Present (D) loop
5012 if Chars (D) = Chars (Bound) then
5013 return New_Occurrence_Of (Discriminal (D), Loc);
5014 end if;
ee6ba406 5015
ee6ba406 5016 Next_Discriminant (D);
5017 end loop;
5018
2af58f67 5019 return Bound;
ee6ba406 5020 end Get_Discriminal;
5021
2af58f67 5022 ----------------------
5023 -- Get_Range_Checks --
5024 ----------------------
5025
5026 function Get_Range_Checks
5027 (Ck_Node : Node_Id;
5028 Target_Typ : Entity_Id;
5029 Source_Typ : Entity_Id := Empty;
5030 Warn_Node : Node_Id := Empty) return Check_Result
5031 is
5032 begin
5033 return Selected_Range_Checks
5034 (Ck_Node, Target_Typ, Source_Typ, Warn_Node);
5035 end Get_Range_Checks;
5036
ee6ba406 5037 ------------------
5038 -- Guard_Access --
5039 ------------------
5040
5041 function Guard_Access
5042 (Cond : Node_Id;
5043 Loc : Source_Ptr;
314a23b6 5044 Ck_Node : Node_Id) return Node_Id
ee6ba406 5045 is
5046 begin
5047 if Nkind (Cond) = N_Or_Else then
5048 Set_Paren_Count (Cond, 1);
5049 end if;
5050
5051 if Nkind (Ck_Node) = N_Allocator then
5052 return Cond;
5053 else
5054 return
5055 Make_And_Then (Loc,
5056 Left_Opnd =>
5057 Make_Op_Ne (Loc,
9dfe12ae 5058 Left_Opnd => Duplicate_Subexpr_No_Checks (Ck_Node),
ee6ba406 5059 Right_Opnd => Make_Null (Loc)),
5060 Right_Opnd => Cond);
5061 end if;
5062 end Guard_Access;
5063
5064 -----------------------------
5065 -- Index_Checks_Suppressed --
5066 -----------------------------
5067
5068 function Index_Checks_Suppressed (E : Entity_Id) return Boolean is
5069 begin
9dfe12ae 5070 if Present (E) and then Checks_May_Be_Suppressed (E) then
5071 return Is_Check_Suppressed (E, Index_Check);
5072 else
5073 return Scope_Suppress (Index_Check);
5074 end if;
ee6ba406 5075 end Index_Checks_Suppressed;
5076
5077 ----------------
5078 -- Initialize --
5079 ----------------
5080
5081 procedure Initialize is
5082 begin
5083 for J in Determine_Range_Cache_N'Range loop
5084 Determine_Range_Cache_N (J) := Empty;
5085 end loop;
2af58f67 5086
5087 Check_Names.Init;
5088
5089 for J in Int range 1 .. All_Checks loop
5090 Check_Names.Append (Name_Id (Int (First_Check_Name) + J - 1));
5091 end loop;
ee6ba406 5092 end Initialize;
5093
5094 -------------------------
5095 -- Insert_Range_Checks --
5096 -------------------------
5097
5098 procedure Insert_Range_Checks
5099 (Checks : Check_Result;
5100 Node : Node_Id;
5101 Suppress_Typ : Entity_Id;
5102 Static_Sloc : Source_Ptr := No_Location;
5103 Flag_Node : Node_Id := Empty;
5104 Do_Before : Boolean := False)
5105 is
5106 Internal_Flag_Node : Node_Id := Flag_Node;
5107 Internal_Static_Sloc : Source_Ptr := Static_Sloc;
5108
5109 Check_Node : Node_Id;
5110 Checks_On : constant Boolean :=
5111 (not Index_Checks_Suppressed (Suppress_Typ))
5112 or else
5113 (not Range_Checks_Suppressed (Suppress_Typ));
5114
5115 begin
feff2f05 5116 -- For now we just return if Checks_On is false, however this should be
5117 -- enhanced to check for an always True value in the condition and to
5118 -- generate a compilation warning???
ee6ba406 5119
5120 if not Expander_Active or else not Checks_On then
5121 return;
5122 end if;
5123
5124 if Static_Sloc = No_Location then
5125 Internal_Static_Sloc := Sloc (Node);
5126 end if;
5127
5128 if No (Flag_Node) then
5129 Internal_Flag_Node := Node;
5130 end if;
5131
5132 for J in 1 .. 2 loop
5133 exit when No (Checks (J));
5134
5135 if Nkind (Checks (J)) = N_Raise_Constraint_Error
5136 and then Present (Condition (Checks (J)))
5137 then
5138 if not Has_Dynamic_Range_Check (Internal_Flag_Node) then
5139 Check_Node := Checks (J);
5140 Mark_Rewrite_Insertion (Check_Node);
5141
5142 if Do_Before then
5143 Insert_Before_And_Analyze (Node, Check_Node);
5144 else
5145 Insert_After_And_Analyze (Node, Check_Node);
5146 end if;
5147
5148 Set_Has_Dynamic_Range_Check (Internal_Flag_Node);
5149 end if;
5150
5151 else
5152 Check_Node :=
f15731c4 5153 Make_Raise_Constraint_Error (Internal_Static_Sloc,
5154 Reason => CE_Range_Check_Failed);
ee6ba406 5155 Mark_Rewrite_Insertion (Check_Node);
5156
5157 if Do_Before then
5158 Insert_Before_And_Analyze (Node, Check_Node);
5159 else
5160 Insert_After_And_Analyze (Node, Check_Node);
5161 end if;
5162 end if;
5163 end loop;
5164 end Insert_Range_Checks;
5165
5166 ------------------------
5167 -- Insert_Valid_Check --
5168 ------------------------
5169
5170 procedure Insert_Valid_Check (Expr : Node_Id) is
5171 Loc : constant Source_Ptr := Sloc (Expr);
8b718dab 5172 Exp : Node_Id;
ee6ba406 5173
5174 begin
06ad5813 5175 -- Do not insert if checks off, or if not checking validity or
5176 -- if expression is known to be valid
ee6ba406 5177
0577b0b1 5178 if not Validity_Checks_On
5179 or else Range_Or_Validity_Checks_Suppressed (Expr)
06ad5813 5180 or else Expr_Known_Valid (Expr)
ee6ba406 5181 then
8b718dab 5182 return;
5183 end if;
ee6ba406 5184
8b718dab 5185 -- If we have a checked conversion, then validity check applies to
5186 -- the expression inside the conversion, not the result, since if
5187 -- the expression inside is valid, then so is the conversion result.
ee6ba406 5188
8b718dab 5189 Exp := Expr;
5190 while Nkind (Exp) = N_Type_Conversion loop
5191 Exp := Expression (Exp);
5192 end loop;
5193
0577b0b1 5194 -- We are about to insert the validity check for Exp. We save and
5195 -- reset the Do_Range_Check flag over this validity check, and then
5196 -- put it back for the final original reference (Exp may be rewritten).
5197
5198 declare
5199 DRC : constant Boolean := Do_Range_Check (Exp);
05fcfafb 5200
0577b0b1 5201 begin
5202 Set_Do_Range_Check (Exp, False);
5203
06ad5813 5204 -- Force evaluation to avoid multiple reads for atomic/volatile
5205
5206 if Is_Entity_Name (Exp)
5207 and then Is_Volatile (Entity (Exp))
5208 then
5209 Force_Evaluation (Exp, Name_Req => True);
5210 end if;
5211
0577b0b1 5212 -- Insert the validity check. Note that we do this with validity
5213 -- checks turned off, to avoid recursion, we do not want validity
5214 -- checks on the validity checking code itself!
5215
5216 Insert_Action
5217 (Expr,
5218 Make_Raise_Constraint_Error (Loc,
5219 Condition =>
5220 Make_Op_Not (Loc,
5221 Right_Opnd =>
5222 Make_Attribute_Reference (Loc,
5223 Prefix =>
5224 Duplicate_Subexpr_No_Checks (Exp, Name_Req => True),
5225 Attribute_Name => Name_Valid)),
5226 Reason => CE_Invalid_Data),
5227 Suppress => Validity_Check);
5228
5229 -- If the expression is a a reference to an element of a bit-packed
5230 -- array, then it is rewritten as a renaming declaration. If the
5231 -- expression is an actual in a call, it has not been expanded,
5232 -- waiting for the proper point at which to do it. The same happens
5233 -- with renamings, so that we have to force the expansion now. This
5234 -- non-local complication is due to code in exp_ch2,adb, exp_ch4.adb
5235 -- and exp_ch6.adb.
5236
5237 if Is_Entity_Name (Exp)
5238 and then Nkind (Parent (Entity (Exp))) =
5239 N_Object_Renaming_Declaration
5240 then
5241 declare
5242 Old_Exp : constant Node_Id := Name (Parent (Entity (Exp)));
5243 begin
5244 if Nkind (Old_Exp) = N_Indexed_Component
5245 and then Is_Bit_Packed_Array (Etype (Prefix (Old_Exp)))
5246 then
5247 Expand_Packed_Element_Reference (Old_Exp);
5248 end if;
5249 end;
5250 end if;
5251
5252 -- Put back the Do_Range_Check flag on the resulting (possibly
5253 -- rewritten) expression.
5254
5255 -- Note: it might be thought that a validity check is not required
5256 -- when a range check is present, but that's not the case, because
5257 -- the back end is allowed to assume for the range check that the
5258 -- operand is within its declared range (an assumption that validity
5259 -- checking is all about NOT assuming!)
5260
00c403ee 5261 -- Note: no need to worry about Possible_Local_Raise here, it will
5262 -- already have been called if original node has Do_Range_Check set.
5263
0577b0b1 5264 Set_Do_Range_Check (Exp, DRC);
5265 end;
ee6ba406 5266 end Insert_Valid_Check;
5267
fa7497e8 5268 ----------------------------------
5269 -- Install_Null_Excluding_Check --
5270 ----------------------------------
5271
5272 procedure Install_Null_Excluding_Check (N : Node_Id) is
9f294c82 5273 Loc : constant Source_Ptr := Sloc (Parent (N));
84d0d4a5 5274 Typ : constant Entity_Id := Etype (N);
5275
7b31b357 5276 function Safe_To_Capture_In_Parameter_Value return Boolean;
5277 -- Determines if it is safe to capture Known_Non_Null status for an
5278 -- the entity referenced by node N. The caller ensures that N is indeed
5279 -- an entity name. It is safe to capture the non-null status for an IN
5280 -- parameter when the reference occurs within a declaration that is sure
5281 -- to be executed as part of the declarative region.
7870823d 5282
84d0d4a5 5283 procedure Mark_Non_Null;
7870823d 5284 -- After installation of check, if the node in question is an entity
5285 -- name, then mark this entity as non-null if possible.
5286
7b31b357 5287 function Safe_To_Capture_In_Parameter_Value return Boolean is
7870823d 5288 E : constant Entity_Id := Entity (N);
5289 S : constant Entity_Id := Current_Scope;
5290 S_Par : Node_Id;
5291
5292 begin
7b31b357 5293 if Ekind (E) /= E_In_Parameter then
5294 return False;
5295 end if;
7870823d 5296
5297 -- Two initial context checks. We must be inside a subprogram body
5298 -- with declarations and reference must not appear in nested scopes.
5299
7b31b357 5300 if (Ekind (S) /= E_Function and then Ekind (S) /= E_Procedure)
7870823d 5301 or else Scope (E) /= S
5302 then
5303 return False;
5304 end if;
5305
5306 S_Par := Parent (Parent (S));
5307
5308 if Nkind (S_Par) /= N_Subprogram_Body
5309 or else No (Declarations (S_Par))
5310 then
5311 return False;
5312 end if;
5313
5314 declare
5315 N_Decl : Node_Id;
5316 P : Node_Id;
5317
5318 begin
5319 -- Retrieve the declaration node of N (if any). Note that N
5320 -- may be a part of a complex initialization expression.
5321
5322 P := Parent (N);
5323 N_Decl := Empty;
5324 while Present (P) loop
5325
7b31b357 5326 -- If we have a short circuit form, and we are within the right
5327 -- hand expression, we return false, since the right hand side
5328 -- is not guaranteed to be elaborated.
5329
5330 if Nkind (P) in N_Short_Circuit
5331 and then N = Right_Opnd (P)
5332 then
5333 return False;
5334 end if;
5335
5336 -- Similarly, if we are in a conditional expression and not
5337 -- part of the condition, then we return False, since neither
5338 -- the THEN or ELSE expressions will always be elaborated.
5339
5340 if Nkind (P) = N_Conditional_Expression
5341 and then N /= First (Expressions (P))
5342 then
5343 return False;
e977c0cf 5344 end if;
5345
5346 -- If we are in a case eexpression, and not part of the
5347 -- expression, then we return False, since a particular
5348 -- branch may not always be elaborated
5349
5350 if Nkind (P) = N_Case_Expression
5351 and then N /= Expression (P)
5352 then
5353 return False;
7b31b357 5354 end if;
5355
7870823d 5356 -- While traversing the parent chain, we find that N
5357 -- belongs to a statement, thus it may never appear in
5358 -- a declarative region.
5359
5360 if Nkind (P) in N_Statement_Other_Than_Procedure_Call
5361 or else Nkind (P) = N_Procedure_Call_Statement
5362 then
5363 return False;
5364 end if;
5365
7b31b357 5366 -- If we are at a declaration, record it and exit
5367
7870823d 5368 if Nkind (P) in N_Declaration
5369 and then Nkind (P) not in N_Subprogram_Specification
5370 then
5371 N_Decl := P;
5372 exit;
5373 end if;
5374
5375 P := Parent (P);
5376 end loop;
5377
5378 if No (N_Decl) then
5379 return False;
5380 end if;
5381
5382 return List_Containing (N_Decl) = Declarations (S_Par);
5383 end;
7b31b357 5384 end Safe_To_Capture_In_Parameter_Value;
84d0d4a5 5385
5386 -------------------
5387 -- Mark_Non_Null --
5388 -------------------
5389
5390 procedure Mark_Non_Null is
5391 begin
7870823d 5392 -- Only case of interest is if node N is an entity name
5393
84d0d4a5 5394 if Is_Entity_Name (N) then
7870823d 5395
5396 -- For sure, we want to clear an indication that this is known to
5397 -- be null, since if we get past this check, it definitely is not!
5398
84d0d4a5 5399 Set_Is_Known_Null (Entity (N), False);
5400
7870823d 5401 -- We can mark the entity as known to be non-null if either it is
5402 -- safe to capture the value, or in the case of an IN parameter,
5403 -- which is a constant, if the check we just installed is in the
5404 -- declarative region of the subprogram body. In this latter case,
7b31b357 5405 -- a check is decisive for the rest of the body if the expression
5406 -- is sure to be elaborated, since we know we have to elaborate
5407 -- all declarations before executing the body.
5408
5409 -- Couldn't this always be part of Safe_To_Capture_Value ???
7870823d 5410
5411 if Safe_To_Capture_Value (N, Entity (N))
7b31b357 5412 or else Safe_To_Capture_In_Parameter_Value
7870823d 5413 then
5414 Set_Is_Known_Non_Null (Entity (N));
84d0d4a5 5415 end if;
5416 end if;
5417 end Mark_Non_Null;
5418
5419 -- Start of processing for Install_Null_Excluding_Check
fa7497e8 5420
5421 begin
84d0d4a5 5422 pragma Assert (Is_Access_Type (Typ));
fa7497e8 5423
84d0d4a5 5424 -- No check inside a generic (why not???)
fa7497e8 5425
84d0d4a5 5426 if Inside_A_Generic then
fa7497e8 5427 return;
84d0d4a5 5428 end if;
5429
5430 -- No check needed if known to be non-null
5431
5432 if Known_Non_Null (N) then
05fcfafb 5433 return;
84d0d4a5 5434 end if;
fa7497e8 5435
84d0d4a5 5436 -- If known to be null, here is where we generate a compile time check
5437
5438 if Known_Null (N) then
d16989f1 5439
5440 -- Avoid generating warning message inside init procs
5441
5442 if not Inside_Init_Proc then
5443 Apply_Compile_Time_Constraint_Error
5444 (N,
5445 "null value not allowed here?",
5446 CE_Access_Check_Failed);
5447 else
5448 Insert_Action (N,
5449 Make_Raise_Constraint_Error (Loc,
5450 Reason => CE_Access_Check_Failed));
5451 end if;
5452
84d0d4a5 5453 Mark_Non_Null;
5454 return;
5455 end if;
5456
5457 -- If entity is never assigned, for sure a warning is appropriate
5458
5459 if Is_Entity_Name (N) then
5460 Check_Unset_Reference (N);
fa7497e8 5461 end if;
84d0d4a5 5462
5463 -- No check needed if checks are suppressed on the range. Note that we
5464 -- don't set Is_Known_Non_Null in this case (we could legitimately do
5465 -- so, since the program is erroneous, but we don't like to casually
5466 -- propagate such conclusions from erroneosity).
5467
5468 if Access_Checks_Suppressed (Typ) then
5469 return;
5470 end if;
5471
2af58f67 5472 -- No check needed for access to concurrent record types generated by
5473 -- the expander. This is not just an optimization (though it does indeed
5474 -- remove junk checks). It also avoids generation of junk warnings.
5475
5476 if Nkind (N) in N_Has_Chars
5477 and then Chars (N) = Name_uObject
5478 and then Is_Concurrent_Record_Type
5479 (Directly_Designated_Type (Etype (N)))
5480 then
5481 return;
5482 end if;
5483
84d0d4a5 5484 -- Otherwise install access check
5485
5486 Insert_Action (N,
5487 Make_Raise_Constraint_Error (Loc,
5488 Condition =>
5489 Make_Op_Eq (Loc,
5490 Left_Opnd => Duplicate_Subexpr_Move_Checks (N),
5491 Right_Opnd => Make_Null (Loc)),
5492 Reason => CE_Access_Check_Failed));
5493
5494 Mark_Non_Null;
fa7497e8 5495 end Install_Null_Excluding_Check;
5496
ee6ba406 5497 --------------------------
5498 -- Install_Static_Check --
5499 --------------------------
5500
5501 procedure Install_Static_Check (R_Cno : Node_Id; Loc : Source_Ptr) is
5502 Stat : constant Boolean := Is_Static_Expression (R_Cno);
5503 Typ : constant Entity_Id := Etype (R_Cno);
5504
5505 begin
f15731c4 5506 Rewrite (R_Cno,
5507 Make_Raise_Constraint_Error (Loc,
5508 Reason => CE_Range_Check_Failed));
ee6ba406 5509 Set_Analyzed (R_Cno);
5510 Set_Etype (R_Cno, Typ);
5511 Set_Raises_Constraint_Error (R_Cno);
5512 Set_Is_Static_Expression (R_Cno, Stat);
840ab274 5513
5514 -- Now deal with possible local raise handling
5515
5516 Possible_Local_Raise (R_Cno, Standard_Constraint_Error);
ee6ba406 5517 end Install_Static_Check;
5518
9dfe12ae 5519 ---------------------
5520 -- Kill_All_Checks --
5521 ---------------------
5522
5523 procedure Kill_All_Checks is
5524 begin
5525 if Debug_Flag_CC then
5526 w ("Kill_All_Checks");
5527 end if;
5528
feff2f05 5529 -- We reset the number of saved checks to zero, and also modify all
5530 -- stack entries for statement ranges to indicate that the number of
5531 -- checks at each level is now zero.
9dfe12ae 5532
5533 Num_Saved_Checks := 0;
5534
96da3284 5535 -- Note: the Int'Min here avoids any possibility of J being out of
5536 -- range when called from e.g. Conditional_Statements_Begin.
5537
5538 for J in 1 .. Int'Min (Saved_Checks_TOS, Saved_Checks_Stack'Last) loop
9dfe12ae 5539 Saved_Checks_Stack (J) := 0;
5540 end loop;
5541 end Kill_All_Checks;
5542
5543 -----------------
5544 -- Kill_Checks --
5545 -----------------
5546
5547 procedure Kill_Checks (V : Entity_Id) is
5548 begin
5549 if Debug_Flag_CC then
5550 w ("Kill_Checks for entity", Int (V));
5551 end if;
5552
5553 for J in 1 .. Num_Saved_Checks loop
5554 if Saved_Checks (J).Entity = V then
5555 if Debug_Flag_CC then
5556 w (" Checks killed for saved check ", J);
5557 end if;
5558
5559 Saved_Checks (J).Killed := True;
5560 end if;
5561 end loop;
5562 end Kill_Checks;
5563
ee6ba406 5564 ------------------------------
5565 -- Length_Checks_Suppressed --
5566 ------------------------------
5567
5568 function Length_Checks_Suppressed (E : Entity_Id) return Boolean is
5569 begin
9dfe12ae 5570 if Present (E) and then Checks_May_Be_Suppressed (E) then
5571 return Is_Check_Suppressed (E, Length_Check);
5572 else
5573 return Scope_Suppress (Length_Check);
5574 end if;
ee6ba406 5575 end Length_Checks_Suppressed;
5576
5577 --------------------------------
5578 -- Overflow_Checks_Suppressed --
5579 --------------------------------
5580
5581 function Overflow_Checks_Suppressed (E : Entity_Id) return Boolean is
5582 begin
9dfe12ae 5583 if Present (E) and then Checks_May_Be_Suppressed (E) then
5584 return Is_Check_Suppressed (E, Overflow_Check);
5585 else
5586 return Scope_Suppress (Overflow_Check);
5587 end if;
ee6ba406 5588 end Overflow_Checks_Suppressed;
fc75802a 5589
ee6ba406 5590 -----------------------------
5591 -- Range_Checks_Suppressed --
5592 -----------------------------
5593
5594 function Range_Checks_Suppressed (E : Entity_Id) return Boolean is
5595 begin
9dfe12ae 5596 if Present (E) then
5597
5598 -- Note: for now we always suppress range checks on Vax float types,
5599 -- since Gigi does not know how to generate these checks.
5600
5601 if Vax_Float (E) then
5602 return True;
5603 elsif Kill_Range_Checks (E) then
5604 return True;
5605 elsif Checks_May_Be_Suppressed (E) then
5606 return Is_Check_Suppressed (E, Range_Check);
5607 end if;
5608 end if;
ee6ba406 5609
9dfe12ae 5610 return Scope_Suppress (Range_Check);
ee6ba406 5611 end Range_Checks_Suppressed;
5612
0577b0b1 5613 -----------------------------------------
5614 -- Range_Or_Validity_Checks_Suppressed --
5615 -----------------------------------------
5616
5617 -- Note: the coding would be simpler here if we simply made appropriate
5618 -- calls to Range/Validity_Checks_Suppressed, but that would result in
5619 -- duplicated checks which we prefer to avoid.
5620
5621 function Range_Or_Validity_Checks_Suppressed
5622 (Expr : Node_Id) return Boolean
5623 is
5624 begin
5625 -- Immediate return if scope checks suppressed for either check
5626
5627 if Scope_Suppress (Range_Check) or Scope_Suppress (Validity_Check) then
5628 return True;
5629 end if;
5630
5631 -- If no expression, that's odd, decide that checks are suppressed,
5632 -- since we don't want anyone trying to do checks in this case, which
5633 -- is most likely the result of some other error.
5634
5635 if No (Expr) then
5636 return True;
5637 end if;
5638
5639 -- Expression is present, so perform suppress checks on type
5640
5641 declare
5642 Typ : constant Entity_Id := Etype (Expr);
5643 begin
5644 if Vax_Float (Typ) then
5645 return True;
5646 elsif Checks_May_Be_Suppressed (Typ)
5647 and then (Is_Check_Suppressed (Typ, Range_Check)
5648 or else
5649 Is_Check_Suppressed (Typ, Validity_Check))
5650 then
5651 return True;
5652 end if;
5653 end;
5654
5655 -- If expression is an entity name, perform checks on this entity
5656
5657 if Is_Entity_Name (Expr) then
5658 declare
5659 Ent : constant Entity_Id := Entity (Expr);
5660 begin
5661 if Checks_May_Be_Suppressed (Ent) then
5662 return Is_Check_Suppressed (Ent, Range_Check)
5663 or else Is_Check_Suppressed (Ent, Validity_Check);
5664 end if;
5665 end;
5666 end if;
5667
5668 -- If we fall through, no checks suppressed
5669
5670 return False;
5671 end Range_Or_Validity_Checks_Suppressed;
5672
226494a3 5673 -------------------
5674 -- Remove_Checks --
5675 -------------------
5676
5677 procedure Remove_Checks (Expr : Node_Id) is
226494a3 5678 function Process (N : Node_Id) return Traverse_Result;
5679 -- Process a single node during the traversal
5680
8f6e4fd5 5681 procedure Traverse is new Traverse_Proc (Process);
5682 -- The traversal procedure itself
226494a3 5683
5684 -------------
5685 -- Process --
5686 -------------
5687
5688 function Process (N : Node_Id) return Traverse_Result is
5689 begin
5690 if Nkind (N) not in N_Subexpr then
5691 return Skip;
5692 end if;
5693
5694 Set_Do_Range_Check (N, False);
5695
5696 case Nkind (N) is
5697 when N_And_Then =>
8f6e4fd5 5698 Traverse (Left_Opnd (N));
226494a3 5699 return Skip;
5700
5701 when N_Attribute_Reference =>
226494a3 5702 Set_Do_Overflow_Check (N, False);
5703
226494a3 5704 when N_Function_Call =>
5705 Set_Do_Tag_Check (N, False);
5706
226494a3 5707 when N_Op =>
5708 Set_Do_Overflow_Check (N, False);
5709
5710 case Nkind (N) is
5711 when N_Op_Divide =>
5712 Set_Do_Division_Check (N, False);
5713
5714 when N_Op_And =>
5715 Set_Do_Length_Check (N, False);
5716
5717 when N_Op_Mod =>
5718 Set_Do_Division_Check (N, False);
5719
5720 when N_Op_Or =>
5721 Set_Do_Length_Check (N, False);
5722
5723 when N_Op_Rem =>
5724 Set_Do_Division_Check (N, False);
5725
5726 when N_Op_Xor =>
5727 Set_Do_Length_Check (N, False);
5728
5729 when others =>
5730 null;
5731 end case;
5732
5733 when N_Or_Else =>
8f6e4fd5 5734 Traverse (Left_Opnd (N));
226494a3 5735 return Skip;
5736
5737 when N_Selected_Component =>
226494a3 5738 Set_Do_Discriminant_Check (N, False);
5739
226494a3 5740 when N_Type_Conversion =>
9dfe12ae 5741 Set_Do_Length_Check (N, False);
5742 Set_Do_Tag_Check (N, False);
226494a3 5743 Set_Do_Overflow_Check (N, False);
226494a3 5744
5745 when others =>
5746 null;
5747 end case;
5748
5749 return OK;
5750 end Process;
5751
5752 -- Start of processing for Remove_Checks
5753
5754 begin
8f6e4fd5 5755 Traverse (Expr);
226494a3 5756 end Remove_Checks;
5757
ee6ba406 5758 ----------------------------
5759 -- Selected_Length_Checks --
5760 ----------------------------
5761
5762 function Selected_Length_Checks
5763 (Ck_Node : Node_Id;
5764 Target_Typ : Entity_Id;
5765 Source_Typ : Entity_Id;
314a23b6 5766 Warn_Node : Node_Id) return Check_Result
ee6ba406 5767 is
5768 Loc : constant Source_Ptr := Sloc (Ck_Node);
5769 S_Typ : Entity_Id;
5770 T_Typ : Entity_Id;
5771 Expr_Actual : Node_Id;
5772 Exptyp : Entity_Id;
5773 Cond : Node_Id := Empty;
5774 Do_Access : Boolean := False;
5775 Wnode : Node_Id := Warn_Node;
5776 Ret_Result : Check_Result := (Empty, Empty);
5777 Num_Checks : Natural := 0;
5778
5779 procedure Add_Check (N : Node_Id);
5780 -- Adds the action given to Ret_Result if N is non-Empty
5781
5782 function Get_E_Length (E : Entity_Id; Indx : Nat) return Node_Id;
5783 function Get_N_Length (N : Node_Id; Indx : Nat) return Node_Id;
314a23b6 5784 -- Comments required ???
ee6ba406 5785
5786 function Same_Bounds (L : Node_Id; R : Node_Id) return Boolean;
5787 -- True for equal literals and for nodes that denote the same constant
5f260d20 5788 -- entity, even if its value is not a static constant. This includes the
9dfe12ae 5789 -- case of a discriminal reference within an init proc. Removes some
5f260d20 5790 -- obviously superfluous checks.
ee6ba406 5791
5792 function Length_E_Cond
5793 (Exptyp : Entity_Id;
5794 Typ : Entity_Id;
314a23b6 5795 Indx : Nat) return Node_Id;
ee6ba406 5796 -- Returns expression to compute:
5797 -- Typ'Length /= Exptyp'Length
5798
5799 function Length_N_Cond
5800 (Expr : Node_Id;
5801 Typ : Entity_Id;
314a23b6 5802 Indx : Nat) return Node_Id;
ee6ba406 5803 -- Returns expression to compute:
5804 -- Typ'Length /= Expr'Length
5805
5806 ---------------
5807 -- Add_Check --
5808 ---------------
5809
5810 procedure Add_Check (N : Node_Id) is
5811 begin
5812 if Present (N) then
5813
5814 -- For now, ignore attempt to place more than 2 checks ???
5815
5816 if Num_Checks = 2 then
5817 return;
5818 end if;
5819
5820 pragma Assert (Num_Checks <= 1);
5821 Num_Checks := Num_Checks + 1;
5822 Ret_Result (Num_Checks) := N;
5823 end if;
5824 end Add_Check;
5825
5826 ------------------
5827 -- Get_E_Length --
5828 ------------------
5829
5830 function Get_E_Length (E : Entity_Id; Indx : Nat) return Node_Id is
00c403ee 5831 SE : constant Entity_Id := Scope (E);
ee6ba406 5832 N : Node_Id;
5833 E1 : Entity_Id := E;
ee6ba406 5834
5835 begin
5836 if Ekind (Scope (E)) = E_Record_Type
5837 and then Has_Discriminants (Scope (E))
5838 then
5839 N := Build_Discriminal_Subtype_Of_Component (E);
5840
5841 if Present (N) then
5842 Insert_Action (Ck_Node, N);
5843 E1 := Defining_Identifier (N);
5844 end if;
5845 end if;
5846
5847 if Ekind (E1) = E_String_Literal_Subtype then
5848 return
5849 Make_Integer_Literal (Loc,
5850 Intval => String_Literal_Length (E1));
5851
00c403ee 5852 elsif SE /= Standard_Standard
5853 and then Ekind (Scope (SE)) = E_Protected_Type
5854 and then Has_Discriminants (Scope (SE))
5855 and then Has_Completion (Scope (SE))
ee6ba406 5856 and then not Inside_Init_Proc
5857 then
ee6ba406 5858 -- If the type whose length is needed is a private component
5859 -- constrained by a discriminant, we must expand the 'Length
5860 -- attribute into an explicit computation, using the discriminal
5861 -- of the current protected operation. This is because the actual
5862 -- type of the prival is constructed after the protected opera-
5863 -- tion has been fully expanded.
5864
5865 declare
5866 Indx_Type : Node_Id;
5867 Lo : Node_Id;
5868 Hi : Node_Id;
5869 Do_Expand : Boolean := False;
5870
5871 begin
5872 Indx_Type := First_Index (E);
5873
5874 for J in 1 .. Indx - 1 loop
5875 Next_Index (Indx_Type);
5876 end loop;
5877
2af58f67 5878 Get_Index_Bounds (Indx_Type, Lo, Hi);
ee6ba406 5879
5880 if Nkind (Lo) = N_Identifier
5881 and then Ekind (Entity (Lo)) = E_In_Parameter
5882 then
5883 Lo := Get_Discriminal (E, Lo);
5884 Do_Expand := True;
5885 end if;
5886
5887 if Nkind (Hi) = N_Identifier
5888 and then Ekind (Entity (Hi)) = E_In_Parameter
5889 then
5890 Hi := Get_Discriminal (E, Hi);
5891 Do_Expand := True;
5892 end if;
5893
5894 if Do_Expand then
5895 if not Is_Entity_Name (Lo) then
9dfe12ae 5896 Lo := Duplicate_Subexpr_No_Checks (Lo);
ee6ba406 5897 end if;
5898
5899 if not Is_Entity_Name (Hi) then
9dfe12ae 5900 Lo := Duplicate_Subexpr_No_Checks (Hi);
ee6ba406 5901 end if;
5902
5903 N :=
5904 Make_Op_Add (Loc,
5905 Left_Opnd =>
5906 Make_Op_Subtract (Loc,
5907 Left_Opnd => Hi,
5908 Right_Opnd => Lo),
5909
5910 Right_Opnd => Make_Integer_Literal (Loc, 1));
5911 return N;
5912
5913 else
5914 N :=
5915 Make_Attribute_Reference (Loc,
5916 Attribute_Name => Name_Length,
5917 Prefix =>
5918 New_Occurrence_Of (E1, Loc));
5919
5920 if Indx > 1 then
5921 Set_Expressions (N, New_List (
5922 Make_Integer_Literal (Loc, Indx)));
5923 end if;
5924
5925 return N;
5926 end if;
5927 end;
5928
5929 else
5930 N :=
5931 Make_Attribute_Reference (Loc,
5932 Attribute_Name => Name_Length,
5933 Prefix =>
5934 New_Occurrence_Of (E1, Loc));
5935
5936 if Indx > 1 then
5937 Set_Expressions (N, New_List (
5938 Make_Integer_Literal (Loc, Indx)));
5939 end if;
5940
5941 return N;
ee6ba406 5942 end if;
5943 end Get_E_Length;
5944
5945 ------------------
5946 -- Get_N_Length --
5947 ------------------
5948
5949 function Get_N_Length (N : Node_Id; Indx : Nat) return Node_Id is
5950 begin
5951 return
5952 Make_Attribute_Reference (Loc,
5953 Attribute_Name => Name_Length,
5954 Prefix =>
9dfe12ae 5955 Duplicate_Subexpr_No_Checks (N, Name_Req => True),
ee6ba406 5956 Expressions => New_List (
5957 Make_Integer_Literal (Loc, Indx)));
ee6ba406 5958 end Get_N_Length;
5959
5960 -------------------
5961 -- Length_E_Cond --
5962 -------------------
5963
5964 function Length_E_Cond
5965 (Exptyp : Entity_Id;
5966 Typ : Entity_Id;
314a23b6 5967 Indx : Nat) return Node_Id
ee6ba406 5968 is
5969 begin
5970 return
5971 Make_Op_Ne (Loc,
5972 Left_Opnd => Get_E_Length (Typ, Indx),
5973 Right_Opnd => Get_E_Length (Exptyp, Indx));
ee6ba406 5974 end Length_E_Cond;
5975
5976 -------------------
5977 -- Length_N_Cond --
5978 -------------------
5979
5980 function Length_N_Cond
5981 (Expr : Node_Id;
5982 Typ : Entity_Id;
314a23b6 5983 Indx : Nat) return Node_Id
ee6ba406 5984 is
5985 begin
5986 return
5987 Make_Op_Ne (Loc,
5988 Left_Opnd => Get_E_Length (Typ, Indx),
5989 Right_Opnd => Get_N_Length (Expr, Indx));
ee6ba406 5990 end Length_N_Cond;
5991
feff2f05 5992 -----------------
5993 -- Same_Bounds --
5994 -----------------
5995
ee6ba406 5996 function Same_Bounds (L : Node_Id; R : Node_Id) return Boolean is
5997 begin
5998 return
5999 (Nkind (L) = N_Integer_Literal
6000 and then Nkind (R) = N_Integer_Literal
6001 and then Intval (L) = Intval (R))
6002
6003 or else
6004 (Is_Entity_Name (L)
6005 and then Ekind (Entity (L)) = E_Constant
6006 and then ((Is_Entity_Name (R)
6007 and then Entity (L) = Entity (R))
6008 or else
6009 (Nkind (R) = N_Type_Conversion
6010 and then Is_Entity_Name (Expression (R))
6011 and then Entity (L) = Entity (Expression (R)))))
6012
6013 or else
6014 (Is_Entity_Name (R)
6015 and then Ekind (Entity (R)) = E_Constant
6016 and then Nkind (L) = N_Type_Conversion
6017 and then Is_Entity_Name (Expression (L))
5f260d20 6018 and then Entity (R) = Entity (Expression (L)))
6019
6020 or else
6021 (Is_Entity_Name (L)
6022 and then Is_Entity_Name (R)
6023 and then Entity (L) = Entity (R)
6024 and then Ekind (Entity (L)) = E_In_Parameter
6025 and then Inside_Init_Proc);
ee6ba406 6026 end Same_Bounds;
6027
6028 -- Start of processing for Selected_Length_Checks
6029
6030 begin
6031 if not Expander_Active then
6032 return Ret_Result;
6033 end if;
6034
6035 if Target_Typ = Any_Type
6036 or else Target_Typ = Any_Composite
6037 or else Raises_Constraint_Error (Ck_Node)
6038 then
6039 return Ret_Result;
6040 end if;
6041
6042 if No (Wnode) then
6043 Wnode := Ck_Node;
6044 end if;
6045
6046 T_Typ := Target_Typ;
6047
6048 if No (Source_Typ) then
6049 S_Typ := Etype (Ck_Node);
6050 else
6051 S_Typ := Source_Typ;
6052 end if;
6053
6054 if S_Typ = Any_Type or else S_Typ = Any_Composite then
6055 return Ret_Result;
6056 end if;
6057
6058 if Is_Access_Type (T_Typ) and then Is_Access_Type (S_Typ) then
6059 S_Typ := Designated_Type (S_Typ);
6060 T_Typ := Designated_Type (T_Typ);
6061 Do_Access := True;
6062
2af58f67 6063 -- A simple optimization for the null case
ee6ba406 6064
2af58f67 6065 if Known_Null (Ck_Node) then
ee6ba406 6066 return Ret_Result;
6067 end if;
6068 end if;
6069
6070 if Is_Array_Type (T_Typ) and then Is_Array_Type (S_Typ) then
6071 if Is_Constrained (T_Typ) then
6072
6073 -- The checking code to be generated will freeze the
6074 -- corresponding array type. However, we must freeze the
6075 -- type now, so that the freeze node does not appear within
6076 -- the generated condional expression, but ahead of it.
6077
6078 Freeze_Before (Ck_Node, T_Typ);
6079
6080 Expr_Actual := Get_Referenced_Object (Ck_Node);
84d0d4a5 6081 Exptyp := Get_Actual_Subtype (Ck_Node);
ee6ba406 6082
6083 if Is_Access_Type (Exptyp) then
6084 Exptyp := Designated_Type (Exptyp);
6085 end if;
6086
6087 -- String_Literal case. This needs to be handled specially be-
6088 -- cause no index types are available for string literals. The
6089 -- condition is simply:
6090
6091 -- T_Typ'Length = string-literal-length
6092
9dfe12ae 6093 if Nkind (Expr_Actual) = N_String_Literal
6094 and then Ekind (Etype (Expr_Actual)) = E_String_Literal_Subtype
6095 then
ee6ba406 6096 Cond :=
6097 Make_Op_Ne (Loc,
6098 Left_Opnd => Get_E_Length (T_Typ, 1),
6099 Right_Opnd =>
6100 Make_Integer_Literal (Loc,
6101 Intval =>
6102 String_Literal_Length (Etype (Expr_Actual))));
6103
6104 -- General array case. Here we have a usable actual subtype for
6105 -- the expression, and the condition is built from the two types
6106 -- (Do_Length):
6107
6108 -- T_Typ'Length /= Exptyp'Length or else
6109 -- T_Typ'Length (2) /= Exptyp'Length (2) or else
6110 -- T_Typ'Length (3) /= Exptyp'Length (3) or else
6111 -- ...
6112
6113 elsif Is_Constrained (Exptyp) then
6114 declare
9dfe12ae 6115 Ndims : constant Nat := Number_Dimensions (T_Typ);
6116
6117 L_Index : Node_Id;
6118 R_Index : Node_Id;
6119 L_Low : Node_Id;
6120 L_High : Node_Id;
6121 R_Low : Node_Id;
6122 R_High : Node_Id;
ee6ba406 6123 L_Length : Uint;
6124 R_Length : Uint;
9dfe12ae 6125 Ref_Node : Node_Id;
ee6ba406 6126
6127 begin
feff2f05 6128 -- At the library level, we need to ensure that the type of
6129 -- the object is elaborated before the check itself is
6130 -- emitted. This is only done if the object is in the
6131 -- current compilation unit, otherwise the type is frozen
6132 -- and elaborated in its unit.
9dfe12ae 6133
6134 if Is_Itype (Exptyp)
6135 and then
6136 Ekind (Cunit_Entity (Current_Sem_Unit)) = E_Package
6137 and then
6138 not In_Package_Body (Cunit_Entity (Current_Sem_Unit))
d66aa9f6 6139 and then In_Open_Scopes (Scope (Exptyp))
9dfe12ae 6140 then
6141 Ref_Node := Make_Itype_Reference (Sloc (Ck_Node));
6142 Set_Itype (Ref_Node, Exptyp);
6143 Insert_Action (Ck_Node, Ref_Node);
6144 end if;
6145
ee6ba406 6146 L_Index := First_Index (T_Typ);
6147 R_Index := First_Index (Exptyp);
6148
6149 for Indx in 1 .. Ndims loop
6150 if not (Nkind (L_Index) = N_Raise_Constraint_Error
f15731c4 6151 or else
6152 Nkind (R_Index) = N_Raise_Constraint_Error)
ee6ba406 6153 then
6154 Get_Index_Bounds (L_Index, L_Low, L_High);
6155 Get_Index_Bounds (R_Index, R_Low, R_High);
6156
6157 -- Deal with compile time length check. Note that we
6158 -- skip this in the access case, because the access
6159 -- value may be null, so we cannot know statically.
6160
6161 if not Do_Access
6162 and then Compile_Time_Known_Value (L_Low)
6163 and then Compile_Time_Known_Value (L_High)
6164 and then Compile_Time_Known_Value (R_Low)
6165 and then Compile_Time_Known_Value (R_High)
6166 then
6167 if Expr_Value (L_High) >= Expr_Value (L_Low) then
6168 L_Length := Expr_Value (L_High) -
6169 Expr_Value (L_Low) + 1;
6170 else
6171 L_Length := UI_From_Int (0);
6172 end if;
6173
6174 if Expr_Value (R_High) >= Expr_Value (R_Low) then
6175 R_Length := Expr_Value (R_High) -
6176 Expr_Value (R_Low) + 1;
6177 else
6178 R_Length := UI_From_Int (0);
6179 end if;
6180
6181 if L_Length > R_Length then
6182 Add_Check
6183 (Compile_Time_Constraint_Error
6184 (Wnode, "too few elements for}?", T_Typ));
6185
6186 elsif L_Length < R_Length then
6187 Add_Check
6188 (Compile_Time_Constraint_Error
6189 (Wnode, "too many elements for}?", T_Typ));
6190 end if;
6191
6192 -- The comparison for an individual index subtype
6193 -- is omitted if the corresponding index subtypes
6194 -- statically match, since the result is known to
6195 -- be true. Note that this test is worth while even
6196 -- though we do static evaluation, because non-static
6197 -- subtypes can statically match.
6198
6199 elsif not
6200 Subtypes_Statically_Match
6201 (Etype (L_Index), Etype (R_Index))
6202
6203 and then not
6204 (Same_Bounds (L_Low, R_Low)
6205 and then Same_Bounds (L_High, R_High))
6206 then
6207 Evolve_Or_Else
6208 (Cond, Length_E_Cond (Exptyp, T_Typ, Indx));
6209 end if;
6210
6211 Next (L_Index);
6212 Next (R_Index);
6213 end if;
6214 end loop;
6215 end;
6216
6217 -- Handle cases where we do not get a usable actual subtype that
6218 -- is constrained. This happens for example in the function call
6219 -- and explicit dereference cases. In these cases, we have to get
6220 -- the length or range from the expression itself, making sure we
6221 -- do not evaluate it more than once.
6222
6223 -- Here Ck_Node is the original expression, or more properly the
feff2f05 6224 -- result of applying Duplicate_Expr to the original tree, forcing
6225 -- the result to be a name.
ee6ba406 6226
6227 else
6228 declare
9dfe12ae 6229 Ndims : constant Nat := Number_Dimensions (T_Typ);
ee6ba406 6230
6231 begin
6232 -- Build the condition for the explicit dereference case
6233
6234 for Indx in 1 .. Ndims loop
6235 Evolve_Or_Else
6236 (Cond, Length_N_Cond (Ck_Node, T_Typ, Indx));
6237 end loop;
6238 end;
6239 end if;
6240 end if;
6241 end if;
6242
6243 -- Construct the test and insert into the tree
6244
6245 if Present (Cond) then
6246 if Do_Access then
6247 Cond := Guard_Access (Cond, Loc, Ck_Node);
6248 end if;
6249
f15731c4 6250 Add_Check
6251 (Make_Raise_Constraint_Error (Loc,
6252 Condition => Cond,
6253 Reason => CE_Length_Check_Failed));
ee6ba406 6254 end if;
6255
6256 return Ret_Result;
ee6ba406 6257 end Selected_Length_Checks;
6258
6259 ---------------------------
6260 -- Selected_Range_Checks --
6261 ---------------------------
6262
6263 function Selected_Range_Checks
6264 (Ck_Node : Node_Id;
6265 Target_Typ : Entity_Id;
6266 Source_Typ : Entity_Id;
314a23b6 6267 Warn_Node : Node_Id) return Check_Result
ee6ba406 6268 is
6269 Loc : constant Source_Ptr := Sloc (Ck_Node);
6270 S_Typ : Entity_Id;
6271 T_Typ : Entity_Id;
6272 Expr_Actual : Node_Id;
6273 Exptyp : Entity_Id;
6274 Cond : Node_Id := Empty;
6275 Do_Access : Boolean := False;
6276 Wnode : Node_Id := Warn_Node;
6277 Ret_Result : Check_Result := (Empty, Empty);
6278 Num_Checks : Integer := 0;
6279
6280 procedure Add_Check (N : Node_Id);
6281 -- Adds the action given to Ret_Result if N is non-Empty
6282
6283 function Discrete_Range_Cond
6284 (Expr : Node_Id;
314a23b6 6285 Typ : Entity_Id) return Node_Id;
ee6ba406 6286 -- Returns expression to compute:
6287 -- Low_Bound (Expr) < Typ'First
6288 -- or else
6289 -- High_Bound (Expr) > Typ'Last
6290
6291 function Discrete_Expr_Cond
6292 (Expr : Node_Id;
314a23b6 6293 Typ : Entity_Id) return Node_Id;
ee6ba406 6294 -- Returns expression to compute:
6295 -- Expr < Typ'First
6296 -- or else
6297 -- Expr > Typ'Last
6298
6299 function Get_E_First_Or_Last
3cb12758 6300 (Loc : Source_Ptr;
6301 E : Entity_Id;
ee6ba406 6302 Indx : Nat;
314a23b6 6303 Nam : Name_Id) return Node_Id;
79212397 6304 -- Returns an attribute reference
ee6ba406 6305 -- E'First or E'Last
79212397 6306 -- with a source location of Loc.
f73ee678 6307 --
79212397 6308 -- Nam is Name_First or Name_Last, according to which attribute is
6309 -- desired. If Indx is non-zero, it is passed as a literal in the
6310 -- Expressions of the attribute reference (identifying the desired
6311 -- array dimension).
ee6ba406 6312
6313 function Get_N_First (N : Node_Id; Indx : Nat) return Node_Id;
6314 function Get_N_Last (N : Node_Id; Indx : Nat) return Node_Id;
6315 -- Returns expression to compute:
9dfe12ae 6316 -- N'First or N'Last using Duplicate_Subexpr_No_Checks
ee6ba406 6317
6318 function Range_E_Cond
6319 (Exptyp : Entity_Id;
6320 Typ : Entity_Id;
6321 Indx : Nat)
6322 return Node_Id;
6323 -- Returns expression to compute:
6324 -- Exptyp'First < Typ'First or else Exptyp'Last > Typ'Last
6325
6326 function Range_Equal_E_Cond
6327 (Exptyp : Entity_Id;
6328 Typ : Entity_Id;
314a23b6 6329 Indx : Nat) return Node_Id;
ee6ba406 6330 -- Returns expression to compute:
6331 -- Exptyp'First /= Typ'First or else Exptyp'Last /= Typ'Last
6332
6333 function Range_N_Cond
6334 (Expr : Node_Id;
6335 Typ : Entity_Id;
314a23b6 6336 Indx : Nat) return Node_Id;
ee6ba406 6337 -- Return expression to compute:
6338 -- Expr'First < Typ'First or else Expr'Last > Typ'Last
6339
6340 ---------------
6341 -- Add_Check --
6342 ---------------
6343
6344 procedure Add_Check (N : Node_Id) is
6345 begin
6346 if Present (N) then
6347
6348 -- For now, ignore attempt to place more than 2 checks ???
6349
6350 if Num_Checks = 2 then
6351 return;
6352 end if;
6353
6354 pragma Assert (Num_Checks <= 1);
6355 Num_Checks := Num_Checks + 1;
6356 Ret_Result (Num_Checks) := N;
6357 end if;
6358 end Add_Check;
6359
6360 -------------------------
6361 -- Discrete_Expr_Cond --
6362 -------------------------
6363
6364 function Discrete_Expr_Cond
6365 (Expr : Node_Id;
314a23b6 6366 Typ : Entity_Id) return Node_Id
ee6ba406 6367 is
6368 begin
6369 return
6370 Make_Or_Else (Loc,
6371 Left_Opnd =>
6372 Make_Op_Lt (Loc,
6373 Left_Opnd =>
9dfe12ae 6374 Convert_To (Base_Type (Typ),
6375 Duplicate_Subexpr_No_Checks (Expr)),
ee6ba406 6376 Right_Opnd =>
6377 Convert_To (Base_Type (Typ),
3cb12758 6378 Get_E_First_Or_Last (Loc, Typ, 0, Name_First))),
ee6ba406 6379
6380 Right_Opnd =>
6381 Make_Op_Gt (Loc,
6382 Left_Opnd =>
9dfe12ae 6383 Convert_To (Base_Type (Typ),
6384 Duplicate_Subexpr_No_Checks (Expr)),
ee6ba406 6385 Right_Opnd =>
6386 Convert_To
6387 (Base_Type (Typ),
3cb12758 6388 Get_E_First_Or_Last (Loc, Typ, 0, Name_Last))));
ee6ba406 6389 end Discrete_Expr_Cond;
6390
6391 -------------------------
6392 -- Discrete_Range_Cond --
6393 -------------------------
6394
6395 function Discrete_Range_Cond
6396 (Expr : Node_Id;
314a23b6 6397 Typ : Entity_Id) return Node_Id
ee6ba406 6398 is
6399 LB : Node_Id := Low_Bound (Expr);
6400 HB : Node_Id := High_Bound (Expr);
6401
6402 Left_Opnd : Node_Id;
6403 Right_Opnd : Node_Id;
6404
6405 begin
6406 if Nkind (LB) = N_Identifier
feff2f05 6407 and then Ekind (Entity (LB)) = E_Discriminant
6408 then
ee6ba406 6409 LB := New_Occurrence_Of (Discriminal (Entity (LB)), Loc);
6410 end if;
6411
6412 if Nkind (HB) = N_Identifier
feff2f05 6413 and then Ekind (Entity (HB)) = E_Discriminant
6414 then
ee6ba406 6415 HB := New_Occurrence_Of (Discriminal (Entity (HB)), Loc);
6416 end if;
6417
6418 Left_Opnd :=
6419 Make_Op_Lt (Loc,
6420 Left_Opnd =>
6421 Convert_To
9dfe12ae 6422 (Base_Type (Typ), Duplicate_Subexpr_No_Checks (LB)),
ee6ba406 6423
6424 Right_Opnd =>
6425 Convert_To
3cb12758 6426 (Base_Type (Typ),
6427 Get_E_First_Or_Last (Loc, Typ, 0, Name_First)));
ee6ba406 6428
6429 if Base_Type (Typ) = Typ then
6430 return Left_Opnd;
6431
6432 elsif Compile_Time_Known_Value (High_Bound (Scalar_Range (Typ)))
6433 and then
6434 Compile_Time_Known_Value (High_Bound (Scalar_Range
6435 (Base_Type (Typ))))
6436 then
6437 if Is_Floating_Point_Type (Typ) then
6438 if Expr_Value_R (High_Bound (Scalar_Range (Typ))) =
6439 Expr_Value_R (High_Bound (Scalar_Range (Base_Type (Typ))))
6440 then
6441 return Left_Opnd;
6442 end if;
6443
6444 else
6445 if Expr_Value (High_Bound (Scalar_Range (Typ))) =
6446 Expr_Value (High_Bound (Scalar_Range (Base_Type (Typ))))
6447 then
6448 return Left_Opnd;
6449 end if;
6450 end if;
6451 end if;
6452
6453 Right_Opnd :=
6454 Make_Op_Gt (Loc,
6455 Left_Opnd =>
6456 Convert_To
9dfe12ae 6457 (Base_Type (Typ), Duplicate_Subexpr_No_Checks (HB)),
ee6ba406 6458
6459 Right_Opnd =>
6460 Convert_To
6461 (Base_Type (Typ),
3cb12758 6462 Get_E_First_Or_Last (Loc, Typ, 0, Name_Last)));
ee6ba406 6463
6464 return Make_Or_Else (Loc, Left_Opnd, Right_Opnd);
6465 end Discrete_Range_Cond;
6466
6467 -------------------------
6468 -- Get_E_First_Or_Last --
6469 -------------------------
6470
6471 function Get_E_First_Or_Last
3cb12758 6472 (Loc : Source_Ptr;
6473 E : Entity_Id;
ee6ba406 6474 Indx : Nat;
314a23b6 6475 Nam : Name_Id) return Node_Id
ee6ba406 6476 is
3cb12758 6477 Exprs : List_Id;
ee6ba406 6478 begin
3cb12758 6479 if Indx > 0 then
6480 Exprs := New_List (Make_Integer_Literal (Loc, UI_From_Int (Indx)));
ee6ba406 6481 else
3cb12758 6482 Exprs := No_List;
ee6ba406 6483 end if;
6484
3cb12758 6485 return Make_Attribute_Reference (Loc,
6486 Prefix => New_Occurrence_Of (E, Loc),
6487 Attribute_Name => Nam,
6488 Expressions => Exprs);
ee6ba406 6489 end Get_E_First_Or_Last;
6490
6491 -----------------
6492 -- Get_N_First --
6493 -----------------
6494
6495 function Get_N_First (N : Node_Id; Indx : Nat) return Node_Id is
6496 begin
6497 return
6498 Make_Attribute_Reference (Loc,
6499 Attribute_Name => Name_First,
6500 Prefix =>
9dfe12ae 6501 Duplicate_Subexpr_No_Checks (N, Name_Req => True),
ee6ba406 6502 Expressions => New_List (
6503 Make_Integer_Literal (Loc, Indx)));
ee6ba406 6504 end Get_N_First;
6505
6506 ----------------
6507 -- Get_N_Last --
6508 ----------------
6509
6510 function Get_N_Last (N : Node_Id; Indx : Nat) return Node_Id is
6511 begin
6512 return
6513 Make_Attribute_Reference (Loc,
6514 Attribute_Name => Name_Last,
6515 Prefix =>
9dfe12ae 6516 Duplicate_Subexpr_No_Checks (N, Name_Req => True),
ee6ba406 6517 Expressions => New_List (
6518 Make_Integer_Literal (Loc, Indx)));
ee6ba406 6519 end Get_N_Last;
6520
6521 ------------------
6522 -- Range_E_Cond --
6523 ------------------
6524
6525 function Range_E_Cond
6526 (Exptyp : Entity_Id;
6527 Typ : Entity_Id;
314a23b6 6528 Indx : Nat) return Node_Id
ee6ba406 6529 is
6530 begin
6531 return
6532 Make_Or_Else (Loc,
6533 Left_Opnd =>
6534 Make_Op_Lt (Loc,
3cb12758 6535 Left_Opnd =>
6536 Get_E_First_Or_Last (Loc, Exptyp, Indx, Name_First),
6537 Right_Opnd =>
6538 Get_E_First_Or_Last (Loc, Typ, Indx, Name_First)),
ee6ba406 6539
6540 Right_Opnd =>
6541 Make_Op_Gt (Loc,
3cb12758 6542 Left_Opnd =>
6543 Get_E_First_Or_Last (Loc, Exptyp, Indx, Name_Last),
6544 Right_Opnd =>
6545 Get_E_First_Or_Last (Loc, Typ, Indx, Name_Last)));
ee6ba406 6546 end Range_E_Cond;
6547
6548 ------------------------
6549 -- Range_Equal_E_Cond --
6550 ------------------------
6551
6552 function Range_Equal_E_Cond
6553 (Exptyp : Entity_Id;
6554 Typ : Entity_Id;
314a23b6 6555 Indx : Nat) return Node_Id
ee6ba406 6556 is
6557 begin
6558 return
6559 Make_Or_Else (Loc,
6560 Left_Opnd =>
6561 Make_Op_Ne (Loc,
3cb12758 6562 Left_Opnd =>
6563 Get_E_First_Or_Last (Loc, Exptyp, Indx, Name_First),
6564 Right_Opnd =>
6565 Get_E_First_Or_Last (Loc, Typ, Indx, Name_First)),
6566
ee6ba406 6567 Right_Opnd =>
6568 Make_Op_Ne (Loc,
3cb12758 6569 Left_Opnd =>
6570 Get_E_First_Or_Last (Loc, Exptyp, Indx, Name_Last),
6571 Right_Opnd =>
6572 Get_E_First_Or_Last (Loc, Typ, Indx, Name_Last)));
ee6ba406 6573 end Range_Equal_E_Cond;
6574
6575 ------------------
6576 -- Range_N_Cond --
6577 ------------------
6578
6579 function Range_N_Cond
6580 (Expr : Node_Id;
6581 Typ : Entity_Id;
314a23b6 6582 Indx : Nat) return Node_Id
ee6ba406 6583 is
6584 begin
6585 return
6586 Make_Or_Else (Loc,
6587 Left_Opnd =>
6588 Make_Op_Lt (Loc,
3cb12758 6589 Left_Opnd =>
6590 Get_N_First (Expr, Indx),
6591 Right_Opnd =>
6592 Get_E_First_Or_Last (Loc, Typ, Indx, Name_First)),
ee6ba406 6593
6594 Right_Opnd =>
6595 Make_Op_Gt (Loc,
3cb12758 6596 Left_Opnd =>
6597 Get_N_Last (Expr, Indx),
6598 Right_Opnd =>
6599 Get_E_First_Or_Last (Loc, Typ, Indx, Name_Last)));
ee6ba406 6600 end Range_N_Cond;
6601
6602 -- Start of processing for Selected_Range_Checks
6603
6604 begin
6605 if not Expander_Active then
6606 return Ret_Result;
6607 end if;
6608
6609 if Target_Typ = Any_Type
6610 or else Target_Typ = Any_Composite
6611 or else Raises_Constraint_Error (Ck_Node)
6612 then
6613 return Ret_Result;
6614 end if;
6615
6616 if No (Wnode) then
6617 Wnode := Ck_Node;
6618 end if;
6619
6620 T_Typ := Target_Typ;
6621
6622 if No (Source_Typ) then
6623 S_Typ := Etype (Ck_Node);
6624 else
6625 S_Typ := Source_Typ;
6626 end if;
6627
6628 if S_Typ = Any_Type or else S_Typ = Any_Composite then
6629 return Ret_Result;
6630 end if;
6631
6632 -- The order of evaluating T_Typ before S_Typ seems to be critical
6633 -- because S_Typ can be derived from Etype (Ck_Node), if it's not passed
6634 -- in, and since Node can be an N_Range node, it might be invalid.
6635 -- Should there be an assert check somewhere for taking the Etype of
6636 -- an N_Range node ???
6637
6638 if Is_Access_Type (T_Typ) and then Is_Access_Type (S_Typ) then
6639 S_Typ := Designated_Type (S_Typ);
6640 T_Typ := Designated_Type (T_Typ);
6641 Do_Access := True;
6642
2af58f67 6643 -- A simple optimization for the null case
ee6ba406 6644
2af58f67 6645 if Known_Null (Ck_Node) then
ee6ba406 6646 return Ret_Result;
6647 end if;
6648 end if;
6649
6650 -- For an N_Range Node, check for a null range and then if not
6651 -- null generate a range check action.
6652
6653 if Nkind (Ck_Node) = N_Range then
6654
6655 -- There's no point in checking a range against itself
6656
6657 if Ck_Node = Scalar_Range (T_Typ) then
6658 return Ret_Result;
6659 end if;
6660
6661 declare
6662 T_LB : constant Node_Id := Type_Low_Bound (T_Typ);
6663 T_HB : constant Node_Id := Type_High_Bound (T_Typ);
eefa141b 6664 Known_T_LB : constant Boolean := Compile_Time_Known_Value (T_LB);
6665 Known_T_HB : constant Boolean := Compile_Time_Known_Value (T_HB);
ee6ba406 6666
eefa141b 6667 LB : Node_Id := Low_Bound (Ck_Node);
6668 HB : Node_Id := High_Bound (Ck_Node);
6669 Known_LB : Boolean;
6670 Known_HB : Boolean;
6671
6672 Null_Range : Boolean;
ee6ba406 6673 Out_Of_Range_L : Boolean;
6674 Out_Of_Range_H : Boolean;
6675
6676 begin
eefa141b 6677 -- Compute what is known at compile time
6678
6679 if Known_T_LB and Known_T_HB then
6680 if Compile_Time_Known_Value (LB) then
6681 Known_LB := True;
6682
6683 -- There's no point in checking that a bound is within its
6684 -- own range so pretend that it is known in this case. First
6685 -- deal with low bound.
6686
6687 elsif Ekind (Etype (LB)) = E_Signed_Integer_Subtype
6688 and then Scalar_Range (Etype (LB)) = Scalar_Range (T_Typ)
6689 then
6690 LB := T_LB;
6691 Known_LB := True;
6692
6693 else
6694 Known_LB := False;
6695 end if;
6696
6697 -- Likewise for the high bound
6698
6699 if Compile_Time_Known_Value (HB) then
6700 Known_HB := True;
6701
6702 elsif Ekind (Etype (HB)) = E_Signed_Integer_Subtype
6703 and then Scalar_Range (Etype (HB)) = Scalar_Range (T_Typ)
6704 then
6705 HB := T_HB;
6706 Known_HB := True;
6707
6708 else
6709 Known_HB := False;
6710 end if;
6711 end if;
6712
6713 -- Check for case where everything is static and we can do the
6714 -- check at compile time. This is skipped if we have an access
6715 -- type, since the access value may be null.
6716
6717 -- ??? This code can be improved since you only need to know that
6718 -- the two respective bounds (LB & T_LB or HB & T_HB) are known at
6719 -- compile time to emit pertinent messages.
6720
6721 if Known_T_LB and Known_T_HB and Known_LB and Known_HB
6722 and not Do_Access
ee6ba406 6723 then
6724 -- Floating-point case
6725
6726 if Is_Floating_Point_Type (S_Typ) then
6727 Null_Range := Expr_Value_R (HB) < Expr_Value_R (LB);
6728 Out_Of_Range_L :=
6729 (Expr_Value_R (LB) < Expr_Value_R (T_LB))
eefa141b 6730 or else
ee6ba406 6731 (Expr_Value_R (LB) > Expr_Value_R (T_HB));
6732
6733 Out_Of_Range_H :=
6734 (Expr_Value_R (HB) > Expr_Value_R (T_HB))
eefa141b 6735 or else
ee6ba406 6736 (Expr_Value_R (HB) < Expr_Value_R (T_LB));
6737
6738 -- Fixed or discrete type case
6739
6740 else
6741 Null_Range := Expr_Value (HB) < Expr_Value (LB);
6742 Out_Of_Range_L :=
6743 (Expr_Value (LB) < Expr_Value (T_LB))
eefa141b 6744 or else
ee6ba406 6745 (Expr_Value (LB) > Expr_Value (T_HB));
6746
6747 Out_Of_Range_H :=
6748 (Expr_Value (HB) > Expr_Value (T_HB))
eefa141b 6749 or else
ee6ba406 6750 (Expr_Value (HB) < Expr_Value (T_LB));
6751 end if;
6752
6753 if not Null_Range then
6754 if Out_Of_Range_L then
6755 if No (Warn_Node) then
6756 Add_Check
6757 (Compile_Time_Constraint_Error
6758 (Low_Bound (Ck_Node),
6759 "static value out of range of}?", T_Typ));
6760
6761 else
6762 Add_Check
6763 (Compile_Time_Constraint_Error
6764 (Wnode,
6765 "static range out of bounds of}?", T_Typ));
6766 end if;
6767 end if;
6768
6769 if Out_Of_Range_H then
6770 if No (Warn_Node) then
6771 Add_Check
6772 (Compile_Time_Constraint_Error
6773 (High_Bound (Ck_Node),
6774 "static value out of range of}?", T_Typ));
6775
6776 else
6777 Add_Check
6778 (Compile_Time_Constraint_Error
6779 (Wnode,
6780 "static range out of bounds of}?", T_Typ));
6781 end if;
6782 end if;
ee6ba406 6783 end if;
6784
6785 else
6786 declare
6787 LB : Node_Id := Low_Bound (Ck_Node);
6788 HB : Node_Id := High_Bound (Ck_Node);
6789
6790 begin
feff2f05 6791 -- If either bound is a discriminant and we are within the
6792 -- record declaration, it is a use of the discriminant in a
6793 -- constraint of a component, and nothing can be checked
6794 -- here. The check will be emitted within the init proc.
6795 -- Before then, the discriminal has no real meaning.
6796 -- Similarly, if the entity is a discriminal, there is no
6797 -- check to perform yet.
6798
6799 -- The same holds within a discriminated synchronized type,
6800 -- where the discriminant may constrain a component or an
6801 -- entry family.
ee6ba406 6802
6803 if Nkind (LB) = N_Identifier
0577b0b1 6804 and then Denotes_Discriminant (LB, True)
ee6ba406 6805 then
0577b0b1 6806 if Current_Scope = Scope (Entity (LB))
6807 or else Is_Concurrent_Type (Current_Scope)
6808 or else Ekind (Entity (LB)) /= E_Discriminant
6809 then
ee6ba406 6810 return Ret_Result;
6811 else
6812 LB :=
6813 New_Occurrence_Of (Discriminal (Entity (LB)), Loc);
6814 end if;
6815 end if;
6816
6817 if Nkind (HB) = N_Identifier
0577b0b1 6818 and then Denotes_Discriminant (HB, True)
ee6ba406 6819 then
0577b0b1 6820 if Current_Scope = Scope (Entity (HB))
6821 or else Is_Concurrent_Type (Current_Scope)
6822 or else Ekind (Entity (HB)) /= E_Discriminant
6823 then
ee6ba406 6824 return Ret_Result;
6825 else
6826 HB :=
6827 New_Occurrence_Of (Discriminal (Entity (HB)), Loc);
6828 end if;
6829 end if;
6830
6831 Cond := Discrete_Range_Cond (Ck_Node, T_Typ);
6832 Set_Paren_Count (Cond, 1);
6833
6834 Cond :=
6835 Make_And_Then (Loc,
6836 Left_Opnd =>
6837 Make_Op_Ge (Loc,
9dfe12ae 6838 Left_Opnd => Duplicate_Subexpr_No_Checks (HB),
6839 Right_Opnd => Duplicate_Subexpr_No_Checks (LB)),
ee6ba406 6840 Right_Opnd => Cond);
6841 end;
ee6ba406 6842 end if;
6843 end;
6844
6845 elsif Is_Scalar_Type (S_Typ) then
6846
6847 -- This somewhat duplicates what Apply_Scalar_Range_Check does,
6848 -- except the above simply sets a flag in the node and lets
6849 -- gigi generate the check base on the Etype of the expression.
6850 -- Sometimes, however we want to do a dynamic check against an
6851 -- arbitrary target type, so we do that here.
6852
6853 if Ekind (Base_Type (S_Typ)) /= Ekind (Base_Type (T_Typ)) then
6854 Cond := Discrete_Expr_Cond (Ck_Node, T_Typ);
6855
6856 -- For literals, we can tell if the constraint error will be
6857 -- raised at compile time, so we never need a dynamic check, but
6858 -- if the exception will be raised, then post the usual warning,
6859 -- and replace the literal with a raise constraint error
6860 -- expression. As usual, skip this for access types
6861
6862 elsif Compile_Time_Known_Value (Ck_Node)
6863 and then not Do_Access
6864 then
6865 declare
6866 LB : constant Node_Id := Type_Low_Bound (T_Typ);
6867 UB : constant Node_Id := Type_High_Bound (T_Typ);
6868
6869 Out_Of_Range : Boolean;
6870 Static_Bounds : constant Boolean :=
6871 Compile_Time_Known_Value (LB)
6872 and Compile_Time_Known_Value (UB);
6873
6874 begin
6875 -- Following range tests should use Sem_Eval routine ???
6876
6877 if Static_Bounds then
6878 if Is_Floating_Point_Type (S_Typ) then
6879 Out_Of_Range :=
6880 (Expr_Value_R (Ck_Node) < Expr_Value_R (LB))
6881 or else
6882 (Expr_Value_R (Ck_Node) > Expr_Value_R (UB));
6883
eefa141b 6884 -- Fixed or discrete type
6885
6886 else
ee6ba406 6887 Out_Of_Range :=
6888 Expr_Value (Ck_Node) < Expr_Value (LB)
6889 or else
6890 Expr_Value (Ck_Node) > Expr_Value (UB);
6891 end if;
6892
eefa141b 6893 -- Bounds of the type are static and the literal is out of
6894 -- range so output a warning message.
ee6ba406 6895
6896 if Out_Of_Range then
6897 if No (Warn_Node) then
6898 Add_Check
6899 (Compile_Time_Constraint_Error
6900 (Ck_Node,
6901 "static value out of range of}?", T_Typ));
6902
6903 else
6904 Add_Check
6905 (Compile_Time_Constraint_Error
6906 (Wnode,
6907 "static value out of range of}?", T_Typ));
6908 end if;
6909 end if;
6910
6911 else
6912 Cond := Discrete_Expr_Cond (Ck_Node, T_Typ);
6913 end if;
6914 end;
6915
6916 -- Here for the case of a non-static expression, we need a runtime
6917 -- check unless the source type range is guaranteed to be in the
6918 -- range of the target type.
6919
6920 else
7a1dabb3 6921 if not In_Subrange_Of (S_Typ, T_Typ) then
ee6ba406 6922 Cond := Discrete_Expr_Cond (Ck_Node, T_Typ);
6923 end if;
6924 end if;
6925 end if;
6926
6927 if Is_Array_Type (T_Typ) and then Is_Array_Type (S_Typ) then
6928 if Is_Constrained (T_Typ) then
6929
6930 Expr_Actual := Get_Referenced_Object (Ck_Node);
6931 Exptyp := Get_Actual_Subtype (Expr_Actual);
6932
6933 if Is_Access_Type (Exptyp) then
6934 Exptyp := Designated_Type (Exptyp);
6935 end if;
6936
6937 -- String_Literal case. This needs to be handled specially be-
6938 -- cause no index types are available for string literals. The
6939 -- condition is simply:
6940
6941 -- T_Typ'Length = string-literal-length
6942
6943 if Nkind (Expr_Actual) = N_String_Literal then
6944 null;
6945
6946 -- General array case. Here we have a usable actual subtype for
6947 -- the expression, and the condition is built from the two types
6948
6949 -- T_Typ'First < Exptyp'First or else
6950 -- T_Typ'Last > Exptyp'Last or else
6951 -- T_Typ'First(1) < Exptyp'First(1) or else
6952 -- T_Typ'Last(1) > Exptyp'Last(1) or else
6953 -- ...
6954
6955 elsif Is_Constrained (Exptyp) then
6956 declare
9dfe12ae 6957 Ndims : constant Nat := Number_Dimensions (T_Typ);
6958
ee6ba406 6959 L_Index : Node_Id;
6960 R_Index : Node_Id;
ee6ba406 6961
6962 begin
6963 L_Index := First_Index (T_Typ);
6964 R_Index := First_Index (Exptyp);
6965
6966 for Indx in 1 .. Ndims loop
6967 if not (Nkind (L_Index) = N_Raise_Constraint_Error
f15731c4 6968 or else
6969 Nkind (R_Index) = N_Raise_Constraint_Error)
ee6ba406 6970 then
ee6ba406 6971 -- Deal with compile time length check. Note that we
6972 -- skip this in the access case, because the access
6973 -- value may be null, so we cannot know statically.
6974
6975 if not
6976 Subtypes_Statically_Match
6977 (Etype (L_Index), Etype (R_Index))
6978 then
6979 -- If the target type is constrained then we
6980 -- have to check for exact equality of bounds
6981 -- (required for qualified expressions).
6982
6983 if Is_Constrained (T_Typ) then
6984 Evolve_Or_Else
6985 (Cond,
6986 Range_Equal_E_Cond (Exptyp, T_Typ, Indx));
ee6ba406 6987 else
6988 Evolve_Or_Else
6989 (Cond, Range_E_Cond (Exptyp, T_Typ, Indx));
6990 end if;
6991 end if;
6992
6993 Next (L_Index);
6994 Next (R_Index);
ee6ba406 6995 end if;
6996 end loop;
6997 end;
6998
6999 -- Handle cases where we do not get a usable actual subtype that
7000 -- is constrained. This happens for example in the function call
7001 -- and explicit dereference cases. In these cases, we have to get
7002 -- the length or range from the expression itself, making sure we
7003 -- do not evaluate it more than once.
7004
7005 -- Here Ck_Node is the original expression, or more properly the
7006 -- result of applying Duplicate_Expr to the original tree,
7007 -- forcing the result to be a name.
7008
7009 else
7010 declare
9dfe12ae 7011 Ndims : constant Nat := Number_Dimensions (T_Typ);
ee6ba406 7012
7013 begin
7014 -- Build the condition for the explicit dereference case
7015
7016 for Indx in 1 .. Ndims loop
7017 Evolve_Or_Else
7018 (Cond, Range_N_Cond (Ck_Node, T_Typ, Indx));
7019 end loop;
7020 end;
ee6ba406 7021 end if;
7022
7023 else
feff2f05 7024 -- For a conversion to an unconstrained array type, generate an
7025 -- Action to check that the bounds of the source value are within
7026 -- the constraints imposed by the target type (RM 4.6(38)). No
7027 -- check is needed for a conversion to an access to unconstrained
7028 -- array type, as 4.6(24.15/2) requires the designated subtypes
7029 -- of the two access types to statically match.
7030
7031 if Nkind (Parent (Ck_Node)) = N_Type_Conversion
7032 and then not Do_Access
7033 then
ee6ba406 7034 declare
7035 Opnd_Index : Node_Id;
7036 Targ_Index : Node_Id;
00c403ee 7037 Opnd_Range : Node_Id;
ee6ba406 7038
7039 begin
feff2f05 7040 Opnd_Index := First_Index (Get_Actual_Subtype (Ck_Node));
ee6ba406 7041 Targ_Index := First_Index (T_Typ);
00c403ee 7042 while Present (Opnd_Index) loop
7043
7044 -- If the index is a range, use its bounds. If it is an
7045 -- entity (as will be the case if it is a named subtype
7046 -- or an itype created for a slice) retrieve its range.
7047
7048 if Is_Entity_Name (Opnd_Index)
7049 and then Is_Type (Entity (Opnd_Index))
7050 then
7051 Opnd_Range := Scalar_Range (Entity (Opnd_Index));
7052 else
7053 Opnd_Range := Opnd_Index;
7054 end if;
7055
7056 if Nkind (Opnd_Range) = N_Range then
9c486805 7057 if Is_In_Range
7058 (Low_Bound (Opnd_Range), Etype (Targ_Index),
7059 Assume_Valid => True)
ee6ba406 7060 and then
7061 Is_In_Range
9c486805 7062 (High_Bound (Opnd_Range), Etype (Targ_Index),
7063 Assume_Valid => True)
ee6ba406 7064 then
7065 null;
7066
feff2f05 7067 -- If null range, no check needed
f2a06be9 7068
9dfe12ae 7069 elsif
00c403ee 7070 Compile_Time_Known_Value (High_Bound (Opnd_Range))
9dfe12ae 7071 and then
00c403ee 7072 Compile_Time_Known_Value (Low_Bound (Opnd_Range))
9dfe12ae 7073 and then
00c403ee 7074 Expr_Value (High_Bound (Opnd_Range)) <
7075 Expr_Value (Low_Bound (Opnd_Range))
9dfe12ae 7076 then
7077 null;
7078
ee6ba406 7079 elsif Is_Out_Of_Range
9c486805 7080 (Low_Bound (Opnd_Range), Etype (Targ_Index),
7081 Assume_Valid => True)
ee6ba406 7082 or else
7083 Is_Out_Of_Range
9c486805 7084 (High_Bound (Opnd_Range), Etype (Targ_Index),
7085 Assume_Valid => True)
ee6ba406 7086 then
7087 Add_Check
7088 (Compile_Time_Constraint_Error
7089 (Wnode, "value out of range of}?", T_Typ));
7090
7091 else
7092 Evolve_Or_Else
7093 (Cond,
7094 Discrete_Range_Cond
00c403ee 7095 (Opnd_Range, Etype (Targ_Index)));
ee6ba406 7096 end if;
7097 end if;
7098
7099 Next_Index (Opnd_Index);
7100 Next_Index (Targ_Index);
7101 end loop;
7102 end;
7103 end if;
7104 end if;
7105 end if;
7106
7107 -- Construct the test and insert into the tree
7108
7109 if Present (Cond) then
7110 if Do_Access then
7111 Cond := Guard_Access (Cond, Loc, Ck_Node);
7112 end if;
7113
f15731c4 7114 Add_Check
7115 (Make_Raise_Constraint_Error (Loc,
eefa141b 7116 Condition => Cond,
7117 Reason => CE_Range_Check_Failed));
ee6ba406 7118 end if;
7119
7120 return Ret_Result;
ee6ba406 7121 end Selected_Range_Checks;
7122
7123 -------------------------------
7124 -- Storage_Checks_Suppressed --
7125 -------------------------------
7126
7127 function Storage_Checks_Suppressed (E : Entity_Id) return Boolean is
7128 begin
9dfe12ae 7129 if Present (E) and then Checks_May_Be_Suppressed (E) then
7130 return Is_Check_Suppressed (E, Storage_Check);
7131 else
7132 return Scope_Suppress (Storage_Check);
7133 end if;
ee6ba406 7134 end Storage_Checks_Suppressed;
7135
7136 ---------------------------
7137 -- Tag_Checks_Suppressed --
7138 ---------------------------
7139
7140 function Tag_Checks_Suppressed (E : Entity_Id) return Boolean is
7141 begin
9dfe12ae 7142 if Present (E) then
7143 if Kill_Tag_Checks (E) then
7144 return True;
7145 elsif Checks_May_Be_Suppressed (E) then
7146 return Is_Check_Suppressed (E, Tag_Check);
7147 end if;
7148 end if;
7149
7150 return Scope_Suppress (Tag_Check);
ee6ba406 7151 end Tag_Checks_Suppressed;
7152
0577b0b1 7153 --------------------------
7154 -- Validity_Check_Range --
7155 --------------------------
7156
7157 procedure Validity_Check_Range (N : Node_Id) is
7158 begin
7159 if Validity_Checks_On and Validity_Check_Operands then
7160 if Nkind (N) = N_Range then
7161 Ensure_Valid (Low_Bound (N));
7162 Ensure_Valid (High_Bound (N));
7163 end if;
7164 end if;
7165 end Validity_Check_Range;
7166
7167 --------------------------------
7168 -- Validity_Checks_Suppressed --
7169 --------------------------------
7170
7171 function Validity_Checks_Suppressed (E : Entity_Id) return Boolean is
7172 begin
7173 if Present (E) and then Checks_May_Be_Suppressed (E) then
7174 return Is_Check_Suppressed (E, Validity_Check);
7175 else
7176 return Scope_Suppress (Validity_Check);
7177 end if;
7178 end Validity_Checks_Suppressed;
7179
ee6ba406 7180end Checks;