]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/ada/checks.adb
2012-10-02 Robert Dewar <dewar@adacore.com>
[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-- --
301d5ec3 9-- Copyright (C) 1992-2012, 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;
301d5ec3 34with Exp_Tss; use Exp_Tss;
ee6ba406 35with Exp_Util; use Exp_Util;
36with Elists; use Elists;
5329ca64 37with Eval_Fat; use Eval_Fat;
ee6ba406 38with Freeze; use Freeze;
9dfe12ae 39with Lib; use Lib;
ee6ba406 40with Nlists; use Nlists;
41with Nmake; use Nmake;
42with Opt; use Opt;
9dfe12ae 43with Output; use Output;
c2b56224 44with Restrict; use Restrict;
1e16c51c 45with Rident; use Rident;
ee6ba406 46with Rtsfind; use Rtsfind;
47with Sem; use Sem;
d60c9ff7 48with Sem_Aux; use Sem_Aux;
ee6ba406 49with Sem_Eval; use Sem_Eval;
00f91aef 50with Sem_Ch3; use Sem_Ch3;
9dfe12ae 51with Sem_Ch8; use Sem_Ch8;
ee6ba406 52with Sem_Res; use Sem_Res;
53with Sem_Util; use Sem_Util;
54with Sem_Warn; use Sem_Warn;
55with Sinfo; use Sinfo;
9dfe12ae 56with Sinput; use Sinput;
ee6ba406 57with Snames; use Snames;
9dfe12ae 58with Sprint; use Sprint;
ee6ba406 59with Stand; use Stand;
f15731c4 60with Targparm; use Targparm;
ee6ba406 61with Tbuild; use Tbuild;
62with Ttypes; use Ttypes;
63with Urealp; use Urealp;
64with Validsw; use Validsw;
65
66package body Checks is
67
68 -- General note: many of these routines are concerned with generating
69 -- checking code to make sure that constraint error is raised at runtime.
70 -- Clearly this code is only needed if the expander is active, since
71 -- otherwise we will not be generating code or going into the runtime
72 -- execution anyway.
73
74 -- We therefore disconnect most of these checks if the expander is
75 -- inactive. This has the additional benefit that we do not need to
76 -- worry about the tree being messed up by previous errors (since errors
77 -- turn off expansion anyway).
78
79 -- There are a few exceptions to the above rule. For instance routines
80 -- such as Apply_Scalar_Range_Check that do not insert any code can be
81 -- safely called even when the Expander is inactive (but Errors_Detected
82 -- is 0). The benefit of executing this code when expansion is off, is
83 -- the ability to emit constraint error warning for static expressions
84 -- even when we are not generating code.
85
9dfe12ae 86 -------------------------------------
87 -- Suppression of Redundant Checks --
88 -------------------------------------
89
90 -- This unit implements a limited circuit for removal of redundant
91 -- checks. The processing is based on a tracing of simple sequential
92 -- flow. For any sequence of statements, we save expressions that are
93 -- marked to be checked, and then if the same expression appears later
94 -- with the same check, then under certain circumstances, the second
95 -- check can be suppressed.
96
97 -- Basically, we can suppress the check if we know for certain that
98 -- the previous expression has been elaborated (together with its
99 -- check), and we know that the exception frame is the same, and that
100 -- nothing has happened to change the result of the exception.
101
102 -- Let us examine each of these three conditions in turn to describe
103 -- how we ensure that this condition is met.
104
105 -- First, we need to know for certain that the previous expression has
6fb3c314 106 -- been executed. This is done principally by the mechanism of calling
9dfe12ae 107 -- Conditional_Statements_Begin at the start of any statement sequence
108 -- and Conditional_Statements_End at the end. The End call causes all
109 -- checks remembered since the Begin call to be discarded. This does
110 -- miss a few cases, notably the case of a nested BEGIN-END block with
111 -- no exception handlers. But the important thing is to be conservative.
112 -- The other protection is that all checks are discarded if a label
113 -- is encountered, since then the assumption of sequential execution
114 -- is violated, and we don't know enough about the flow.
115
116 -- Second, we need to know that the exception frame is the same. We
117 -- do this by killing all remembered checks when we enter a new frame.
118 -- Again, that's over-conservative, but generally the cases we can help
119 -- with are pretty local anyway (like the body of a loop for example).
120
121 -- Third, we must be sure to forget any checks which are no longer valid.
122 -- This is done by two mechanisms, first the Kill_Checks_Variable call is
123 -- used to note any changes to local variables. We only attempt to deal
124 -- with checks involving local variables, so we do not need to worry
125 -- about global variables. Second, a call to any non-global procedure
126 -- causes us to abandon all stored checks, since such a all may affect
127 -- the values of any local variables.
128
129 -- The following define the data structures used to deal with remembering
130 -- checks so that redundant checks can be eliminated as described above.
131
132 -- Right now, the only expressions that we deal with are of the form of
133 -- simple local objects (either declared locally, or IN parameters) or
134 -- such objects plus/minus a compile time known constant. We can do
135 -- more later on if it seems worthwhile, but this catches many simple
136 -- cases in practice.
137
138 -- The following record type reflects a single saved check. An entry
139 -- is made in the stack of saved checks if and only if the expression
140 -- has been elaborated with the indicated checks.
141
142 type Saved_Check is record
143 Killed : Boolean;
144 -- Set True if entry is killed by Kill_Checks
145
146 Entity : Entity_Id;
147 -- The entity involved in the expression that is checked
148
149 Offset : Uint;
150 -- A compile time value indicating the result of adding or
151 -- subtracting a compile time value. This value is to be
152 -- added to the value of the Entity. A value of zero is
153 -- used for the case of a simple entity reference.
154
155 Check_Type : Character;
156 -- This is set to 'R' for a range check (in which case Target_Type
157 -- is set to the target type for the range check) or to 'O' for an
158 -- overflow check (in which case Target_Type is set to Empty).
159
160 Target_Type : Entity_Id;
161 -- Used only if Do_Range_Check is set. Records the target type for
162 -- the check. We need this, because a check is a duplicate only if
6fb3c314 163 -- it has the same target type (or more accurately one with a
9dfe12ae 164 -- range that is smaller or equal to the stored target type of a
165 -- saved check).
166 end record;
167
168 -- The following table keeps track of saved checks. Rather than use an
169 -- extensible table. We just use a table of fixed size, and we discard
170 -- any saved checks that do not fit. That's very unlikely to happen and
171 -- this is only an optimization in any case.
172
173 Saved_Checks : array (Int range 1 .. 200) of Saved_Check;
174 -- Array of saved checks
175
176 Num_Saved_Checks : Nat := 0;
177 -- Number of saved checks
178
179 -- The following stack keeps track of statement ranges. It is treated
180 -- as a stack. When Conditional_Statements_Begin is called, an entry
181 -- is pushed onto this stack containing the value of Num_Saved_Checks
182 -- at the time of the call. Then when Conditional_Statements_End is
183 -- called, this value is popped off and used to reset Num_Saved_Checks.
184
185 -- Note: again, this is a fixed length stack with a size that should
186 -- always be fine. If the value of the stack pointer goes above the
187 -- limit, then we just forget all saved checks.
188
189 Saved_Checks_Stack : array (Int range 1 .. 100) of Nat;
190 Saved_Checks_TOS : Nat := 0;
191
192 -----------------------
193 -- Local Subprograms --
194 -----------------------
ee6ba406 195
0326b4d4 196 procedure Apply_Arithmetic_Overflow_Checked_Suppressed (N : Node_Id);
3cce7f32 197 -- Used to apply arithmetic overflow checks for all cases except operators
198 -- on signed arithmetic types in Minimized/Eliminate case (for which we
0326b4d4 199 -- call Apply_Arithmetic_Overflow_Minimized_Eliminated below). N is always
92f1631f 200 -- a signed integer arithmetic operator (if and case expressions are not
201 -- included for this case).
3cce7f32 202
203 procedure Apply_Arithmetic_Overflow_Minimized_Eliminated (Op : Node_Id);
204 -- Used to apply arithmetic overflow checks for the case where the overflow
205 -- checking mode is Minimized or Eliminated (and the Do_Overflow_Check flag
0326b4d4 206 -- is known to be set) and we have an signed integer arithmetic op (which
92f1631f 207 -- includes the case of if and case expressions).
3cce7f32 208
2fe22c69 209 procedure Apply_Division_Check
210 (N : Node_Id;
211 Rlo : Uint;
212 Rhi : Uint;
213 ROK : Boolean);
214 -- N is an N_Op_Div, N_Op_Rem, or N_Op_Mod node. This routine applies
215 -- division checks as required if the Do_Division_Check flag is set.
216 -- Rlo and Rhi give the possible range of the right operand, these values
217 -- can be referenced and trusted only if ROK is set True.
218
219 procedure Apply_Float_Conversion_Check
220 (Ck_Node : Node_Id;
221 Target_Typ : Entity_Id);
222 -- The checks on a conversion from a floating-point type to an integer
223 -- type are delicate. They have to be performed before conversion, they
224 -- have to raise an exception when the operand is a NaN, and rounding must
225 -- be taken into account to determine the safe bounds of the operand.
226
ee6ba406 227 procedure Apply_Selected_Length_Checks
228 (Ck_Node : Node_Id;
229 Target_Typ : Entity_Id;
230 Source_Typ : Entity_Id;
231 Do_Static : Boolean);
232 -- This is the subprogram that does all the work for Apply_Length_Check
233 -- and Apply_Static_Length_Check. Expr, Target_Typ and Source_Typ are as
234 -- described for the above routines. The Do_Static flag indicates that
235 -- only a static check is to be done.
236
237 procedure Apply_Selected_Range_Checks
238 (Ck_Node : Node_Id;
239 Target_Typ : Entity_Id;
240 Source_Typ : Entity_Id;
241 Do_Static : Boolean);
242 -- This is the subprogram that does all the work for Apply_Range_Check.
243 -- Expr, Target_Typ and Source_Typ are as described for the above
244 -- routine. The Do_Static flag indicates that only a static check is
245 -- to be done.
246
2af58f67 247 type Check_Type is new Check_Id range Access_Check .. Division_Check;
13dbf220 248 function Check_Needed (Nod : Node_Id; Check : Check_Type) return Boolean;
249 -- This function is used to see if an access or division by zero check is
250 -- needed. The check is to be applied to a single variable appearing in the
251 -- source, and N is the node for the reference. If N is not of this form,
252 -- True is returned with no further processing. If N is of the right form,
253 -- then further processing determines if the given Check is needed.
254 --
255 -- The particular circuit is to see if we have the case of a check that is
256 -- not needed because it appears in the right operand of a short circuited
257 -- conditional where the left operand guards the check. For example:
258 --
259 -- if Var = 0 or else Q / Var > 12 then
260 -- ...
261 -- end if;
262 --
263 -- In this example, the division check is not required. At the same time
264 -- we can issue warnings for suspicious use of non-short-circuited forms,
265 -- such as:
266 --
267 -- if Var = 0 or Q / Var > 12 then
268 -- ...
269 -- end if;
270
9dfe12ae 271 procedure Find_Check
272 (Expr : Node_Id;
273 Check_Type : Character;
274 Target_Type : Entity_Id;
275 Entry_OK : out Boolean;
276 Check_Num : out Nat;
277 Ent : out Entity_Id;
278 Ofs : out Uint);
279 -- This routine is used by Enable_Range_Check and Enable_Overflow_Check
280 -- to see if a check is of the form for optimization, and if so, to see
281 -- if it has already been performed. Expr is the expression to check,
282 -- and Check_Type is 'R' for a range check, 'O' for an overflow check.
283 -- Target_Type is the target type for a range check, and Empty for an
284 -- overflow check. If the entry is not of the form for optimization,
285 -- then Entry_OK is set to False, and the remaining out parameters
286 -- are undefined. If the entry is OK, then Ent/Ofs are set to the
287 -- entity and offset from the expression. Check_Num is the number of
288 -- a matching saved entry in Saved_Checks, or zero if no such entry
289 -- is located.
290
ee6ba406 291 function Get_Discriminal (E : Entity_Id; Bound : Node_Id) return Node_Id;
292 -- If a discriminal is used in constraining a prival, Return reference
293 -- to the discriminal of the protected body (which renames the parameter
294 -- of the enclosing protected operation). This clumsy transformation is
295 -- needed because privals are created too late and their actual subtypes
296 -- are not available when analysing the bodies of the protected operations.
0577b0b1 297 -- This function is called whenever the bound is an entity and the scope
298 -- indicates a protected operation. If the bound is an in-parameter of
299 -- a protected operation that is not a prival, the function returns the
300 -- bound itself.
ee6ba406 301 -- To be cleaned up???
302
303 function Guard_Access
304 (Cond : Node_Id;
305 Loc : Source_Ptr;
314a23b6 306 Ck_Node : Node_Id) return Node_Id;
ee6ba406 307 -- In the access type case, guard the test with a test to ensure
308 -- that the access value is non-null, since the checks do not
309 -- not apply to null access values.
310
311 procedure Install_Static_Check (R_Cno : Node_Id; Loc : Source_Ptr);
312 -- Called by Apply_{Length,Range}_Checks to rewrite the tree with the
313 -- Constraint_Error node.
314
3cce7f32 315 function Is_Signed_Integer_Arithmetic_Op (N : Node_Id) return Boolean;
316 -- Returns True if node N is for an arithmetic operation with signed
0326b4d4 317 -- integer operands. This includes unary and binary operators, and also
318 -- if and case expression nodes where the dependent expressions are of
319 -- a signed integer type. These are the kinds of nodes for which special
320 -- handling applies in MINIMIZED or EXTENDED overflow checking mode.
3cce7f32 321
0577b0b1 322 function Range_Or_Validity_Checks_Suppressed
323 (Expr : Node_Id) return Boolean;
324 -- Returns True if either range or validity checks or both are suppressed
325 -- for the type of the given expression, or, if the expression is the name
326 -- of an entity, if these checks are suppressed for the entity.
327
ee6ba406 328 function Selected_Length_Checks
329 (Ck_Node : Node_Id;
330 Target_Typ : Entity_Id;
331 Source_Typ : Entity_Id;
314a23b6 332 Warn_Node : Node_Id) return Check_Result;
ee6ba406 333 -- Like Apply_Selected_Length_Checks, except it doesn't modify
334 -- anything, just returns a list of nodes as described in the spec of
335 -- this package for the Range_Check function.
336
337 function Selected_Range_Checks
338 (Ck_Node : Node_Id;
339 Target_Typ : Entity_Id;
340 Source_Typ : Entity_Id;
314a23b6 341 Warn_Node : Node_Id) return Check_Result;
ee6ba406 342 -- Like Apply_Selected_Range_Checks, except it doesn't modify anything,
343 -- just returns a list of nodes as described in the spec of this package
344 -- for the Range_Check function.
345
346 ------------------------------
347 -- Access_Checks_Suppressed --
348 ------------------------------
349
350 function Access_Checks_Suppressed (E : Entity_Id) return Boolean is
351 begin
9dfe12ae 352 if Present (E) and then Checks_May_Be_Suppressed (E) then
353 return Is_Check_Suppressed (E, Access_Check);
354 else
fafc6b97 355 return Scope_Suppress.Suppress (Access_Check);
9dfe12ae 356 end if;
ee6ba406 357 end Access_Checks_Suppressed;
358
359 -------------------------------------
360 -- Accessibility_Checks_Suppressed --
361 -------------------------------------
362
363 function Accessibility_Checks_Suppressed (E : Entity_Id) return Boolean is
364 begin
9dfe12ae 365 if Present (E) and then Checks_May_Be_Suppressed (E) then
366 return Is_Check_Suppressed (E, Accessibility_Check);
367 else
fafc6b97 368 return Scope_Suppress.Suppress (Accessibility_Check);
9dfe12ae 369 end if;
ee6ba406 370 end Accessibility_Checks_Suppressed;
371
00c403ee 372 -----------------------------
373 -- Activate_Division_Check --
374 -----------------------------
375
376 procedure Activate_Division_Check (N : Node_Id) is
377 begin
378 Set_Do_Division_Check (N, True);
379 Possible_Local_Raise (N, Standard_Constraint_Error);
380 end Activate_Division_Check;
381
382 -----------------------------
383 -- Activate_Overflow_Check --
384 -----------------------------
385
386 procedure Activate_Overflow_Check (N : Node_Id) is
387 begin
388 Set_Do_Overflow_Check (N, True);
389 Possible_Local_Raise (N, Standard_Constraint_Error);
390 end Activate_Overflow_Check;
391
392 --------------------------
393 -- Activate_Range_Check --
394 --------------------------
395
396 procedure Activate_Range_Check (N : Node_Id) is
397 begin
398 Set_Do_Range_Check (N, True);
399 Possible_Local_Raise (N, Standard_Constraint_Error);
400 end Activate_Range_Check;
401
0577b0b1 402 ---------------------------------
403 -- Alignment_Checks_Suppressed --
404 ---------------------------------
405
406 function Alignment_Checks_Suppressed (E : Entity_Id) return Boolean is
407 begin
408 if Present (E) and then Checks_May_Be_Suppressed (E) then
409 return Is_Check_Suppressed (E, Alignment_Check);
410 else
fafc6b97 411 return Scope_Suppress.Suppress (Alignment_Check);
0577b0b1 412 end if;
413 end Alignment_Checks_Suppressed;
414
ee6ba406 415 -------------------------
416 -- Append_Range_Checks --
417 -------------------------
418
419 procedure Append_Range_Checks
420 (Checks : Check_Result;
421 Stmts : List_Id;
422 Suppress_Typ : Entity_Id;
423 Static_Sloc : Source_Ptr;
424 Flag_Node : Node_Id)
425 is
9dfe12ae 426 Internal_Flag_Node : constant Node_Id := Flag_Node;
427 Internal_Static_Sloc : constant Source_Ptr := Static_Sloc;
428
ee6ba406 429 Checks_On : constant Boolean :=
b6341c67 430 (not Index_Checks_Suppressed (Suppress_Typ))
431 or else (not Range_Checks_Suppressed (Suppress_Typ));
ee6ba406 432
433 begin
434 -- For now we just return if Checks_On is false, however this should
435 -- be enhanced to check for an always True value in the condition
436 -- and to generate a compilation warning???
437
438 if not Checks_On then
439 return;
440 end if;
441
442 for J in 1 .. 2 loop
443 exit when No (Checks (J));
444
445 if Nkind (Checks (J)) = N_Raise_Constraint_Error
446 and then Present (Condition (Checks (J)))
447 then
448 if not Has_Dynamic_Range_Check (Internal_Flag_Node) then
449 Append_To (Stmts, Checks (J));
450 Set_Has_Dynamic_Range_Check (Internal_Flag_Node);
451 end if;
452
453 else
454 Append_To
f15731c4 455 (Stmts,
456 Make_Raise_Constraint_Error (Internal_Static_Sloc,
457 Reason => CE_Range_Check_Failed));
ee6ba406 458 end if;
459 end loop;
460 end Append_Range_Checks;
461
462 ------------------------
463 -- Apply_Access_Check --
464 ------------------------
465
466 procedure Apply_Access_Check (N : Node_Id) is
467 P : constant Node_Id := Prefix (N);
468
469 begin
13dbf220 470 -- We do not need checks if we are not generating code (i.e. the
471 -- expander is not active). This is not just an optimization, there
472 -- are cases (e.g. with pragma Debug) where generating the checks
473 -- can cause real trouble).
284faf8b 474
6dbcfcd9 475 if not Full_Expander_Active then
13dbf220 476 return;
9dfe12ae 477 end if;
ee6ba406 478
84d0d4a5 479 -- No check if short circuiting makes check unnecessary
9dfe12ae 480
84d0d4a5 481 if not Check_Needed (P, Access_Check) then
482 return;
ee6ba406 483 end if;
9dfe12ae 484
cc60bd16 485 -- No check if accessing the Offset_To_Top component of a dispatch
486 -- table. They are safe by construction.
487
040277b1 488 if Tagged_Type_Expansion
489 and then Present (Etype (P))
cc60bd16 490 and then RTU_Loaded (Ada_Tags)
491 and then RTE_Available (RE_Offset_To_Top_Ptr)
492 and then Etype (P) = RTE (RE_Offset_To_Top_Ptr)
493 then
494 return;
495 end if;
496
84d0d4a5 497 -- Otherwise go ahead and install the check
9dfe12ae 498
fa7497e8 499 Install_Null_Excluding_Check (P);
ee6ba406 500 end Apply_Access_Check;
501
502 -------------------------------
503 -- Apply_Accessibility_Check --
504 -------------------------------
505
55dc6dc2 506 procedure Apply_Accessibility_Check
507 (N : Node_Id;
508 Typ : Entity_Id;
509 Insert_Node : Node_Id)
510 is
ee6ba406 511 Loc : constant Source_Ptr := Sloc (N);
1a9cc6cd 512 Param_Ent : Entity_Id := Param_Entity (N);
ee6ba406 513 Param_Level : Node_Id;
514 Type_Level : Node_Id;
515
516 begin
47d210a3 517 if Ada_Version >= Ada_2012
518 and then not Present (Param_Ent)
519 and then Is_Entity_Name (N)
520 and then Ekind_In (Entity (N), E_Constant, E_Variable)
521 and then Present (Effective_Extra_Accessibility (Entity (N)))
522 then
523 Param_Ent := Entity (N);
524 while Present (Renamed_Object (Param_Ent)) loop
1a9cc6cd 525
47d210a3 526 -- Renamed_Object must return an Entity_Name here
527 -- because of preceding "Present (E_E_A (...))" test.
528
529 Param_Ent := Entity (Renamed_Object (Param_Ent));
530 end loop;
531 end if;
532
ee6ba406 533 if Inside_A_Generic then
534 return;
535
6ffc64fc 536 -- Only apply the run-time check if the access parameter has an
537 -- associated extra access level parameter and when the level of the
538 -- type is less deep than the level of the access parameter, and
539 -- accessibility checks are not suppressed.
ee6ba406 540
541 elsif Present (Param_Ent)
542 and then Present (Extra_Accessibility (Param_Ent))
47d210a3 543 and then UI_Gt (Object_Access_Level (N),
1a9cc6cd 544 Deepest_Type_Access_Level (Typ))
ee6ba406 545 and then not Accessibility_Checks_Suppressed (Param_Ent)
546 and then not Accessibility_Checks_Suppressed (Typ)
547 then
548 Param_Level :=
549 New_Occurrence_Of (Extra_Accessibility (Param_Ent), Loc);
550
1a9cc6cd 551 Type_Level :=
552 Make_Integer_Literal (Loc, Deepest_Type_Access_Level (Typ));
ee6ba406 553
bf3e1520 554 -- Raise Program_Error if the accessibility level of the access
84d0d4a5 555 -- parameter is deeper than the level of the target access type.
ee6ba406 556
55dc6dc2 557 Insert_Action (Insert_Node,
ee6ba406 558 Make_Raise_Program_Error (Loc,
559 Condition =>
560 Make_Op_Gt (Loc,
561 Left_Opnd => Param_Level,
f15731c4 562 Right_Opnd => Type_Level),
563 Reason => PE_Accessibility_Check_Failed));
ee6ba406 564
565 Analyze_And_Resolve (N);
566 end if;
567 end Apply_Accessibility_Check;
568
0577b0b1 569 --------------------------------
570 -- Apply_Address_Clause_Check --
571 --------------------------------
572
573 procedure Apply_Address_Clause_Check (E : Entity_Id; N : Node_Id) is
574 AC : constant Node_Id := Address_Clause (E);
575 Loc : constant Source_Ptr := Sloc (AC);
576 Typ : constant Entity_Id := Etype (E);
577 Aexp : constant Node_Id := Expression (AC);
c2b56224 578
c2b56224 579 Expr : Node_Id;
0577b0b1 580 -- Address expression (not necessarily the same as Aexp, for example
581 -- when Aexp is a reference to a constant, in which case Expr gets
582 -- reset to reference the value expression of the constant.
583
0577b0b1 584 procedure Compile_Time_Bad_Alignment;
585 -- Post error warnings when alignment is known to be incompatible. Note
586 -- that we do not go as far as inserting a raise of Program_Error since
587 -- this is an erroneous case, and it may happen that we are lucky and an
d6da7448 588 -- underaligned address turns out to be OK after all.
0577b0b1 589
590 --------------------------------
591 -- Compile_Time_Bad_Alignment --
592 --------------------------------
593
594 procedure Compile_Time_Bad_Alignment is
595 begin
d6da7448 596 if Address_Clause_Overlay_Warnings then
0577b0b1 597 Error_Msg_FE
598 ("?specified address for& may be inconsistent with alignment ",
599 Aexp, E);
600 Error_Msg_FE
2af58f67 601 ("\?program execution may be erroneous (RM 13.3(27))",
0577b0b1 602 Aexp, E);
83f8f0a6 603 Set_Address_Warning_Posted (AC);
0577b0b1 604 end if;
605 end Compile_Time_Bad_Alignment;
c2b56224 606
2af58f67 607 -- Start of processing for Apply_Address_Clause_Check
5c61a0ff 608
c2b56224 609 begin
d6da7448 610 -- See if alignment check needed. Note that we never need a check if the
611 -- maximum alignment is one, since the check will always succeed.
612
613 -- Note: we do not check for checks suppressed here, since that check
614 -- was done in Sem_Ch13 when the address clause was processed. We are
615 -- only called if checks were not suppressed. The reason for this is
616 -- that we have to delay the call to Apply_Alignment_Check till freeze
617 -- time (so that all types etc are elaborated), but we have to check
618 -- the status of check suppressing at the point of the address clause.
619
620 if No (AC)
621 or else not Check_Address_Alignment (AC)
622 or else Maximum_Alignment = 1
623 then
624 return;
625 end if;
626
627 -- Obtain expression from address clause
9dfe12ae 628
0577b0b1 629 Expr := Expression (AC);
630
631 -- The following loop digs for the real expression to use in the check
632
633 loop
634 -- For constant, get constant expression
635
636 if Is_Entity_Name (Expr)
637 and then Ekind (Entity (Expr)) = E_Constant
638 then
639 Expr := Constant_Value (Entity (Expr));
640
641 -- For unchecked conversion, get result to convert
642
643 elsif Nkind (Expr) = N_Unchecked_Type_Conversion then
644 Expr := Expression (Expr);
645
646 -- For (common case) of To_Address call, get argument
647
648 elsif Nkind (Expr) = N_Function_Call
649 and then Is_Entity_Name (Name (Expr))
650 and then Is_RTE (Entity (Name (Expr)), RE_To_Address)
651 then
652 Expr := First (Parameter_Associations (Expr));
653
654 if Nkind (Expr) = N_Parameter_Association then
655 Expr := Explicit_Actual_Parameter (Expr);
656 end if;
657
658 -- We finally have the real expression
659
660 else
661 exit;
662 end if;
663 end loop;
664
d6da7448 665 -- See if we know that Expr has a bad alignment at compile time
c2b56224 666
667 if Compile_Time_Known_Value (Expr)
f2a06be9 668 and then (Known_Alignment (E) or else Known_Alignment (Typ))
c2b56224 669 then
f2a06be9 670 declare
671 AL : Uint := Alignment (Typ);
672
673 begin
674 -- The object alignment might be more restrictive than the
675 -- type alignment.
676
677 if Known_Alignment (E) then
678 AL := Alignment (E);
679 end if;
680
681 if Expr_Value (Expr) mod AL /= 0 then
0577b0b1 682 Compile_Time_Bad_Alignment;
683 else
684 return;
f2a06be9 685 end if;
686 end;
c2b56224 687
0577b0b1 688 -- If the expression has the form X'Address, then we can find out if
689 -- the object X has an alignment that is compatible with the object E.
d6da7448 690 -- If it hasn't or we don't know, we defer issuing the warning until
691 -- the end of the compilation to take into account back end annotations.
c2b56224 692
0577b0b1 693 elsif Nkind (Expr) = N_Attribute_Reference
694 and then Attribute_Name (Expr) = Name_Address
d6da7448 695 and then Has_Compatible_Alignment (E, Prefix (Expr)) = Known_Compatible
0577b0b1 696 then
d6da7448 697 return;
0577b0b1 698 end if;
c2b56224 699
6fb3c314 700 -- Here we do not know if the value is acceptable. Strictly we don't
701 -- have to do anything, since if the alignment is bad, we have an
702 -- erroneous program. However we are allowed to check for erroneous
703 -- conditions and we decide to do this by default if the check is not
704 -- suppressed.
0577b0b1 705
706 -- However, don't do the check if elaboration code is unwanted
707
708 if Restriction_Active (No_Elaboration_Code) then
709 return;
710
711 -- Generate a check to raise PE if alignment may be inappropriate
712
713 else
714 -- If the original expression is a non-static constant, use the
715 -- name of the constant itself rather than duplicating its
00c403ee 716 -- defining expression, which was extracted above.
0577b0b1 717
00c403ee 718 -- Note: Expr is empty if the address-clause is applied to in-mode
719 -- actuals (allowed by 13.1(22)).
720
721 if not Present (Expr)
722 or else
723 (Is_Entity_Name (Expression (AC))
724 and then Ekind (Entity (Expression (AC))) = E_Constant
725 and then Nkind (Parent (Entity (Expression (AC))))
726 = N_Object_Declaration)
0577b0b1 727 then
728 Expr := New_Copy_Tree (Expression (AC));
729 else
730 Remove_Side_Effects (Expr);
c2b56224 731 end if;
c2b56224 732
0577b0b1 733 Insert_After_And_Analyze (N,
734 Make_Raise_Program_Error (Loc,
735 Condition =>
736 Make_Op_Ne (Loc,
737 Left_Opnd =>
738 Make_Op_Mod (Loc,
739 Left_Opnd =>
740 Unchecked_Convert_To
741 (RTE (RE_Integer_Address), Expr),
742 Right_Opnd =>
743 Make_Attribute_Reference (Loc,
744 Prefix => New_Occurrence_Of (E, Loc),
745 Attribute_Name => Name_Alignment)),
746 Right_Opnd => Make_Integer_Literal (Loc, Uint_0)),
747 Reason => PE_Misaligned_Address_Value),
748 Suppress => All_Checks);
749 return;
750 end if;
9dfe12ae 751
752 exception
0577b0b1 753 -- If we have some missing run time component in configurable run time
754 -- mode then just skip the check (it is not required in any case).
755
9dfe12ae 756 when RE_Not_Available =>
757 return;
0577b0b1 758 end Apply_Address_Clause_Check;
c2b56224 759
ee6ba406 760 -------------------------------------
761 -- Apply_Arithmetic_Overflow_Check --
762 -------------------------------------
763
3cce7f32 764 procedure Apply_Arithmetic_Overflow_Check (N : Node_Id) is
765 begin
766 -- Use old routine in almost all cases (the only case we are treating
767 -- specially is the case of an signed integer arithmetic op with the
768 -- Do_Overflow_Check flag set on the node, and the overflow checking
769 -- mode is either Minimized_Or_Eliminated.
770
771 if Overflow_Check_Mode (Etype (N)) not in Minimized_Or_Eliminated
772 or else not Do_Overflow_Check (N)
773 or else not Is_Signed_Integer_Arithmetic_Op (N)
774 then
0326b4d4 775 Apply_Arithmetic_Overflow_Checked_Suppressed (N);
3cce7f32 776
777 -- Otherwise use the new routine for Minimized/Eliminated modes for
778 -- the case of a signed integer arithmetic op, with Do_Overflow_Check
779 -- set True, and the checking mode is Minimized_Or_Eliminated.
780
781 else
782 Apply_Arithmetic_Overflow_Minimized_Eliminated (N);
783 end if;
784 end Apply_Arithmetic_Overflow_Check;
785
0326b4d4 786 --------------------------------------------------
787 -- Apply_Arithmetic_Overflow_Checked_Suppressed --
788 --------------------------------------------------
3cce7f32 789
f40f9731 790 -- This routine is called only if the type is an integer type, and a
791 -- software arithmetic overflow check may be needed for op (add, subtract,
792 -- or multiply). This check is performed only if Software_Overflow_Checking
793 -- is enabled and Do_Overflow_Check is set. In this case we expand the
794 -- operation into a more complex sequence of tests that ensures that
795 -- overflow is properly caught.
ee6ba406 796
3cce7f32 797 -- This is used in SUPPRESSED/CHECKED modes. It is identical to the
798 -- code for these cases before the big overflow earthquake, thus ensuring
799 -- that in these modes we have compatible behavior (and realibility) to
800 -- what was there before. It is also called for types other than signed
801 -- integers, and if the Do_Overflow_Check flag is off.
802
803 -- Note: we also call this routine if we decide in the MINIMIZED case
804 -- to give up and just generate an overflow check without any fuss.
805
0326b4d4 806 procedure Apply_Arithmetic_Overflow_Checked_Suppressed (N : Node_Id) is
ee6ba406 807 Loc : constant Source_Ptr := Sloc (N);
780bfb21 808 Typ : constant Entity_Id := Etype (N);
809 Rtyp : constant Entity_Id := Root_Type (Typ);
ee6ba406 810
811 begin
f40f9731 812 -- An interesting special case. If the arithmetic operation appears as
813 -- the operand of a type conversion:
814
815 -- type1 (x op y)
816
817 -- and all the following conditions apply:
818
819 -- arithmetic operation is for a signed integer type
820 -- target type type1 is a static integer subtype
821 -- range of x and y are both included in the range of type1
822 -- range of x op y is included in the range of type1
823 -- size of type1 is at least twice the result size of op
824
825 -- then we don't do an overflow check in any case, instead we transform
826 -- the operation so that we end up with:
827
828 -- type1 (type1 (x) op type1 (y))
829
830 -- This avoids intermediate overflow before the conversion. It is
831 -- explicitly permitted by RM 3.5.4(24):
832
833 -- For the execution of a predefined operation of a signed integer
834 -- type, the implementation need not raise Constraint_Error if the
835 -- result is outside the base range of the type, so long as the
836 -- correct result is produced.
837
838 -- It's hard to imagine that any programmer counts on the exception
839 -- being raised in this case, and in any case it's wrong coding to
840 -- have this expectation, given the RM permission. Furthermore, other
841 -- Ada compilers do allow such out of range results.
842
843 -- Note that we do this transformation even if overflow checking is
844 -- off, since this is precisely about giving the "right" result and
845 -- avoiding the need for an overflow check.
846
8eb4a5eb 847 -- Note: this circuit is partially redundant with respect to the similar
848 -- processing in Exp_Ch4.Expand_N_Type_Conversion, but the latter deals
849 -- with cases that do not come through here. We still need the following
850 -- processing even with the Exp_Ch4 code in place, since we want to be
851 -- sure not to generate the arithmetic overflow check in these cases
852 -- (Exp_Ch4 would have a hard time removing them once generated).
853
f40f9731 854 if Is_Signed_Integer_Type (Typ)
855 and then Nkind (Parent (N)) = N_Type_Conversion
ee6ba406 856 then
f40f9731 857 declare
858 Target_Type : constant Entity_Id :=
b6341c67 859 Base_Type (Entity (Subtype_Mark (Parent (N))));
f40f9731 860
861 Llo, Lhi : Uint;
862 Rlo, Rhi : Uint;
863 LOK, ROK : Boolean;
864
865 Vlo : Uint;
866 Vhi : Uint;
867 VOK : Boolean;
868
869 Tlo : Uint;
870 Thi : Uint;
871
872 begin
873 if Is_Integer_Type (Target_Type)
874 and then RM_Size (Root_Type (Target_Type)) >= 2 * RM_Size (Rtyp)
875 then
876 Tlo := Expr_Value (Type_Low_Bound (Target_Type));
877 Thi := Expr_Value (Type_High_Bound (Target_Type));
878
9c486805 879 Determine_Range
880 (Left_Opnd (N), LOK, Llo, Lhi, Assume_Valid => True);
881 Determine_Range
882 (Right_Opnd (N), ROK, Rlo, Rhi, Assume_Valid => True);
f40f9731 883
884 if (LOK and ROK)
885 and then Tlo <= Llo and then Lhi <= Thi
886 and then Tlo <= Rlo and then Rhi <= Thi
887 then
9c486805 888 Determine_Range (N, VOK, Vlo, Vhi, Assume_Valid => True);
f40f9731 889
890 if VOK and then Tlo <= Vlo and then Vhi <= Thi then
891 Rewrite (Left_Opnd (N),
892 Make_Type_Conversion (Loc,
893 Subtype_Mark => New_Occurrence_Of (Target_Type, Loc),
894 Expression => Relocate_Node (Left_Opnd (N))));
895
896 Rewrite (Right_Opnd (N),
897 Make_Type_Conversion (Loc,
898 Subtype_Mark => New_Occurrence_Of (Target_Type, Loc),
899 Expression => Relocate_Node (Right_Opnd (N))));
900
780bfb21 901 -- Rewrite the conversion operand so that the original
902 -- node is retained, in order to avoid the warning for
903 -- redundant conversions in Resolve_Type_Conversion.
904
905 Rewrite (N, Relocate_Node (N));
906
f40f9731 907 Set_Etype (N, Target_Type);
780bfb21 908
f40f9731 909 Analyze_And_Resolve (Left_Opnd (N), Target_Type);
910 Analyze_And_Resolve (Right_Opnd (N), Target_Type);
911
912 -- Given that the target type is twice the size of the
913 -- source type, overflow is now impossible, so we can
914 -- safely kill the overflow check and return.
915
916 Set_Do_Overflow_Check (N, False);
917 return;
918 end if;
919 end if;
920 end if;
921 end;
ee6ba406 922 end if;
923
f40f9731 924 -- Now see if an overflow check is required
925
926 declare
927 Siz : constant Int := UI_To_Int (Esize (Rtyp));
928 Dsiz : constant Int := Siz * 2;
929 Opnod : Node_Id;
930 Ctyp : Entity_Id;
931 Opnd : Node_Id;
932 Cent : RE_Id;
ee6ba406 933
f40f9731 934 begin
935 -- Skip check if back end does overflow checks, or the overflow flag
df40eeb0 936 -- is not set anyway, or we are not doing code expansion, or the
937 -- parent node is a type conversion whose operand is an arithmetic
938 -- operation on signed integers on which the expander can promote
bbbed24b 939 -- later the operands to type Integer (see Expand_N_Type_Conversion).
ee6ba406 940
f40f9731 941 -- Special case CLI target, where arithmetic overflow checks can be
942 -- performed for integer and long_integer
ee6ba406 943
f40f9731 944 if Backend_Overflow_Checks_On_Target
945 or else not Do_Overflow_Check (N)
6dbcfcd9 946 or else not Full_Expander_Active
df40eeb0 947 or else (Present (Parent (N))
948 and then Nkind (Parent (N)) = N_Type_Conversion
949 and then Integer_Promotion_Possible (Parent (N)))
f40f9731 950 or else
951 (VM_Target = CLI_Target and then Siz >= Standard_Integer_Size)
952 then
953 return;
954 end if;
ee6ba406 955
f40f9731 956 -- Otherwise, generate the full general code for front end overflow
957 -- detection, which works by doing arithmetic in a larger type:
ee6ba406 958
f40f9731 959 -- x op y
ee6ba406 960
f40f9731 961 -- is expanded into
ee6ba406 962
f40f9731 963 -- Typ (Checktyp (x) op Checktyp (y));
ee6ba406 964
f40f9731 965 -- where Typ is the type of the original expression, and Checktyp is
966 -- an integer type of sufficient length to hold the largest possible
967 -- result.
ee6ba406 968
f40f9731 969 -- If the size of check type exceeds the size of Long_Long_Integer,
970 -- we use a different approach, expanding to:
ee6ba406 971
f40f9731 972 -- typ (xxx_With_Ovflo_Check (Integer_64 (x), Integer (y)))
ee6ba406 973
f40f9731 974 -- where xxx is Add, Multiply or Subtract as appropriate
ee6ba406 975
f40f9731 976 -- Find check type if one exists
977
978 if Dsiz <= Standard_Integer_Size then
979 Ctyp := Standard_Integer;
ee6ba406 980
f40f9731 981 elsif Dsiz <= Standard_Long_Long_Integer_Size then
982 Ctyp := Standard_Long_Long_Integer;
983
984 -- No check type exists, use runtime call
ee6ba406 985
986 else
f40f9731 987 if Nkind (N) = N_Op_Add then
988 Cent := RE_Add_With_Ovflo_Check;
ee6ba406 989
f40f9731 990 elsif Nkind (N) = N_Op_Multiply then
991 Cent := RE_Multiply_With_Ovflo_Check;
ee6ba406 992
f40f9731 993 else
994 pragma Assert (Nkind (N) = N_Op_Subtract);
995 Cent := RE_Subtract_With_Ovflo_Check;
996 end if;
997
998 Rewrite (N,
999 OK_Convert_To (Typ,
1000 Make_Function_Call (Loc,
1001 Name => New_Reference_To (RTE (Cent), Loc),
1002 Parameter_Associations => New_List (
1003 OK_Convert_To (RTE (RE_Integer_64), Left_Opnd (N)),
1004 OK_Convert_To (RTE (RE_Integer_64), Right_Opnd (N))))));
ee6ba406 1005
f40f9731 1006 Analyze_And_Resolve (N, Typ);
1007 return;
1008 end if;
ee6ba406 1009
f40f9731 1010 -- If we fall through, we have the case where we do the arithmetic
1011 -- in the next higher type and get the check by conversion. In these
1012 -- cases Ctyp is set to the type to be used as the check type.
ee6ba406 1013
f40f9731 1014 Opnod := Relocate_Node (N);
ee6ba406 1015
f40f9731 1016 Opnd := OK_Convert_To (Ctyp, Left_Opnd (Opnod));
ee6ba406 1017
f40f9731 1018 Analyze (Opnd);
1019 Set_Etype (Opnd, Ctyp);
1020 Set_Analyzed (Opnd, True);
1021 Set_Left_Opnd (Opnod, Opnd);
ee6ba406 1022
f40f9731 1023 Opnd := OK_Convert_To (Ctyp, Right_Opnd (Opnod));
ee6ba406 1024
f40f9731 1025 Analyze (Opnd);
1026 Set_Etype (Opnd, Ctyp);
1027 Set_Analyzed (Opnd, True);
1028 Set_Right_Opnd (Opnod, Opnd);
ee6ba406 1029
f40f9731 1030 -- The type of the operation changes to the base type of the check
1031 -- type, and we reset the overflow check indication, since clearly no
1032 -- overflow is possible now that we are using a double length type.
1033 -- We also set the Analyzed flag to avoid a recursive attempt to
1034 -- expand the node.
ee6ba406 1035
f40f9731 1036 Set_Etype (Opnod, Base_Type (Ctyp));
1037 Set_Do_Overflow_Check (Opnod, False);
1038 Set_Analyzed (Opnod, True);
ee6ba406 1039
f40f9731 1040 -- Now build the outer conversion
ee6ba406 1041
f40f9731 1042 Opnd := OK_Convert_To (Typ, Opnod);
1043 Analyze (Opnd);
1044 Set_Etype (Opnd, Typ);
9dfe12ae 1045
f40f9731 1046 -- In the discrete type case, we directly generate the range check
1047 -- for the outer operand. This range check will implement the
1048 -- required overflow check.
9dfe12ae 1049
f40f9731 1050 if Is_Discrete_Type (Typ) then
1051 Rewrite (N, Opnd);
1052 Generate_Range_Check
1053 (Expression (N), Typ, CE_Overflow_Check_Failed);
9dfe12ae 1054
f40f9731 1055 -- For other types, we enable overflow checking on the conversion,
1056 -- after setting the node as analyzed to prevent recursive attempts
1057 -- to expand the conversion node.
9dfe12ae 1058
f40f9731 1059 else
1060 Set_Analyzed (Opnd, True);
1061 Enable_Overflow_Check (Opnd);
1062 Rewrite (N, Opnd);
1063 end if;
1064
1065 exception
1066 when RE_Not_Available =>
1067 return;
1068 end;
0326b4d4 1069 end Apply_Arithmetic_Overflow_Checked_Suppressed;
3cce7f32 1070
1071 ----------------------------------------------------
1072 -- Apply_Arithmetic_Overflow_Minimized_Eliminated --
1073 ----------------------------------------------------
1074
1075 procedure Apply_Arithmetic_Overflow_Minimized_Eliminated (Op : Node_Id) is
1076 pragma Assert (Is_Signed_Integer_Arithmetic_Op (Op));
1077 pragma Assert (Do_Overflow_Check (Op));
1078
1079 Loc : constant Source_Ptr := Sloc (Op);
1080 P : constant Node_Id := Parent (Op);
1081
49b3a812 1082 LLIB : constant Entity_Id := Base_Type (Standard_Long_Long_Integer);
1083 -- Operands and results are of this type when we convert
1084
3cce7f32 1085 Result_Type : constant Entity_Id := Etype (Op);
1086 -- Original result type
1087
1088 Check_Mode : constant Overflow_Check_Type :=
0326b4d4 1089 Overflow_Check_Mode (Etype (Op));
3cce7f32 1090 pragma Assert (Check_Mode in Minimized_Or_Eliminated);
1091
1092 Lo, Hi : Uint;
1093 -- Ranges of values for result
1094
1095 begin
1096 -- Nothing to do if our parent is one of the following:
1097
0326b4d4 1098 -- Another signed integer arithmetic op
3cce7f32 1099 -- A membership operation
1100 -- A comparison operation
1101
1102 -- In all these cases, we will process at the higher level (and then
1103 -- this node will be processed during the downwards recursion that
1104 -- is part of the processing in Minimize_Eliminate_Overflow_Checks.
1105
1106 if Is_Signed_Integer_Arithmetic_Op (P)
1107 or else Nkind (Op) in N_Membership_Test
1108 or else Nkind (Op) in N_Op_Compare
aa4b16cb 1109
1110 -- We may also be a range operand in a membership test
1111
1112 or else (Nkind (Op) = N_Range
1113 and then Nkind (Parent (Op)) in N_Membership_Test)
1114
3cce7f32 1115 then
1116 return;
1117 end if;
1118
0326b4d4 1119 -- Otherwise, we have a top level arithmetic operation node, and this
3cce7f32 1120 -- is where we commence the special processing for minimize/eliminate.
61016a7a 1121 -- This is the case where we tell the machinery not to move into Bignum
1122 -- mode at this top level (of course the top level operation will still
1123 -- be in Bignum mode if either of its operands are of type Bignum).
3cce7f32 1124
61016a7a 1125 Minimize_Eliminate_Overflow_Checks (Op, Lo, Hi, Top_Level => True);
3cce7f32 1126
1127 -- That call may but does not necessarily change the result type of Op.
1128 -- It is the job of this routine to undo such changes, so that at the
1129 -- top level, we have the proper type. This "undoing" is a point at
1130 -- which a final overflow check may be applied.
1131
1132 -- If the result type was not fiddled we are all set
1133
1134 if Etype (Op) = Result_Type then
1135 return;
1136
1137 -- Bignum case
1138
49b3a812 1139 elsif Is_RTE (Etype (Op), RE_Bignum) then
3cce7f32 1140
d94b5da2 1141 -- We need a sequence that looks like:
3cce7f32 1142
1143 -- Rnn : Result_Type;
1144
1145 -- declare
d94b5da2 1146 -- M : Mark_Id := SS_Mark;
3cce7f32 1147 -- begin
49b3a812 1148 -- Rnn := Long_Long_Integer'Base (From_Bignum (Op));
3cce7f32 1149 -- SS_Release (M);
1150 -- end;
1151
1152 -- This block is inserted (using Insert_Actions), and then the node
1153 -- is replaced with a reference to Rnn.
1154
1155 -- A special case arises if our parent is a conversion node. In this
1156 -- case no point in generating a conversion to Result_Type, we will
1157 -- let the parent handle this. Note that this special case is not
1158 -- just about optimization. Consider
1159
1160 -- A,B,C : Integer;
1161 -- ...
49b3a812 1162 -- X := Long_Long_Integer'Base (A * (B ** C));
3cce7f32 1163
1164 -- Now the product may fit in Long_Long_Integer but not in Integer.
1165 -- In Minimize/Eliminate mode, we don't want to introduce an overflow
1166 -- exception for this intermediate value.
1167
1168 declare
49b3a812 1169 Blk : constant Node_Id := Make_Bignum_Block (Loc);
3cce7f32 1170 Rnn : constant Entity_Id := Make_Temporary (Loc, 'R', Op);
1171 RHS : Node_Id;
1172
1173 Rtype : Entity_Id;
1174
1175 begin
1176 RHS := Convert_From_Bignum (Op);
1177
1178 if Nkind (P) /= N_Type_Conversion then
49b3a812 1179 Convert_To_And_Rewrite (Result_Type, RHS);
3cce7f32 1180 Rtype := Result_Type;
1181
1182 -- Interesting question, do we need a check on that conversion
1183 -- operation. Answer, not if we know the result is in range.
1184 -- At the moment we are not taking advantage of this. To be
1185 -- looked at later ???
1186
1187 else
49b3a812 1188 Rtype := LLIB;
3cce7f32 1189 end if;
1190
1191 Insert_Before
1192 (First (Statements (Handled_Statement_Sequence (Blk))),
1193 Make_Assignment_Statement (Loc,
1194 Name => New_Occurrence_Of (Rnn, Loc),
1195 Expression => RHS));
1196
1197 Insert_Actions (Op, New_List (
1198 Make_Object_Declaration (Loc,
1199 Defining_Identifier => Rnn,
1200 Object_Definition => New_Occurrence_Of (Rtype, Loc)),
1201 Blk));
1202
1203 Rewrite (Op, New_Occurrence_Of (Rnn, Loc));
1204 Analyze_And_Resolve (Op);
1205 end;
1206
49b3a812 1207 -- Here we know the result is Long_Long_Integer'Base
3cce7f32 1208
1209 else
49b3a812 1210 pragma Assert (Etype (Op) = LLIB);
3cce7f32 1211
1212 -- All we need to do here is to convert the result to the proper
1213 -- result type. As explained above for the Bignum case, we can
1214 -- omit this if our parent is a type conversion.
1215
1216 if Nkind (P) /= N_Type_Conversion then
1217 Convert_To_And_Rewrite (Result_Type, Op);
1218 end if;
1219
1220 Analyze_And_Resolve (Op);
1221 end if;
1222 end Apply_Arithmetic_Overflow_Minimized_Eliminated;
ee6ba406 1223
ee6ba406 1224 ----------------------------
1225 -- Apply_Constraint_Check --
1226 ----------------------------
1227
1228 procedure Apply_Constraint_Check
1229 (N : Node_Id;
1230 Typ : Entity_Id;
1231 No_Sliding : Boolean := False)
1232 is
1233 Desig_Typ : Entity_Id;
1234
1235 begin
7aafae1c 1236 -- No checks inside a generic (check the instantiations)
1237
ee6ba406 1238 if Inside_A_Generic then
1239 return;
7aafae1c 1240 end if;
ee6ba406 1241
6fb3c314 1242 -- Apply required constraint checks
7aafae1c 1243
1244 if Is_Scalar_Type (Typ) then
ee6ba406 1245 Apply_Scalar_Range_Check (N, Typ);
1246
1247 elsif Is_Array_Type (Typ) then
1248
05fcfafb 1249 -- A useful optimization: an aggregate with only an others clause
5f260d20 1250 -- always has the right bounds.
1251
1252 if Nkind (N) = N_Aggregate
1253 and then No (Expressions (N))
1254 and then Nkind
1255 (First (Choices (First (Component_Associations (N)))))
1256 = N_Others_Choice
1257 then
1258 return;
1259 end if;
1260
ee6ba406 1261 if Is_Constrained (Typ) then
1262 Apply_Length_Check (N, Typ);
1263
1264 if No_Sliding then
1265 Apply_Range_Check (N, Typ);
1266 end if;
1267 else
1268 Apply_Range_Check (N, Typ);
1269 end if;
1270
1271 elsif (Is_Record_Type (Typ)
1272 or else Is_Private_Type (Typ))
1273 and then Has_Discriminants (Base_Type (Typ))
1274 and then Is_Constrained (Typ)
1275 then
1276 Apply_Discriminant_Check (N, Typ);
1277
1278 elsif Is_Access_Type (Typ) then
1279
1280 Desig_Typ := Designated_Type (Typ);
1281
1282 -- No checks necessary if expression statically null
1283
2af58f67 1284 if Known_Null (N) then
00c403ee 1285 if Can_Never_Be_Null (Typ) then
1286 Install_Null_Excluding_Check (N);
1287 end if;
ee6ba406 1288
1289 -- No sliding possible on access to arrays
1290
1291 elsif Is_Array_Type (Desig_Typ) then
1292 if Is_Constrained (Desig_Typ) then
1293 Apply_Length_Check (N, Typ);
1294 end if;
1295
1296 Apply_Range_Check (N, Typ);
1297
1298 elsif Has_Discriminants (Base_Type (Desig_Typ))
1299 and then Is_Constrained (Desig_Typ)
1300 then
1301 Apply_Discriminant_Check (N, Typ);
1302 end if;
fa7497e8 1303
bf3e1520 1304 -- Apply the 2005 Null_Excluding check. Note that we do not apply
00c403ee 1305 -- this check if the constraint node is illegal, as shown by having
1306 -- an error posted. This additional guard prevents cascaded errors
1307 -- and compiler aborts on illegal programs involving Ada 2005 checks.
1308
fa7497e8 1309 if Can_Never_Be_Null (Typ)
1310 and then not Can_Never_Be_Null (Etype (N))
00c403ee 1311 and then not Error_Posted (N)
fa7497e8 1312 then
1313 Install_Null_Excluding_Check (N);
1314 end if;
ee6ba406 1315 end if;
1316 end Apply_Constraint_Check;
1317
1318 ------------------------------
1319 -- Apply_Discriminant_Check --
1320 ------------------------------
1321
1322 procedure Apply_Discriminant_Check
1323 (N : Node_Id;
1324 Typ : Entity_Id;
1325 Lhs : Node_Id := Empty)
1326 is
1327 Loc : constant Source_Ptr := Sloc (N);
1328 Do_Access : constant Boolean := Is_Access_Type (Typ);
1329 S_Typ : Entity_Id := Etype (N);
1330 Cond : Node_Id;
1331 T_Typ : Entity_Id;
1332
7be5088a 1333 function Denotes_Explicit_Dereference (Obj : Node_Id) return Boolean;
1334 -- A heap object with an indefinite subtype is constrained by its
1335 -- initial value, and assigning to it requires a constraint_check.
1336 -- The target may be an explicit dereference, or a renaming of one.
1337
ee6ba406 1338 function Is_Aliased_Unconstrained_Component return Boolean;
1339 -- It is possible for an aliased component to have a nominal
1340 -- unconstrained subtype (through instantiation). If this is a
1341 -- discriminated component assigned in the expansion of an aggregate
1342 -- in an initialization, the check must be suppressed. This unusual
2af58f67 1343 -- situation requires a predicate of its own.
ee6ba406 1344
7be5088a 1345 ----------------------------------
1346 -- Denotes_Explicit_Dereference --
1347 ----------------------------------
1348
1349 function Denotes_Explicit_Dereference (Obj : Node_Id) return Boolean is
1350 begin
1351 return
1352 Nkind (Obj) = N_Explicit_Dereference
1353 or else
1354 (Is_Entity_Name (Obj)
1355 and then Present (Renamed_Object (Entity (Obj)))
9474aa9c 1356 and then Nkind (Renamed_Object (Entity (Obj))) =
1357 N_Explicit_Dereference);
7be5088a 1358 end Denotes_Explicit_Dereference;
1359
ee6ba406 1360 ----------------------------------------
1361 -- Is_Aliased_Unconstrained_Component --
1362 ----------------------------------------
1363
1364 function Is_Aliased_Unconstrained_Component return Boolean is
1365 Comp : Entity_Id;
1366 Pref : Node_Id;
1367
1368 begin
1369 if Nkind (Lhs) /= N_Selected_Component then
1370 return False;
1371 else
1372 Comp := Entity (Selector_Name (Lhs));
1373 Pref := Prefix (Lhs);
1374 end if;
1375
1376 if Ekind (Comp) /= E_Component
1377 or else not Is_Aliased (Comp)
1378 then
1379 return False;
1380 end if;
1381
1382 return not Comes_From_Source (Pref)
1383 and then In_Instance
1384 and then not Is_Constrained (Etype (Comp));
1385 end Is_Aliased_Unconstrained_Component;
1386
1387 -- Start of processing for Apply_Discriminant_Check
1388
1389 begin
1390 if Do_Access then
1391 T_Typ := Designated_Type (Typ);
1392 else
1393 T_Typ := Typ;
1394 end if;
1395
1396 -- Nothing to do if discriminant checks are suppressed or else no code
1397 -- is to be generated
1398
6dbcfcd9 1399 if not Full_Expander_Active
ee6ba406 1400 or else Discriminant_Checks_Suppressed (T_Typ)
1401 then
1402 return;
1403 end if;
1404
feff2f05 1405 -- No discriminant checks necessary for an access when expression is
1406 -- statically Null. This is not only an optimization, it is fundamental
1407 -- because otherwise discriminant checks may be generated in init procs
1408 -- for types containing an access to a not-yet-frozen record, causing a
1409 -- deadly forward reference.
ee6ba406 1410
feff2f05 1411 -- Also, if the expression is of an access type whose designated type is
1412 -- incomplete, then the access value must be null and we suppress the
1413 -- check.
ee6ba406 1414
2af58f67 1415 if Known_Null (N) then
ee6ba406 1416 return;
1417
1418 elsif Is_Access_Type (S_Typ) then
1419 S_Typ := Designated_Type (S_Typ);
1420
1421 if Ekind (S_Typ) = E_Incomplete_Type then
1422 return;
1423 end if;
1424 end if;
1425
0577b0b1 1426 -- If an assignment target is present, then we need to generate the
1427 -- actual subtype if the target is a parameter or aliased object with
1428 -- an unconstrained nominal subtype.
1429
1430 -- Ada 2005 (AI-363): For Ada 2005, we limit the building of the actual
1431 -- subtype to the parameter and dereference cases, since other aliased
1432 -- objects are unconstrained (unless the nominal subtype is explicitly
7be5088a 1433 -- constrained).
ee6ba406 1434
1435 if Present (Lhs)
1436 and then (Present (Param_Entity (Lhs))
de54c5ab 1437 or else (Ada_Version < Ada_2005
0577b0b1 1438 and then not Is_Constrained (T_Typ)
ee6ba406 1439 and then Is_Aliased_View (Lhs)
0577b0b1 1440 and then not Is_Aliased_Unconstrained_Component)
de54c5ab 1441 or else (Ada_Version >= Ada_2005
0577b0b1 1442 and then not Is_Constrained (T_Typ)
7be5088a 1443 and then Denotes_Explicit_Dereference (Lhs)
0577b0b1 1444 and then Nkind (Original_Node (Lhs)) /=
1445 N_Function_Call))
ee6ba406 1446 then
1447 T_Typ := Get_Actual_Subtype (Lhs);
1448 end if;
1449
feff2f05 1450 -- Nothing to do if the type is unconstrained (this is the case where
1451 -- the actual subtype in the RM sense of N is unconstrained and no check
1452 -- is required).
ee6ba406 1453
1454 if not Is_Constrained (T_Typ) then
1455 return;
05fcfafb 1456
1457 -- Ada 2005: nothing to do if the type is one for which there is a
1458 -- partial view that is constrained.
1459
de54c5ab 1460 elsif Ada_Version >= Ada_2005
d41a3f41 1461 and then Effectively_Has_Constrained_Partial_View
1462 (Typ => Base_Type (T_Typ),
1463 Scop => Current_Scope)
05fcfafb 1464 then
1465 return;
ee6ba406 1466 end if;
1467
00f91aef 1468 -- Nothing to do if the type is an Unchecked_Union
1469
1470 if Is_Unchecked_Union (Base_Type (T_Typ)) then
1471 return;
1472 end if;
1473
feff2f05 1474 -- Suppress checks if the subtypes are the same. the check must be
1475 -- preserved in an assignment to a formal, because the constraint is
1476 -- given by the actual.
ee6ba406 1477
1478 if Nkind (Original_Node (N)) /= N_Allocator
1479 and then (No (Lhs)
1480 or else not Is_Entity_Name (Lhs)
9dfe12ae 1481 or else No (Param_Entity (Lhs)))
ee6ba406 1482 then
1483 if (Etype (N) = Typ
1484 or else (Do_Access and then Designated_Type (Typ) = S_Typ))
1485 and then not Is_Aliased_View (Lhs)
1486 then
1487 return;
1488 end if;
1489
feff2f05 1490 -- We can also eliminate checks on allocators with a subtype mark that
1491 -- coincides with the context type. The context type may be a subtype
1492 -- without a constraint (common case, a generic actual).
ee6ba406 1493
1494 elsif Nkind (Original_Node (N)) = N_Allocator
1495 and then Is_Entity_Name (Expression (Original_Node (N)))
1496 then
1497 declare
9dfe12ae 1498 Alloc_Typ : constant Entity_Id :=
b6341c67 1499 Entity (Expression (Original_Node (N)));
ee6ba406 1500
1501 begin
1502 if Alloc_Typ = T_Typ
1503 or else (Nkind (Parent (T_Typ)) = N_Subtype_Declaration
1504 and then Is_Entity_Name (
1505 Subtype_Indication (Parent (T_Typ)))
1506 and then Alloc_Typ = Base_Type (T_Typ))
1507
1508 then
1509 return;
1510 end if;
1511 end;
1512 end if;
1513
feff2f05 1514 -- See if we have a case where the types are both constrained, and all
1515 -- the constraints are constants. In this case, we can do the check
1516 -- successfully at compile time.
ee6ba406 1517
9dfe12ae 1518 -- We skip this check for the case where the node is a rewritten`
ee6ba406 1519 -- allocator, because it already carries the context subtype, and
1520 -- extracting the discriminants from the aggregate is messy.
1521
1522 if Is_Constrained (S_Typ)
1523 and then Nkind (Original_Node (N)) /= N_Allocator
1524 then
1525 declare
1526 DconT : Elmt_Id;
1527 Discr : Entity_Id;
1528 DconS : Elmt_Id;
1529 ItemS : Node_Id;
1530 ItemT : Node_Id;
1531
1532 begin
1533 -- S_Typ may not have discriminants in the case where it is a
feff2f05 1534 -- private type completed by a default discriminated type. In that
1535 -- case, we need to get the constraints from the underlying_type.
1536 -- If the underlying type is unconstrained (i.e. has no default
1537 -- discriminants) no check is needed.
ee6ba406 1538
1539 if Has_Discriminants (S_Typ) then
1540 Discr := First_Discriminant (S_Typ);
1541 DconS := First_Elmt (Discriminant_Constraint (S_Typ));
1542
1543 else
1544 Discr := First_Discriminant (Underlying_Type (S_Typ));
1545 DconS :=
1546 First_Elmt
1547 (Discriminant_Constraint (Underlying_Type (S_Typ)));
1548
1549 if No (DconS) then
1550 return;
1551 end if;
fccb5da7 1552
1553 -- A further optimization: if T_Typ is derived from S_Typ
1554 -- without imposing a constraint, no check is needed.
1555
1556 if Nkind (Original_Node (Parent (T_Typ))) =
1557 N_Full_Type_Declaration
1558 then
1559 declare
5c61a0ff 1560 Type_Def : constant Node_Id :=
b6341c67 1561 Type_Definition (Original_Node (Parent (T_Typ)));
fccb5da7 1562 begin
1563 if Nkind (Type_Def) = N_Derived_Type_Definition
1564 and then Is_Entity_Name (Subtype_Indication (Type_Def))
1565 and then Entity (Subtype_Indication (Type_Def)) = S_Typ
1566 then
1567 return;
1568 end if;
1569 end;
1570 end if;
ee6ba406 1571 end if;
1572
1573 DconT := First_Elmt (Discriminant_Constraint (T_Typ));
1574
1575 while Present (Discr) loop
1576 ItemS := Node (DconS);
1577 ItemT := Node (DconT);
1578
00c403ee 1579 -- For a discriminated component type constrained by the
1580 -- current instance of an enclosing type, there is no
1581 -- applicable discriminant check.
1582
1583 if Nkind (ItemT) = N_Attribute_Reference
1584 and then Is_Access_Type (Etype (ItemT))
1585 and then Is_Entity_Name (Prefix (ItemT))
1586 and then Is_Type (Entity (Prefix (ItemT)))
1587 then
1588 return;
1589 end if;
1590
cc60bd16 1591 -- If the expressions for the discriminants are identical
1592 -- and it is side-effect free (for now just an entity),
1593 -- this may be a shared constraint, e.g. from a subtype
1594 -- without a constraint introduced as a generic actual.
1595 -- Examine other discriminants if any.
1596
1597 if ItemS = ItemT
1598 and then Is_Entity_Name (ItemS)
1599 then
1600 null;
1601
1602 elsif not Is_OK_Static_Expression (ItemS)
1603 or else not Is_OK_Static_Expression (ItemT)
1604 then
1605 exit;
ee6ba406 1606
cc60bd16 1607 elsif Expr_Value (ItemS) /= Expr_Value (ItemT) then
ee6ba406 1608 if Do_Access then -- needs run-time check.
1609 exit;
1610 else
1611 Apply_Compile_Time_Constraint_Error
f15731c4 1612 (N, "incorrect value for discriminant&?",
1613 CE_Discriminant_Check_Failed, Ent => Discr);
ee6ba406 1614 return;
1615 end if;
1616 end if;
1617
1618 Next_Elmt (DconS);
1619 Next_Elmt (DconT);
1620 Next_Discriminant (Discr);
1621 end loop;
1622
1623 if No (Discr) then
1624 return;
1625 end if;
1626 end;
1627 end if;
1628
1629 -- Here we need a discriminant check. First build the expression
1630 -- for the comparisons of the discriminants:
1631
1632 -- (n.disc1 /= typ.disc1) or else
1633 -- (n.disc2 /= typ.disc2) or else
1634 -- ...
1635 -- (n.discn /= typ.discn)
1636
1637 Cond := Build_Discriminant_Checks (N, T_Typ);
1638
3cce7f32 1639 -- If Lhs is set and is a parameter, then the condition is guarded by:
1640 -- lhs'constrained and then (condition built above)
ee6ba406 1641
1642 if Present (Param_Entity (Lhs)) then
1643 Cond :=
1644 Make_And_Then (Loc,
1645 Left_Opnd =>
1646 Make_Attribute_Reference (Loc,
1647 Prefix => New_Occurrence_Of (Param_Entity (Lhs), Loc),
1648 Attribute_Name => Name_Constrained),
1649 Right_Opnd => Cond);
1650 end if;
1651
1652 if Do_Access then
1653 Cond := Guard_Access (Cond, Loc, N);
1654 end if;
1655
1656 Insert_Action (N,
f15731c4 1657 Make_Raise_Constraint_Error (Loc,
1658 Condition => Cond,
1659 Reason => CE_Discriminant_Check_Failed));
ee6ba406 1660 end Apply_Discriminant_Check;
1661
2fe22c69 1662 -------------------------
1663 -- Apply_Divide_Checks --
1664 -------------------------
ee6ba406 1665
2fe22c69 1666 procedure Apply_Divide_Checks (N : Node_Id) is
ee6ba406 1667 Loc : constant Source_Ptr := Sloc (N);
1668 Typ : constant Entity_Id := Etype (N);
1669 Left : constant Node_Id := Left_Opnd (N);
1670 Right : constant Node_Id := Right_Opnd (N);
1671
2fe22c69 1672 Mode : constant Overflow_Check_Type := Overflow_Check_Mode (Typ);
1673 -- Current overflow checking mode
1674
ee6ba406 1675 LLB : Uint;
1676 Llo : Uint;
1677 Lhi : Uint;
1678 LOK : Boolean;
1679 Rlo : Uint;
1680 Rhi : Uint;
2fe22c69 1681 ROK : Boolean;
96da3284 1682
1683 pragma Warnings (Off, Lhi);
1684 -- Don't actually use this value
ee6ba406 1685
1686 begin
2fe22c69 1687 -- If we are operating in MINIMIZED or ELIMINATED mode, and the
1688 -- Do_Overflow_Check flag is set and we are operating on signed
1689 -- integer types, then the only thing this routine does is to call
1690 -- Apply_Arithmetic_Overflow_Minimized_Eliminated. That procedure will
1691 -- (possibly later on during recursive downward calls), make sure that
1692 -- any needed overflow and division checks are properly applied.
1693
1694 if Mode in Minimized_Or_Eliminated
1695 and then Do_Overflow_Check (N)
1696 and then Is_Signed_Integer_Type (Typ)
1697 then
1698 Apply_Arithmetic_Overflow_Minimized_Eliminated (N);
1699 return;
1700 end if;
1701
1702 -- Proceed here in SUPPRESSED or CHECKED modes
1703
6dbcfcd9 1704 if Full_Expander_Active
13dbf220 1705 and then not Backend_Divide_Checks_On_Target
1706 and then Check_Needed (Right, Division_Check)
ee6ba406 1707 then
9c486805 1708 Determine_Range (Right, ROK, Rlo, Rhi, Assume_Valid => True);
ee6ba406 1709
2fe22c69 1710 -- Deal with division check
ee6ba406 1711
2fe22c69 1712 if Do_Division_Check (N)
1713 and then not Division_Checks_Suppressed (Typ)
1714 then
1715 Apply_Division_Check (N, Rlo, Rhi, ROK);
ee6ba406 1716 end if;
1717
2fe22c69 1718 -- Deal with overflow check
1719
1720 if Do_Overflow_Check (N) and then Mode /= Suppressed then
1721
1722 -- Test for extremely annoying case of xxx'First divided by -1
1723 -- for division of signed integer types (only overflow case).
ee6ba406 1724
ee6ba406 1725 if Nkind (N) = N_Op_Divide
1726 and then Is_Signed_Integer_Type (Typ)
1727 then
9c486805 1728 Determine_Range (Left, LOK, Llo, Lhi, Assume_Valid => True);
ee6ba406 1729 LLB := Expr_Value (Type_Low_Bound (Base_Type (Typ)));
1730
1731 if ((not ROK) or else (Rlo <= (-1) and then (-1) <= Rhi))
2fe22c69 1732 and then
1733 ((not LOK) or else (Llo = LLB))
ee6ba406 1734 then
1735 Insert_Action (N,
1736 Make_Raise_Constraint_Error (Loc,
1737 Condition =>
1738 Make_And_Then (Loc,
2fe22c69 1739 Left_Opnd =>
1740 Make_Op_Eq (Loc,
1741 Left_Opnd =>
1742 Duplicate_Subexpr_Move_Checks (Left),
1743 Right_Opnd => Make_Integer_Literal (Loc, LLB)),
ee6ba406 1744
2fe22c69 1745 Right_Opnd =>
1746 Make_Op_Eq (Loc,
1747 Left_Opnd => Duplicate_Subexpr (Right),
1748 Right_Opnd => Make_Integer_Literal (Loc, -1))),
ee6ba406 1749
f15731c4 1750 Reason => CE_Overflow_Check_Failed));
ee6ba406 1751 end if;
1752 end if;
1753 end if;
1754 end if;
2fe22c69 1755 end Apply_Divide_Checks;
1756
1757 --------------------------
1758 -- Apply_Division_Check --
1759 --------------------------
1760
1761 procedure Apply_Division_Check
1762 (N : Node_Id;
1763 Rlo : Uint;
1764 Rhi : Uint;
1765 ROK : Boolean)
1766 is
1767 pragma Assert (Do_Division_Check (N));
1768
1769 Loc : constant Source_Ptr := Sloc (N);
1770 Right : constant Node_Id := Right_Opnd (N);
1771
1772 begin
1773 if Full_Expander_Active
1774 and then not Backend_Divide_Checks_On_Target
1775 and then Check_Needed (Right, Division_Check)
1776 then
1777 -- See if division by zero possible, and if so generate test. This
1778 -- part of the test is not controlled by the -gnato switch, since
1779 -- it is a Division_Check and not an Overflow_Check.
1780
1781 if Do_Division_Check (N) then
1782 if (not ROK) or else (Rlo <= 0 and then 0 <= Rhi) then
1783 Insert_Action (N,
1784 Make_Raise_Constraint_Error (Loc,
1785 Condition =>
1786 Make_Op_Eq (Loc,
1787 Left_Opnd => Duplicate_Subexpr_Move_Checks (Right),
1788 Right_Opnd => Make_Integer_Literal (Loc, 0)),
1789 Reason => CE_Divide_By_Zero));
1790 end if;
1791 end if;
1792 end if;
1793 end Apply_Division_Check;
ee6ba406 1794
5329ca64 1795 ----------------------------------
1796 -- Apply_Float_Conversion_Check --
1797 ----------------------------------
1798
feff2f05 1799 -- Let F and I be the source and target types of the conversion. The RM
1800 -- specifies that a floating-point value X is rounded to the nearest
1801 -- integer, with halfway cases being rounded away from zero. The rounded
1802 -- value of X is checked against I'Range.
1803
1804 -- The catch in the above paragraph is that there is no good way to know
1805 -- whether the round-to-integer operation resulted in overflow. A remedy is
1806 -- to perform a range check in the floating-point domain instead, however:
5329ca64 1807
5329ca64 1808 -- (1) The bounds may not be known at compile time
2af58f67 1809 -- (2) The check must take into account rounding or truncation.
5329ca64 1810 -- (3) The range of type I may not be exactly representable in F.
2af58f67 1811 -- (4) For the rounding case, The end-points I'First - 0.5 and
1812 -- I'Last + 0.5 may or may not be in range, depending on the
1813 -- sign of I'First and I'Last.
5329ca64 1814 -- (5) X may be a NaN, which will fail any comparison
1815
2af58f67 1816 -- The following steps correctly convert X with rounding:
feff2f05 1817
5329ca64 1818 -- (1) If either I'First or I'Last is not known at compile time, use
1819 -- I'Base instead of I in the next three steps and perform a
1820 -- regular range check against I'Range after conversion.
1821 -- (2) If I'First - 0.5 is representable in F then let Lo be that
1822 -- value and define Lo_OK as (I'First > 0). Otherwise, let Lo be
2af58f67 1823 -- F'Machine (I'First) and let Lo_OK be (Lo >= I'First).
1824 -- In other words, take one of the closest floating-point numbers
1825 -- (which is an integer value) to I'First, and see if it is in
1826 -- range or not.
5329ca64 1827 -- (3) If I'Last + 0.5 is representable in F then let Hi be that value
1828 -- and define Hi_OK as (I'Last < 0). Otherwise, let Hi be
2af58f67 1829 -- F'Machine (I'Last) and let Hi_OK be (Hi <= I'Last).
5329ca64 1830 -- (4) Raise CE when (Lo_OK and X < Lo) or (not Lo_OK and X <= Lo)
1831 -- or (Hi_OK and X > Hi) or (not Hi_OK and X >= Hi)
1832
2af58f67 1833 -- For the truncating case, replace steps (2) and (3) as follows:
1834 -- (2) If I'First > 0, then let Lo be F'Pred (I'First) and let Lo_OK
1835 -- be False. Otherwise, let Lo be F'Succ (I'First - 1) and let
1836 -- Lo_OK be True.
1837 -- (3) If I'Last < 0, then let Hi be F'Succ (I'Last) and let Hi_OK
1838 -- be False. Otherwise let Hi be F'Pred (I'Last + 1) and let
141d591a 1839 -- Hi_OK be True.
2af58f67 1840
5329ca64 1841 procedure Apply_Float_Conversion_Check
1842 (Ck_Node : Node_Id;
1843 Target_Typ : Entity_Id)
1844 is
feff2f05 1845 LB : constant Node_Id := Type_Low_Bound (Target_Typ);
1846 HB : constant Node_Id := Type_High_Bound (Target_Typ);
5329ca64 1847 Loc : constant Source_Ptr := Sloc (Ck_Node);
1848 Expr_Type : constant Entity_Id := Base_Type (Etype (Ck_Node));
feff2f05 1849 Target_Base : constant Entity_Id :=
b6341c67 1850 Implementation_Base_Type (Target_Typ);
feff2f05 1851
2af58f67 1852 Par : constant Node_Id := Parent (Ck_Node);
1853 pragma Assert (Nkind (Par) = N_Type_Conversion);
1854 -- Parent of check node, must be a type conversion
1855
1856 Truncate : constant Boolean := Float_Truncate (Par);
1857 Max_Bound : constant Uint :=
b6341c67 1858 UI_Expon
1859 (Machine_Radix_Value (Expr_Type),
1860 Machine_Mantissa_Value (Expr_Type) - 1) - 1;
2af58f67 1861
5329ca64 1862 -- Largest bound, so bound plus or minus half is a machine number of F
1863
feff2f05 1864 Ifirst, Ilast : Uint;
1865 -- Bounds of integer type
1866
1867 Lo, Hi : Ureal;
1868 -- Bounds to check in floating-point domain
5329ca64 1869
feff2f05 1870 Lo_OK, Hi_OK : Boolean;
1871 -- True iff Lo resp. Hi belongs to I'Range
5329ca64 1872
feff2f05 1873 Lo_Chk, Hi_Chk : Node_Id;
1874 -- Expressions that are False iff check fails
1875
1876 Reason : RT_Exception_Code;
5329ca64 1877
1878 begin
1879 if not Compile_Time_Known_Value (LB)
1880 or not Compile_Time_Known_Value (HB)
1881 then
1882 declare
feff2f05 1883 -- First check that the value falls in the range of the base type,
1884 -- to prevent overflow during conversion and then perform a
1885 -- regular range check against the (dynamic) bounds.
5329ca64 1886
5329ca64 1887 pragma Assert (Target_Base /= Target_Typ);
5329ca64 1888
46eb6933 1889 Temp : constant Entity_Id := Make_Temporary (Loc, 'T', Par);
5329ca64 1890
1891 begin
1892 Apply_Float_Conversion_Check (Ck_Node, Target_Base);
1893 Set_Etype (Temp, Target_Base);
1894
1895 Insert_Action (Parent (Par),
1896 Make_Object_Declaration (Loc,
1897 Defining_Identifier => Temp,
1898 Object_Definition => New_Occurrence_Of (Target_Typ, Loc),
1899 Expression => New_Copy_Tree (Par)),
1900 Suppress => All_Checks);
1901
1902 Insert_Action (Par,
1903 Make_Raise_Constraint_Error (Loc,
1904 Condition =>
1905 Make_Not_In (Loc,
1906 Left_Opnd => New_Occurrence_Of (Temp, Loc),
1907 Right_Opnd => New_Occurrence_Of (Target_Typ, Loc)),
1908 Reason => CE_Range_Check_Failed));
1909 Rewrite (Par, New_Occurrence_Of (Temp, Loc));
1910
1911 return;
1912 end;
1913 end if;
1914
7d86aa98 1915 -- Get the (static) bounds of the target type
5329ca64 1916
1917 Ifirst := Expr_Value (LB);
1918 Ilast := Expr_Value (HB);
1919
7d86aa98 1920 -- A simple optimization: if the expression is a universal literal,
1921 -- we can do the comparison with the bounds and the conversion to
1922 -- an integer type statically. The range checks are unchanged.
1923
1924 if Nkind (Ck_Node) = N_Real_Literal
1925 and then Etype (Ck_Node) = Universal_Real
1926 and then Is_Integer_Type (Target_Typ)
1927 and then Nkind (Parent (Ck_Node)) = N_Type_Conversion
1928 then
1929 declare
1930 Int_Val : constant Uint := UR_To_Uint (Realval (Ck_Node));
1931
1932 begin
1933 if Int_Val <= Ilast and then Int_Val >= Ifirst then
1934
4309515d 1935 -- Conversion is safe
7d86aa98 1936
1937 Rewrite (Parent (Ck_Node),
1938 Make_Integer_Literal (Loc, UI_To_Int (Int_Val)));
1939 Analyze_And_Resolve (Parent (Ck_Node), Target_Typ);
1940 return;
1941 end if;
1942 end;
1943 end if;
1944
5329ca64 1945 -- Check against lower bound
1946
2af58f67 1947 if Truncate and then Ifirst > 0 then
1948 Lo := Pred (Expr_Type, UR_From_Uint (Ifirst));
1949 Lo_OK := False;
1950
1951 elsif Truncate then
1952 Lo := Succ (Expr_Type, UR_From_Uint (Ifirst - 1));
1953 Lo_OK := True;
1954
1955 elsif abs (Ifirst) < Max_Bound then
5329ca64 1956 Lo := UR_From_Uint (Ifirst) - Ureal_Half;
1957 Lo_OK := (Ifirst > 0);
2af58f67 1958
5329ca64 1959 else
1960 Lo := Machine (Expr_Type, UR_From_Uint (Ifirst), Round_Even, Ck_Node);
1961 Lo_OK := (Lo >= UR_From_Uint (Ifirst));
1962 end if;
1963
1964 if Lo_OK then
1965
1966 -- Lo_Chk := (X >= Lo)
1967
1968 Lo_Chk := Make_Op_Ge (Loc,
1969 Left_Opnd => Duplicate_Subexpr_No_Checks (Ck_Node),
1970 Right_Opnd => Make_Real_Literal (Loc, Lo));
1971
1972 else
1973 -- Lo_Chk := (X > Lo)
1974
1975 Lo_Chk := Make_Op_Gt (Loc,
1976 Left_Opnd => Duplicate_Subexpr_No_Checks (Ck_Node),
1977 Right_Opnd => Make_Real_Literal (Loc, Lo));
1978 end if;
1979
1980 -- Check against higher bound
1981
2af58f67 1982 if Truncate and then Ilast < 0 then
1983 Hi := Succ (Expr_Type, UR_From_Uint (Ilast));
b2c42753 1984 Hi_OK := False;
2af58f67 1985
1986 elsif Truncate then
1987 Hi := Pred (Expr_Type, UR_From_Uint (Ilast + 1));
1988 Hi_OK := True;
1989
1990 elsif abs (Ilast) < Max_Bound then
5329ca64 1991 Hi := UR_From_Uint (Ilast) + Ureal_Half;
1992 Hi_OK := (Ilast < 0);
1993 else
1994 Hi := Machine (Expr_Type, UR_From_Uint (Ilast), Round_Even, Ck_Node);
1995 Hi_OK := (Hi <= UR_From_Uint (Ilast));
1996 end if;
1997
1998 if Hi_OK then
1999
2000 -- Hi_Chk := (X <= Hi)
2001
2002 Hi_Chk := Make_Op_Le (Loc,
2003 Left_Opnd => Duplicate_Subexpr_No_Checks (Ck_Node),
2004 Right_Opnd => Make_Real_Literal (Loc, Hi));
2005
2006 else
2007 -- Hi_Chk := (X < Hi)
2008
2009 Hi_Chk := Make_Op_Lt (Loc,
2010 Left_Opnd => Duplicate_Subexpr_No_Checks (Ck_Node),
2011 Right_Opnd => Make_Real_Literal (Loc, Hi));
2012 end if;
2013
feff2f05 2014 -- If the bounds of the target type are the same as those of the base
2015 -- type, the check is an overflow check as a range check is not
2016 -- performed in these cases.
5329ca64 2017
2018 if Expr_Value (Type_Low_Bound (Target_Base)) = Ifirst
2019 and then Expr_Value (Type_High_Bound (Target_Base)) = Ilast
2020 then
2021 Reason := CE_Overflow_Check_Failed;
2022 else
2023 Reason := CE_Range_Check_Failed;
2024 end if;
2025
2026 -- Raise CE if either conditions does not hold
2027
2028 Insert_Action (Ck_Node,
2029 Make_Raise_Constraint_Error (Loc,
05fcfafb 2030 Condition => Make_Op_Not (Loc, Make_And_Then (Loc, Lo_Chk, Hi_Chk)),
5329ca64 2031 Reason => Reason));
2032 end Apply_Float_Conversion_Check;
2033
ee6ba406 2034 ------------------------
2035 -- Apply_Length_Check --
2036 ------------------------
2037
2038 procedure Apply_Length_Check
2039 (Ck_Node : Node_Id;
2040 Target_Typ : Entity_Id;
2041 Source_Typ : Entity_Id := Empty)
2042 is
2043 begin
2044 Apply_Selected_Length_Checks
2045 (Ck_Node, Target_Typ, Source_Typ, Do_Static => False);
2046 end Apply_Length_Check;
2047
3b045963 2048 -------------------------------------
2049 -- Apply_Parameter_Aliasing_Checks --
2050 -------------------------------------
b73adb97 2051
3b045963 2052 procedure Apply_Parameter_Aliasing_Checks
2053 (Call : Node_Id;
2054 Subp : Entity_Id)
2055 is
2056 function May_Cause_Aliasing
2057 (Formal_1 : Entity_Id;
2058 Formal_2 : Entity_Id) return Boolean;
2059 -- Determine whether two formal parameters can alias each other
2060 -- depending on their modes.
2061
2062 function Original_Actual (N : Node_Id) return Node_Id;
2063 -- The expander may replace an actual with a temporary for the sake of
2064 -- side effect removal. The temporary may hide a potential aliasing as
2065 -- it does not share the address of the actual. This routine attempts
2066 -- to retrieve the original actual.
2067
2068 ------------------------
2069 -- May_Cause_Aliasing --
2070 ------------------------
b73adb97 2071
3b045963 2072 function May_Cause_Aliasing
4a9e7f0c 2073 (Formal_1 : Entity_Id;
3b045963 2074 Formal_2 : Entity_Id) return Boolean
2075 is
2076 begin
2077 -- The following combination cannot lead to aliasing
2078
2079 -- Formal 1 Formal 2
2080 -- IN IN
2081
2082 if Ekind (Formal_1) = E_In_Parameter
a45d946f 2083 and then
2084 Ekind (Formal_2) = E_In_Parameter
3b045963 2085 then
2086 return False;
2087
2088 -- The following combinations may lead to aliasing
2089
2090 -- Formal 1 Formal 2
2091 -- IN OUT
2092 -- IN IN OUT
2093 -- OUT IN
2094 -- OUT IN OUT
2095 -- OUT OUT
2096
2097 else
2098 return True;
2099 end if;
2100 end May_Cause_Aliasing;
2101
2102 ---------------------
2103 -- Original_Actual --
2104 ---------------------
2105
2106 function Original_Actual (N : Node_Id) return Node_Id is
2107 begin
2108 if Nkind (N) = N_Type_Conversion then
2109 return Expression (N);
2110
2111 -- The expander created a temporary to capture the result of a type
2112 -- conversion where the expression is the real actual.
2113
2114 elsif Nkind (N) = N_Identifier
2115 and then Present (Original_Node (N))
2116 and then Nkind (Original_Node (N)) = N_Type_Conversion
2117 then
2118 return Expression (Original_Node (N));
2119 end if;
2120
2121 return N;
2122 end Original_Actual;
2123
2124 -- Local variables
2125
2126 Loc : constant Source_Ptr := Sloc (Call);
2127 Actual_1 : Node_Id;
2128 Actual_2 : Node_Id;
2129 Check : Node_Id;
2130 Cond : Node_Id;
2131 Formal_1 : Entity_Id;
2132 Formal_2 : Entity_Id;
2133
2134 -- Start of processing for Apply_Parameter_Aliasing_Checks
2135
2136 begin
2137 Cond := Empty;
2138
2139 Actual_1 := First_Actual (Call);
2140 Formal_1 := First_Formal (Subp);
2141 while Present (Actual_1) and then Present (Formal_1) loop
2142
2143 -- Ensure that the actual is an object that is not passed by value.
2144 -- Elementary types are always passed by value, therefore actuals of
2145 -- such types cannot lead to aliasing.
2146
2147 if Is_Object_Reference (Original_Actual (Actual_1))
2148 and then not Is_Elementary_Type (Etype (Original_Actual (Actual_1)))
2149 then
2150 Actual_2 := Next_Actual (Actual_1);
2151 Formal_2 := Next_Formal (Formal_1);
2152 while Present (Actual_2) and then Present (Formal_2) loop
2153
2154 -- The other actual we are testing against must also denote
2155 -- a non pass-by-value object. Generate the check only when
2156 -- the mode of the two formals may lead to aliasing.
2157
2158 if Is_Object_Reference (Original_Actual (Actual_2))
2159 and then not
2160 Is_Elementary_Type (Etype (Original_Actual (Actual_2)))
2161 and then May_Cause_Aliasing (Formal_1, Formal_2)
2162 then
2163 -- Generate:
2164 -- Actual_1'Overlaps_Storage (Actual_2)
2165
2166 Check :=
2167 Make_Attribute_Reference (Loc,
2168 Prefix =>
2169 New_Copy_Tree (Original_Actual (Actual_1)),
2170 Attribute_Name => Name_Overlaps_Storage,
2171 Expressions =>
2172 New_List (New_Copy_Tree (Original_Actual (Actual_2))));
2173
2174 if No (Cond) then
2175 Cond := Check;
2176 else
2177 Cond :=
2178 Make_And_Then (Loc,
2179 Left_Opnd => Cond,
2180 Right_Opnd => Check);
2181 end if;
2182 end if;
2183
2184 Next_Actual (Actual_2);
2185 Next_Formal (Formal_2);
2186 end loop;
2187 end if;
2188
2189 Next_Actual (Actual_1);
2190 Next_Formal (Formal_1);
2191 end loop;
2192
2193 -- Place the check right before the call
2194
2195 if Present (Cond) then
2196 Insert_Action (Call,
2197 Make_Raise_Program_Error (Loc,
2198 Condition => Cond,
2199 Reason => PE_Explicit_Raise));
2200 end if;
2201 end Apply_Parameter_Aliasing_Checks;
2202
2203 -------------------------------------
2204 -- Apply_Parameter_Validity_Checks --
2205 -------------------------------------
2206
2207 procedure Apply_Parameter_Validity_Checks (Subp : Entity_Id) is
2208 Subp_Decl : Node_Id;
b73adb97 2209
4a9e7f0c 2210 procedure Add_Validity_Check
2211 (Context : Entity_Id;
2212 PPC_Nam : Name_Id;
2213 For_Result : Boolean := False);
2214 -- Add a single 'Valid[_Scalar] check which verifies the initialization
2215 -- of Context. PPC_Nam denotes the pre or post condition pragma name.
2216 -- Set flag For_Result when to verify the result of a function.
b73adb97 2217
4a9e7f0c 2218 procedure Build_PPC_Pragma (PPC_Nam : Name_Id; Check : Node_Id);
2219 -- Create a pre or post condition pragma with name PPC_Nam which
2220 -- tests expression Check.
b73adb97 2221
b73adb97 2222 ------------------------
2223 -- Add_Validity_Check --
2224 ------------------------
2225
2226 procedure Add_Validity_Check
2227 (Context : Entity_Id;
4a9e7f0c 2228 PPC_Nam : Name_Id;
b73adb97 2229 For_Result : Boolean := False)
2230 is
4a9e7f0c 2231 Loc : constant Source_Ptr := Sloc (Subp);
2232 Typ : constant Entity_Id := Etype (Context);
b73adb97 2233 Check : Node_Id;
2234 Nam : Name_Id;
2235
2236 begin
2237 -- Pick the proper version of 'Valid depending on the type of the
2238 -- context. If the context is not eligible for such a check, return.
2239
2240 if Is_Scalar_Type (Typ) then
2241 Nam := Name_Valid;
2242 elsif not No_Scalar_Parts (Typ) then
2243 Nam := Name_Valid_Scalars;
2244 else
2245 return;
2246 end if;
2247
2248 -- Step 1: Create the expression to verify the validity of the
2249 -- context.
2250
2251 Check := New_Reference_To (Context, Loc);
2252
2253 -- When processing a function result, use 'Result. Generate
2254 -- Context'Result
2255
2256 if For_Result then
2257 Check :=
2258 Make_Attribute_Reference (Loc,
2259 Prefix => Check,
2260 Attribute_Name => Name_Result);
2261 end if;
2262
2263 -- Generate:
2264 -- Context['Result]'Valid[_Scalars]
2265
2266 Check :=
2267 Make_Attribute_Reference (Loc,
2268 Prefix => Check,
2269 Attribute_Name => Nam);
2270
4a9e7f0c 2271 -- Step 2: Create a pre or post condition pragma
2272
2273 Build_PPC_Pragma (PPC_Nam, Check);
2274 end Add_Validity_Check;
2275
2276 ----------------------
2277 -- Build_PPC_Pragma --
2278 ----------------------
b73adb97 2279
4a9e7f0c 2280 procedure Build_PPC_Pragma (PPC_Nam : Name_Id; Check : Node_Id) is
7c443ae8 2281 Loc : constant Source_Ptr := Sloc (Subp);
2282 Decls : List_Id;
2283 Prag : Node_Id;
4a9e7f0c 2284
2285 begin
2286 Prag :=
2287 Make_Pragma (Loc,
2288 Pragma_Identifier => Make_Identifier (Loc, PPC_Nam),
2289 Pragma_Argument_Associations => New_List (
2290 Make_Pragma_Argument_Association (Loc,
2291 Chars => Name_Check,
2292 Expression => Check)));
2293
2294 -- Add a message unless exception messages are suppressed
2295
2296 if not Exception_Locations_Suppressed then
2297 Append_To (Pragma_Argument_Associations (Prag),
2298 Make_Pragma_Argument_Association (Loc,
2299 Chars => Name_Message,
2300 Expression =>
2301 Make_String_Literal (Loc,
2302 Strval => "failed " & Get_Name_String (PPC_Nam) &
2303 " from " & Build_Location_String (Loc))));
2304 end if;
2305
2306 -- Insert the pragma in the tree
2307
2308 if Nkind (Parent (Subp_Decl)) = N_Compilation_Unit then
2309 Add_Global_Declaration (Prag);
7c443ae8 2310 Analyze (Prag);
2311
2312 -- PPC pragmas associated with subprogram bodies must be inserted in
2313 -- the declarative part of the body.
2314
2315 elsif Nkind (Subp_Decl) = N_Subprogram_Body then
2316 Decls := Declarations (Subp_Decl);
2317
2318 if No (Decls) then
2319 Decls := New_List;
2320 Set_Declarations (Subp_Decl, Decls);
2321 end if;
2322
1bd93de5 2323 Prepend_To (Decls, Prag);
7c443ae8 2324
2325 -- Ensure the proper visibility of the subprogram body and its
2326 -- parameters.
2327
2328 Push_Scope (Subp);
2329 Analyze (Prag);
2330 Pop_Scope;
2331
2332 -- For subprogram declarations insert the PPC pragma right after the
2333 -- declarative node.
2334
b73adb97 2335 else
7c443ae8 2336 Insert_After_And_Analyze (Subp_Decl, Prag);
b73adb97 2337 end if;
4a9e7f0c 2338 end Build_PPC_Pragma;
2339
2340 -- Local variables
2341
2342 Formal : Entity_Id;
4a9e7f0c 2343 Subp_Spec : Node_Id;
2344
3b045963 2345 -- Start of processing for Apply_Parameter_Validity_Checks
b73adb97 2346
2347 begin
4a9e7f0c 2348 -- Extract the subprogram specification and declaration nodes
b73adb97 2349
4a9e7f0c 2350 Subp_Spec := Parent (Subp);
a45d946f 2351
4a9e7f0c 2352 if Nkind (Subp_Spec) = N_Defining_Program_Unit_Name then
2353 Subp_Spec := Parent (Subp_Spec);
2354 end if;
a45d946f 2355
4a9e7f0c 2356 Subp_Decl := Parent (Subp_Spec);
9e58d7ed 2357
b73adb97 2358 if not Comes_From_Source (Subp)
4a9e7f0c 2359
2360 -- Do not process formal subprograms because the corresponding actual
2361 -- will receive the proper checks when the instance is analyzed.
2362
2363 or else Is_Formal_Subprogram (Subp)
2364
a45d946f 2365 -- Do not process imported subprograms since pre and post conditions
2366 -- are never verified on routines coming from a different language.
4a9e7f0c 2367
b73adb97 2368 or else Is_Imported (Subp)
2369 or else Is_Intrinsic_Subprogram (Subp)
4a9e7f0c 2370
a45d946f 2371 -- The PPC pragmas generated by this routine do not correspond to
2372 -- source aspects, therefore they cannot be applied to abstract
2373 -- subprograms.
4a9e7f0c 2374
7c443ae8 2375 or else Nkind (Subp_Decl) = N_Abstract_Subprogram_Declaration
4a9e7f0c 2376
a45d946f 2377 -- Do not consider subprogram renaminds because the renamed entity
2378 -- already has the proper PPC pragmas.
1bd93de5 2379
2380 or else Nkind (Subp_Decl) = N_Subprogram_Renaming_Declaration
2381
a45d946f 2382 -- Do not process null procedures because there is no benefit of
2383 -- adding the checks to a no action routine.
4a9e7f0c 2384
2385 or else (Nkind (Subp_Spec) = N_Procedure_Specification
a45d946f 2386 and then Null_Present (Subp_Spec))
b73adb97 2387 then
2388 return;
2389 end if;
2390
4a9e7f0c 2391 -- Inspect all the formals applying aliasing and scalar initialization
2392 -- checks where applicable.
b73adb97 2393
2394 Formal := First_Formal (Subp);
2395 while Present (Formal) loop
4a9e7f0c 2396
2397 -- Generate the following scalar initialization checks for each
2398 -- formal parameter:
2399
2400 -- mode IN - Pre => Formal'Valid[_Scalars]
2401 -- mode IN OUT - Pre, Post => Formal'Valid[_Scalars]
2402 -- mode OUT - Post => Formal'Valid[_Scalars]
2403
2404 if Check_Validity_Of_Parameters then
2405 if Ekind_In (Formal, E_In_Parameter, E_In_Out_Parameter) then
2406 Add_Validity_Check (Formal, Name_Precondition, False);
2407 end if;
2408
2409 if Ekind_In (Formal, E_In_Out_Parameter, E_Out_Parameter) then
2410 Add_Validity_Check (Formal, Name_Postcondition, False);
2411 end if;
b73adb97 2412 end if;
2413
b73adb97 2414 Next_Formal (Formal);
2415 end loop;
2416
a45d946f 2417 -- Generate following scalar initialization check for function result:
4a9e7f0c 2418
2419 -- Post => Subp'Result'Valid[_Scalars]
b73adb97 2420
a45d946f 2421 if Check_Validity_Of_Parameters and then Ekind (Subp) = E_Function then
4a9e7f0c 2422 Add_Validity_Check (Subp, Name_Postcondition, True);
b73adb97 2423 end if;
3b045963 2424 end Apply_Parameter_Validity_Checks;
b73adb97 2425
7aafae1c 2426 ---------------------------
2427 -- Apply_Predicate_Check --
2428 ---------------------------
2429
2430 procedure Apply_Predicate_Check (N : Node_Id; Typ : Entity_Id) is
301d5ec3 2431 S : Entity_Id;
9e58d7ed 2432
7aafae1c 2433 begin
701d57a4 2434 if Present (Predicate_Function (Typ)) then
301d5ec3 2435
2436 -- A predicate check does not apply within internally generated
2437 -- subprograms, such as TSS functions.
2438
2439 S := Current_Scope;
9e58d7ed 2440 while Present (S) and then not Is_Subprogram (S) loop
301d5ec3 2441 S := Scope (S);
2442 end loop;
2443
9e58d7ed 2444 if Present (S) and then Get_TSS_Name (S) /= TSS_Null then
301d5ec3 2445 return;
22631b41 2446
96a2d100 2447 -- If the check appears within the predicate function itself, it
2448 -- means that the user specified a check whose formal is the
2449 -- predicated subtype itself, rather than some covering type. This
2450 -- is likely to be a common error, and thus deserves a warning.
22631b41 2451
2452 elsif S = Predicate_Function (Typ) then
96a2d100 2453 Error_Msg_N
2454 ("predicate check includes a function call that "
2455 & "requires a predicate check?", Parent (N));
2456 Error_Msg_N
2457 ("\this will result in infinite recursion?", Parent (N));
2458 Insert_Action (N,
61016a7a 2459 Make_Raise_Storage_Error (Sloc (N),
2460 Reason => SE_Infinite_Recursion));
22631b41 2461
61016a7a 2462 -- Here for normal case of predicate active.
e6281d47 2463
61016a7a 2464 else
e6281d47 2465 -- If the predicate is a static predicate and the operand is
2466 -- static, the predicate must be evaluated statically. If the
cac18f71 2467 -- evaluation fails this is a static constraint error. This check
2468 -- is disabled in -gnatc mode, because the compiler is incapable
2469 -- of evaluating static expressions in that case.
e6281d47 2470
2471 if Is_OK_Static_Expression (N) then
61016a7a 2472 if Present (Static_Predicate (Typ)) then
a45d946f 2473 if Operating_Mode < Generate_Code
2474 or else Eval_Static_Predicate_Check (N, Typ)
cac18f71 2475 then
e6281d47 2476 return;
2477 else
2478 Error_Msg_NE
2479 ("static expression fails static predicate check on&",
61016a7a 2480 N, Typ);
e6281d47 2481 end if;
2482 end if;
2483 end if;
2484
301d5ec3 2485 Insert_Action (N,
2486 Make_Predicate_Check (Typ, Duplicate_Subexpr (N)));
2487 end if;
7aafae1c 2488 end if;
2489 end Apply_Predicate_Check;
2490
ee6ba406 2491 -----------------------
2492 -- Apply_Range_Check --
2493 -----------------------
2494
2495 procedure Apply_Range_Check
2496 (Ck_Node : Node_Id;
2497 Target_Typ : Entity_Id;
2498 Source_Typ : Entity_Id := Empty)
2499 is
2500 begin
2501 Apply_Selected_Range_Checks
2502 (Ck_Node, Target_Typ, Source_Typ, Do_Static => False);
2503 end Apply_Range_Check;
2504
2505 ------------------------------
2506 -- Apply_Scalar_Range_Check --
2507 ------------------------------
2508
feff2f05 2509 -- Note that Apply_Scalar_Range_Check never turns the Do_Range_Check flag
2510 -- off if it is already set on.
ee6ba406 2511
2512 procedure Apply_Scalar_Range_Check
2513 (Expr : Node_Id;
2514 Target_Typ : Entity_Id;
2515 Source_Typ : Entity_Id := Empty;
2516 Fixed_Int : Boolean := False)
2517 is
2518 Parnt : constant Node_Id := Parent (Expr);
2519 S_Typ : Entity_Id;
2520 Arr : Node_Id := Empty; -- initialize to prevent warning
2521 Arr_Typ : Entity_Id := Empty; -- initialize to prevent warning
2522 OK : Boolean;
2523
2524 Is_Subscr_Ref : Boolean;
2525 -- Set true if Expr is a subscript
2526
2527 Is_Unconstrained_Subscr_Ref : Boolean;
2528 -- Set true if Expr is a subscript of an unconstrained array. In this
2529 -- case we do not attempt to do an analysis of the value against the
2530 -- range of the subscript, since we don't know the actual subtype.
2531
2532 Int_Real : Boolean;
feff2f05 2533 -- Set to True if Expr should be regarded as a real value even though
2534 -- the type of Expr might be discrete.
ee6ba406 2535
2536 procedure Bad_Value;
2537 -- Procedure called if value is determined to be out of range
2538
9dfe12ae 2539 ---------------
2540 -- Bad_Value --
2541 ---------------
2542
ee6ba406 2543 procedure Bad_Value is
2544 begin
2545 Apply_Compile_Time_Constraint_Error
f15731c4 2546 (Expr, "value not in range of}?", CE_Range_Check_Failed,
ee6ba406 2547 Ent => Target_Typ,
2548 Typ => Target_Typ);
2549 end Bad_Value;
2550
9dfe12ae 2551 -- Start of processing for Apply_Scalar_Range_Check
2552
ee6ba406 2553 begin
2af58f67 2554 -- Return if check obviously not needed
ee6ba406 2555
2af58f67 2556 if
2557 -- Not needed inside generic
ee6ba406 2558
2af58f67 2559 Inside_A_Generic
2560
2561 -- Not needed if previous error
2562
2563 or else Target_Typ = Any_Type
2564 or else Nkind (Expr) = N_Error
2565
2566 -- Not needed for non-scalar type
2567
2568 or else not Is_Scalar_Type (Target_Typ)
2569
2570 -- Not needed if we know node raises CE already
2571
2572 or else Raises_Constraint_Error (Expr)
ee6ba406 2573 then
2574 return;
2575 end if;
2576
2577 -- Now, see if checks are suppressed
2578
2579 Is_Subscr_Ref :=
2580 Is_List_Member (Expr) and then Nkind (Parnt) = N_Indexed_Component;
2581
2582 if Is_Subscr_Ref then
2583 Arr := Prefix (Parnt);
2584 Arr_Typ := Get_Actual_Subtype_If_Available (Arr);
cce84b09 2585
a3a76ccc 2586 if Is_Access_Type (Arr_Typ) then
245e87df 2587 Arr_Typ := Designated_Type (Arr_Typ);
a3a76ccc 2588 end if;
ee6ba406 2589 end if;
2590
2591 if not Do_Range_Check (Expr) then
2592
2593 -- Subscript reference. Check for Index_Checks suppressed
2594
2595 if Is_Subscr_Ref then
2596
2597 -- Check array type and its base type
2598
2599 if Index_Checks_Suppressed (Arr_Typ)
9dfe12ae 2600 or else Index_Checks_Suppressed (Base_Type (Arr_Typ))
ee6ba406 2601 then
2602 return;
2603
2604 -- Check array itself if it is an entity name
2605
2606 elsif Is_Entity_Name (Arr)
9dfe12ae 2607 and then Index_Checks_Suppressed (Entity (Arr))
ee6ba406 2608 then
2609 return;
2610
2611 -- Check expression itself if it is an entity name
2612
2613 elsif Is_Entity_Name (Expr)
9dfe12ae 2614 and then Index_Checks_Suppressed (Entity (Expr))
ee6ba406 2615 then
2616 return;
2617 end if;
2618
2619 -- All other cases, check for Range_Checks suppressed
2620
2621 else
2622 -- Check target type and its base type
2623
2624 if Range_Checks_Suppressed (Target_Typ)
9dfe12ae 2625 or else Range_Checks_Suppressed (Base_Type (Target_Typ))
ee6ba406 2626 then
2627 return;
2628
2629 -- Check expression itself if it is an entity name
2630
2631 elsif Is_Entity_Name (Expr)
9dfe12ae 2632 and then Range_Checks_Suppressed (Entity (Expr))
ee6ba406 2633 then
2634 return;
2635
feff2f05 2636 -- If Expr is part of an assignment statement, then check left
2637 -- side of assignment if it is an entity name.
ee6ba406 2638
2639 elsif Nkind (Parnt) = N_Assignment_Statement
2640 and then Is_Entity_Name (Name (Parnt))
9dfe12ae 2641 and then Range_Checks_Suppressed (Entity (Name (Parnt)))
ee6ba406 2642 then
2643 return;
2644 end if;
2645 end if;
2646 end if;
2647
9dfe12ae 2648 -- Do not set range checks if they are killed
2649
2650 if Nkind (Expr) = N_Unchecked_Type_Conversion
2651 and then Kill_Range_Check (Expr)
2652 then
2653 return;
2654 end if;
2655
2656 -- Do not set range checks for any values from System.Scalar_Values
2657 -- since the whole idea of such values is to avoid checking them!
2658
2659 if Is_Entity_Name (Expr)
2660 and then Is_RTU (Scope (Entity (Expr)), System_Scalar_Values)
2661 then
2662 return;
2663 end if;
2664
ee6ba406 2665 -- Now see if we need a check
2666
2667 if No (Source_Typ) then
2668 S_Typ := Etype (Expr);
2669 else
2670 S_Typ := Source_Typ;
2671 end if;
2672
2673 if not Is_Scalar_Type (S_Typ) or else S_Typ = Any_Type then
2674 return;
2675 end if;
2676
2677 Is_Unconstrained_Subscr_Ref :=
2678 Is_Subscr_Ref and then not Is_Constrained (Arr_Typ);
2679
feff2f05 2680 -- Always do a range check if the source type includes infinities and
2681 -- the target type does not include infinities. We do not do this if
2682 -- range checks are killed.
ee6ba406 2683
2684 if Is_Floating_Point_Type (S_Typ)
2685 and then Has_Infinities (S_Typ)
2686 and then not Has_Infinities (Target_Typ)
2687 then
2688 Enable_Range_Check (Expr);
2689 end if;
2690
feff2f05 2691 -- Return if we know expression is definitely in the range of the target
2692 -- type as determined by Determine_Range. Right now we only do this for
2693 -- discrete types, and not fixed-point or floating-point types.
ee6ba406 2694
f2a06be9 2695 -- The additional less-precise tests below catch these cases
ee6ba406 2696
feff2f05 2697 -- Note: skip this if we are given a source_typ, since the point of
2698 -- supplying a Source_Typ is to stop us looking at the expression.
2699 -- We could sharpen this test to be out parameters only ???
ee6ba406 2700
2701 if Is_Discrete_Type (Target_Typ)
2702 and then Is_Discrete_Type (Etype (Expr))
2703 and then not Is_Unconstrained_Subscr_Ref
2704 and then No (Source_Typ)
2705 then
2706 declare
2707 Tlo : constant Node_Id := Type_Low_Bound (Target_Typ);
2708 Thi : constant Node_Id := Type_High_Bound (Target_Typ);
2709 Lo : Uint;
2710 Hi : Uint;
2711
2712 begin
2713 if Compile_Time_Known_Value (Tlo)
2714 and then Compile_Time_Known_Value (Thi)
2715 then
9dfe12ae 2716 declare
2717 Lov : constant Uint := Expr_Value (Tlo);
2718 Hiv : constant Uint := Expr_Value (Thi);
ee6ba406 2719
9dfe12ae 2720 begin
2721 -- If range is null, we for sure have a constraint error
2722 -- (we don't even need to look at the value involved,
2723 -- since all possible values will raise CE).
2724
2725 if Lov > Hiv then
2726 Bad_Value;
2727 return;
2728 end if;
2729
2730 -- Otherwise determine range of value
2731
9c486805 2732 Determine_Range (Expr, OK, Lo, Hi, Assume_Valid => True);
9dfe12ae 2733
2734 if OK then
2735
2736 -- If definitely in range, all OK
ee6ba406 2737
ee6ba406 2738 if Lo >= Lov and then Hi <= Hiv then
2739 return;
2740
9dfe12ae 2741 -- If definitely not in range, warn
2742
ee6ba406 2743 elsif Lov > Hi or else Hiv < Lo then
2744 Bad_Value;
2745 return;
9dfe12ae 2746
2747 -- Otherwise we don't know
2748
2749 else
2750 null;
ee6ba406 2751 end if;
9dfe12ae 2752 end if;
2753 end;
ee6ba406 2754 end if;
2755 end;
2756 end if;
2757
2758 Int_Real :=
2759 Is_Floating_Point_Type (S_Typ)
2760 or else (Is_Fixed_Point_Type (S_Typ) and then not Fixed_Int);
2761
2762 -- Check if we can determine at compile time whether Expr is in the
9dfe12ae 2763 -- range of the target type. Note that if S_Typ is within the bounds
2764 -- of Target_Typ then this must be the case. This check is meaningful
2765 -- only if this is not a conversion between integer and real types.
ee6ba406 2766
2767 if not Is_Unconstrained_Subscr_Ref
2768 and then
2769 Is_Discrete_Type (S_Typ) = Is_Discrete_Type (Target_Typ)
2770 and then
7a1dabb3 2771 (In_Subrange_Of (S_Typ, Target_Typ, Fixed_Int)
ee6ba406 2772 or else
9c486805 2773 Is_In_Range (Expr, Target_Typ,
2774 Assume_Valid => True,
2775 Fixed_Int => Fixed_Int,
2776 Int_Real => Int_Real))
ee6ba406 2777 then
2778 return;
2779
9c486805 2780 elsif Is_Out_Of_Range (Expr, Target_Typ,
2781 Assume_Valid => True,
2782 Fixed_Int => Fixed_Int,
2783 Int_Real => Int_Real)
2784 then
ee6ba406 2785 Bad_Value;
2786 return;
2787
feff2f05 2788 -- In the floating-point case, we only do range checks if the type is
2789 -- constrained. We definitely do NOT want range checks for unconstrained
2790 -- types, since we want to have infinities
ee6ba406 2791
9dfe12ae 2792 elsif Is_Floating_Point_Type (S_Typ) then
2793 if Is_Constrained (S_Typ) then
2794 Enable_Range_Check (Expr);
2795 end if;
ee6ba406 2796
9dfe12ae 2797 -- For all other cases we enable a range check unconditionally
ee6ba406 2798
2799 else
2800 Enable_Range_Check (Expr);
2801 return;
2802 end if;
ee6ba406 2803 end Apply_Scalar_Range_Check;
2804
2805 ----------------------------------
2806 -- Apply_Selected_Length_Checks --
2807 ----------------------------------
2808
2809 procedure Apply_Selected_Length_Checks
2810 (Ck_Node : Node_Id;
2811 Target_Typ : Entity_Id;
2812 Source_Typ : Entity_Id;
2813 Do_Static : Boolean)
2814 is
2815 Cond : Node_Id;
2816 R_Result : Check_Result;
2817 R_Cno : Node_Id;
2818
2819 Loc : constant Source_Ptr := Sloc (Ck_Node);
2820 Checks_On : constant Boolean :=
b6341c67 2821 (not Index_Checks_Suppressed (Target_Typ))
2822 or else (not Length_Checks_Suppressed (Target_Typ));
ee6ba406 2823
2824 begin
6dbcfcd9 2825 if not Full_Expander_Active then
ee6ba406 2826 return;
2827 end if;
2828
2829 R_Result :=
2830 Selected_Length_Checks (Ck_Node, Target_Typ, Source_Typ, Empty);
2831
2832 for J in 1 .. 2 loop
ee6ba406 2833 R_Cno := R_Result (J);
2834 exit when No (R_Cno);
2835
2836 -- A length check may mention an Itype which is attached to a
2837 -- subsequent node. At the top level in a package this can cause
2838 -- an order-of-elaboration problem, so we make sure that the itype
2839 -- is referenced now.
2840
2841 if Ekind (Current_Scope) = E_Package
2842 and then Is_Compilation_Unit (Current_Scope)
2843 then
2844 Ensure_Defined (Target_Typ, Ck_Node);
2845
2846 if Present (Source_Typ) then
2847 Ensure_Defined (Source_Typ, Ck_Node);
2848
2849 elsif Is_Itype (Etype (Ck_Node)) then
2850 Ensure_Defined (Etype (Ck_Node), Ck_Node);
2851 end if;
2852 end if;
2853
feff2f05 2854 -- If the item is a conditional raise of constraint error, then have
2855 -- a look at what check is being performed and ???
ee6ba406 2856
2857 if Nkind (R_Cno) = N_Raise_Constraint_Error
2858 and then Present (Condition (R_Cno))
2859 then
2860 Cond := Condition (R_Cno);
2861
0577b0b1 2862 -- Case where node does not now have a dynamic check
ee6ba406 2863
0577b0b1 2864 if not Has_Dynamic_Length_Check (Ck_Node) then
2865
2866 -- If checks are on, just insert the check
2867
2868 if Checks_On then
2869 Insert_Action (Ck_Node, R_Cno);
2870
2871 if not Do_Static then
2872 Set_Has_Dynamic_Length_Check (Ck_Node);
2873 end if;
2874
2875 -- If checks are off, then analyze the length check after
2876 -- temporarily attaching it to the tree in case the relevant
6fb3c314 2877 -- condition can be evaluated at compile time. We still want a
0577b0b1 2878 -- compile time warning in this case.
2879
2880 else
2881 Set_Parent (R_Cno, Ck_Node);
2882 Analyze (R_Cno);
ee6ba406 2883 end if;
ee6ba406 2884 end if;
2885
2886 -- Output a warning if the condition is known to be True
2887
2888 if Is_Entity_Name (Cond)
2889 and then Entity (Cond) = Standard_True
2890 then
2891 Apply_Compile_Time_Constraint_Error
2892 (Ck_Node, "wrong length for array of}?",
f15731c4 2893 CE_Length_Check_Failed,
ee6ba406 2894 Ent => Target_Typ,
2895 Typ => Target_Typ);
2896
2897 -- If we were only doing a static check, or if checks are not
2898 -- on, then we want to delete the check, since it is not needed.
2899 -- We do this by replacing the if statement by a null statement
2900
2901 elsif Do_Static or else not Checks_On then
00c403ee 2902 Remove_Warning_Messages (R_Cno);
ee6ba406 2903 Rewrite (R_Cno, Make_Null_Statement (Loc));
2904 end if;
2905
2906 else
2907 Install_Static_Check (R_Cno, Loc);
2908 end if;
ee6ba406 2909 end loop;
ee6ba406 2910 end Apply_Selected_Length_Checks;
2911
2912 ---------------------------------
2913 -- Apply_Selected_Range_Checks --
2914 ---------------------------------
2915
2916 procedure Apply_Selected_Range_Checks
2917 (Ck_Node : Node_Id;
2918 Target_Typ : Entity_Id;
2919 Source_Typ : Entity_Id;
2920 Do_Static : Boolean)
2921 is
2922 Cond : Node_Id;
2923 R_Result : Check_Result;
2924 R_Cno : Node_Id;
2925
2926 Loc : constant Source_Ptr := Sloc (Ck_Node);
2927 Checks_On : constant Boolean :=
b6341c67 2928 (not Index_Checks_Suppressed (Target_Typ))
2929 or else (not Range_Checks_Suppressed (Target_Typ));
ee6ba406 2930
2931 begin
6dbcfcd9 2932 if not Full_Expander_Active or else not Checks_On then
ee6ba406 2933 return;
2934 end if;
2935
2936 R_Result :=
2937 Selected_Range_Checks (Ck_Node, Target_Typ, Source_Typ, Empty);
2938
2939 for J in 1 .. 2 loop
2940
2941 R_Cno := R_Result (J);
2942 exit when No (R_Cno);
2943
feff2f05 2944 -- If the item is a conditional raise of constraint error, then have
2945 -- a look at what check is being performed and ???
ee6ba406 2946
2947 if Nkind (R_Cno) = N_Raise_Constraint_Error
2948 and then Present (Condition (R_Cno))
2949 then
2950 Cond := Condition (R_Cno);
2951
2952 if not Has_Dynamic_Range_Check (Ck_Node) then
2953 Insert_Action (Ck_Node, R_Cno);
2954
2955 if not Do_Static then
2956 Set_Has_Dynamic_Range_Check (Ck_Node);
2957 end if;
2958 end if;
2959
2960 -- Output a warning if the condition is known to be True
2961
2962 if Is_Entity_Name (Cond)
2963 and then Entity (Cond) = Standard_True
2964 then
feff2f05 2965 -- Since an N_Range is technically not an expression, we have
2966 -- to set one of the bounds to C_E and then just flag the
2967 -- N_Range. The warning message will point to the lower bound
2968 -- and complain about a range, which seems OK.
ee6ba406 2969
2970 if Nkind (Ck_Node) = N_Range then
2971 Apply_Compile_Time_Constraint_Error
2972 (Low_Bound (Ck_Node), "static range out of bounds of}?",
f15731c4 2973 CE_Range_Check_Failed,
ee6ba406 2974 Ent => Target_Typ,
2975 Typ => Target_Typ);
2976
2977 Set_Raises_Constraint_Error (Ck_Node);
2978
2979 else
2980 Apply_Compile_Time_Constraint_Error
2981 (Ck_Node, "static value out of range of}?",
f15731c4 2982 CE_Range_Check_Failed,
ee6ba406 2983 Ent => Target_Typ,
2984 Typ => Target_Typ);
2985 end if;
2986
2987 -- If we were only doing a static check, or if checks are not
2988 -- on, then we want to delete the check, since it is not needed.
2989 -- We do this by replacing the if statement by a null statement
2990
2991 elsif Do_Static or else not Checks_On then
00c403ee 2992 Remove_Warning_Messages (R_Cno);
ee6ba406 2993 Rewrite (R_Cno, Make_Null_Statement (Loc));
2994 end if;
2995
2996 else
2997 Install_Static_Check (R_Cno, Loc);
2998 end if;
ee6ba406 2999 end loop;
ee6ba406 3000 end Apply_Selected_Range_Checks;
3001
3002 -------------------------------
3003 -- Apply_Static_Length_Check --
3004 -------------------------------
3005
3006 procedure Apply_Static_Length_Check
3007 (Expr : Node_Id;
3008 Target_Typ : Entity_Id;
3009 Source_Typ : Entity_Id := Empty)
3010 is
3011 begin
3012 Apply_Selected_Length_Checks
3013 (Expr, Target_Typ, Source_Typ, Do_Static => True);
3014 end Apply_Static_Length_Check;
3015
3016 -------------------------------------
3017 -- Apply_Subscript_Validity_Checks --
3018 -------------------------------------
3019
3020 procedure Apply_Subscript_Validity_Checks (Expr : Node_Id) is
3021 Sub : Node_Id;
3022
3023 begin
3024 pragma Assert (Nkind (Expr) = N_Indexed_Component);
3025
3026 -- Loop through subscripts
3027
3028 Sub := First (Expressions (Expr));
3029 while Present (Sub) loop
3030
feff2f05 3031 -- Check one subscript. Note that we do not worry about enumeration
3032 -- type with holes, since we will convert the value to a Pos value
3033 -- for the subscript, and that convert will do the necessary validity
3034 -- check.
ee6ba406 3035
3036 Ensure_Valid (Sub, Holes_OK => True);
3037
3038 -- Move to next subscript
3039
3040 Sub := Next (Sub);
3041 end loop;
3042 end Apply_Subscript_Validity_Checks;
3043
3044 ----------------------------------
3045 -- Apply_Type_Conversion_Checks --
3046 ----------------------------------
3047
3048 procedure Apply_Type_Conversion_Checks (N : Node_Id) is
3049 Target_Type : constant Entity_Id := Etype (N);
3050 Target_Base : constant Entity_Id := Base_Type (Target_Type);
9dfe12ae 3051 Expr : constant Node_Id := Expression (N);
f4532fe1 3052
3053 Expr_Type : constant Entity_Id := Underlying_Type (Etype (Expr));
141d591a 3054 -- Note: if Etype (Expr) is a private type without discriminants, its
3055 -- full view might have discriminants with defaults, so we need the
3056 -- full view here to retrieve the constraints.
ee6ba406 3057
3058 begin
3059 if Inside_A_Generic then
3060 return;
3061
f15731c4 3062 -- Skip these checks if serious errors detected, there are some nasty
ee6ba406 3063 -- situations of incomplete trees that blow things up.
3064
f15731c4 3065 elsif Serious_Errors_Detected > 0 then
ee6ba406 3066 return;
3067
feff2f05 3068 -- Scalar type conversions of the form Target_Type (Expr) require a
3069 -- range check if we cannot be sure that Expr is in the base type of
3070 -- Target_Typ and also that Expr is in the range of Target_Typ. These
3071 -- are not quite the same condition from an implementation point of
3072 -- view, but clearly the second includes the first.
ee6ba406 3073
3074 elsif Is_Scalar_Type (Target_Type) then
3075 declare
3076 Conv_OK : constant Boolean := Conversion_OK (N);
feff2f05 3077 -- If the Conversion_OK flag on the type conversion is set and no
3078 -- floating point type is involved in the type conversion then
3079 -- fixed point values must be read as integral values.
ee6ba406 3080
5329ca64 3081 Float_To_Int : constant Boolean :=
b6341c67 3082 Is_Floating_Point_Type (Expr_Type)
3083 and then Is_Integer_Type (Target_Type);
5329ca64 3084
ee6ba406 3085 begin
ee6ba406 3086 if not Overflow_Checks_Suppressed (Target_Base)
e254d721 3087 and then not
7a1dabb3 3088 In_Subrange_Of (Expr_Type, Target_Base, Fixed_Int => Conv_OK)
5329ca64 3089 and then not Float_To_Int
ee6ba406 3090 then
00c403ee 3091 Activate_Overflow_Check (N);
ee6ba406 3092 end if;
3093
3094 if not Range_Checks_Suppressed (Target_Type)
3095 and then not Range_Checks_Suppressed (Expr_Type)
3096 then
5329ca64 3097 if Float_To_Int then
3098 Apply_Float_Conversion_Check (Expr, Target_Type);
3099 else
3100 Apply_Scalar_Range_Check
3101 (Expr, Target_Type, Fixed_Int => Conv_OK);
798afddc 3102
3103 -- If the target type has predicates, we need to indicate
3104 -- the need for a check, even if Determine_Range finds
3105 -- that the value is within bounds. This may be the case
3106 -- e.g for a division with a constant denominator.
3107
3108 if Has_Predicates (Target_Type) then
3109 Enable_Range_Check (Expr);
3110 end if;
5329ca64 3111 end if;
ee6ba406 3112 end if;
3113 end;
3114
3115 elsif Comes_From_Source (N)
f40f9731 3116 and then not Discriminant_Checks_Suppressed (Target_Type)
ee6ba406 3117 and then Is_Record_Type (Target_Type)
3118 and then Is_Derived_Type (Target_Type)
3119 and then not Is_Tagged_Type (Target_Type)
3120 and then not Is_Constrained (Target_Type)
9dfe12ae 3121 and then Present (Stored_Constraint (Target_Type))
ee6ba406 3122 then
141d591a 3123 -- An unconstrained derived type may have inherited discriminant.
9dfe12ae 3124 -- Build an actual discriminant constraint list using the stored
ee6ba406 3125 -- constraint, to verify that the expression of the parent type
3126 -- satisfies the constraints imposed by the (unconstrained!)
3127 -- derived type. This applies to value conversions, not to view
3128 -- conversions of tagged types.
3129
3130 declare
9dfe12ae 3131 Loc : constant Source_Ptr := Sloc (N);
3132 Cond : Node_Id;
3133 Constraint : Elmt_Id;
3134 Discr_Value : Node_Id;
3135 Discr : Entity_Id;
3136
3137 New_Constraints : constant Elist_Id := New_Elmt_List;
3138 Old_Constraints : constant Elist_Id :=
b6341c67 3139 Discriminant_Constraint (Expr_Type);
ee6ba406 3140
3141 begin
9dfe12ae 3142 Constraint := First_Elmt (Stored_Constraint (Target_Type));
ee6ba406 3143 while Present (Constraint) loop
3144 Discr_Value := Node (Constraint);
3145
3146 if Is_Entity_Name (Discr_Value)
3147 and then Ekind (Entity (Discr_Value)) = E_Discriminant
3148 then
3149 Discr := Corresponding_Discriminant (Entity (Discr_Value));
3150
3151 if Present (Discr)
3152 and then Scope (Discr) = Base_Type (Expr_Type)
3153 then
3154 -- Parent is constrained by new discriminant. Obtain
feff2f05 3155 -- Value of original discriminant in expression. If the
3156 -- new discriminant has been used to constrain more than
3157 -- one of the stored discriminants, this will provide the
3158 -- required consistency check.
ee6ba406 3159
55868293 3160 Append_Elmt
3161 (Make_Selected_Component (Loc,
3162 Prefix =>
9dfe12ae 3163 Duplicate_Subexpr_No_Checks
3164 (Expr, Name_Req => True),
ee6ba406 3165 Selector_Name =>
3166 Make_Identifier (Loc, Chars (Discr))),
55868293 3167 New_Constraints);
ee6ba406 3168
3169 else
3170 -- Discriminant of more remote ancestor ???
3171
3172 return;
3173 end if;
3174
feff2f05 3175 -- Derived type definition has an explicit value for this
3176 -- stored discriminant.
ee6ba406 3177
3178 else
3179 Append_Elmt
9dfe12ae 3180 (Duplicate_Subexpr_No_Checks (Discr_Value),
3181 New_Constraints);
ee6ba406 3182 end if;
3183
3184 Next_Elmt (Constraint);
3185 end loop;
3186
3187 -- Use the unconstrained expression type to retrieve the
3188 -- discriminants of the parent, and apply momentarily the
3189 -- discriminant constraint synthesized above.
3190
3191 Set_Discriminant_Constraint (Expr_Type, New_Constraints);
3192 Cond := Build_Discriminant_Checks (Expr, Expr_Type);
3193 Set_Discriminant_Constraint (Expr_Type, Old_Constraints);
3194
3195 Insert_Action (N,
f15731c4 3196 Make_Raise_Constraint_Error (Loc,
3197 Condition => Cond,
3198 Reason => CE_Discriminant_Check_Failed));
ee6ba406 3199 end;
3200
feff2f05 3201 -- For arrays, conversions are applied during expansion, to take into
3202 -- accounts changes of representation. The checks become range checks on
3203 -- the base type or length checks on the subtype, depending on whether
3204 -- the target type is unconstrained or constrained.
ee6ba406 3205
3206 else
3207 null;
3208 end if;
ee6ba406 3209 end Apply_Type_Conversion_Checks;
3210
3211 ----------------------------------------------
3212 -- Apply_Universal_Integer_Attribute_Checks --
3213 ----------------------------------------------
3214
3215 procedure Apply_Universal_Integer_Attribute_Checks (N : Node_Id) is
3216 Loc : constant Source_Ptr := Sloc (N);
3217 Typ : constant Entity_Id := Etype (N);
3218
3219 begin
3220 if Inside_A_Generic then
3221 return;
3222
3223 -- Nothing to do if checks are suppressed
3224
3225 elsif Range_Checks_Suppressed (Typ)
3226 and then Overflow_Checks_Suppressed (Typ)
3227 then
3228 return;
3229
3230 -- Nothing to do if the attribute does not come from source. The
3231 -- internal attributes we generate of this type do not need checks,
3232 -- and furthermore the attempt to check them causes some circular
3233 -- elaboration orders when dealing with packed types.
3234
3235 elsif not Comes_From_Source (N) then
3236 return;
3237
9dfe12ae 3238 -- If the prefix is a selected component that depends on a discriminant
3239 -- the check may improperly expose a discriminant instead of using
3240 -- the bounds of the object itself. Set the type of the attribute to
3241 -- the base type of the context, so that a check will be imposed when
3242 -- needed (e.g. if the node appears as an index).
3243
3244 elsif Nkind (Prefix (N)) = N_Selected_Component
3245 and then Ekind (Typ) = E_Signed_Integer_Subtype
3246 and then Depends_On_Discriminant (Scalar_Range (Typ))
3247 then
3248 Set_Etype (N, Base_Type (Typ));
3249
feff2f05 3250 -- Otherwise, replace the attribute node with a type conversion node
3251 -- whose expression is the attribute, retyped to universal integer, and
3252 -- whose subtype mark is the target type. The call to analyze this
3253 -- conversion will set range and overflow checks as required for proper
3254 -- detection of an out of range value.
ee6ba406 3255
3256 else
3257 Set_Etype (N, Universal_Integer);
3258 Set_Analyzed (N, True);
3259
3260 Rewrite (N,
3261 Make_Type_Conversion (Loc,
3262 Subtype_Mark => New_Occurrence_Of (Typ, Loc),
3263 Expression => Relocate_Node (N)));
3264
3265 Analyze_And_Resolve (N, Typ);
3266 return;
3267 end if;
ee6ba406 3268 end Apply_Universal_Integer_Attribute_Checks;
3269
07c191b0 3270 -------------------------------------
3271 -- Atomic_Synchronization_Disabled --
3272 -------------------------------------
3273
3274 -- Note: internally Disable/Enable_Atomic_Synchronization is implemented
3275 -- using a bogus check called Atomic_Synchronization. This is to make it
3276 -- more convenient to get exactly the same semantics as [Un]Suppress.
3277
3278 function Atomic_Synchronization_Disabled (E : Entity_Id) return Boolean is
3279 begin
b444f81d 3280 -- If debug flag d.e is set, always return False, i.e. all atomic sync
3281 -- looks enabled, since it is never disabled.
3282
3283 if Debug_Flag_Dot_E then
3284 return False;
3285
3286 -- If debug flag d.d is set then always return True, i.e. all atomic
3287 -- sync looks disabled, since it always tests True.
3288
3289 elsif Debug_Flag_Dot_D then
3290 return True;
3291
3292 -- If entity present, then check result for that entity
3293
3294 elsif Present (E) and then Checks_May_Be_Suppressed (E) then
07c191b0 3295 return Is_Check_Suppressed (E, Atomic_Synchronization);
b444f81d 3296
3297 -- Otherwise result depends on current scope setting
3298
07c191b0 3299 else
fafc6b97 3300 return Scope_Suppress.Suppress (Atomic_Synchronization);
07c191b0 3301 end if;
3302 end Atomic_Synchronization_Disabled;
3303
ee6ba406 3304 -------------------------------
3305 -- Build_Discriminant_Checks --
3306 -------------------------------
3307
3308 function Build_Discriminant_Checks
3309 (N : Node_Id;
314a23b6 3310 T_Typ : Entity_Id) return Node_Id
ee6ba406 3311 is
3312 Loc : constant Source_Ptr := Sloc (N);
3313 Cond : Node_Id;
3314 Disc : Elmt_Id;
3315 Disc_Ent : Entity_Id;
9dfe12ae 3316 Dref : Node_Id;
ee6ba406 3317 Dval : Node_Id;
3318
84d0d4a5 3319 function Aggregate_Discriminant_Val (Disc : Entity_Id) return Node_Id;
3320
3321 ----------------------------------
3322 -- Aggregate_Discriminant_Value --
3323 ----------------------------------
3324
3325 function Aggregate_Discriminant_Val (Disc : Entity_Id) return Node_Id is
3326 Assoc : Node_Id;
3327
3328 begin
feff2f05 3329 -- The aggregate has been normalized with named associations. We use
3330 -- the Chars field to locate the discriminant to take into account
3331 -- discriminants in derived types, which carry the same name as those
3332 -- in the parent.
84d0d4a5 3333
3334 Assoc := First (Component_Associations (N));
3335 while Present (Assoc) loop
3336 if Chars (First (Choices (Assoc))) = Chars (Disc) then
3337 return Expression (Assoc);
3338 else
3339 Next (Assoc);
3340 end if;
3341 end loop;
3342
3343 -- Discriminant must have been found in the loop above
3344
3345 raise Program_Error;
3346 end Aggregate_Discriminant_Val;
3347
3348 -- Start of processing for Build_Discriminant_Checks
3349
ee6ba406 3350 begin
84d0d4a5 3351 -- Loop through discriminants evolving the condition
3352
ee6ba406 3353 Cond := Empty;
3354 Disc := First_Elmt (Discriminant_Constraint (T_Typ));
3355
9dfe12ae 3356 -- For a fully private type, use the discriminants of the parent type
ee6ba406 3357
3358 if Is_Private_Type (T_Typ)
3359 and then No (Full_View (T_Typ))
3360 then
3361 Disc_Ent := First_Discriminant (Etype (Base_Type (T_Typ)));
3362 else
3363 Disc_Ent := First_Discriminant (T_Typ);
3364 end if;
3365
3366 while Present (Disc) loop
ee6ba406 3367 Dval := Node (Disc);
3368
3369 if Nkind (Dval) = N_Identifier
3370 and then Ekind (Entity (Dval)) = E_Discriminant
3371 then
3372 Dval := New_Occurrence_Of (Discriminal (Entity (Dval)), Loc);
3373 else
9dfe12ae 3374 Dval := Duplicate_Subexpr_No_Checks (Dval);
ee6ba406 3375 end if;
3376
00f91aef 3377 -- If we have an Unchecked_Union node, we can infer the discriminants
3378 -- of the node.
9dfe12ae 3379
00f91aef 3380 if Is_Unchecked_Union (Base_Type (T_Typ)) then
3381 Dref := New_Copy (
3382 Get_Discriminant_Value (
3383 First_Discriminant (T_Typ),
3384 T_Typ,
3385 Stored_Constraint (T_Typ)));
3386
84d0d4a5 3387 elsif Nkind (N) = N_Aggregate then
3388 Dref :=
3389 Duplicate_Subexpr_No_Checks
3390 (Aggregate_Discriminant_Val (Disc_Ent));
3391
00f91aef 3392 else
3393 Dref :=
3394 Make_Selected_Component (Loc,
3395 Prefix =>
3396 Duplicate_Subexpr_No_Checks (N, Name_Req => True),
3397 Selector_Name =>
3398 Make_Identifier (Loc, Chars (Disc_Ent)));
3399
3400 Set_Is_In_Discriminant_Check (Dref);
3401 end if;
9dfe12ae 3402
ee6ba406 3403 Evolve_Or_Else (Cond,
3404 Make_Op_Ne (Loc,
9dfe12ae 3405 Left_Opnd => Dref,
ee6ba406 3406 Right_Opnd => Dval));
3407
3408 Next_Elmt (Disc);
3409 Next_Discriminant (Disc_Ent);
3410 end loop;
3411
3412 return Cond;
3413 end Build_Discriminant_Checks;
3414
13dbf220 3415 ------------------
3416 -- Check_Needed --
3417 ------------------
3418
3419 function Check_Needed (Nod : Node_Id; Check : Check_Type) return Boolean is
3420 N : Node_Id;
3421 P : Node_Id;
3422 K : Node_Kind;
3423 L : Node_Id;
3424 R : Node_Id;
3425
3426 begin
3427 -- Always check if not simple entity
3428
3429 if Nkind (Nod) not in N_Has_Entity
3430 or else not Comes_From_Source (Nod)
3431 then
3432 return True;
3433 end if;
3434
3435 -- Look up tree for short circuit
3436
3437 N := Nod;
3438 loop
3439 P := Parent (N);
3440 K := Nkind (P);
3441
7b17e51b 3442 -- Done if out of subexpression (note that we allow generated stuff
3443 -- such as itype declarations in this context, to keep the loop going
3444 -- since we may well have generated such stuff in complex situations.
3445 -- Also done if no parent (probably an error condition, but no point
3446 -- in behaving nasty if we find it!)
3447
3448 if No (P)
3449 or else (K not in N_Subexpr and then Comes_From_Source (P))
3450 then
13dbf220 3451 return True;
3452
7b17e51b 3453 -- Or/Or Else case, where test is part of the right operand, or is
3454 -- part of one of the actions associated with the right operand, and
3455 -- the left operand is an equality test.
13dbf220 3456
7b17e51b 3457 elsif K = N_Op_Or then
13dbf220 3458 exit when N = Right_Opnd (P)
3459 and then Nkind (Left_Opnd (P)) = N_Op_Eq;
3460
7b17e51b 3461 elsif K = N_Or_Else then
3462 exit when (N = Right_Opnd (P)
3463 or else
3464 (Is_List_Member (N)
3465 and then List_Containing (N) = Actions (P)))
3466 and then Nkind (Left_Opnd (P)) = N_Op_Eq;
13dbf220 3467
7b17e51b 3468 -- Similar test for the And/And then case, where the left operand
3469 -- is an inequality test.
3470
3471 elsif K = N_Op_And then
13dbf220 3472 exit when N = Right_Opnd (P)
38f5559f 3473 and then Nkind (Left_Opnd (P)) = N_Op_Ne;
7b17e51b 3474
3475 elsif K = N_And_Then then
3476 exit when (N = Right_Opnd (P)
3477 or else
3478 (Is_List_Member (N)
3479 and then List_Containing (N) = Actions (P)))
3480 and then Nkind (Left_Opnd (P)) = N_Op_Ne;
13dbf220 3481 end if;
3482
3483 N := P;
3484 end loop;
3485
3486 -- If we fall through the loop, then we have a conditional with an
3487 -- appropriate test as its left operand. So test further.
3488
3489 L := Left_Opnd (P);
13dbf220 3490 R := Right_Opnd (L);
3491 L := Left_Opnd (L);
3492
3493 -- Left operand of test must match original variable
3494
3495 if Nkind (L) not in N_Has_Entity
3496 or else Entity (L) /= Entity (Nod)
3497 then
3498 return True;
3499 end if;
3500
2af58f67 3501 -- Right operand of test must be key value (zero or null)
13dbf220 3502
3503 case Check is
3504 when Access_Check =>
2af58f67 3505 if not Known_Null (R) then
13dbf220 3506 return True;
3507 end if;
3508
3509 when Division_Check =>
3510 if not Compile_Time_Known_Value (R)
3511 or else Expr_Value (R) /= Uint_0
3512 then
3513 return True;
3514 end if;
2af58f67 3515
3516 when others =>
3517 raise Program_Error;
13dbf220 3518 end case;
3519
3520 -- Here we have the optimizable case, warn if not short-circuited
3521
3522 if K = N_Op_And or else K = N_Op_Or then
3523 case Check is
3524 when Access_Check =>
3525 Error_Msg_N
3526 ("Constraint_Error may be raised (access check)?",
3527 Parent (Nod));
3528 when Division_Check =>
3529 Error_Msg_N
3530 ("Constraint_Error may be raised (zero divide)?",
3531 Parent (Nod));
2af58f67 3532
3533 when others =>
3534 raise Program_Error;
13dbf220 3535 end case;
3536
3537 if K = N_Op_And then
e977c0cf 3538 Error_Msg_N -- CODEFIX
3539 ("use `AND THEN` instead of AND?", P);
13dbf220 3540 else
e977c0cf 3541 Error_Msg_N -- CODEFIX
3542 ("use `OR ELSE` instead of OR?", P);
13dbf220 3543 end if;
3544
6fb3c314 3545 -- If not short-circuited, we need the check
13dbf220 3546
3547 return True;
3548
3549 -- If short-circuited, we can omit the check
3550
3551 else
3552 return False;
3553 end if;
3554 end Check_Needed;
3555
ee6ba406 3556 -----------------------------------
3557 -- Check_Valid_Lvalue_Subscripts --
3558 -----------------------------------
3559
3560 procedure Check_Valid_Lvalue_Subscripts (Expr : Node_Id) is
3561 begin
3562 -- Skip this if range checks are suppressed
3563
3564 if Range_Checks_Suppressed (Etype (Expr)) then
3565 return;
3566
feff2f05 3567 -- Only do this check for expressions that come from source. We assume
3568 -- that expander generated assignments explicitly include any necessary
3569 -- checks. Note that this is not just an optimization, it avoids
3570 -- infinite recursions!
ee6ba406 3571
3572 elsif not Comes_From_Source (Expr) then
3573 return;
3574
3575 -- For a selected component, check the prefix
3576
3577 elsif Nkind (Expr) = N_Selected_Component then
3578 Check_Valid_Lvalue_Subscripts (Prefix (Expr));
3579 return;
3580
3581 -- Case of indexed component
3582
3583 elsif Nkind (Expr) = N_Indexed_Component then
3584 Apply_Subscript_Validity_Checks (Expr);
3585
feff2f05 3586 -- Prefix may itself be or contain an indexed component, and these
3587 -- subscripts need checking as well.
ee6ba406 3588
3589 Check_Valid_Lvalue_Subscripts (Prefix (Expr));
3590 end if;
3591 end Check_Valid_Lvalue_Subscripts;
3592
fa7497e8 3593 ----------------------------------
3594 -- Null_Exclusion_Static_Checks --
3595 ----------------------------------
3596
3597 procedure Null_Exclusion_Static_Checks (N : Node_Id) is
0577b0b1 3598 Error_Node : Node_Id;
3599 Expr : Node_Id;
3600 Has_Null : constant Boolean := Has_Null_Exclusion (N);
3601 K : constant Node_Kind := Nkind (N);
3602 Typ : Entity_Id;
fa7497e8 3603
13dbf220 3604 begin
0577b0b1 3605 pragma Assert
3606 (K = N_Component_Declaration
3607 or else K = N_Discriminant_Specification
3608 or else K = N_Function_Specification
3609 or else K = N_Object_Declaration
3610 or else K = N_Parameter_Specification);
3611
3612 if K = N_Function_Specification then
3613 Typ := Etype (Defining_Entity (N));
3614 else
3615 Typ := Etype (Defining_Identifier (N));
3616 end if;
fa7497e8 3617
13dbf220 3618 case K is
13dbf220 3619 when N_Component_Declaration =>
3620 if Present (Access_Definition (Component_Definition (N))) then
0577b0b1 3621 Error_Node := Component_Definition (N);
13dbf220 3622 else
0577b0b1 3623 Error_Node := Subtype_Indication (Component_Definition (N));
13dbf220 3624 end if;
5329ca64 3625
0577b0b1 3626 when N_Discriminant_Specification =>
3627 Error_Node := Discriminant_Type (N);
3628
3629 when N_Function_Specification =>
3630 Error_Node := Result_Definition (N);
3631
3632 when N_Object_Declaration =>
3633 Error_Node := Object_Definition (N);
3634
3635 when N_Parameter_Specification =>
3636 Error_Node := Parameter_Type (N);
3637
13dbf220 3638 when others =>
3639 raise Program_Error;
3640 end case;
5329ca64 3641
0577b0b1 3642 if Has_Null then
5329ca64 3643
0577b0b1 3644 -- Enforce legality rule 3.10 (13): A null exclusion can only be
3645 -- applied to an access [sub]type.
5329ca64 3646
0577b0b1 3647 if not Is_Access_Type (Typ) then
503f7fd3 3648 Error_Msg_N
00c403ee 3649 ("`NOT NULL` allowed only for an access type", Error_Node);
5329ca64 3650
feff2f05 3651 -- Enforce legality rule RM 3.10(14/1): A null exclusion can only
0577b0b1 3652 -- be applied to a [sub]type that does not exclude null already.
3653
3654 elsif Can_Never_Be_Null (Typ)
d16989f1 3655 and then Comes_From_Source (Typ)
0577b0b1 3656 then
503f7fd3 3657 Error_Msg_NE
00c403ee 3658 ("`NOT NULL` not allowed (& already excludes null)",
3659 Error_Node, Typ);
0577b0b1 3660 end if;
13dbf220 3661 end if;
5329ca64 3662
cc60bd16 3663 -- Check that null-excluding objects are always initialized, except for
3664 -- deferred constants, for which the expression will appear in the full
3665 -- declaration.
13dbf220 3666
3667 if K = N_Object_Declaration
84d0d4a5 3668 and then No (Expression (N))
cc60bd16 3669 and then not Constant_Present (N)
feff2f05 3670 and then not No_Initialization (N)
13dbf220 3671 then
feff2f05 3672 -- Add an expression that assigns null. This node is needed by
3673 -- Apply_Compile_Time_Constraint_Error, which will replace this with
3674 -- a Constraint_Error node.
13dbf220 3675
3676 Set_Expression (N, Make_Null (Sloc (N)));
3677 Set_Etype (Expression (N), Etype (Defining_Identifier (N)));
5329ca64 3678
13dbf220 3679 Apply_Compile_Time_Constraint_Error
3680 (N => Expression (N),
3681 Msg => "(Ada 2005) null-excluding objects must be initialized?",
3682 Reason => CE_Null_Not_Allowed);
3683 end if;
5329ca64 3684
cc60bd16 3685 -- Check that a null-excluding component, formal or object is not being
3686 -- assigned a null value. Otherwise generate a warning message and
2c145f84 3687 -- replace Expression (N) by an N_Constraint_Error node.
13dbf220 3688
0577b0b1 3689 if K /= N_Function_Specification then
3690 Expr := Expression (N);
5329ca64 3691
2af58f67 3692 if Present (Expr) and then Known_Null (Expr) then
13dbf220 3693 case K is
0577b0b1 3694 when N_Component_Declaration |
3695 N_Discriminant_Specification =>
7189d17f 3696 Apply_Compile_Time_Constraint_Error
0577b0b1 3697 (N => Expr,
2af58f67 3698 Msg => "(Ada 2005) null not allowed " &
0577b0b1 3699 "in null-excluding components?",
3700 Reason => CE_Null_Not_Allowed);
5329ca64 3701
0577b0b1 3702 when N_Object_Declaration =>
7189d17f 3703 Apply_Compile_Time_Constraint_Error
0577b0b1 3704 (N => Expr,
2af58f67 3705 Msg => "(Ada 2005) null not allowed " &
0577b0b1 3706 "in null-excluding objects?",
3707 Reason => CE_Null_Not_Allowed);
5329ca64 3708
0577b0b1 3709 when N_Parameter_Specification =>
7189d17f 3710 Apply_Compile_Time_Constraint_Error
0577b0b1 3711 (N => Expr,
2af58f67 3712 Msg => "(Ada 2005) null not allowed " &
0577b0b1 3713 "in null-excluding formals?",
3714 Reason => CE_Null_Not_Allowed);
13dbf220 3715
3716 when others =>
3717 null;
5329ca64 3718 end case;
3719 end if;
0577b0b1 3720 end if;
fa7497e8 3721 end Null_Exclusion_Static_Checks;
3722
9dfe12ae 3723 ----------------------------------
3724 -- Conditional_Statements_Begin --
3725 ----------------------------------
3726
3727 procedure Conditional_Statements_Begin is
3728 begin
3729 Saved_Checks_TOS := Saved_Checks_TOS + 1;
3730
feff2f05 3731 -- If stack overflows, kill all checks, that way we know to simply reset
3732 -- the number of saved checks to zero on return. This should never occur
3733 -- in practice.
9dfe12ae 3734
3735 if Saved_Checks_TOS > Saved_Checks_Stack'Last then
3736 Kill_All_Checks;
3737
feff2f05 3738 -- In the normal case, we just make a new stack entry saving the current
3739 -- number of saved checks for a later restore.
9dfe12ae 3740
3741 else
3742 Saved_Checks_Stack (Saved_Checks_TOS) := Num_Saved_Checks;
3743
3744 if Debug_Flag_CC then
3745 w ("Conditional_Statements_Begin: Num_Saved_Checks = ",
3746 Num_Saved_Checks);
3747 end if;
3748 end if;
3749 end Conditional_Statements_Begin;
3750
3751 --------------------------------
3752 -- Conditional_Statements_End --
3753 --------------------------------
3754
3755 procedure Conditional_Statements_End is
3756 begin
3757 pragma Assert (Saved_Checks_TOS > 0);
3758
feff2f05 3759 -- If the saved checks stack overflowed, then we killed all checks, so
3760 -- setting the number of saved checks back to zero is correct. This
3761 -- should never occur in practice.
9dfe12ae 3762
3763 if Saved_Checks_TOS > Saved_Checks_Stack'Last then
3764 Num_Saved_Checks := 0;
3765
feff2f05 3766 -- In the normal case, restore the number of saved checks from the top
3767 -- stack entry.
9dfe12ae 3768
3769 else
3770 Num_Saved_Checks := Saved_Checks_Stack (Saved_Checks_TOS);
3771 if Debug_Flag_CC then
3772 w ("Conditional_Statements_End: Num_Saved_Checks = ",
3773 Num_Saved_Checks);
3774 end if;
3775 end if;
3776
3777 Saved_Checks_TOS := Saved_Checks_TOS - 1;
3778 end Conditional_Statements_End;
3779
3cce7f32 3780 -------------------------
3781 -- Convert_From_Bignum --
3782 -------------------------
3783
3784 function Convert_From_Bignum (N : Node_Id) return Node_Id is
3785 Loc : constant Source_Ptr := Sloc (N);
3786
3787 begin
3788 pragma Assert (Is_RTE (Etype (N), RE_Bignum));
3789
3790 -- Construct call From Bignum
3791
3792 return
3793 Make_Function_Call (Loc,
3794 Name =>
3795 New_Occurrence_Of (RTE (RE_From_Bignum), Loc),
3796 Parameter_Associations => New_List (Relocate_Node (N)));
3797 end Convert_From_Bignum;
3798
3799 -----------------------
3800 -- Convert_To_Bignum --
3801 -----------------------
3802
3803 function Convert_To_Bignum (N : Node_Id) return Node_Id is
3804 Loc : constant Source_Ptr := Sloc (N);
3805
3806 begin
0326b4d4 3807 -- Nothing to do if Bignum already except call Relocate_Node
3cce7f32 3808
3809 if Is_RTE (Etype (N), RE_Bignum) then
3810 return Relocate_Node (N);
3811
3812 -- Otherwise construct call to To_Bignum, converting the operand to
3813 -- the required Long_Long_Integer form.
3814
3815 else
3816 pragma Assert (Is_Signed_Integer_Type (Etype (N)));
3817 return
3818 Make_Function_Call (Loc,
3819 Name =>
3820 New_Occurrence_Of (RTE (RE_To_Bignum), Loc),
3821 Parameter_Associations => New_List (
3822 Convert_To (Standard_Long_Long_Integer, Relocate_Node (N))));
3823 end if;
3824 end Convert_To_Bignum;
3825
ee6ba406 3826 ---------------------
3827 -- Determine_Range --
3828 ---------------------
3829
6af1bdbc 3830 Cache_Size : constant := 2 ** 10;
ee6ba406 3831 type Cache_Index is range 0 .. Cache_Size - 1;
3832 -- Determine size of below cache (power of 2 is more efficient!)
3833
3834 Determine_Range_Cache_N : array (Cache_Index) of Node_Id;
9c486805 3835 Determine_Range_Cache_V : array (Cache_Index) of Boolean;
ee6ba406 3836 Determine_Range_Cache_Lo : array (Cache_Index) of Uint;
3837 Determine_Range_Cache_Hi : array (Cache_Index) of Uint;
feff2f05 3838 -- The above arrays are used to implement a small direct cache for
3839 -- Determine_Range calls. Because of the way Determine_Range recursively
3840 -- traces subexpressions, and because overflow checking calls the routine
3841 -- on the way up the tree, a quadratic behavior can otherwise be
3842 -- encountered in large expressions. The cache entry for node N is stored
3843 -- in the (N mod Cache_Size) entry, and can be validated by checking the
9c486805 3844 -- actual node value stored there. The Range_Cache_V array records the
3845 -- setting of Assume_Valid for the cache entry.
ee6ba406 3846
3847 procedure Determine_Range
9c486805 3848 (N : Node_Id;
3849 OK : out Boolean;
3850 Lo : out Uint;
3851 Hi : out Uint;
3852 Assume_Valid : Boolean := False)
ee6ba406 3853 is
e254d721 3854 Typ : Entity_Id := Etype (N);
3855 -- Type to use, may get reset to base type for possibly invalid entity
8880be85 3856
3857 Lo_Left : Uint;
3858 Hi_Left : Uint;
3859 -- Lo and Hi bounds of left operand
ee6ba406 3860
ee6ba406 3861 Lo_Right : Uint;
ee6ba406 3862 Hi_Right : Uint;
8880be85 3863 -- Lo and Hi bounds of right (or only) operand
3864
3865 Bound : Node_Id;
3866 -- Temp variable used to hold a bound node
3867
3868 Hbound : Uint;
3869 -- High bound of base type of expression
3870
3871 Lor : Uint;
3872 Hir : Uint;
3873 -- Refined values for low and high bounds, after tightening
3874
3875 OK1 : Boolean;
3876 -- Used in lower level calls to indicate if call succeeded
3877
3878 Cindex : Cache_Index;
3879 -- Used to search cache
ee6ba406 3880
094ed68e 3881 Btyp : Entity_Id;
3882 -- Base type
3883
ee6ba406 3884 function OK_Operands return Boolean;
3885 -- Used for binary operators. Determines the ranges of the left and
3886 -- right operands, and if they are both OK, returns True, and puts
341bd953 3887 -- the results in Lo_Right, Hi_Right, Lo_Left, Hi_Left.
ee6ba406 3888
3889 -----------------
3890 -- OK_Operands --
3891 -----------------
3892
3893 function OK_Operands return Boolean is
3894 begin
9c486805 3895 Determine_Range
3896 (Left_Opnd (N), OK1, Lo_Left, Hi_Left, Assume_Valid);
ee6ba406 3897
3898 if not OK1 then
3899 return False;
3900 end if;
3901
9c486805 3902 Determine_Range
3903 (Right_Opnd (N), OK1, Lo_Right, Hi_Right, Assume_Valid);
ee6ba406 3904 return OK1;
3905 end OK_Operands;
3906
3907 -- Start of processing for Determine_Range
3908
3909 begin
87bdc21d 3910 -- For temporary constants internally generated to remove side effects
3911 -- we must use the corresponding expression to determine the range of
3912 -- the expression.
3913
3914 if Is_Entity_Name (N)
3915 and then Nkind (Parent (Entity (N))) = N_Object_Declaration
3916 and then Ekind (Entity (N)) = E_Constant
3917 and then Is_Internal_Name (Chars (Entity (N)))
3918 then
3919 Determine_Range
3920 (Expression (Parent (Entity (N))), OK, Lo, Hi, Assume_Valid);
3921 return;
3922 end if;
3923
ee6ba406 3924 -- Prevent junk warnings by initializing range variables
3925
3926 Lo := No_Uint;
3927 Hi := No_Uint;
3928 Lor := No_Uint;
3929 Hir := No_Uint;
3930
a781c0fc 3931 -- If type is not defined, we can't determine its range
ee6ba406 3932
a781c0fc 3933 if No (Typ)
3934
3935 -- We don't deal with anything except discrete types
3936
3937 or else not Is_Discrete_Type (Typ)
3938
3939 -- Ignore type for which an error has been posted, since range in
3940 -- this case may well be a bogosity deriving from the error. Also
3941 -- ignore if error posted on the reference node.
3942
3943 or else Error_Posted (N) or else Error_Posted (Typ)
ee6ba406 3944 then
3945 OK := False;
3946 return;
3947 end if;
3948
3949 -- For all other cases, we can determine the range
3950
3951 OK := True;
3952
feff2f05 3953 -- If value is compile time known, then the possible range is the one
3954 -- value that we know this expression definitely has!
ee6ba406 3955
3956 if Compile_Time_Known_Value (N) then
3957 Lo := Expr_Value (N);
3958 Hi := Lo;
3959 return;
3960 end if;
3961
3962 -- Return if already in the cache
3963
3964 Cindex := Cache_Index (N mod Cache_Size);
3965
9c486805 3966 if Determine_Range_Cache_N (Cindex) = N
3967 and then
3968 Determine_Range_Cache_V (Cindex) = Assume_Valid
3969 then
ee6ba406 3970 Lo := Determine_Range_Cache_Lo (Cindex);
3971 Hi := Determine_Range_Cache_Hi (Cindex);
3972 return;
3973 end if;
3974
feff2f05 3975 -- Otherwise, start by finding the bounds of the type of the expression,
3976 -- the value cannot be outside this range (if it is, then we have an
3977 -- overflow situation, which is a separate check, we are talking here
3978 -- only about the expression value).
ee6ba406 3979
341bd953 3980 -- First a check, never try to find the bounds of a generic type, since
3981 -- these bounds are always junk values, and it is only valid to look at
3982 -- the bounds in an instance.
3983
3984 if Is_Generic_Type (Typ) then
3985 OK := False;
3986 return;
3987 end if;
3988
9c486805 3989 -- First step, change to use base type unless we know the value is valid
e254d721 3990
9c486805 3991 if (Is_Entity_Name (N) and then Is_Known_Valid (Entity (N)))
3992 or else Assume_No_Invalid_Values
3993 or else Assume_Valid
e254d721 3994 then
9c486805 3995 null;
3996 else
3997 Typ := Underlying_Type (Base_Type (Typ));
e254d721 3998 end if;
3999
094ed68e 4000 -- Retrieve the base type. Handle the case where the base type is a
4001 -- private enumeration type.
4002
4003 Btyp := Base_Type (Typ);
4004
4005 if Is_Private_Type (Btyp) and then Present (Full_View (Btyp)) then
4006 Btyp := Full_View (Btyp);
4007 end if;
4008
feff2f05 4009 -- We use the actual bound unless it is dynamic, in which case use the
4010 -- corresponding base type bound if possible. If we can't get a bound
4011 -- then we figure we can't determine the range (a peculiar case, that
4012 -- perhaps cannot happen, but there is no point in bombing in this
4013 -- optimization circuit.
8880be85 4014
4015 -- First the low bound
ee6ba406 4016
4017 Bound := Type_Low_Bound (Typ);
4018
4019 if Compile_Time_Known_Value (Bound) then
4020 Lo := Expr_Value (Bound);
4021
094ed68e 4022 elsif Compile_Time_Known_Value (Type_Low_Bound (Btyp)) then
4023 Lo := Expr_Value (Type_Low_Bound (Btyp));
ee6ba406 4024
4025 else
4026 OK := False;
4027 return;
4028 end if;
4029
8880be85 4030 -- Now the high bound
4031
ee6ba406 4032 Bound := Type_High_Bound (Typ);
4033
8880be85 4034 -- We need the high bound of the base type later on, and this should
4035 -- always be compile time known. Again, it is not clear that this
4036 -- can ever be false, but no point in bombing.
ee6ba406 4037
094ed68e 4038 if Compile_Time_Known_Value (Type_High_Bound (Btyp)) then
4039 Hbound := Expr_Value (Type_High_Bound (Btyp));
ee6ba406 4040 Hi := Hbound;
4041
4042 else
4043 OK := False;
4044 return;
4045 end if;
4046
feff2f05 4047 -- If we have a static subtype, then that may have a tighter bound so
4048 -- use the upper bound of the subtype instead in this case.
8880be85 4049
4050 if Compile_Time_Known_Value (Bound) then
4051 Hi := Expr_Value (Bound);
4052 end if;
4053
feff2f05 4054 -- We may be able to refine this value in certain situations. If any
4055 -- refinement is possible, then Lor and Hir are set to possibly tighter
4056 -- bounds, and OK1 is set to True.
ee6ba406 4057
4058 case Nkind (N) is
4059
4060 -- For unary plus, result is limited by range of operand
4061
4062 when N_Op_Plus =>
9c486805 4063 Determine_Range
4064 (Right_Opnd (N), OK1, Lor, Hir, Assume_Valid);
ee6ba406 4065
4066 -- For unary minus, determine range of operand, and negate it
4067
4068 when N_Op_Minus =>
9c486805 4069 Determine_Range
4070 (Right_Opnd (N), OK1, Lo_Right, Hi_Right, Assume_Valid);
ee6ba406 4071
4072 if OK1 then
4073 Lor := -Hi_Right;
4074 Hir := -Lo_Right;
4075 end if;
4076
4077 -- For binary addition, get range of each operand and do the
4078 -- addition to get the result range.
4079
4080 when N_Op_Add =>
4081 if OK_Operands then
4082 Lor := Lo_Left + Lo_Right;
4083 Hir := Hi_Left + Hi_Right;
4084 end if;
4085
feff2f05 4086 -- Division is tricky. The only case we consider is where the right
4087 -- operand is a positive constant, and in this case we simply divide
4088 -- the bounds of the left operand
ee6ba406 4089
4090 when N_Op_Divide =>
4091 if OK_Operands then
4092 if Lo_Right = Hi_Right
4093 and then Lo_Right > 0
4094 then
4095 Lor := Lo_Left / Lo_Right;
4096 Hir := Hi_Left / Lo_Right;
4097
4098 else
4099 OK1 := False;
4100 end if;
4101 end if;
4102
feff2f05 4103 -- For binary subtraction, get range of each operand and do the worst
4104 -- case subtraction to get the result range.
ee6ba406 4105
4106 when N_Op_Subtract =>
4107 if OK_Operands then
4108 Lor := Lo_Left - Hi_Right;
4109 Hir := Hi_Left - Lo_Right;
4110 end if;
4111
feff2f05 4112 -- For MOD, if right operand is a positive constant, then result must
4113 -- be in the allowable range of mod results.
ee6ba406 4114
4115 when N_Op_Mod =>
4116 if OK_Operands then
9dfe12ae 4117 if Lo_Right = Hi_Right
4118 and then Lo_Right /= 0
4119 then
ee6ba406 4120 if Lo_Right > 0 then
4121 Lor := Uint_0;
4122 Hir := Lo_Right - 1;
4123
9dfe12ae 4124 else -- Lo_Right < 0
ee6ba406 4125 Lor := Lo_Right + 1;
4126 Hir := Uint_0;
4127 end if;
4128
4129 else
4130 OK1 := False;
4131 end if;
4132 end if;
4133
feff2f05 4134 -- For REM, if right operand is a positive constant, then result must
4135 -- be in the allowable range of mod results.
ee6ba406 4136
4137 when N_Op_Rem =>
4138 if OK_Operands then
9dfe12ae 4139 if Lo_Right = Hi_Right
4140 and then Lo_Right /= 0
4141 then
ee6ba406 4142 declare
4143 Dval : constant Uint := (abs Lo_Right) - 1;
4144
4145 begin
4146 -- The sign of the result depends on the sign of the
4147 -- dividend (but not on the sign of the divisor, hence
4148 -- the abs operation above).
4149
4150 if Lo_Left < 0 then
4151 Lor := -Dval;
4152 else
4153 Lor := Uint_0;
4154 end if;
4155
4156 if Hi_Left < 0 then
4157 Hir := Uint_0;
4158 else
4159 Hir := Dval;
4160 end if;
4161 end;
4162
4163 else
4164 OK1 := False;
4165 end if;
4166 end if;
4167
4168 -- Attribute reference cases
4169
4170 when N_Attribute_Reference =>
4171 case Attribute_Name (N) is
4172
4173 -- For Pos/Val attributes, we can refine the range using the
ddbf7f2e 4174 -- possible range of values of the attribute expression.
ee6ba406 4175
4176 when Name_Pos | Name_Val =>
9c486805 4177 Determine_Range
4178 (First (Expressions (N)), OK1, Lor, Hir, Assume_Valid);
ee6ba406 4179
4180 -- For Length attribute, use the bounds of the corresponding
4181 -- index type to refine the range.
4182
4183 when Name_Length =>
4184 declare
4185 Atyp : Entity_Id := Etype (Prefix (N));
4186 Inum : Nat;
4187 Indx : Node_Id;
4188
4189 LL, LU : Uint;
4190 UL, UU : Uint;
4191
4192 begin
4193 if Is_Access_Type (Atyp) then
4194 Atyp := Designated_Type (Atyp);
4195 end if;
4196
4197 -- For string literal, we know exact value
4198
4199 if Ekind (Atyp) = E_String_Literal_Subtype then
4200 OK := True;
4201 Lo := String_Literal_Length (Atyp);
4202 Hi := String_Literal_Length (Atyp);
4203 return;
4204 end if;
4205
4206 -- Otherwise check for expression given
4207
4208 if No (Expressions (N)) then
4209 Inum := 1;
4210 else
4211 Inum :=
4212 UI_To_Int (Expr_Value (First (Expressions (N))));
4213 end if;
4214
4215 Indx := First_Index (Atyp);
4216 for J in 2 .. Inum loop
4217 Indx := Next_Index (Indx);
4218 end loop;
4219
9116df93 4220 -- If the index type is a formal type or derived from
c8da6114 4221 -- one, the bounds are not static.
4222
4223 if Is_Generic_Type (Root_Type (Etype (Indx))) then
4224 OK := False;
4225 return;
4226 end if;
4227
ee6ba406 4228 Determine_Range
9c486805 4229 (Type_Low_Bound (Etype (Indx)), OK1, LL, LU,
4230 Assume_Valid);
ee6ba406 4231
4232 if OK1 then
4233 Determine_Range
9c486805 4234 (Type_High_Bound (Etype (Indx)), OK1, UL, UU,
4235 Assume_Valid);
ee6ba406 4236
4237 if OK1 then
4238
4239 -- The maximum value for Length is the biggest
4240 -- possible gap between the values of the bounds.
4241 -- But of course, this value cannot be negative.
4242
9c486805 4243 Hir := UI_Max (Uint_0, UU - LL + 1);
ee6ba406 4244
4245 -- For constrained arrays, the minimum value for
4246 -- Length is taken from the actual value of the
9116df93 4247 -- bounds, since the index will be exactly of this
4248 -- subtype.
ee6ba406 4249
4250 if Is_Constrained (Atyp) then
9c486805 4251 Lor := UI_Max (Uint_0, UL - LU + 1);
ee6ba406 4252
4253 -- For an unconstrained array, the minimum value
4254 -- for length is always zero.
4255
4256 else
4257 Lor := Uint_0;
4258 end if;
4259 end if;
4260 end if;
4261 end;
4262
4263 -- No special handling for other attributes
9116df93 4264 -- Probably more opportunities exist here???
ee6ba406 4265
4266 when others =>
4267 OK1 := False;
4268
4269 end case;
4270
feff2f05 4271 -- For type conversion from one discrete type to another, we can
4272 -- refine the range using the converted value.
ee6ba406 4273
4274 when N_Type_Conversion =>
9c486805 4275 Determine_Range (Expression (N), OK1, Lor, Hir, Assume_Valid);
ee6ba406 4276
4277 -- Nothing special to do for all other expression kinds
4278
4279 when others =>
4280 OK1 := False;
4281 Lor := No_Uint;
4282 Hir := No_Uint;
4283 end case;
4284
9116df93 4285 -- At this stage, if OK1 is true, then we know that the actual result of
4286 -- the computed expression is in the range Lor .. Hir. We can use this
4287 -- to restrict the possible range of results.
ee6ba406 4288
4289 if OK1 then
4290
9116df93 4291 -- If the refined value of the low bound is greater than the type
4292 -- high bound, then reset it to the more restrictive value. However,
4293 -- we do NOT do this for the case of a modular type where the
4294 -- possible upper bound on the value is above the base type high
4295 -- bound, because that means the result could wrap.
ee6ba406 4296
4297 if Lor > Lo
9116df93 4298 and then not (Is_Modular_Integer_Type (Typ) and then Hir > Hbound)
ee6ba406 4299 then
4300 Lo := Lor;
4301 end if;
4302
9116df93 4303 -- Similarly, if the refined value of the high bound is less than the
4304 -- value so far, then reset it to the more restrictive value. Again,
4305 -- we do not do this if the refined low bound is negative for a
4306 -- modular type, since this would wrap.
ee6ba406 4307
4308 if Hir < Hi
9116df93 4309 and then not (Is_Modular_Integer_Type (Typ) and then Lor < Uint_0)
ee6ba406 4310 then
4311 Hi := Hir;
4312 end if;
4313 end if;
4314
4315 -- Set cache entry for future call and we are all done
4316
4317 Determine_Range_Cache_N (Cindex) := N;
9c486805 4318 Determine_Range_Cache_V (Cindex) := Assume_Valid;
ee6ba406 4319 Determine_Range_Cache_Lo (Cindex) := Lo;
4320 Determine_Range_Cache_Hi (Cindex) := Hi;
4321 return;
4322
9116df93 4323 -- If any exception occurs, it means that we have some bug in the compiler,
4324 -- possibly triggered by a previous error, or by some unforeseen peculiar
ee6ba406 4325 -- occurrence. However, this is only an optimization attempt, so there is
4326 -- really no point in crashing the compiler. Instead we just decide, too
4327 -- bad, we can't figure out a range in this case after all.
4328
4329 exception
4330 when others =>
4331
4332 -- Debug flag K disables this behavior (useful for debugging)
4333
4334 if Debug_Flag_K then
4335 raise;
4336 else
4337 OK := False;
4338 Lo := No_Uint;
4339 Hi := No_Uint;
4340 return;
4341 end if;
ee6ba406 4342 end Determine_Range;
4343
4344 ------------------------------------
4345 -- Discriminant_Checks_Suppressed --
4346 ------------------------------------
4347
4348 function Discriminant_Checks_Suppressed (E : Entity_Id) return Boolean is
4349 begin
9dfe12ae 4350 if Present (E) then
4351 if Is_Unchecked_Union (E) then
4352 return True;
4353 elsif Checks_May_Be_Suppressed (E) then
4354 return Is_Check_Suppressed (E, Discriminant_Check);
4355 end if;
4356 end if;
4357
fafc6b97 4358 return Scope_Suppress.Suppress (Discriminant_Check);
ee6ba406 4359 end Discriminant_Checks_Suppressed;
4360
4361 --------------------------------
4362 -- Division_Checks_Suppressed --
4363 --------------------------------
4364
4365 function Division_Checks_Suppressed (E : Entity_Id) return Boolean is
4366 begin
9dfe12ae 4367 if Present (E) and then Checks_May_Be_Suppressed (E) then
4368 return Is_Check_Suppressed (E, Division_Check);
4369 else
fafc6b97 4370 return Scope_Suppress.Suppress (Division_Check);
9dfe12ae 4371 end if;
ee6ba406 4372 end Division_Checks_Suppressed;
4373
4374 -----------------------------------
4375 -- Elaboration_Checks_Suppressed --
4376 -----------------------------------
4377
4378 function Elaboration_Checks_Suppressed (E : Entity_Id) return Boolean is
4379 begin
38f5559f 4380 -- The complication in this routine is that if we are in the dynamic
4381 -- model of elaboration, we also check All_Checks, since All_Checks
4382 -- does not set Elaboration_Check explicitly.
4383
9dfe12ae 4384 if Present (E) then
4385 if Kill_Elaboration_Checks (E) then
4386 return True;
38f5559f 4387
9dfe12ae 4388 elsif Checks_May_Be_Suppressed (E) then
38f5559f 4389 if Is_Check_Suppressed (E, Elaboration_Check) then
4390 return True;
4391 elsif Dynamic_Elaboration_Checks then
4392 return Is_Check_Suppressed (E, All_Checks);
4393 else
4394 return False;
4395 end if;
9dfe12ae 4396 end if;
4397 end if;
4398
fafc6b97 4399 if Scope_Suppress.Suppress (Elaboration_Check) then
38f5559f 4400 return True;
4401 elsif Dynamic_Elaboration_Checks then
fafc6b97 4402 return Scope_Suppress.Suppress (All_Checks);
38f5559f 4403 else
4404 return False;
4405 end if;
ee6ba406 4406 end Elaboration_Checks_Suppressed;
4407
9dfe12ae 4408 ---------------------------
4409 -- Enable_Overflow_Check --
4410 ---------------------------
4411
4412 procedure Enable_Overflow_Check (N : Node_Id) is
3cce7f32 4413 Typ : constant Entity_Id := Base_Type (Etype (N));
4414 Mode : constant Overflow_Check_Type := Overflow_Check_Mode (Etype (N));
4415 Chk : Nat;
4416 OK : Boolean;
4417 Ent : Entity_Id;
4418 Ofs : Uint;
4419 Lo : Uint;
4420 Hi : Uint;
ee6ba406 4421
ee6ba406 4422 begin
9dfe12ae 4423 if Debug_Flag_CC then
4424 w ("Enable_Overflow_Check for node ", Int (N));
4425 Write_Str (" Source location = ");
4426 wl (Sloc (N));
00c403ee 4427 pg (Union_Id (N));
ee6ba406 4428 end if;
ee6ba406 4429
75209ec5 4430 -- No check if overflow checks suppressed for type of node
4431
3cce7f32 4432 if Mode = Suppressed then
75209ec5 4433 return;
4434
49260fa5 4435 -- Nothing to do for unsigned integer types, which do not overflow
4436
4437 elsif Is_Modular_Integer_Type (Typ) then
4438 return;
3cce7f32 4439 end if;
4440
4441 -- This is the point at which processing for CHECKED mode diverges from
4442 -- processing for MINIMIZED/ELIMINATED mode. This divergence is probably
4443 -- more extreme that it needs to be, but what is going on here is that
4444 -- when we introduced MINIMIZED/ELININATED modes, we wanted to leave the
4445 -- processing for CHECKED mode untouched. There were two reasons for
4446 -- this. First it avoided any incomptible change of behavior. Second,
4447 -- it guaranteed that CHECKED mode continued to be legacy reliable.
4448
4449 -- The big difference is that in CHECKED mode there is a fair amount of
4450 -- circuitry to try to avoid setting the Do_Overflow_Check flag if we
4451 -- know that no check is needed. We skip all that in the two new modes,
4452 -- since really overflow checking happens over a whole subtree, and we
4453 -- do the corresponding optimizations later on when applying the checks.
4454
4455 if Mode in Minimized_Or_Eliminated then
4456 Activate_Overflow_Check (N);
4457
4458 if Debug_Flag_CC then
4459 w ("Minimized/Eliminated mode");
4460 end if;
4461
4462 return;
4463 end if;
4464
4465 -- Remainder of processing is for Checked case, and is unchanged from
4466 -- earlier versions preceding the addition of Minimized/Eliminated.
49260fa5 4467
feff2f05 4468 -- Nothing to do if the range of the result is known OK. We skip this
4469 -- for conversions, since the caller already did the check, and in any
4470 -- case the condition for deleting the check for a type conversion is
cc60bd16 4471 -- different.
ee6ba406 4472
3cce7f32 4473 if Nkind (N) /= N_Type_Conversion then
9c486805 4474 Determine_Range (N, OK, Lo, Hi, Assume_Valid => True);
ee6ba406 4475
cc60bd16 4476 -- Note in the test below that we assume that the range is not OK
4477 -- if a bound of the range is equal to that of the type. That's not
4478 -- quite accurate but we do this for the following reasons:
ee6ba406 4479
9dfe12ae 4480 -- a) The way that Determine_Range works, it will typically report
4481 -- the bounds of the value as being equal to the bounds of the
4482 -- type, because it either can't tell anything more precise, or
4483 -- does not think it is worth the effort to be more precise.
ee6ba406 4484
9dfe12ae 4485 -- b) It is very unusual to have a situation in which this would
4486 -- generate an unnecessary overflow check (an example would be
4487 -- a subtype with a range 0 .. Integer'Last - 1 to which the
cc60bd16 4488 -- literal value one is added).
ee6ba406 4489
9dfe12ae 4490 -- c) The alternative is a lot of special casing in this routine
4491 -- which would partially duplicate Determine_Range processing.
ee6ba406 4492
9dfe12ae 4493 if OK
4494 and then Lo > Expr_Value (Type_Low_Bound (Typ))
4495 and then Hi < Expr_Value (Type_High_Bound (Typ))
4496 then
4497 if Debug_Flag_CC then
4498 w ("No overflow check required");
4499 end if;
4500
4501 return;
4502 end if;
4503 end if;
4504
feff2f05 4505 -- If not in optimizing mode, set flag and we are done. We are also done
4506 -- (and just set the flag) if the type is not a discrete type, since it
4507 -- is not worth the effort to eliminate checks for other than discrete
4508 -- types. In addition, we take this same path if we have stored the
4509 -- maximum number of checks possible already (a very unlikely situation,
4510 -- but we do not want to blow up!)
9dfe12ae 4511
4512 if Optimization_Level = 0
4513 or else not Is_Discrete_Type (Etype (N))
4514 or else Num_Saved_Checks = Saved_Checks'Last
ee6ba406 4515 then
00c403ee 4516 Activate_Overflow_Check (N);
9dfe12ae 4517
4518 if Debug_Flag_CC then
4519 w ("Optimization off");
4520 end if;
4521
ee6ba406 4522 return;
9dfe12ae 4523 end if;
ee6ba406 4524
9dfe12ae 4525 -- Otherwise evaluate and check the expression
4526
4527 Find_Check
4528 (Expr => N,
4529 Check_Type => 'O',
4530 Target_Type => Empty,
4531 Entry_OK => OK,
4532 Check_Num => Chk,
4533 Ent => Ent,
4534 Ofs => Ofs);
4535
4536 if Debug_Flag_CC then
4537 w ("Called Find_Check");
4538 w (" OK = ", OK);
4539
4540 if OK then
4541 w (" Check_Num = ", Chk);
4542 w (" Ent = ", Int (Ent));
4543 Write_Str (" Ofs = ");
4544 pid (Ofs);
4545 end if;
4546 end if;
ee6ba406 4547
9dfe12ae 4548 -- If check is not of form to optimize, then set flag and we are done
4549
4550 if not OK then
00c403ee 4551 Activate_Overflow_Check (N);
ee6ba406 4552 return;
9dfe12ae 4553 end if;
ee6ba406 4554
9dfe12ae 4555 -- If check is already performed, then return without setting flag
4556
4557 if Chk /= 0 then
4558 if Debug_Flag_CC then
4559 w ("Check suppressed!");
4560 end if;
ee6ba406 4561
ee6ba406 4562 return;
9dfe12ae 4563 end if;
ee6ba406 4564
9dfe12ae 4565 -- Here we will make a new entry for the new check
4566
00c403ee 4567 Activate_Overflow_Check (N);
9dfe12ae 4568 Num_Saved_Checks := Num_Saved_Checks + 1;
4569 Saved_Checks (Num_Saved_Checks) :=
4570 (Killed => False,
4571 Entity => Ent,
4572 Offset => Ofs,
4573 Check_Type => 'O',
4574 Target_Type => Empty);
4575
4576 if Debug_Flag_CC then
4577 w ("Make new entry, check number = ", Num_Saved_Checks);
4578 w (" Entity = ", Int (Ent));
4579 Write_Str (" Offset = ");
4580 pid (Ofs);
4581 w (" Check_Type = O");
4582 w (" Target_Type = Empty");
4583 end if;
ee6ba406 4584
feff2f05 4585 -- If we get an exception, then something went wrong, probably because of
4586 -- an error in the structure of the tree due to an incorrect program. Or it
4587 -- may be a bug in the optimization circuit. In either case the safest
4588 -- thing is simply to set the check flag unconditionally.
9dfe12ae 4589
4590 exception
4591 when others =>
00c403ee 4592 Activate_Overflow_Check (N);
9dfe12ae 4593
4594 if Debug_Flag_CC then
4595 w (" exception occurred, overflow flag set");
4596 end if;
4597
4598 return;
4599 end Enable_Overflow_Check;
4600
4601 ------------------------
4602 -- Enable_Range_Check --
4603 ------------------------
4604
4605 procedure Enable_Range_Check (N : Node_Id) is
4606 Chk : Nat;
4607 OK : Boolean;
4608 Ent : Entity_Id;
4609 Ofs : Uint;
4610 Ttyp : Entity_Id;
4611 P : Node_Id;
4612
4613 begin
feff2f05 4614 -- Return if unchecked type conversion with range check killed. In this
4615 -- case we never set the flag (that's what Kill_Range_Check is about!)
9dfe12ae 4616
4617 if Nkind (N) = N_Unchecked_Type_Conversion
4618 and then Kill_Range_Check (N)
ee6ba406 4619 then
4620 return;
9dfe12ae 4621 end if;
ee6ba406 4622
55e8372b 4623 -- Do not set range check flag if parent is assignment statement or
4624 -- object declaration with Suppress_Assignment_Checks flag set
4625
4626 if Nkind_In (Parent (N), N_Assignment_Statement, N_Object_Declaration)
4627 and then Suppress_Assignment_Checks (Parent (N))
4628 then
4629 return;
4630 end if;
4631
0577b0b1 4632 -- Check for various cases where we should suppress the range check
4633
4634 -- No check if range checks suppressed for type of node
4635
4636 if Present (Etype (N))
4637 and then Range_Checks_Suppressed (Etype (N))
4638 then
4639 return;
4640
4641 -- No check if node is an entity name, and range checks are suppressed
4642 -- for this entity, or for the type of this entity.
4643
4644 elsif Is_Entity_Name (N)
4645 and then (Range_Checks_Suppressed (Entity (N))
4646 or else Range_Checks_Suppressed (Etype (Entity (N))))
4647 then
4648 return;
4649
4650 -- No checks if index of array, and index checks are suppressed for
4651 -- the array object or the type of the array.
4652
4653 elsif Nkind (Parent (N)) = N_Indexed_Component then
4654 declare
4655 Pref : constant Node_Id := Prefix (Parent (N));
4656 begin
4657 if Is_Entity_Name (Pref)
4658 and then Index_Checks_Suppressed (Entity (Pref))
4659 then
4660 return;
4661 elsif Index_Checks_Suppressed (Etype (Pref)) then
4662 return;
4663 end if;
4664 end;
4665 end if;
4666
9dfe12ae 4667 -- Debug trace output
ee6ba406 4668
9dfe12ae 4669 if Debug_Flag_CC then
4670 w ("Enable_Range_Check for node ", Int (N));
4671 Write_Str (" Source location = ");
4672 wl (Sloc (N));
00c403ee 4673 pg (Union_Id (N));
9dfe12ae 4674 end if;
4675
feff2f05 4676 -- If not in optimizing mode, set flag and we are done. We are also done
4677 -- (and just set the flag) if the type is not a discrete type, since it
4678 -- is not worth the effort to eliminate checks for other than discrete
4679 -- types. In addition, we take this same path if we have stored the
4680 -- maximum number of checks possible already (a very unlikely situation,
4681 -- but we do not want to blow up!)
9dfe12ae 4682
4683 if Optimization_Level = 0
4684 or else No (Etype (N))
4685 or else not Is_Discrete_Type (Etype (N))
4686 or else Num_Saved_Checks = Saved_Checks'Last
ee6ba406 4687 then
00c403ee 4688 Activate_Range_Check (N);
9dfe12ae 4689
4690 if Debug_Flag_CC then
4691 w ("Optimization off");
4692 end if;
4693
ee6ba406 4694 return;
9dfe12ae 4695 end if;
ee6ba406 4696
9dfe12ae 4697 -- Otherwise find out the target type
ee6ba406 4698
9dfe12ae 4699 P := Parent (N);
ee6ba406 4700
9dfe12ae 4701 -- For assignment, use left side subtype
4702
4703 if Nkind (P) = N_Assignment_Statement
4704 and then Expression (P) = N
4705 then
4706 Ttyp := Etype (Name (P));
4707
4708 -- For indexed component, use subscript subtype
4709
4710 elsif Nkind (P) = N_Indexed_Component then
4711 declare
4712 Atyp : Entity_Id;
4713 Indx : Node_Id;
4714 Subs : Node_Id;
4715
4716 begin
4717 Atyp := Etype (Prefix (P));
4718
4719 if Is_Access_Type (Atyp) then
4720 Atyp := Designated_Type (Atyp);
f07ea091 4721
4722 -- If the prefix is an access to an unconstrained array,
feff2f05 4723 -- perform check unconditionally: it depends on the bounds of
4724 -- an object and we cannot currently recognize whether the test
4725 -- may be redundant.
f07ea091 4726
4727 if not Is_Constrained (Atyp) then
00c403ee 4728 Activate_Range_Check (N);
f07ea091 4729 return;
4730 end if;
7189d17f 4731
feff2f05 4732 -- Ditto if the prefix is an explicit dereference whose designated
4733 -- type is unconstrained.
7189d17f 4734
4735 elsif Nkind (Prefix (P)) = N_Explicit_Dereference
4736 and then not Is_Constrained (Atyp)
4737 then
00c403ee 4738 Activate_Range_Check (N);
7189d17f 4739 return;
9dfe12ae 4740 end if;
4741
4742 Indx := First_Index (Atyp);
4743 Subs := First (Expressions (P));
4744 loop
4745 if Subs = N then
4746 Ttyp := Etype (Indx);
4747 exit;
4748 end if;
4749
4750 Next_Index (Indx);
4751 Next (Subs);
4752 end loop;
4753 end;
4754
4755 -- For now, ignore all other cases, they are not so interesting
4756
4757 else
4758 if Debug_Flag_CC then
4759 w (" target type not found, flag set");
4760 end if;
4761
00c403ee 4762 Activate_Range_Check (N);
9dfe12ae 4763 return;
4764 end if;
4765
4766 -- Evaluate and check the expression
4767
4768 Find_Check
4769 (Expr => N,
4770 Check_Type => 'R',
4771 Target_Type => Ttyp,
4772 Entry_OK => OK,
4773 Check_Num => Chk,
4774 Ent => Ent,
4775 Ofs => Ofs);
4776
4777 if Debug_Flag_CC then
4778 w ("Called Find_Check");
4779 w ("Target_Typ = ", Int (Ttyp));
4780 w (" OK = ", OK);
4781
4782 if OK then
4783 w (" Check_Num = ", Chk);
4784 w (" Ent = ", Int (Ent));
4785 Write_Str (" Ofs = ");
4786 pid (Ofs);
4787 end if;
4788 end if;
4789
4790 -- If check is not of form to optimize, then set flag and we are done
4791
4792 if not OK then
4793 if Debug_Flag_CC then
4794 w (" expression not of optimizable type, flag set");
4795 end if;
4796
00c403ee 4797 Activate_Range_Check (N);
9dfe12ae 4798 return;
4799 end if;
4800
4801 -- If check is already performed, then return without setting flag
4802
4803 if Chk /= 0 then
4804 if Debug_Flag_CC then
4805 w ("Check suppressed!");
4806 end if;
4807
4808 return;
4809 end if;
4810
4811 -- Here we will make a new entry for the new check
4812
00c403ee 4813 Activate_Range_Check (N);
9dfe12ae 4814 Num_Saved_Checks := Num_Saved_Checks + 1;
4815 Saved_Checks (Num_Saved_Checks) :=
4816 (Killed => False,
4817 Entity => Ent,
4818 Offset => Ofs,
4819 Check_Type => 'R',
4820 Target_Type => Ttyp);
4821
4822 if Debug_Flag_CC then
4823 w ("Make new entry, check number = ", Num_Saved_Checks);
4824 w (" Entity = ", Int (Ent));
4825 Write_Str (" Offset = ");
4826 pid (Ofs);
4827 w (" Check_Type = R");
4828 w (" Target_Type = ", Int (Ttyp));
00c403ee 4829 pg (Union_Id (Ttyp));
9dfe12ae 4830 end if;
4831
feff2f05 4832 -- If we get an exception, then something went wrong, probably because of
4833 -- an error in the structure of the tree due to an incorrect program. Or
4834 -- it may be a bug in the optimization circuit. In either case the safest
4835 -- thing is simply to set the check flag unconditionally.
9dfe12ae 4836
4837 exception
4838 when others =>
00c403ee 4839 Activate_Range_Check (N);
9dfe12ae 4840
4841 if Debug_Flag_CC then
4842 w (" exception occurred, range flag set");
4843 end if;
4844
4845 return;
4846 end Enable_Range_Check;
4847
4848 ------------------
4849 -- Ensure_Valid --
4850 ------------------
4851
4852 procedure Ensure_Valid (Expr : Node_Id; Holes_OK : Boolean := False) is
4853 Typ : constant Entity_Id := Etype (Expr);
4854
4855 begin
4856 -- Ignore call if we are not doing any validity checking
4857
4858 if not Validity_Checks_On then
4859 return;
4860
0577b0b1 4861 -- Ignore call if range or validity checks suppressed on entity or type
9dfe12ae 4862
0577b0b1 4863 elsif Range_Or_Validity_Checks_Suppressed (Expr) then
9dfe12ae 4864 return;
4865
feff2f05 4866 -- No check required if expression is from the expander, we assume the
4867 -- expander will generate whatever checks are needed. Note that this is
4868 -- not just an optimization, it avoids infinite recursions!
9dfe12ae 4869
4870 -- Unchecked conversions must be checked, unless they are initialized
4871 -- scalar values, as in a component assignment in an init proc.
4872
4873 -- In addition, we force a check if Force_Validity_Checks is set
4874
4875 elsif not Comes_From_Source (Expr)
4876 and then not Force_Validity_Checks
4877 and then (Nkind (Expr) /= N_Unchecked_Type_Conversion
4878 or else Kill_Range_Check (Expr))
4879 then
4880 return;
4881
4882 -- No check required if expression is known to have valid value
4883
4884 elsif Expr_Known_Valid (Expr) then
4885 return;
4886
feff2f05 4887 -- Ignore case of enumeration with holes where the flag is set not to
4888 -- worry about holes, since no special validity check is needed
9dfe12ae 4889
4890 elsif Is_Enumeration_Type (Typ)
4891 and then Has_Non_Standard_Rep (Typ)
4892 and then Holes_OK
4893 then
4894 return;
4895
f2a06be9 4896 -- No check required on the left-hand side of an assignment
9dfe12ae 4897
4898 elsif Nkind (Parent (Expr)) = N_Assignment_Statement
4899 and then Expr = Name (Parent (Expr))
4900 then
4901 return;
4902
6fb3c314 4903 -- No check on a universal real constant. The context will eventually
38f5559f 4904 -- convert it to a machine number for some target type, or report an
4905 -- illegality.
4906
4907 elsif Nkind (Expr) = N_Real_Literal
4908 and then Etype (Expr) = Universal_Real
4909 then
4910 return;
4911
6fb3c314 4912 -- If the expression denotes a component of a packed boolean array,
0577b0b1 4913 -- no possible check applies. We ignore the old ACATS chestnuts that
4914 -- involve Boolean range True..True.
4915
4916 -- Note: validity checks are generated for expressions that yield a
4917 -- scalar type, when it is possible to create a value that is outside of
4918 -- the type. If this is a one-bit boolean no such value exists. This is
4919 -- an optimization, and it also prevents compiler blowing up during the
4920 -- elaboration of improperly expanded packed array references.
4921
4922 elsif Nkind (Expr) = N_Indexed_Component
4923 and then Is_Bit_Packed_Array (Etype (Prefix (Expr)))
4924 and then Root_Type (Etype (Expr)) = Standard_Boolean
4925 then
4926 return;
4927
9dfe12ae 4928 -- An annoying special case. If this is an out parameter of a scalar
4929 -- type, then the value is not going to be accessed, therefore it is
4930 -- inappropriate to do any validity check at the call site.
4931
4932 else
4933 -- Only need to worry about scalar types
4934
4935 if Is_Scalar_Type (Typ) then
ee6ba406 4936 declare
4937 P : Node_Id;
4938 N : Node_Id;
4939 E : Entity_Id;
4940 F : Entity_Id;
4941 A : Node_Id;
4942 L : List_Id;
4943
4944 begin
4945 -- Find actual argument (which may be a parameter association)
4946 -- and the parent of the actual argument (the call statement)
4947
4948 N := Expr;
4949 P := Parent (Expr);
4950
4951 if Nkind (P) = N_Parameter_Association then
4952 N := P;
4953 P := Parent (N);
4954 end if;
4955
feff2f05 4956 -- Only need to worry if we are argument of a procedure call
4957 -- since functions don't have out parameters. If this is an
4958 -- indirect or dispatching call, get signature from the
4959 -- subprogram type.
ee6ba406 4960
4961 if Nkind (P) = N_Procedure_Call_Statement then
4962 L := Parameter_Associations (P);
9dfe12ae 4963
4964 if Is_Entity_Name (Name (P)) then
4965 E := Entity (Name (P));
4966 else
4967 pragma Assert (Nkind (Name (P)) = N_Explicit_Dereference);
4968 E := Etype (Name (P));
4969 end if;
ee6ba406 4970
feff2f05 4971 -- Only need to worry if there are indeed actuals, and if
4972 -- this could be a procedure call, otherwise we cannot get a
4973 -- match (either we are not an argument, or the mode of the
4974 -- formal is not OUT). This test also filters out the
4975 -- generic case.
ee6ba406 4976
4977 if Is_Non_Empty_List (L)
4978 and then Is_Subprogram (E)
4979 then
feff2f05 4980 -- This is the loop through parameters, looking for an
4981 -- OUT parameter for which we are the argument.
ee6ba406 4982
4983 F := First_Formal (E);
4984 A := First (L);
ee6ba406 4985 while Present (F) loop
4986 if Ekind (F) = E_Out_Parameter and then A = N then
4987 return;
4988 end if;
4989
4990 Next_Formal (F);
4991 Next (A);
4992 end loop;
4993 end if;
4994 end if;
4995 end;
4996 end if;
4997 end if;
4998
fa6a6949 4999 -- If this is a boolean expression, only its elementary operands need
90a07d4c 5000 -- checking: if they are valid, a boolean or short-circuit operation
5001 -- with them will be valid as well.
784d4230 5002
5003 if Base_Type (Typ) = Standard_Boolean
7af38999 5004 and then
fa6a6949 5005 (Nkind (Expr) in N_Op or else Nkind (Expr) in N_Short_Circuit)
784d4230 5006 then
5007 return;
5008 end if;
5009
0577b0b1 5010 -- If we fall through, a validity check is required
ee6ba406 5011
5012 Insert_Valid_Check (Expr);
ce7498d3 5013
5014 if Is_Entity_Name (Expr)
5015 and then Safe_To_Capture_Value (Expr, Entity (Expr))
5016 then
5017 Set_Is_Known_Valid (Entity (Expr));
5018 end if;
ee6ba406 5019 end Ensure_Valid;
5020
5021 ----------------------
5022 -- Expr_Known_Valid --
5023 ----------------------
5024
5025 function Expr_Known_Valid (Expr : Node_Id) return Boolean is
5026 Typ : constant Entity_Id := Etype (Expr);
5027
5028 begin
feff2f05 5029 -- Non-scalar types are always considered valid, since they never give
5030 -- rise to the issues of erroneous or bounded error behavior that are
5031 -- the concern. In formal reference manual terms the notion of validity
5032 -- only applies to scalar types. Note that even when packed arrays are
5033 -- represented using modular types, they are still arrays semantically,
5034 -- so they are also always valid (in particular, the unused bits can be
5035 -- random rubbish without affecting the validity of the array value).
ee6ba406 5036
fa814356 5037 if not Is_Scalar_Type (Typ) or else Is_Packed_Array_Type (Typ) then
ee6ba406 5038 return True;
5039
5040 -- If no validity checking, then everything is considered valid
5041
5042 elsif not Validity_Checks_On then
5043 return True;
5044
5045 -- Floating-point types are considered valid unless floating-point
5046 -- validity checks have been specifically turned on.
5047
5048 elsif Is_Floating_Point_Type (Typ)
5049 and then not Validity_Check_Floating_Point
5050 then
5051 return True;
5052
feff2f05 5053 -- If the expression is the value of an object that is known to be
5054 -- valid, then clearly the expression value itself is valid.
ee6ba406 5055
5056 elsif Is_Entity_Name (Expr)
5057 and then Is_Known_Valid (Entity (Expr))
5058 then
5059 return True;
5060
0577b0b1 5061 -- References to discriminants are always considered valid. The value
5062 -- of a discriminant gets checked when the object is built. Within the
5063 -- record, we consider it valid, and it is important to do so, since
5064 -- otherwise we can try to generate bogus validity checks which
feff2f05 5065 -- reference discriminants out of scope. Discriminants of concurrent
5066 -- types are excluded for the same reason.
0577b0b1 5067
5068 elsif Is_Entity_Name (Expr)
feff2f05 5069 and then Denotes_Discriminant (Expr, Check_Concurrent => True)
0577b0b1 5070 then
5071 return True;
5072
feff2f05 5073 -- If the type is one for which all values are known valid, then we are
5074 -- sure that the value is valid except in the slightly odd case where
5075 -- the expression is a reference to a variable whose size has been
5076 -- explicitly set to a value greater than the object size.
ee6ba406 5077
5078 elsif Is_Known_Valid (Typ) then
5079 if Is_Entity_Name (Expr)
5080 and then Ekind (Entity (Expr)) = E_Variable
5081 and then Esize (Entity (Expr)) > Esize (Typ)
5082 then
5083 return False;
5084 else
5085 return True;
5086 end if;
5087
5088 -- Integer and character literals always have valid values, where
5089 -- appropriate these will be range checked in any case.
5090
5091 elsif Nkind (Expr) = N_Integer_Literal
5092 or else
5093 Nkind (Expr) = N_Character_Literal
5094 then
5095 return True;
5096
91e47010 5097 -- Real literals are assumed to be valid in VM targets
5098
5099 elsif VM_Target /= No_VM
5100 and then Nkind (Expr) = N_Real_Literal
5101 then
5102 return True;
5103
ee6ba406 5104 -- If we have a type conversion or a qualification of a known valid
5105 -- value, then the result will always be valid.
5106
5107 elsif Nkind (Expr) = N_Type_Conversion
5108 or else
5109 Nkind (Expr) = N_Qualified_Expression
5110 then
5111 return Expr_Known_Valid (Expression (Expr));
5112
38f5559f 5113 -- The result of any operator is always considered valid, since we
5114 -- assume the necessary checks are done by the operator. For operators
5115 -- on floating-point operations, we must also check when the operation
5116 -- is the right-hand side of an assignment, or is an actual in a call.
ee6ba406 5117
0577b0b1 5118 elsif Nkind (Expr) in N_Op then
1d90d657 5119 if Is_Floating_Point_Type (Typ)
5120 and then Validity_Check_Floating_Point
5121 and then
5122 (Nkind (Parent (Expr)) = N_Assignment_Statement
5123 or else Nkind (Parent (Expr)) = N_Function_Call
5124 or else Nkind (Parent (Expr)) = N_Parameter_Association)
5125 then
5126 return False;
5127 else
5128 return True;
5129 end if;
5130
feff2f05 5131 -- The result of a membership test is always valid, since it is true or
5132 -- false, there are no other possibilities.
0577b0b1 5133
5134 elsif Nkind (Expr) in N_Membership_Test then
5135 return True;
5136
ee6ba406 5137 -- For all other cases, we do not know the expression is valid
5138
5139 else
5140 return False;
5141 end if;
5142 end Expr_Known_Valid;
5143
9dfe12ae 5144 ----------------
5145 -- Find_Check --
5146 ----------------
5147
5148 procedure Find_Check
5149 (Expr : Node_Id;
5150 Check_Type : Character;
5151 Target_Type : Entity_Id;
5152 Entry_OK : out Boolean;
5153 Check_Num : out Nat;
5154 Ent : out Entity_Id;
5155 Ofs : out Uint)
5156 is
5157 function Within_Range_Of
5158 (Target_Type : Entity_Id;
314a23b6 5159 Check_Type : Entity_Id) return Boolean;
9dfe12ae 5160 -- Given a requirement for checking a range against Target_Type, and
5161 -- and a range Check_Type against which a check has already been made,
5162 -- determines if the check against check type is sufficient to ensure
5163 -- that no check against Target_Type is required.
5164
5165 ---------------------
5166 -- Within_Range_Of --
5167 ---------------------
5168
5169 function Within_Range_Of
5170 (Target_Type : Entity_Id;
314a23b6 5171 Check_Type : Entity_Id) return Boolean
9dfe12ae 5172 is
5173 begin
5174 if Target_Type = Check_Type then
5175 return True;
5176
5177 else
5178 declare
5179 Tlo : constant Node_Id := Type_Low_Bound (Target_Type);
5180 Thi : constant Node_Id := Type_High_Bound (Target_Type);
5181 Clo : constant Node_Id := Type_Low_Bound (Check_Type);
5182 Chi : constant Node_Id := Type_High_Bound (Check_Type);
5183
5184 begin
5185 if (Tlo = Clo
5186 or else (Compile_Time_Known_Value (Tlo)
5187 and then
5188 Compile_Time_Known_Value (Clo)
5189 and then
5190 Expr_Value (Clo) >= Expr_Value (Tlo)))
5191 and then
5192 (Thi = Chi
5193 or else (Compile_Time_Known_Value (Thi)
5194 and then
5195 Compile_Time_Known_Value (Chi)
5196 and then
5197 Expr_Value (Chi) <= Expr_Value (Clo)))
5198 then
5199 return True;
5200 else
5201 return False;
5202 end if;
5203 end;
5204 end if;
5205 end Within_Range_Of;
5206
5207 -- Start of processing for Find_Check
5208
5209 begin
ed195555 5210 -- Establish default, in case no entry is found
9dfe12ae 5211
5212 Check_Num := 0;
5213
5214 -- Case of expression is simple entity reference
5215
5216 if Is_Entity_Name (Expr) then
5217 Ent := Entity (Expr);
5218 Ofs := Uint_0;
5219
5220 -- Case of expression is entity + known constant
5221
5222 elsif Nkind (Expr) = N_Op_Add
5223 and then Compile_Time_Known_Value (Right_Opnd (Expr))
5224 and then Is_Entity_Name (Left_Opnd (Expr))
5225 then
5226 Ent := Entity (Left_Opnd (Expr));
5227 Ofs := Expr_Value (Right_Opnd (Expr));
5228
5229 -- Case of expression is entity - known constant
5230
5231 elsif Nkind (Expr) = N_Op_Subtract
5232 and then Compile_Time_Known_Value (Right_Opnd (Expr))
5233 and then Is_Entity_Name (Left_Opnd (Expr))
5234 then
5235 Ent := Entity (Left_Opnd (Expr));
5236 Ofs := UI_Negate (Expr_Value (Right_Opnd (Expr)));
5237
5238 -- Any other expression is not of the right form
5239
5240 else
5241 Ent := Empty;
5242 Ofs := Uint_0;
5243 Entry_OK := False;
5244 return;
5245 end if;
5246
feff2f05 5247 -- Come here with expression of appropriate form, check if entity is an
5248 -- appropriate one for our purposes.
9dfe12ae 5249
5250 if (Ekind (Ent) = E_Variable
cc60bd16 5251 or else Is_Constant_Object (Ent))
9dfe12ae 5252 and then not Is_Library_Level_Entity (Ent)
5253 then
5254 Entry_OK := True;
5255 else
5256 Entry_OK := False;
5257 return;
5258 end if;
5259
5260 -- See if there is matching check already
5261
5262 for J in reverse 1 .. Num_Saved_Checks loop
5263 declare
5264 SC : Saved_Check renames Saved_Checks (J);
5265
5266 begin
5267 if SC.Killed = False
5268 and then SC.Entity = Ent
5269 and then SC.Offset = Ofs
5270 and then SC.Check_Type = Check_Type
5271 and then Within_Range_Of (Target_Type, SC.Target_Type)
5272 then
5273 Check_Num := J;
5274 return;
5275 end if;
5276 end;
5277 end loop;
5278
5279 -- If we fall through entry was not found
5280
9dfe12ae 5281 return;
5282 end Find_Check;
5283
5284 ---------------------------------
5285 -- Generate_Discriminant_Check --
5286 ---------------------------------
5287
5288 -- Note: the code for this procedure is derived from the
feff2f05 5289 -- Emit_Discriminant_Check Routine in trans.c.
9dfe12ae 5290
5291 procedure Generate_Discriminant_Check (N : Node_Id) is
5292 Loc : constant Source_Ptr := Sloc (N);
5293 Pref : constant Node_Id := Prefix (N);
5294 Sel : constant Node_Id := Selector_Name (N);
5295
5296 Orig_Comp : constant Entity_Id :=
b6341c67 5297 Original_Record_Component (Entity (Sel));
9dfe12ae 5298 -- The original component to be checked
5299
5300 Discr_Fct : constant Entity_Id :=
b6341c67 5301 Discriminant_Checking_Func (Orig_Comp);
9dfe12ae 5302 -- The discriminant checking function
5303
5304 Discr : Entity_Id;
5305 -- One discriminant to be checked in the type
5306
5307 Real_Discr : Entity_Id;
5308 -- Actual discriminant in the call
5309
5310 Pref_Type : Entity_Id;
5311 -- Type of relevant prefix (ignoring private/access stuff)
5312
5313 Args : List_Id;
5314 -- List of arguments for function call
5315
5316 Formal : Entity_Id;
feff2f05 5317 -- Keep track of the formal corresponding to the actual we build for
5318 -- each discriminant, in order to be able to perform the necessary type
5319 -- conversions.
9dfe12ae 5320
5321 Scomp : Node_Id;
5322 -- Selected component reference for checking function argument
5323
5324 begin
5325 Pref_Type := Etype (Pref);
5326
5327 -- Force evaluation of the prefix, so that it does not get evaluated
5328 -- twice (once for the check, once for the actual reference). Such a
5329 -- double evaluation is always a potential source of inefficiency,
5330 -- and is functionally incorrect in the volatile case, or when the
5331 -- prefix may have side-effects. An entity or a component of an
5332 -- entity requires no evaluation.
5333
5334 if Is_Entity_Name (Pref) then
5335 if Treat_As_Volatile (Entity (Pref)) then
5336 Force_Evaluation (Pref, Name_Req => True);
5337 end if;
5338
5339 elsif Treat_As_Volatile (Etype (Pref)) then
5340 Force_Evaluation (Pref, Name_Req => True);
5341
5342 elsif Nkind (Pref) = N_Selected_Component
5343 and then Is_Entity_Name (Prefix (Pref))
5344 then
5345 null;
5346
5347 else
5348 Force_Evaluation (Pref, Name_Req => True);
5349 end if;
5350
5351 -- For a tagged type, use the scope of the original component to
5352 -- obtain the type, because ???
5353
5354 if Is_Tagged_Type (Scope (Orig_Comp)) then
5355 Pref_Type := Scope (Orig_Comp);
5356
feff2f05 5357 -- For an untagged derived type, use the discriminants of the parent
5358 -- which have been renamed in the derivation, possibly by a one-to-many
5359 -- discriminant constraint. For non-tagged type, initially get the Etype
5360 -- of the prefix
9dfe12ae 5361
5362 else
5363 if Is_Derived_Type (Pref_Type)
5364 and then Number_Discriminants (Pref_Type) /=
5365 Number_Discriminants (Etype (Base_Type (Pref_Type)))
5366 then
5367 Pref_Type := Etype (Base_Type (Pref_Type));
5368 end if;
5369 end if;
5370
5371 -- We definitely should have a checking function, This routine should
5372 -- not be called if no discriminant checking function is present.
5373
5374 pragma Assert (Present (Discr_Fct));
5375
5376 -- Create the list of the actual parameters for the call. This list
5377 -- is the list of the discriminant fields of the record expression to
5378 -- be discriminant checked.
5379
5380 Args := New_List;
5381 Formal := First_Formal (Discr_Fct);
5382 Discr := First_Discriminant (Pref_Type);
5383 while Present (Discr) loop
5384
5385 -- If we have a corresponding discriminant field, and a parent
5386 -- subtype is present, then we want to use the corresponding
5387 -- discriminant since this is the one with the useful value.
5388
5389 if Present (Corresponding_Discriminant (Discr))
5390 and then Ekind (Pref_Type) = E_Record_Type
5391 and then Present (Parent_Subtype (Pref_Type))
5392 then
5393 Real_Discr := Corresponding_Discriminant (Discr);
5394 else
5395 Real_Discr := Discr;
5396 end if;
5397
5398 -- Construct the reference to the discriminant
5399
5400 Scomp :=
5401 Make_Selected_Component (Loc,
5402 Prefix =>
5403 Unchecked_Convert_To (Pref_Type,
5404 Duplicate_Subexpr (Pref)),
5405 Selector_Name => New_Occurrence_Of (Real_Discr, Loc));
5406
5407 -- Manually analyze and resolve this selected component. We really
5408 -- want it just as it appears above, and do not want the expander
feff2f05 5409 -- playing discriminal games etc with this reference. Then we append
5410 -- the argument to the list we are gathering.
9dfe12ae 5411
5412 Set_Etype (Scomp, Etype (Real_Discr));
5413 Set_Analyzed (Scomp, True);
5414 Append_To (Args, Convert_To (Etype (Formal), Scomp));
5415
5416 Next_Formal_With_Extras (Formal);
5417 Next_Discriminant (Discr);
5418 end loop;
5419
5420 -- Now build and insert the call
5421
5422 Insert_Action (N,
5423 Make_Raise_Constraint_Error (Loc,
5424 Condition =>
5425 Make_Function_Call (Loc,
5426 Name => New_Occurrence_Of (Discr_Fct, Loc),
5427 Parameter_Associations => Args),
5428 Reason => CE_Discriminant_Check_Failed));
5429 end Generate_Discriminant_Check;
5430
5c99c290 5431 ---------------------------
5432 -- Generate_Index_Checks --
5433 ---------------------------
9dfe12ae 5434
5435 procedure Generate_Index_Checks (N : Node_Id) is
05f3e139 5436
5437 function Entity_Of_Prefix return Entity_Id;
5438 -- Returns the entity of the prefix of N (or Empty if not found)
5439
3f42e2a7 5440 ----------------------
5441 -- Entity_Of_Prefix --
5442 ----------------------
5443
05f3e139 5444 function Entity_Of_Prefix return Entity_Id is
e5d38095 5445 P : Node_Id;
5446
05f3e139 5447 begin
e5d38095 5448 P := Prefix (N);
05f3e139 5449 while not Is_Entity_Name (P) loop
5450 if not Nkind_In (P, N_Selected_Component,
5451 N_Indexed_Component)
5452 then
5453 return Empty;
5454 end if;
5455
5456 P := Prefix (P);
5457 end loop;
5458
5459 return Entity (P);
5460 end Entity_Of_Prefix;
5461
5462 -- Local variables
5463
5464 Loc : constant Source_Ptr := Sloc (N);
5465 A : constant Node_Id := Prefix (N);
5466 A_Ent : constant Entity_Id := Entity_Of_Prefix;
5467 Sub : Node_Id;
9dfe12ae 5468
3f42e2a7 5469 -- Start of processing for Generate_Index_Checks
5470
9dfe12ae 5471 begin
05f3e139 5472 -- Ignore call if the prefix is not an array since we have a serious
5473 -- error in the sources. Ignore it also if index checks are suppressed
5474 -- for array object or type.
0577b0b1 5475
05f3e139 5476 if not Is_Array_Type (Etype (A))
5477 or else (Present (A_Ent)
e5d38095 5478 and then Index_Checks_Suppressed (A_Ent))
0577b0b1 5479 or else Index_Checks_Suppressed (Etype (A))
5480 then
5481 return;
5482 end if;
5483
05f3e139 5484 -- Generate a raise of constraint error with the appropriate reason and
5485 -- a condition of the form:
5486
3f42e2a7 5487 -- Base_Type (Sub) not in Array'Range (Subscript)
05f3e139 5488
5489 -- Note that the reason we generate the conversion to the base type here
5490 -- is that we definitely want the range check to take place, even if it
5491 -- looks like the subtype is OK. Optimization considerations that allow
5492 -- us to omit the check have already been taken into account in the
5493 -- setting of the Do_Range_Check flag earlier on.
0577b0b1 5494
9dfe12ae 5495 Sub := First (Expressions (N));
05f3e139 5496
5497 -- Handle string literals
5498
5499 if Ekind (Etype (A)) = E_String_Literal_Subtype then
9dfe12ae 5500 if Do_Range_Check (Sub) then
5501 Set_Do_Range_Check (Sub, False);
5502
05f3e139 5503 -- For string literals we obtain the bounds of the string from the
5504 -- associated subtype.
9dfe12ae 5505
05f3e139 5506 Insert_Action (N,
094ed68e 5507 Make_Raise_Constraint_Error (Loc,
5508 Condition =>
5509 Make_Not_In (Loc,
5510 Left_Opnd =>
5511 Convert_To (Base_Type (Etype (Sub)),
5512 Duplicate_Subexpr_Move_Checks (Sub)),
5513 Right_Opnd =>
5514 Make_Attribute_Reference (Loc,
5515 Prefix => New_Reference_To (Etype (A), Loc),
5516 Attribute_Name => Name_Range)),
5517 Reason => CE_Index_Check_Failed));
05f3e139 5518 end if;
9dfe12ae 5519
05f3e139 5520 -- General case
9dfe12ae 5521
05f3e139 5522 else
5523 declare
5524 A_Idx : Node_Id := Empty;
5525 A_Range : Node_Id;
5526 Ind : Nat;
5527 Num : List_Id;
5528 Range_N : Node_Id;
9dfe12ae 5529
05f3e139 5530 begin
5531 A_Idx := First_Index (Etype (A));
5532 Ind := 1;
5533 while Present (Sub) loop
5534 if Do_Range_Check (Sub) then
5535 Set_Do_Range_Check (Sub, False);
9dfe12ae 5536
05f3e139 5537 -- Force evaluation except for the case of a simple name of
5538 -- a non-volatile entity.
9dfe12ae 5539
05f3e139 5540 if not Is_Entity_Name (Sub)
5541 or else Treat_As_Volatile (Entity (Sub))
5542 then
5543 Force_Evaluation (Sub);
5544 end if;
9dfe12ae 5545
05f3e139 5546 if Nkind (A_Idx) = N_Range then
5547 A_Range := A_Idx;
5548
5549 elsif Nkind (A_Idx) = N_Identifier
5550 or else Nkind (A_Idx) = N_Expanded_Name
5551 then
5552 A_Range := Scalar_Range (Entity (A_Idx));
5553
5554 else pragma Assert (Nkind (A_Idx) = N_Subtype_Indication);
5555 A_Range := Range_Expression (Constraint (A_Idx));
5556 end if;
5557
5558 -- For array objects with constant bounds we can generate
5559 -- the index check using the bounds of the type of the index
5560
5561 if Present (A_Ent)
5562 and then Ekind (A_Ent) = E_Variable
5563 and then Is_Constant_Bound (Low_Bound (A_Range))
5564 and then Is_Constant_Bound (High_Bound (A_Range))
5565 then
5566 Range_N :=
5567 Make_Attribute_Reference (Loc,
3f42e2a7 5568 Prefix =>
5569 New_Reference_To (Etype (A_Idx), Loc),
05f3e139 5570 Attribute_Name => Name_Range);
5571
5572 -- For arrays with non-constant bounds we cannot generate
5573 -- the index check using the bounds of the type of the index
5574 -- since it may reference discriminants of some enclosing
5575 -- type. We obtain the bounds directly from the prefix
5576 -- object.
5577
5578 else
5579 if Ind = 1 then
5580 Num := No_List;
5581 else
5582 Num := New_List (Make_Integer_Literal (Loc, Ind));
5583 end if;
5584
5585 Range_N :=
5586 Make_Attribute_Reference (Loc,
5587 Prefix =>
5588 Duplicate_Subexpr_Move_Checks (A, Name_Req => True),
5589 Attribute_Name => Name_Range,
5590 Expressions => Num);
5591 end if;
5592
5593 Insert_Action (N,
094ed68e 5594 Make_Raise_Constraint_Error (Loc,
5595 Condition =>
5596 Make_Not_In (Loc,
5597 Left_Opnd =>
5598 Convert_To (Base_Type (Etype (Sub)),
5599 Duplicate_Subexpr_Move_Checks (Sub)),
5600 Right_Opnd => Range_N),
5601 Reason => CE_Index_Check_Failed));
05f3e139 5602 end if;
5603
5604 A_Idx := Next_Index (A_Idx);
5605 Ind := Ind + 1;
5606 Next (Sub);
5607 end loop;
5608 end;
5609 end if;
9dfe12ae 5610 end Generate_Index_Checks;
5611
5612 --------------------------
5613 -- Generate_Range_Check --
5614 --------------------------
5615
5616 procedure Generate_Range_Check
5617 (N : Node_Id;
5618 Target_Type : Entity_Id;
5619 Reason : RT_Exception_Code)
5620 is
5621 Loc : constant Source_Ptr := Sloc (N);
5622 Source_Type : constant Entity_Id := Etype (N);
5623 Source_Base_Type : constant Entity_Id := Base_Type (Source_Type);
5624 Target_Base_Type : constant Entity_Id := Base_Type (Target_Type);
5625
5626 begin
feff2f05 5627 -- First special case, if the source type is already within the range
5628 -- of the target type, then no check is needed (probably we should have
5629 -- stopped Do_Range_Check from being set in the first place, but better
5630 -- late than later in preventing junk code!
9dfe12ae 5631
feff2f05 5632 -- We do NOT apply this if the source node is a literal, since in this
5633 -- case the literal has already been labeled as having the subtype of
5634 -- the target.
9dfe12ae 5635
7a1dabb3 5636 if In_Subrange_Of (Source_Type, Target_Type)
9dfe12ae 5637 and then not
5638 (Nkind (N) = N_Integer_Literal
5639 or else
5640 Nkind (N) = N_Real_Literal
5641 or else
5642 Nkind (N) = N_Character_Literal
5643 or else
5644 (Is_Entity_Name (N)
5645 and then Ekind (Entity (N)) = E_Enumeration_Literal))
5646 then
5647 return;
5648 end if;
5649
5650 -- We need a check, so force evaluation of the node, so that it does
5651 -- not get evaluated twice (once for the check, once for the actual
5652 -- reference). Such a double evaluation is always a potential source
5653 -- of inefficiency, and is functionally incorrect in the volatile case.
5654
5655 if not Is_Entity_Name (N)
5656 or else Treat_As_Volatile (Entity (N))
5657 then
5658 Force_Evaluation (N);
5659 end if;
5660
feff2f05 5661 -- The easiest case is when Source_Base_Type and Target_Base_Type are
5662 -- the same since in this case we can simply do a direct check of the
5663 -- value of N against the bounds of Target_Type.
9dfe12ae 5664
5665 -- [constraint_error when N not in Target_Type]
5666
5667 -- Note: this is by far the most common case, for example all cases of
5668 -- checks on the RHS of assignments are in this category, but not all
5669 -- cases are like this. Notably conversions can involve two types.
5670
5671 if Source_Base_Type = Target_Base_Type then
5672 Insert_Action (N,
5673 Make_Raise_Constraint_Error (Loc,
5674 Condition =>
5675 Make_Not_In (Loc,
5676 Left_Opnd => Duplicate_Subexpr (N),
5677 Right_Opnd => New_Occurrence_Of (Target_Type, Loc)),
5678 Reason => Reason));
5679
5680 -- Next test for the case where the target type is within the bounds
5681 -- of the base type of the source type, since in this case we can
5682 -- simply convert these bounds to the base type of T to do the test.
5683
5684 -- [constraint_error when N not in
5685 -- Source_Base_Type (Target_Type'First)
5686 -- ..
5687 -- Source_Base_Type(Target_Type'Last))]
5688
f2a06be9 5689 -- The conversions will always work and need no check
9dfe12ae 5690
a9b57347 5691 -- Unchecked_Convert_To is used instead of Convert_To to handle the case
5692 -- of converting from an enumeration value to an integer type, such as
5693 -- occurs for the case of generating a range check on Enum'Val(Exp)
5694 -- (which used to be handled by gigi). This is OK, since the conversion
5695 -- itself does not require a check.
5696
7a1dabb3 5697 elsif In_Subrange_Of (Target_Type, Source_Base_Type) then
9dfe12ae 5698 Insert_Action (N,
5699 Make_Raise_Constraint_Error (Loc,
5700 Condition =>
5701 Make_Not_In (Loc,
5702 Left_Opnd => Duplicate_Subexpr (N),
5703
5704 Right_Opnd =>
5705 Make_Range (Loc,
5706 Low_Bound =>
a9b57347 5707 Unchecked_Convert_To (Source_Base_Type,
9dfe12ae 5708 Make_Attribute_Reference (Loc,
5709 Prefix =>
5710 New_Occurrence_Of (Target_Type, Loc),
5711 Attribute_Name => Name_First)),
5712
5713 High_Bound =>
a9b57347 5714 Unchecked_Convert_To (Source_Base_Type,
9dfe12ae 5715 Make_Attribute_Reference (Loc,
5716 Prefix =>
5717 New_Occurrence_Of (Target_Type, Loc),
5718 Attribute_Name => Name_Last)))),
5719 Reason => Reason));
5720
feff2f05 5721 -- Note that at this stage we now that the Target_Base_Type is not in
5722 -- the range of the Source_Base_Type (since even the Target_Type itself
5723 -- is not in this range). It could still be the case that Source_Type is
5724 -- in range of the target base type since we have not checked that case.
9dfe12ae 5725
feff2f05 5726 -- If that is the case, we can freely convert the source to the target,
5727 -- and then test the target result against the bounds.
9dfe12ae 5728
7a1dabb3 5729 elsif In_Subrange_Of (Source_Type, Target_Base_Type) then
9dfe12ae 5730
feff2f05 5731 -- We make a temporary to hold the value of the converted value
5732 -- (converted to the base type), and then we will do the test against
5733 -- this temporary.
9dfe12ae 5734
5735 -- Tnn : constant Target_Base_Type := Target_Base_Type (N);
5736 -- [constraint_error when Tnn not in Target_Type]
5737
5738 -- Then the conversion itself is replaced by an occurrence of Tnn
5739
5740 declare
46eb6933 5741 Tnn : constant Entity_Id := Make_Temporary (Loc, 'T', N);
9dfe12ae 5742
5743 begin
5744 Insert_Actions (N, New_List (
5745 Make_Object_Declaration (Loc,
5746 Defining_Identifier => Tnn,
5747 Object_Definition =>
5748 New_Occurrence_Of (Target_Base_Type, Loc),
5749 Constant_Present => True,
5750 Expression =>
5751 Make_Type_Conversion (Loc,
5752 Subtype_Mark => New_Occurrence_Of (Target_Base_Type, Loc),
5753 Expression => Duplicate_Subexpr (N))),
5754
5755 Make_Raise_Constraint_Error (Loc,
5756 Condition =>
5757 Make_Not_In (Loc,
5758 Left_Opnd => New_Occurrence_Of (Tnn, Loc),
5759 Right_Opnd => New_Occurrence_Of (Target_Type, Loc)),
5760
5761 Reason => Reason)));
5762
5763 Rewrite (N, New_Occurrence_Of (Tnn, Loc));
2af58f67 5764
5765 -- Set the type of N, because the declaration for Tnn might not
5766 -- be analyzed yet, as is the case if N appears within a record
5767 -- declaration, as a discriminant constraint or expression.
5768
5769 Set_Etype (N, Target_Base_Type);
9dfe12ae 5770 end;
5771
5772 -- At this stage, we know that we have two scalar types, which are
5773 -- directly convertible, and where neither scalar type has a base
5774 -- range that is in the range of the other scalar type.
5775
5776 -- The only way this can happen is with a signed and unsigned type.
5777 -- So test for these two cases:
5778
5779 else
5780 -- Case of the source is unsigned and the target is signed
5781
5782 if Is_Unsigned_Type (Source_Base_Type)
5783 and then not Is_Unsigned_Type (Target_Base_Type)
5784 then
5785 -- If the source is unsigned and the target is signed, then we
5786 -- know that the source is not shorter than the target (otherwise
5787 -- the source base type would be in the target base type range).
5788
feff2f05 5789 -- In other words, the unsigned type is either the same size as
5790 -- the target, or it is larger. It cannot be smaller.
9dfe12ae 5791
5792 pragma Assert
5793 (Esize (Source_Base_Type) >= Esize (Target_Base_Type));
5794
5795 -- We only need to check the low bound if the low bound of the
5796 -- target type is non-negative. If the low bound of the target
5797 -- type is negative, then we know that we will fit fine.
5798
5799 -- If the high bound of the target type is negative, then we
5800 -- know we have a constraint error, since we can't possibly
5801 -- have a negative source.
5802
5803 -- With these two checks out of the way, we can do the check
5804 -- using the source type safely
5805
5806 -- This is definitely the most annoying case!
5807
5808 -- [constraint_error
5809 -- when (Target_Type'First >= 0
5810 -- and then
5811 -- N < Source_Base_Type (Target_Type'First))
5812 -- or else Target_Type'Last < 0
5813 -- or else N > Source_Base_Type (Target_Type'Last)];
5814
5815 -- We turn off all checks since we know that the conversions
5816 -- will work fine, given the guards for negative values.
5817
5818 Insert_Action (N,
5819 Make_Raise_Constraint_Error (Loc,
5820 Condition =>
5821 Make_Or_Else (Loc,
5822 Make_Or_Else (Loc,
5823 Left_Opnd =>
5824 Make_And_Then (Loc,
5825 Left_Opnd => Make_Op_Ge (Loc,
5826 Left_Opnd =>
5827 Make_Attribute_Reference (Loc,
5828 Prefix =>
5829 New_Occurrence_Of (Target_Type, Loc),
5830 Attribute_Name => Name_First),
5831 Right_Opnd => Make_Integer_Literal (Loc, Uint_0)),
5832
5833 Right_Opnd =>
5834 Make_Op_Lt (Loc,
5835 Left_Opnd => Duplicate_Subexpr (N),
5836 Right_Opnd =>
5837 Convert_To (Source_Base_Type,
5838 Make_Attribute_Reference (Loc,
5839 Prefix =>
5840 New_Occurrence_Of (Target_Type, Loc),
5841 Attribute_Name => Name_First)))),
5842
5843 Right_Opnd =>
5844 Make_Op_Lt (Loc,
5845 Left_Opnd =>
5846 Make_Attribute_Reference (Loc,
5847 Prefix => New_Occurrence_Of (Target_Type, Loc),
5848 Attribute_Name => Name_Last),
5849 Right_Opnd => Make_Integer_Literal (Loc, Uint_0))),
5850
5851 Right_Opnd =>
5852 Make_Op_Gt (Loc,
5853 Left_Opnd => Duplicate_Subexpr (N),
5854 Right_Opnd =>
5855 Convert_To (Source_Base_Type,
5856 Make_Attribute_Reference (Loc,
5857 Prefix => New_Occurrence_Of (Target_Type, Loc),
5858 Attribute_Name => Name_Last)))),
5859
5860 Reason => Reason),
5861 Suppress => All_Checks);
5862
5863 -- Only remaining possibility is that the source is signed and
fc75802a 5864 -- the target is unsigned.
9dfe12ae 5865
5866 else
5867 pragma Assert (not Is_Unsigned_Type (Source_Base_Type)
5868 and then Is_Unsigned_Type (Target_Base_Type));
5869
feff2f05 5870 -- If the source is signed and the target is unsigned, then we
5871 -- know that the target is not shorter than the source (otherwise
5872 -- the target base type would be in the source base type range).
9dfe12ae 5873
feff2f05 5874 -- In other words, the unsigned type is either the same size as
5875 -- the target, or it is larger. It cannot be smaller.
9dfe12ae 5876
feff2f05 5877 -- Clearly we have an error if the source value is negative since
5878 -- no unsigned type can have negative values. If the source type
5879 -- is non-negative, then the check can be done using the target
5880 -- type.
9dfe12ae 5881
5882 -- Tnn : constant Target_Base_Type (N) := Target_Type;
5883
5884 -- [constraint_error
5885 -- when N < 0 or else Tnn not in Target_Type];
5886
feff2f05 5887 -- We turn off all checks for the conversion of N to the target
5888 -- base type, since we generate the explicit check to ensure that
5889 -- the value is non-negative
9dfe12ae 5890
5891 declare
46eb6933 5892 Tnn : constant Entity_Id := Make_Temporary (Loc, 'T', N);
9dfe12ae 5893
5894 begin
5895 Insert_Actions (N, New_List (
5896 Make_Object_Declaration (Loc,
5897 Defining_Identifier => Tnn,
5898 Object_Definition =>
5899 New_Occurrence_Of (Target_Base_Type, Loc),
5900 Constant_Present => True,
5901 Expression =>
a9b57347 5902 Make_Unchecked_Type_Conversion (Loc,
9dfe12ae 5903 Subtype_Mark =>
5904 New_Occurrence_Of (Target_Base_Type, Loc),
5905 Expression => Duplicate_Subexpr (N))),
5906
5907 Make_Raise_Constraint_Error (Loc,
5908 Condition =>
5909 Make_Or_Else (Loc,
5910 Left_Opnd =>
5911 Make_Op_Lt (Loc,
5912 Left_Opnd => Duplicate_Subexpr (N),
5913 Right_Opnd => Make_Integer_Literal (Loc, Uint_0)),
5914
5915 Right_Opnd =>
5916 Make_Not_In (Loc,
5917 Left_Opnd => New_Occurrence_Of (Tnn, Loc),
5918 Right_Opnd =>
5919 New_Occurrence_Of (Target_Type, Loc))),
5920
5921 Reason => Reason)),
5922 Suppress => All_Checks);
5923
feff2f05 5924 -- Set the Etype explicitly, because Insert_Actions may have
5925 -- placed the declaration in the freeze list for an enclosing
5926 -- construct, and thus it is not analyzed yet.
9dfe12ae 5927
5928 Set_Etype (Tnn, Target_Base_Type);
5929 Rewrite (N, New_Occurrence_Of (Tnn, Loc));
5930 end;
5931 end if;
5932 end if;
5933 end Generate_Range_Check;
5934
2af58f67 5935 ------------------
5936 -- Get_Check_Id --
5937 ------------------
5938
5939 function Get_Check_Id (N : Name_Id) return Check_Id is
5940 begin
5941 -- For standard check name, we can do a direct computation
5942
5943 if N in First_Check_Name .. Last_Check_Name then
5944 return Check_Id (N - (First_Check_Name - 1));
5945
5946 -- For non-standard names added by pragma Check_Name, search table
5947
5948 else
5949 for J in All_Checks + 1 .. Check_Names.Last loop
5950 if Check_Names.Table (J) = N then
5951 return J;
5952 end if;
5953 end loop;
5954 end if;
5955
5956 -- No matching name found
5957
5958 return No_Check_Id;
5959 end Get_Check_Id;
5960
ee6ba406 5961 ---------------------
5962 -- Get_Discriminal --
5963 ---------------------
5964
5965 function Get_Discriminal (E : Entity_Id; Bound : Node_Id) return Node_Id is
5966 Loc : constant Source_Ptr := Sloc (E);
5967 D : Entity_Id;
5968 Sc : Entity_Id;
5969
5970 begin
0577b0b1 5971 -- The bound can be a bona fide parameter of a protected operation,
5972 -- rather than a prival encoded as an in-parameter.
5973
5974 if No (Discriminal_Link (Entity (Bound))) then
5975 return Bound;
5976 end if;
5977
2af58f67 5978 -- Climb the scope stack looking for an enclosing protected type. If
5979 -- we run out of scopes, return the bound itself.
5980
5981 Sc := Scope (E);
5982 while Present (Sc) loop
5983 if Sc = Standard_Standard then
5984 return Bound;
5985
5986 elsif Ekind (Sc) = E_Protected_Type then
5987 exit;
5988 end if;
5989
5990 Sc := Scope (Sc);
5991 end loop;
5992
ee6ba406 5993 D := First_Discriminant (Sc);
2af58f67 5994 while Present (D) loop
5995 if Chars (D) = Chars (Bound) then
5996 return New_Occurrence_Of (Discriminal (D), Loc);
5997 end if;
ee6ba406 5998
ee6ba406 5999 Next_Discriminant (D);
6000 end loop;
6001
2af58f67 6002 return Bound;
ee6ba406 6003 end Get_Discriminal;
6004
2af58f67 6005 ----------------------
6006 -- Get_Range_Checks --
6007 ----------------------
6008
6009 function Get_Range_Checks
6010 (Ck_Node : Node_Id;
6011 Target_Typ : Entity_Id;
6012 Source_Typ : Entity_Id := Empty;
6013 Warn_Node : Node_Id := Empty) return Check_Result
6014 is
6015 begin
6016 return Selected_Range_Checks
6017 (Ck_Node, Target_Typ, Source_Typ, Warn_Node);
6018 end Get_Range_Checks;
6019
ee6ba406 6020 ------------------
6021 -- Guard_Access --
6022 ------------------
6023
6024 function Guard_Access
6025 (Cond : Node_Id;
6026 Loc : Source_Ptr;
314a23b6 6027 Ck_Node : Node_Id) return Node_Id
ee6ba406 6028 is
6029 begin
6030 if Nkind (Cond) = N_Or_Else then
6031 Set_Paren_Count (Cond, 1);
6032 end if;
6033
6034 if Nkind (Ck_Node) = N_Allocator then
6035 return Cond;
6036 else
6037 return
6038 Make_And_Then (Loc,
6039 Left_Opnd =>
6040 Make_Op_Ne (Loc,
9dfe12ae 6041 Left_Opnd => Duplicate_Subexpr_No_Checks (Ck_Node),
ee6ba406 6042 Right_Opnd => Make_Null (Loc)),
6043 Right_Opnd => Cond);
6044 end if;
6045 end Guard_Access;
6046
6047 -----------------------------
6048 -- Index_Checks_Suppressed --
6049 -----------------------------
6050
6051 function Index_Checks_Suppressed (E : Entity_Id) return Boolean is
6052 begin
9dfe12ae 6053 if Present (E) and then Checks_May_Be_Suppressed (E) then
6054 return Is_Check_Suppressed (E, Index_Check);
6055 else
fafc6b97 6056 return Scope_Suppress.Suppress (Index_Check);
9dfe12ae 6057 end if;
ee6ba406 6058 end Index_Checks_Suppressed;
6059
6060 ----------------
6061 -- Initialize --
6062 ----------------
6063
6064 procedure Initialize is
6065 begin
6066 for J in Determine_Range_Cache_N'Range loop
6067 Determine_Range_Cache_N (J) := Empty;
6068 end loop;
2af58f67 6069
6070 Check_Names.Init;
6071
6072 for J in Int range 1 .. All_Checks loop
6073 Check_Names.Append (Name_Id (Int (First_Check_Name) + J - 1));
6074 end loop;
ee6ba406 6075 end Initialize;
6076
6077 -------------------------
6078 -- Insert_Range_Checks --
6079 -------------------------
6080
6081 procedure Insert_Range_Checks
6082 (Checks : Check_Result;
6083 Node : Node_Id;
6084 Suppress_Typ : Entity_Id;
6085 Static_Sloc : Source_Ptr := No_Location;
6086 Flag_Node : Node_Id := Empty;
6087 Do_Before : Boolean := False)
6088 is
6089 Internal_Flag_Node : Node_Id := Flag_Node;
6090 Internal_Static_Sloc : Source_Ptr := Static_Sloc;
6091
6092 Check_Node : Node_Id;
6093 Checks_On : constant Boolean :=
b6341c67 6094 (not Index_Checks_Suppressed (Suppress_Typ))
6095 or else (not Range_Checks_Suppressed (Suppress_Typ));
ee6ba406 6096
6097 begin
feff2f05 6098 -- For now we just return if Checks_On is false, however this should be
6099 -- enhanced to check for an always True value in the condition and to
6100 -- generate a compilation warning???
ee6ba406 6101
6dbcfcd9 6102 if not Full_Expander_Active or else not Checks_On then
ee6ba406 6103 return;
6104 end if;
6105
6106 if Static_Sloc = No_Location then
6107 Internal_Static_Sloc := Sloc (Node);
6108 end if;
6109
6110 if No (Flag_Node) then
6111 Internal_Flag_Node := Node;
6112 end if;
6113
6114 for J in 1 .. 2 loop
6115 exit when No (Checks (J));
6116
6117 if Nkind (Checks (J)) = N_Raise_Constraint_Error
6118 and then Present (Condition (Checks (J)))
6119 then
6120 if not Has_Dynamic_Range_Check (Internal_Flag_Node) then
6121 Check_Node := Checks (J);
6122 Mark_Rewrite_Insertion (Check_Node);
6123
6124 if Do_Before then
6125 Insert_Before_And_Analyze (Node, Check_Node);
6126 else
6127 Insert_After_And_Analyze (Node, Check_Node);
6128 end if;
6129
6130 Set_Has_Dynamic_Range_Check (Internal_Flag_Node);
6131 end if;
6132
6133 else
6134 Check_Node :=
f15731c4 6135 Make_Raise_Constraint_Error (Internal_Static_Sloc,
6136 Reason => CE_Range_Check_Failed);
ee6ba406 6137 Mark_Rewrite_Insertion (Check_Node);
6138
6139 if Do_Before then
6140 Insert_Before_And_Analyze (Node, Check_Node);
6141 else
6142 Insert_After_And_Analyze (Node, Check_Node);
6143 end if;
6144 end if;
6145 end loop;
6146 end Insert_Range_Checks;
6147
6148 ------------------------
6149 -- Insert_Valid_Check --
6150 ------------------------
6151
6152 procedure Insert_Valid_Check (Expr : Node_Id) is
6153 Loc : constant Source_Ptr := Sloc (Expr);
8b718dab 6154 Exp : Node_Id;
ee6ba406 6155
6156 begin
06ad5813 6157 -- Do not insert if checks off, or if not checking validity or
6158 -- if expression is known to be valid
ee6ba406 6159
0577b0b1 6160 if not Validity_Checks_On
6161 or else Range_Or_Validity_Checks_Suppressed (Expr)
06ad5813 6162 or else Expr_Known_Valid (Expr)
ee6ba406 6163 then
8b718dab 6164 return;
6165 end if;
ee6ba406 6166
8b718dab 6167 -- If we have a checked conversion, then validity check applies to
6168 -- the expression inside the conversion, not the result, since if
6169 -- the expression inside is valid, then so is the conversion result.
ee6ba406 6170
8b718dab 6171 Exp := Expr;
6172 while Nkind (Exp) = N_Type_Conversion loop
6173 Exp := Expression (Exp);
6174 end loop;
6175
0577b0b1 6176 -- We are about to insert the validity check for Exp. We save and
6177 -- reset the Do_Range_Check flag over this validity check, and then
6178 -- put it back for the final original reference (Exp may be rewritten).
6179
6180 declare
6181 DRC : constant Boolean := Do_Range_Check (Exp);
05fcfafb 6182
0577b0b1 6183 begin
6184 Set_Do_Range_Check (Exp, False);
6185
06ad5813 6186 -- Force evaluation to avoid multiple reads for atomic/volatile
6187
6188 if Is_Entity_Name (Exp)
6189 and then Is_Volatile (Entity (Exp))
6190 then
6191 Force_Evaluation (Exp, Name_Req => True);
6192 end if;
6193
0577b0b1 6194 -- Insert the validity check. Note that we do this with validity
6195 -- checks turned off, to avoid recursion, we do not want validity
6196 -- checks on the validity checking code itself!
6197
6198 Insert_Action
6199 (Expr,
6200 Make_Raise_Constraint_Error (Loc,
6201 Condition =>
6202 Make_Op_Not (Loc,
6203 Right_Opnd =>
6204 Make_Attribute_Reference (Loc,
6205 Prefix =>
6206 Duplicate_Subexpr_No_Checks (Exp, Name_Req => True),
6207 Attribute_Name => Name_Valid)),
6208 Reason => CE_Invalid_Data),
6209 Suppress => Validity_Check);
6210
6fb3c314 6211 -- If the expression is a reference to an element of a bit-packed
0577b0b1 6212 -- array, then it is rewritten as a renaming declaration. If the
6213 -- expression is an actual in a call, it has not been expanded,
6214 -- waiting for the proper point at which to do it. The same happens
6215 -- with renamings, so that we have to force the expansion now. This
6216 -- non-local complication is due to code in exp_ch2,adb, exp_ch4.adb
6217 -- and exp_ch6.adb.
6218
6219 if Is_Entity_Name (Exp)
6220 and then Nkind (Parent (Entity (Exp))) =
6221 N_Object_Renaming_Declaration
6222 then
6223 declare
6224 Old_Exp : constant Node_Id := Name (Parent (Entity (Exp)));
6225 begin
6226 if Nkind (Old_Exp) = N_Indexed_Component
6227 and then Is_Bit_Packed_Array (Etype (Prefix (Old_Exp)))
6228 then
6229 Expand_Packed_Element_Reference (Old_Exp);
6230 end if;
6231 end;
6232 end if;
6233
6234 -- Put back the Do_Range_Check flag on the resulting (possibly
6235 -- rewritten) expression.
6236
6237 -- Note: it might be thought that a validity check is not required
6238 -- when a range check is present, but that's not the case, because
6239 -- the back end is allowed to assume for the range check that the
6240 -- operand is within its declared range (an assumption that validity
6241 -- checking is all about NOT assuming!)
6242
00c403ee 6243 -- Note: no need to worry about Possible_Local_Raise here, it will
6244 -- already have been called if original node has Do_Range_Check set.
6245
0577b0b1 6246 Set_Do_Range_Check (Exp, DRC);
6247 end;
ee6ba406 6248 end Insert_Valid_Check;
6249
3cce7f32 6250 -------------------------------------
6251 -- Is_Signed_Integer_Arithmetic_Op --
6252 -------------------------------------
6253
6254 function Is_Signed_Integer_Arithmetic_Op (N : Node_Id) return Boolean is
6255 begin
6256 case Nkind (N) is
6257 when N_Op_Abs | N_Op_Add | N_Op_Divide | N_Op_Expon |
6258 N_Op_Minus | N_Op_Mod | N_Op_Multiply | N_Op_Plus |
6259 N_Op_Rem | N_Op_Subtract =>
6260 return Is_Signed_Integer_Type (Etype (N));
6261
92f1631f 6262 when N_If_Expression | N_Case_Expression =>
0326b4d4 6263 return Is_Signed_Integer_Type (Etype (N));
6264
6265 when N_Case_Expression_Alternative =>
6266 return Is_Signed_Integer_Type (Etype (Parent (N)));
6267
3cce7f32 6268 when others =>
6269 return False;
6270 end case;
6271 end Is_Signed_Integer_Arithmetic_Op;
6272
fa7497e8 6273 ----------------------------------
6274 -- Install_Null_Excluding_Check --
6275 ----------------------------------
6276
6277 procedure Install_Null_Excluding_Check (N : Node_Id) is
9f294c82 6278 Loc : constant Source_Ptr := Sloc (Parent (N));
84d0d4a5 6279 Typ : constant Entity_Id := Etype (N);
6280
7b31b357 6281 function Safe_To_Capture_In_Parameter_Value return Boolean;
6282 -- Determines if it is safe to capture Known_Non_Null status for an
6283 -- the entity referenced by node N. The caller ensures that N is indeed
6284 -- an entity name. It is safe to capture the non-null status for an IN
6285 -- parameter when the reference occurs within a declaration that is sure
6286 -- to be executed as part of the declarative region.
7870823d 6287
84d0d4a5 6288 procedure Mark_Non_Null;
7870823d 6289 -- After installation of check, if the node in question is an entity
6290 -- name, then mark this entity as non-null if possible.
6291
7b31b357 6292 function Safe_To_Capture_In_Parameter_Value return Boolean is
7870823d 6293 E : constant Entity_Id := Entity (N);
6294 S : constant Entity_Id := Current_Scope;
6295 S_Par : Node_Id;
6296
6297 begin
7b31b357 6298 if Ekind (E) /= E_In_Parameter then
6299 return False;
6300 end if;
7870823d 6301
6302 -- Two initial context checks. We must be inside a subprogram body
6303 -- with declarations and reference must not appear in nested scopes.
6304
7b31b357 6305 if (Ekind (S) /= E_Function and then Ekind (S) /= E_Procedure)
7870823d 6306 or else Scope (E) /= S
6307 then
6308 return False;
6309 end if;
6310
6311 S_Par := Parent (Parent (S));
6312
6313 if Nkind (S_Par) /= N_Subprogram_Body
6314 or else No (Declarations (S_Par))
6315 then
6316 return False;
6317 end if;
6318
6319 declare
6320 N_Decl : Node_Id;
6321 P : Node_Id;
6322
6323 begin
6324 -- Retrieve the declaration node of N (if any). Note that N
6325 -- may be a part of a complex initialization expression.
6326
6327 P := Parent (N);
6328 N_Decl := Empty;
6329 while Present (P) loop
6330
7b31b357 6331 -- If we have a short circuit form, and we are within the right
6332 -- hand expression, we return false, since the right hand side
6333 -- is not guaranteed to be elaborated.
6334
6335 if Nkind (P) in N_Short_Circuit
6336 and then N = Right_Opnd (P)
6337 then
6338 return False;
6339 end if;
6340
92f1631f 6341 -- Similarly, if we are in an if expression and not part of the
6342 -- condition, then we return False, since neither the THEN or
6343 -- ELSE dependent expressions will always be elaborated.
7b31b357 6344
92f1631f 6345 if Nkind (P) = N_If_Expression
7b31b357 6346 and then N /= First (Expressions (P))
6347 then
6348 return False;
e977c0cf 6349 end if;
6350
6fb3c314 6351 -- If we are in a case expression, and not part of the
e977c0cf 6352 -- expression, then we return False, since a particular
92f1631f 6353 -- dependent expression may not always be elaborated
e977c0cf 6354
6355 if Nkind (P) = N_Case_Expression
6356 and then N /= Expression (P)
6357 then
6358 return False;
7b31b357 6359 end if;
6360
7870823d 6361 -- While traversing the parent chain, we find that N
6362 -- belongs to a statement, thus it may never appear in
6363 -- a declarative region.
6364
6365 if Nkind (P) in N_Statement_Other_Than_Procedure_Call
6366 or else Nkind (P) = N_Procedure_Call_Statement
6367 then
6368 return False;
6369 end if;
6370
7b31b357 6371 -- If we are at a declaration, record it and exit
6372
7870823d 6373 if Nkind (P) in N_Declaration
6374 and then Nkind (P) not in N_Subprogram_Specification
6375 then
6376 N_Decl := P;
6377 exit;
6378 end if;
6379
6380 P := Parent (P);
6381 end loop;
6382
6383 if No (N_Decl) then
6384 return False;
6385 end if;
6386
6387 return List_Containing (N_Decl) = Declarations (S_Par);
6388 end;
7b31b357 6389 end Safe_To_Capture_In_Parameter_Value;
84d0d4a5 6390
6391 -------------------
6392 -- Mark_Non_Null --
6393 -------------------
6394
6395 procedure Mark_Non_Null is
6396 begin
7870823d 6397 -- Only case of interest is if node N is an entity name
6398
84d0d4a5 6399 if Is_Entity_Name (N) then
7870823d 6400
6401 -- For sure, we want to clear an indication that this is known to
6402 -- be null, since if we get past this check, it definitely is not!
6403
84d0d4a5 6404 Set_Is_Known_Null (Entity (N), False);
6405
7870823d 6406 -- We can mark the entity as known to be non-null if either it is
6407 -- safe to capture the value, or in the case of an IN parameter,
6408 -- which is a constant, if the check we just installed is in the
6409 -- declarative region of the subprogram body. In this latter case,
7b31b357 6410 -- a check is decisive for the rest of the body if the expression
6411 -- is sure to be elaborated, since we know we have to elaborate
6412 -- all declarations before executing the body.
6413
6414 -- Couldn't this always be part of Safe_To_Capture_Value ???
7870823d 6415
6416 if Safe_To_Capture_Value (N, Entity (N))
7b31b357 6417 or else Safe_To_Capture_In_Parameter_Value
7870823d 6418 then
6419 Set_Is_Known_Non_Null (Entity (N));
84d0d4a5 6420 end if;
6421 end if;
6422 end Mark_Non_Null;
6423
6424 -- Start of processing for Install_Null_Excluding_Check
fa7497e8 6425
6426 begin
84d0d4a5 6427 pragma Assert (Is_Access_Type (Typ));
fa7497e8 6428
84d0d4a5 6429 -- No check inside a generic (why not???)
fa7497e8 6430
84d0d4a5 6431 if Inside_A_Generic then
fa7497e8 6432 return;
84d0d4a5 6433 end if;
6434
6435 -- No check needed if known to be non-null
6436
6437 if Known_Non_Null (N) then
05fcfafb 6438 return;
84d0d4a5 6439 end if;
fa7497e8 6440
84d0d4a5 6441 -- If known to be null, here is where we generate a compile time check
6442
6443 if Known_Null (N) then
d16989f1 6444
6445 -- Avoid generating warning message inside init procs
6446
6447 if not Inside_Init_Proc then
6448 Apply_Compile_Time_Constraint_Error
6449 (N,
6450 "null value not allowed here?",
6451 CE_Access_Check_Failed);
6452 else
6453 Insert_Action (N,
6454 Make_Raise_Constraint_Error (Loc,
6455 Reason => CE_Access_Check_Failed));
6456 end if;
6457
84d0d4a5 6458 Mark_Non_Null;
6459 return;
6460 end if;
6461
6462 -- If entity is never assigned, for sure a warning is appropriate
6463
6464 if Is_Entity_Name (N) then
6465 Check_Unset_Reference (N);
fa7497e8 6466 end if;
84d0d4a5 6467
6468 -- No check needed if checks are suppressed on the range. Note that we
6469 -- don't set Is_Known_Non_Null in this case (we could legitimately do
6470 -- so, since the program is erroneous, but we don't like to casually
6471 -- propagate such conclusions from erroneosity).
6472
6473 if Access_Checks_Suppressed (Typ) then
6474 return;
6475 end if;
6476
2af58f67 6477 -- No check needed for access to concurrent record types generated by
6478 -- the expander. This is not just an optimization (though it does indeed
6479 -- remove junk checks). It also avoids generation of junk warnings.
6480
6481 if Nkind (N) in N_Has_Chars
6482 and then Chars (N) = Name_uObject
6483 and then Is_Concurrent_Record_Type
6484 (Directly_Designated_Type (Etype (N)))
6485 then
6486 return;
6487 end if;
6488
472ea160 6489 -- No check needed for the Get_Current_Excep.all.all idiom generated by
6490 -- the expander within exception handlers, since we know that the value
6491 -- can never be null.
6492
6493 -- Is this really the right way to do this? Normally we generate such
6494 -- code in the expander with checks off, and that's how we suppress this
6495 -- kind of junk check ???
6496
6497 if Nkind (N) = N_Function_Call
6498 and then Nkind (Name (N)) = N_Explicit_Dereference
6499 and then Nkind (Prefix (Name (N))) = N_Identifier
6500 and then Is_RTE (Entity (Prefix (Name (N))), RE_Get_Current_Excep)
6501 then
6502 return;
6503 end if;
6504
84d0d4a5 6505 -- Otherwise install access check
6506
6507 Insert_Action (N,
6508 Make_Raise_Constraint_Error (Loc,
6509 Condition =>
6510 Make_Op_Eq (Loc,
6511 Left_Opnd => Duplicate_Subexpr_Move_Checks (N),
6512 Right_Opnd => Make_Null (Loc)),
6513 Reason => CE_Access_Check_Failed));
6514
6515 Mark_Non_Null;
fa7497e8 6516 end Install_Null_Excluding_Check;
6517
ee6ba406 6518 --------------------------
6519 -- Install_Static_Check --
6520 --------------------------
6521
6522 procedure Install_Static_Check (R_Cno : Node_Id; Loc : Source_Ptr) is
6523 Stat : constant Boolean := Is_Static_Expression (R_Cno);
6524 Typ : constant Entity_Id := Etype (R_Cno);
6525
6526 begin
f15731c4 6527 Rewrite (R_Cno,
6528 Make_Raise_Constraint_Error (Loc,
6529 Reason => CE_Range_Check_Failed));
ee6ba406 6530 Set_Analyzed (R_Cno);
6531 Set_Etype (R_Cno, Typ);
6532 Set_Raises_Constraint_Error (R_Cno);
6533 Set_Is_Static_Expression (R_Cno, Stat);
840ab274 6534
6535 -- Now deal with possible local raise handling
6536
6537 Possible_Local_Raise (R_Cno, Standard_Constraint_Error);
ee6ba406 6538 end Install_Static_Check;
6539
3cce7f32 6540 -------------------------
6541 -- Is_Check_Suppressed --
6542 -------------------------
6543
6544 function Is_Check_Suppressed (E : Entity_Id; C : Check_Id) return Boolean is
6545 Ptr : Suppress_Stack_Entry_Ptr;
6546
6547 begin
6548 -- First search the local entity suppress stack. We search this from the
6549 -- top of the stack down so that we get the innermost entry that applies
6550 -- to this case if there are nested entries.
6551
6552 Ptr := Local_Suppress_Stack_Top;
6553 while Ptr /= null loop
6554 if (Ptr.Entity = Empty or else Ptr.Entity = E)
6555 and then (Ptr.Check = All_Checks or else Ptr.Check = C)
6556 then
6557 return Ptr.Suppress;
6558 end if;
6559
6560 Ptr := Ptr.Prev;
6561 end loop;
6562
6563 -- Now search the global entity suppress table for a matching entry.
6564 -- We also search this from the top down so that if there are multiple
6565 -- pragmas for the same entity, the last one applies (not clear what
6566 -- or whether the RM specifies this handling, but it seems reasonable).
6567
6568 Ptr := Global_Suppress_Stack_Top;
6569 while Ptr /= null loop
6570 if (Ptr.Entity = Empty or else Ptr.Entity = E)
6571 and then (Ptr.Check = All_Checks or else Ptr.Check = C)
6572 then
6573 return Ptr.Suppress;
6574 end if;
6575
6576 Ptr := Ptr.Prev;
6577 end loop;
6578
6579 -- If we did not find a matching entry, then use the normal scope
6580 -- suppress value after all (actually this will be the global setting
6581 -- since it clearly was not overridden at any point). For a predefined
6582 -- check, we test the specific flag. For a user defined check, we check
6583 -- the All_Checks flag. The Overflow flag requires special handling to
6584 -- deal with the General vs Assertion case
6585
6586 if C = Overflow_Check then
6587 return Overflow_Checks_Suppressed (Empty);
6588 elsif C in Predefined_Check_Id then
6589 return Scope_Suppress.Suppress (C);
6590 else
6591 return Scope_Suppress.Suppress (All_Checks);
6592 end if;
6593 end Is_Check_Suppressed;
6594
9dfe12ae 6595 ---------------------
6596 -- Kill_All_Checks --
6597 ---------------------
6598
6599 procedure Kill_All_Checks is
6600 begin
6601 if Debug_Flag_CC then
6602 w ("Kill_All_Checks");
6603 end if;
6604
feff2f05 6605 -- We reset the number of saved checks to zero, and also modify all
6606 -- stack entries for statement ranges to indicate that the number of
6607 -- checks at each level is now zero.
9dfe12ae 6608
6609 Num_Saved_Checks := 0;
6610
96da3284 6611 -- Note: the Int'Min here avoids any possibility of J being out of
6612 -- range when called from e.g. Conditional_Statements_Begin.
6613
6614 for J in 1 .. Int'Min (Saved_Checks_TOS, Saved_Checks_Stack'Last) loop
9dfe12ae 6615 Saved_Checks_Stack (J) := 0;
6616 end loop;
6617 end Kill_All_Checks;
6618
6619 -----------------
6620 -- Kill_Checks --
6621 -----------------
6622
6623 procedure Kill_Checks (V : Entity_Id) is
6624 begin
6625 if Debug_Flag_CC then
6626 w ("Kill_Checks for entity", Int (V));
6627 end if;
6628
6629 for J in 1 .. Num_Saved_Checks loop
6630 if Saved_Checks (J).Entity = V then
6631 if Debug_Flag_CC then
6632 w (" Checks killed for saved check ", J);
6633 end if;
6634
6635 Saved_Checks (J).Killed := True;
6636 end if;
6637 end loop;
6638 end Kill_Checks;
6639
ee6ba406 6640 ------------------------------
6641 -- Length_Checks_Suppressed --
6642 ------------------------------
6643
6644 function Length_Checks_Suppressed (E : Entity_Id) return Boolean is
6645 begin
9dfe12ae 6646 if Present (E) and then Checks_May_Be_Suppressed (E) then
6647 return Is_Check_Suppressed (E, Length_Check);
6648 else
fafc6b97 6649 return Scope_Suppress.Suppress (Length_Check);
9dfe12ae 6650 end if;
ee6ba406 6651 end Length_Checks_Suppressed;
6652
3cce7f32 6653 -----------------------
6654 -- Make_Bignum_Block --
6655 -----------------------
6656
6657 function Make_Bignum_Block (Loc : Source_Ptr) return Node_Id is
6658 M : constant Entity_Id := Make_Defining_Identifier (Loc, Name_uM);
ee6ba406 6659
3cce7f32 6660 begin
6661 return
6662 Make_Block_Statement (Loc,
6663 Declarations => New_List (
6664 Make_Object_Declaration (Loc,
6665 Defining_Identifier => M,
6666 Object_Definition =>
6667 New_Occurrence_Of (RTE (RE_Mark_Id), Loc),
6668 Expression =>
6669 Make_Function_Call (Loc,
6670 Name => New_Reference_To (RTE (RE_SS_Mark), Loc)))),
6671
6672 Handled_Statement_Sequence =>
6673 Make_Handled_Sequence_Of_Statements (Loc,
6674 Statements => New_List (
6675 Make_Procedure_Call_Statement (Loc,
6676 Name => New_Occurrence_Of (RTE (RE_SS_Release), Loc),
6677 Parameter_Associations => New_List (
6678 New_Reference_To (M, Loc))))));
6679 end Make_Bignum_Block;
6680
6681 ----------------------------------------
6682 -- Minimize_Eliminate_Overflow_Checks --
6683 ----------------------------------------
6684
6685 procedure Minimize_Eliminate_Overflow_Checks
61016a7a 6686 (N : Node_Id;
6687 Lo : out Uint;
6688 Hi : out Uint;
6689 Top_Level : Boolean)
3cce7f32 6690 is
0326b4d4 6691 Rtyp : constant Entity_Id := Etype (N);
6692 pragma Assert (Is_Signed_Integer_Type (Rtyp));
6693 -- Result type, must be a signed integer type
3cce7f32 6694
6695 Check_Mode : constant Overflow_Check_Type := Overflow_Check_Mode (Empty);
6696 pragma Assert (Check_Mode in Minimized_Or_Eliminated);
6697
6698 Loc : constant Source_Ptr := Sloc (N);
6699
6700 Rlo, Rhi : Uint;
0326b4d4 6701 -- Ranges of values for right operand (operator case)
3cce7f32 6702
6703 Llo, Lhi : Uint;
0326b4d4 6704 -- Ranges of values for left operand (operator case)
3cce7f32 6705
49b3a812 6706 LLIB : constant Entity_Id := Base_Type (Standard_Long_Long_Integer);
6707 -- Operands and results are of this type when we convert
6708
0326b4d4 6709 LLLo : constant Uint := Intval (Type_Low_Bound (LLIB));
6710 LLHi : constant Uint := Intval (Type_High_Bound (LLIB));
3cce7f32 6711 -- Bounds of Long_Long_Integer
6712
6713 Binary : constant Boolean := Nkind (N) in N_Binary_Op;
6714 -- Indicates binary operator case
6715
6716 OK : Boolean;
6717 -- Used in call to Determine_Range
6718
61016a7a 6719 Bignum_Operands : Boolean;
6720 -- Set True if one or more operands is already of type Bignum, meaning
6721 -- that for sure (regardless of Top_Level setting) we are committed to
0326b4d4 6722 -- doing the operation in Bignum mode (or in the case of a case or if
6723 -- expression, converting all the dependent expressions to bignum).
6724
6725 Long_Long_Integer_Operands : Boolean;
6726 -- Set True if one r more operands is already of type Long_Loong_Integer
6727 -- which means that if the result is known to be in the result type
6728 -- range, then we must convert such operands back to the result type.
6729 -- This switch is properly set only when Bignum_Operands is False.
6730
6731 function In_Result_Range return Boolean;
6732 -- Returns True iff Lo .. Hi are within range of the result type
61016a7a 6733
2fe22c69 6734 procedure Max (A : in out Uint; B : Uint);
6735 -- If A is No_Uint, sets A to B, else to UI_Max (A, B);
6736
6737 procedure Min (A : in out Uint; B : Uint);
6738 -- If A is No_Uint, sets A to B, else to UI_Min (A, B);
6739
0326b4d4 6740 ---------------------
6741 -- In_Result_Range --
6742 ---------------------
6743
6744 function In_Result_Range return Boolean is
6745 begin
6746 if Is_Static_Subtype (Etype (N)) then
6747 return Lo >= Expr_Value (Type_Low_Bound (Rtyp))
6748 and then
6749 Hi <= Expr_Value (Type_High_Bound (Rtyp));
6750 else
6751 return Lo >= Expr_Value (Type_Low_Bound (Base_Type (Rtyp)))
6752 and then
6753 Hi <= Expr_Value (Type_High_Bound (Base_Type (Rtyp)));
6754 end if;
6755 end In_Result_Range;
6756
2fe22c69 6757 ---------
6758 -- Max --
6759 ---------
6760
6761 procedure Max (A : in out Uint; B : Uint) is
6762 begin
6763 if A = No_Uint or else B > A then
6764 A := B;
6765 end if;
6766 end Max;
6767
6768 ---------
6769 -- Min --
6770 ---------
6771
6772 procedure Min (A : in out Uint; B : Uint) is
6773 begin
6774 if A = No_Uint or else B < A then
6775 A := B;
6776 end if;
6777 end Min;
6778
6779 -- Start of processing for Minimize_Eliminate_Overflow_Checks
6780
3cce7f32 6781 begin
0326b4d4 6782 -- Case where we do not have a signed integer arithmetic operation
3cce7f32 6783
6784 if not Is_Signed_Integer_Arithmetic_Op (N) then
6785
6786 -- Use the normal Determine_Range routine to get the range. We
6787 -- don't require operands to be valid, invalid values may result in
6788 -- rubbish results where the result has not been properly checked for
6789 -- overflow, that's fine!
6790
6791 Determine_Range (N, OK, Lo, Hi, Assume_Valid => False);
6792
6793 -- If Deterine_Range did not work (can this in fact happen? Not
6794 -- clear but might as well protect), use type bounds.
6795
6796 if not OK then
6797 Lo := Intval (Type_Low_Bound (Base_Type (Etype (N))));
6798 Hi := Intval (Type_High_Bound (Base_Type (Etype (N))));
6799 end if;
6800
6801 -- If we don't have a binary operator, all we have to do is to set
6802 -- the Hi/Lo range, so we are done
6803
6804 return;
6805
0326b4d4 6806 -- Processing for if expression
6807
92f1631f 6808 elsif Nkind (N) = N_If_Expression then
0326b4d4 6809 declare
6810 Then_DE : constant Node_Id := Next (First (Expressions (N)));
6811 Else_DE : constant Node_Id := Next (Then_DE);
6812
6813 begin
6814 Bignum_Operands := False;
6815
6816 Minimize_Eliminate_Overflow_Checks
6817 (Then_DE, Lo, Hi, Top_Level => False);
6818
6819 if Lo = No_Uint then
6820 Bignum_Operands := True;
6821 end if;
6822
6823 Minimize_Eliminate_Overflow_Checks
6824 (Else_DE, Rlo, Rhi, Top_Level => False);
6825
6826 if Rlo = No_Uint then
6827 Bignum_Operands := True;
6828 else
6829 Long_Long_Integer_Operands :=
6830 Etype (Then_DE) = LLIB or else Etype (Else_DE) = LLIB;
6831
6832 Min (Lo, Rlo);
6833 Max (Hi, Rhi);
6834 end if;
6835
6836 -- If at least one of our operands is now bignum, we must rebuild
6837 -- the if expression to use bignum operands. We will analyze the
6838 -- rebuilt if expression with overflow checks off, since once we
6839 -- are in bignum mode, we are all done with overflow checks!
6840
6841 if Bignum_Operands then
6842 Rewrite (N,
92f1631f 6843 Make_If_Expression (Loc,
0326b4d4 6844 Expressions => New_List (
6845 Remove_Head (Expressions (N)),
6846 Convert_To_Bignum (Then_DE),
6847 Convert_To_Bignum (Else_DE)),
6848 Is_Elsif => Is_Elsif (N)));
6849
6850 Analyze_And_Resolve
6851 (N, RTE (RE_Bignum), Suppress => Overflow_Check);
6852
6853 -- If we have no Long_Long_Integer operands, then we are in result
6854 -- range, since it means that none of our operands felt the need
6855 -- to worry about overflow (otherwise it would have already been
6856 -- converted to long long integer or bignum).
6857
6858 elsif not Long_Long_Integer_Operands then
6859 Set_Do_Overflow_Check (N, False);
6860
6861 -- Otherwise convert us to long long integer mode. Note that we
6862 -- don't need any further overflow checking at this level.
6863
6864 else
6865 Convert_To_And_Rewrite (LLIB, Then_DE);
6866 Convert_To_And_Rewrite (LLIB, Else_DE);
6867 Set_Etype (N, LLIB);
6868 Set_Do_Overflow_Check (N, False);
6869 end if;
6870 end;
6871
6872 return;
6873
6874 -- Here for case expression
6875
6876 elsif Nkind (N) = N_Case_Expression then
6877 Bignum_Operands := False;
6878 Long_Long_Integer_Operands := False;
6879 Lo := No_Uint;
6880 Hi := No_Uint;
6881
6882 declare
6883 Alt : Node_Id;
6884 New_Alts : List_Id;
6885 New_Exp : Node_Id;
6886 Rtype : Entity_Id;
6887
6888 begin
6889 -- Loop through expressions applying recursive call
6890
6891 Alt := First (Alternatives (N));
6892 while Present (Alt) loop
6893 declare
6894 Aexp : constant Node_Id := Expression (Alt);
6895
6896 begin
6897 Minimize_Eliminate_Overflow_Checks
6898 (Aexp, Lo, Hi, Top_Level => False);
6899
6900 if Lo = No_Uint then
6901 Bignum_Operands := True;
6902 elsif Etype (Aexp) = LLIB then
6903 Long_Long_Integer_Operands := True;
6904 end if;
6905 end;
6906
6907 Next (Alt);
6908 end loop;
6909
6910 -- If we have no bignum or long long integer operands, it means
6911 -- that none of our dependent expressions could raise overflow.
6912 -- In this case, we simply return with no changes except for
6913 -- resetting the overflow flag, since we are done with overflow
6914 -- checks for this node. We will reset the Analyzed flag so that
6915 -- we will properly reexpand and get the needed expansion for
6916 -- the case expression.
6917
6918 if not (Bignum_Operands or else Long_Long_Integer_Operands) then
6919 Set_Do_Overflow_Check (N, False);
6920 Set_Analyzed (N, False);
6921
6922 -- Otherwise we are going to rebuild the case expression using
6923 -- either bignum or long long integer operands throughout.
6924
6925 else
6926 New_Alts := New_List;
6927 Alt := First (Alternatives (N));
6928 while Present (Alt) loop
6929 if Bignum_Operands then
6930 New_Exp := Convert_To_Bignum (Expression (Alt));
6931 Rtype := RTE (RE_Bignum);
6932 else
6933 New_Exp := Convert_To (LLIB, Expression (Alt));
6934 Rtype := LLIB;
6935 end if;
6936
6937 Append_To (New_Alts,
6938 Make_Case_Expression_Alternative (Sloc (Alt),
6939 Actions => No_List,
6940 Discrete_Choices => Discrete_Choices (Alt),
6941 Expression => New_Exp));
6942
6943 Next (Alt);
6944 end loop;
6945
6946 Rewrite (N,
6947 Make_Case_Expression (Loc,
6948 Expression => Expression (N),
6949 Alternatives => New_Alts));
6950
6951 Analyze_And_Resolve (N, Rtype, Suppress => Overflow_Check);
6952 end if;
6953 end;
6954
6955 return;
6956 end if;
6957
6958 -- If we have an arithmetic operator we make recursive calls on the
3cce7f32 6959 -- operands to get the ranges (and to properly process the subtree
6960 -- that lies below us!)
6961
0326b4d4 6962 Minimize_Eliminate_Overflow_Checks
6963 (Right_Opnd (N), Rlo, Rhi, Top_Level => False);
3cce7f32 6964
0326b4d4 6965 if Binary then
6966 Minimize_Eliminate_Overflow_Checks
6967 (Left_Opnd (N), Llo, Lhi, Top_Level => False);
3cce7f32 6968 end if;
6969
6970 -- If either operand is a bignum, then result will be a bignum
6971
6972 if Rlo = No_Uint or else (Binary and then Llo = No_Uint) then
6973 Lo := No_Uint;
6974 Hi := No_Uint;
61016a7a 6975 Bignum_Operands := True;
3cce7f32 6976
6977 -- Otherwise compute result range
6978
6979 else
61016a7a 6980 Bignum_Operands := False;
6981
0326b4d4 6982 Long_Long_Integer_Operands :=
6983 Etype (Right_Opnd (N)) = LLIB
6984 or else (Binary and then Etype (Left_Opnd (N)) = LLIB);
6985
3cce7f32 6986 case Nkind (N) is
6987
6988 -- Absolute value
6989
6990 when N_Op_Abs =>
6991 Lo := Uint_0;
de922300 6992 Hi := UI_Max (abs Rlo, abs Rhi);
3cce7f32 6993
6994 -- Addition
6995
6996 when N_Op_Add =>
6997 Lo := Llo + Rlo;
6998 Hi := Lhi + Rhi;
6999
7000 -- Division
7001
7002 when N_Op_Divide =>
2fe22c69 7003
7004 -- Following seems awfully complex, can it be simplified ???
7005
7006 Hi := No_Uint;
7007 Lo := No_Uint;
7008
7009 declare
7010 S : Uint;
7011
7012 begin
7013 -- First work on finding big absolute result values. These
7014 -- come from dividing large numbers (which we have in Llo
7015 -- and Lhi) by small values, which we need to figure out.
7016
7017 -- Case where right operand can be positive
7018
7019 if Rhi > 0 then
7020
7021 -- Find smallest positive divisor
7022
7023 if Rlo > 0 then
7024 S := Rlo;
7025 else
7026 S := Uint_1;
7027 end if;
7028
7029 -- Big negative value divided by small positive value
7030 -- generates a candidate for lowest possible result.
7031
7032 if Llo < 0 then
7033 Min (Lo, Llo / S);
7034 end if;
7035
7036 -- Big positive value divided by small positive value
7037 -- generates a candidate for highest possible result.
7038
7039 if Lhi > 0 then
7040 Max (Hi, Lhi / S);
7041 end if;
7042 end if;
7043
7044 -- Case where right operand can be negative
7045
7046 if Rlo < 0 then
7047
7048 -- Find smallest absolute value negative divisor
7049
7050 if Rhi < 0 then
7051 S := Rhi;
7052 else
7053 S := -Uint_1;
7054 end if;
7055
7056 -- Big negative value divided by small negative value
7057 -- generates a candidate for largest possible result.
7058
7059 if Llo < 0 then
7060 Max (Hi, Llo / S);
7061 end if;
7062
7063 -- Big positive value divided by small negative value
7064 -- generates a candidate for lowest possible result.
7065
7066 if Lhi > 0 then
7067 Min (Lo, Lhi / S);
7068 end if;
7069 end if;
7070
7071 -- Now work on finding small absolute result values. These
7072 -- come from dividing small numbers, which we need to figure
7073 -- out, by large values (which we have in Rlo, Rhi).
7074
7075 -- Case where left operand can be positive
7076
7077 if Lhi > 0 then
7078
7079 -- Find smallest positive dividend
7080
7081 if Llo > 0 then
7082 S := Llo;
7083 else
7084 S := Uint_1;
7085 end if;
7086
7087 -- Small positive values divided by large negative values
7088 -- generate candidates for low results.
7089
7090 if Rlo < 0 then
7091 Min (Lo, S / Rlo);
7092 end if;
7093
7094 -- Small positive values divided by large positive values
7095 -- generate candidates for high results.
7096
7097 if Rhi > 0 then
7098 Max (Hi, S / Rhi);
7099 end if;
7100 end if;
7101
7102 -- Case where left operand can be negative
7103
7104 if Llo < 0 then
7105
7106 -- Find smallest absolute value negative dividend
7107
7108 if Lhi < 0 then
7109 S := Lhi;
7110 else
7111 S := -Uint_1;
7112 end if;
7113
7114 -- Small negative value divided by large negative value
7115 -- generates a candidate for highest possible result.
7116
7117 if Rlo < 0 then
7118 Max (Hi, Rlo / S);
7119 end if;
7120
7121 -- Small negative value divided by large positive value
7122 -- generates a candidate for lowest possible result.
7123
7124 if Rhi > 0 then
7125 Min (Lo, Rhi / S);
7126 end if;
7127 end if;
7128
7129 -- Finally, if neither Lo or Hi set (happens if the right
7130 -- operand is always zero for example), then set 0 .. 0.
7131
7132 if Lo = No_Uint and then Hi = No_Uint then
7133 Lo := Uint_0;
7134 Hi := Uint_0;
7135
7136 -- If one bound set and not the other copy
7137
7138 elsif Lo = No_Uint then
7139 Lo := Hi;
7140
7141 elsif Hi = No_Uint then
7142 Hi := Lo;
7143 end if;
7144 end;
3cce7f32 7145
7146 -- Exponentiation
7147
7148 when N_Op_Expon =>
de922300 7149
7150 -- Discard negative values for the exponent, since they will
7151 -- simply result in an exception in any case.
7152
7153 if Rhi < 0 then
7154 Rhi := Uint_0;
7155 elsif Rlo < 0 then
7156 Rlo := Uint_0;
7157 end if;
7158
7159 -- Estimate number of bits in result before we go computing
7160 -- giant useless bounds. Basically the number of bits in the
7161 -- result is the number of bits in the base multiplied by the
7162 -- value of the exponent. If this is big enough that the result
7163 -- definitely won't fit in Long_Long_Integer, switch to bignum
7164 -- mode immediately, and avoid computing giant bounds.
7165
7166 -- The comparison here is approximate, but conservative, it
7167 -- only clicks on cases that are sure to exceed the bounds.
7168
7169 if Num_Bits (UI_Max (abs Llo, abs Lhi)) * Rhi + 1 > 100 then
7170 Lo := No_Uint;
7171 Hi := No_Uint;
7172
7173 -- If right operand is zero then result is 1
7174
7175 elsif Rhi = 0 then
7176 Lo := Uint_1;
7177 Hi := Uint_1;
7178
7179 else
7180 -- High bound comes either from exponentiation of largest
7181 -- positive value to largest exponent value, or from the
7182 -- exponentiation of most negative value to an odd exponent.
7183
7184 declare
7185 Hi1, Hi2 : Uint;
7186
7187 begin
7188 if Lhi >= 0 then
7189 Hi1 := Lhi ** Rhi;
7190 else
7191 Hi1 := Uint_0;
7192 end if;
7193
7194 if Llo < 0 then
7195 if Rhi mod 2 = 0 then
7196 Hi2 := Llo ** (Rhi - 1);
7197 else
7198 Hi2 := Llo ** Rhi;
7199 end if;
7200 else
7201 Hi2 := Uint_0;
7202 end if;
7203
7204 Hi := UI_Max (Hi1, Hi2);
7205 end;
7206
7207 -- Result can only be negative if base can be negative
7208
7209 if Llo < 0 then
7210 if UI_Mod (Rhi, 2) = 0 then
7211 Lo := Llo ** (Rhi - 1);
7212 else
7213 Lo := Llo ** Rhi;
7214 end if;
7215
7216 -- Otherwise low bound is minimium ** minimum
7217
7218 else
7219 Lo := Llo ** Rlo;
7220 end if;
7221 end if;
3cce7f32 7222
7223 -- Negation
7224
7225 when N_Op_Minus =>
7226 Lo := -Rhi;
7227 Hi := -Rlo;
7228
7229 -- Mod
7230
7231 when N_Op_Mod =>
2fe22c69 7232 declare
7233 Maxabs : constant Uint := UI_Max (abs Rlo, abs Rhi);
7234 -- This is the maximum absolute value of the result
7235
7236 begin
7237 Lo := Uint_0;
7238 Hi := Uint_0;
7239
7240 -- The result depends only on the sign and magnitude of
7241 -- the right operand, it does not depend on the sign or
7242 -- magnitude of the left operand.
7243
7244 if Rlo < 0 then
7245 Lo := -Maxabs;
7246 end if;
7247
7248 if Rhi > 0 then
7249 Hi := Maxabs;
7250 end if;
7251 end;
3cce7f32 7252
7253 -- Multiplication
7254
7255 when N_Op_Multiply =>
49b3a812 7256
7257 -- Possible bounds of multiplication must come from multiplying
7258 -- end values of the input ranges (four possibilities).
7259
7260 declare
7261 Mrk : constant Uintp.Save_Mark := Mark;
7262 -- Mark so we can release the Ev values
7263
7264 Ev1 : constant Uint := Llo * Rlo;
7265 Ev2 : constant Uint := Llo * Rhi;
7266 Ev3 : constant Uint := Lhi * Rlo;
7267 Ev4 : constant Uint := Lhi * Rhi;
7268
7269 begin
7270 Lo := UI_Min (UI_Min (Ev1, Ev2), UI_Min (Ev3, Ev4));
7271 Hi := UI_Max (UI_Max (Ev1, Ev2), UI_Max (Ev3, Ev4));
7272
7273 -- Release the Ev values
7274
7275 Release_And_Save (Mrk, Lo, Hi);
7276 end;
3cce7f32 7277
7278 -- Plus operator (affirmation)
7279
7280 when N_Op_Plus =>
7281 Lo := Rlo;
7282 Hi := Rhi;
7283
7284 -- Remainder
7285
7286 when N_Op_Rem =>
2fe22c69 7287 declare
7288 Maxabs : constant Uint := UI_Max (abs Rlo, abs Rhi);
7289 -- This is the maximum absolute value of the result. Note
7290 -- that the result range does not depend on the sign of B.
7291
7292 begin
7293 Lo := Uint_0;
7294 Hi := Uint_0;
7295
7296 -- Case of left operand negative, which results in a range
7297 -- of -Maxabs .. 0 for those negative values. If there are
7298 -- no negative values then Lo value of result is always 0.
7299
7300 if Llo < 0 then
7301 Lo := -Maxabs;
7302 end if;
7303
7304 -- Case of left operand positive
7305
7306 if Lhi > 0 then
7307 Hi := Maxabs;
7308 end if;
7309 end;
3cce7f32 7310
7311 -- Subtract
7312
7313 when N_Op_Subtract =>
7314 Lo := Llo - Rhi;
7315 Hi := Lhi - Rlo;
7316
7317 -- Nothing else should be possible
7318
7319 when others =>
7320 raise Program_Error;
3cce7f32 7321 end case;
7322 end if;
7323
7324 -- Case where we do the operation in Bignum mode. This happens either
7325 -- because one of our operands is in Bignum mode already, or because
de922300 7326 -- the computed bounds are outside the bounds of Long_Long_Integer,
7327 -- which in some cases can be indicated by Hi and Lo being No_Uint.
3cce7f32 7328
7329 -- Note: we could do better here and in some cases switch back from
7330 -- Bignum mode to normal mode, e.g. big mod 2 must be in the range
7331 -- 0 .. 1, but the cases are rare and it is not worth the effort.
7332 -- Failing to do this switching back is only an efficiency issue.
7333
3cce7f32 7334 if Lo = No_Uint or else Lo < LLLo or else Hi > LLHi then
7335
61016a7a 7336 -- OK, we are definitely outside the range of Long_Long_Integer. The
7337 -- question is whether to move into Bignum mode, or remain the domain
7338 -- of Long_Long_Integer, signalling that an overflow check is needed.
7339
7340 -- Obviously in MINIMIZED mode we stay with LLI, since we are not in
7341 -- the Bignum business. In ELIMINATED mode, we will normally move
7342 -- into Bignum mode, but there is an exception if neither of our
7343 -- operands is Bignum now, and we are at the top level (Top_Level
7344 -- set True). In this case, there is no point in moving into Bignum
7345 -- mode to prevent overflow if the caller will immediately convert
7346 -- the Bignum value back to LLI with an overflow check. It's more
7347 -- efficient to stay in LLI mode with an overflow check.
7348
7349 if Check_Mode = Minimized
7350 or else (Top_Level and not Bignum_Operands)
7351 then
3cce7f32 7352 Enable_Overflow_Check (N);
7353
61016a7a 7354 -- Since we are doing an overflow check, the result has to be in
7355 -- Long_Long_Integer mode, so adjust the possible range to reflect
7356 -- this. Note these calls also change No_Uint values from the top
7357 -- level case to LLI bounds.
7358
7359 Max (Lo, LLLo);
7360 Min (Hi, LLHi);
7361
7362 -- Otherwise we are in ELIMINATED mode and we switch to Bignum mode
3cce7f32 7363
7364 else
7365 pragma Assert (Check_Mode = Eliminated);
7366
7367 declare
7368 Fent : Entity_Id;
7369 Args : List_Id;
7370
7371 begin
7372 case Nkind (N) is
7373 when N_Op_Abs =>
7374 Fent := RTE (RE_Big_Abs);
7375
7376 when N_Op_Add =>
7377 Fent := RTE (RE_Big_Add);
7378
7379 when N_Op_Divide =>
7380 Fent := RTE (RE_Big_Div);
7381
7382 when N_Op_Expon =>
7383 Fent := RTE (RE_Big_Exp);
7384
7385 when N_Op_Minus =>
7386 Fent := RTE (RE_Big_Neg);
7387
7388 when N_Op_Mod =>
7389 Fent := RTE (RE_Big_Mod);
7390
7391 when N_Op_Multiply =>
7392 Fent := RTE (RE_Big_Mul);
7393
7394 when N_Op_Rem =>
7395 Fent := RTE (RE_Big_Rem);
7396
7397 when N_Op_Subtract =>
7398 Fent := RTE (RE_Big_Sub);
7399
7400 -- Anything else is an internal error, this includes the
7401 -- N_Op_Plus case, since how can plus cause the result
7402 -- to be out of range if the operand is in range?
7403
7404 when others =>
7405 raise Program_Error;
7406 end case;
7407
7408 -- Construct argument list for Bignum call, converting our
7409 -- operands to Bignum form if they are not already there.
7410
7411 Args := New_List;
7412
7413 if Binary then
7414 Append_To (Args, Convert_To_Bignum (Left_Opnd (N)));
7415 end if;
7416
7417 Append_To (Args, Convert_To_Bignum (Right_Opnd (N)));
7418
7419 -- Now rewrite the arithmetic operator with a call to the
7420 -- corresponding bignum function.
7421
7422 Rewrite (N,
7423 Make_Function_Call (Loc,
7424 Name => New_Occurrence_Of (Fent, Loc),
7425 Parameter_Associations => Args));
7426 Analyze_And_Resolve (N, RTE (RE_Bignum));
61016a7a 7427
7428 -- Indicate result is Bignum mode
7429
7430 Lo := No_Uint;
7431 Hi := No_Uint;
de922300 7432 return;
3cce7f32 7433 end;
7434 end if;
7435
7436 -- Otherwise we are in range of Long_Long_Integer, so no overflow
de922300 7437 -- check is required, at least not yet.
3cce7f32 7438
7439 else
de922300 7440 Set_Do_Overflow_Check (N, False);
7441 end if;
3cce7f32 7442
0326b4d4 7443 -- If Result is in range of the result type, and we don't have any
7444 -- Long_Long_Integer operands, then overflow checking is not needed
7445 -- and we have nothing to do (we have already reset Do_Overflow_Check).
7446
7447 if In_Result_Range and not Long_Long_Integer_Operands then
7448 return;
7449 end if;
7450
de922300 7451 -- Here we will do the operation in Long_Long_Integer. We do this even
7452 -- if we know an overflow check is required, better to do this in long
7453 -- long integer mode, since we are less likely to overflow!
3cce7f32 7454
de922300 7455 -- Convert right or only operand to Long_Long_Integer, except that
7456 -- we do not touch the exponentiation right operand.
3cce7f32 7457
de922300 7458 if Nkind (N) /= N_Op_Expon then
7459 Convert_To_And_Rewrite (LLIB, Right_Opnd (N));
7460 end if;
3cce7f32 7461
de922300 7462 -- Convert left operand to Long_Long_Integer for binary case
49b3a812 7463
de922300 7464 if Binary then
7465 Convert_To_And_Rewrite (LLIB, Left_Opnd (N));
7466 end if;
7467
7468 -- Reset node to unanalyzed
7469
7470 Set_Analyzed (N, False);
7471 Set_Etype (N, Empty);
7472 Set_Entity (N, Empty);
7473
2fe22c69 7474 -- Now analyze this new node. This reanalysis will complete processing
7475 -- for the node. In particular we will complete the expansion of an
7476 -- exponentiation operator (e.g. changing A ** 2 to A * A), and also
7477 -- we will complete any division checks (since we have not changed the
7478 -- setting of the Do_Division_Check flag).
3cce7f32 7479
2fe22c69 7480 -- If no overflow check, suppress overflow check to avoid an infinite
7481 -- recursion into this procedure.
3cce7f32 7482
de922300 7483 if not Do_Overflow_Check (N) then
2fe22c69 7484 Analyze_And_Resolve (N, LLIB, Suppress => Overflow_Check);
de922300 7485
7486 -- If an overflow check is required, do it in normal CHECKED mode.
2fe22c69 7487 -- That avoids an infinite recursion, making sure we get a normal
7488 -- overflow check.
de922300 7489
7490 else
7491 declare
7492 SG : constant Overflow_Check_Type :=
7493 Scope_Suppress.Overflow_Checks_General;
7494 SA : constant Overflow_Check_Type :=
7495 Scope_Suppress.Overflow_Checks_Assertions;
7496 begin
7497 Scope_Suppress.Overflow_Checks_General := Checked;
7498 Scope_Suppress.Overflow_Checks_Assertions := Checked;
7499 Analyze_And_Resolve (N, LLIB);
7500 Scope_Suppress.Overflow_Checks_General := SG;
7501 Scope_Suppress.Overflow_Checks_Assertions := SA;
7502 end;
3cce7f32 7503 end if;
7504 end Minimize_Eliminate_Overflow_Checks;
7505
7506 -------------------------
7507 -- Overflow_Check_Mode --
7508 -------------------------
7509
7510 function Overflow_Check_Mode (E : Entity_Id) return Overflow_Check_Type is
ee6ba406 7511 begin
724d2bd8 7512 -- Check overflow suppressed on entity
7513
9dfe12ae 7514 if Present (E) and then Checks_May_Be_Suppressed (E) then
724d2bd8 7515 if Is_Check_Suppressed (E, Overflow_Check) then
3cce7f32 7516 return Suppressed;
724d2bd8 7517 end if;
7518 end if;
7519
7520 -- Else return appropriate scope setting
7521
7522 if In_Assertion_Expr = 0 then
3cce7f32 7523 return Scope_Suppress.Overflow_Checks_General;
9dfe12ae 7524 else
3cce7f32 7525 return Scope_Suppress.Overflow_Checks_Assertions;
9dfe12ae 7526 end if;
3cce7f32 7527 end Overflow_Check_Mode;
7528
7529 --------------------------------
7530 -- Overflow_Checks_Suppressed --
7531 --------------------------------
7532
7533 function Overflow_Checks_Suppressed (E : Entity_Id) return Boolean is
7534 begin
7535 return Overflow_Check_Mode (E) = Suppressed;
ee6ba406 7536 end Overflow_Checks_Suppressed;
fc75802a 7537
ee6ba406 7538 -----------------------------
7539 -- Range_Checks_Suppressed --
7540 -----------------------------
7541
7542 function Range_Checks_Suppressed (E : Entity_Id) return Boolean is
7543 begin
9dfe12ae 7544 if Present (E) then
7545
7546 -- Note: for now we always suppress range checks on Vax float types,
7547 -- since Gigi does not know how to generate these checks.
7548
7549 if Vax_Float (E) then
7550 return True;
7551 elsif Kill_Range_Checks (E) then
7552 return True;
7553 elsif Checks_May_Be_Suppressed (E) then
7554 return Is_Check_Suppressed (E, Range_Check);
7555 end if;
7556 end if;
ee6ba406 7557
fafc6b97 7558 return Scope_Suppress.Suppress (Range_Check);
ee6ba406 7559 end Range_Checks_Suppressed;
7560
0577b0b1 7561 -----------------------------------------
7562 -- Range_Or_Validity_Checks_Suppressed --
7563 -----------------------------------------
7564
7565 -- Note: the coding would be simpler here if we simply made appropriate
7566 -- calls to Range/Validity_Checks_Suppressed, but that would result in
7567 -- duplicated checks which we prefer to avoid.
7568
7569 function Range_Or_Validity_Checks_Suppressed
7570 (Expr : Node_Id) return Boolean
7571 is
7572 begin
7573 -- Immediate return if scope checks suppressed for either check
7574
fafc6b97 7575 if Scope_Suppress.Suppress (Range_Check)
7576 or
7577 Scope_Suppress.Suppress (Validity_Check)
7578 then
0577b0b1 7579 return True;
7580 end if;
7581
7582 -- If no expression, that's odd, decide that checks are suppressed,
7583 -- since we don't want anyone trying to do checks in this case, which
7584 -- is most likely the result of some other error.
7585
7586 if No (Expr) then
7587 return True;
7588 end if;
7589
7590 -- Expression is present, so perform suppress checks on type
7591
7592 declare
7593 Typ : constant Entity_Id := Etype (Expr);
7594 begin
7595 if Vax_Float (Typ) then
7596 return True;
7597 elsif Checks_May_Be_Suppressed (Typ)
7598 and then (Is_Check_Suppressed (Typ, Range_Check)
7599 or else
7600 Is_Check_Suppressed (Typ, Validity_Check))
7601 then
7602 return True;
7603 end if;
7604 end;
7605
7606 -- If expression is an entity name, perform checks on this entity
7607
7608 if Is_Entity_Name (Expr) then
7609 declare
7610 Ent : constant Entity_Id := Entity (Expr);
7611 begin
7612 if Checks_May_Be_Suppressed (Ent) then
7613 return Is_Check_Suppressed (Ent, Range_Check)
7614 or else Is_Check_Suppressed (Ent, Validity_Check);
7615 end if;
7616 end;
7617 end if;
7618
7619 -- If we fall through, no checks suppressed
7620
7621 return False;
7622 end Range_Or_Validity_Checks_Suppressed;
7623
226494a3 7624 -------------------
7625 -- Remove_Checks --
7626 -------------------
7627
7628 procedure Remove_Checks (Expr : Node_Id) is
226494a3 7629 function Process (N : Node_Id) return Traverse_Result;
7630 -- Process a single node during the traversal
7631
8f6e4fd5 7632 procedure Traverse is new Traverse_Proc (Process);
7633 -- The traversal procedure itself
226494a3 7634
7635 -------------
7636 -- Process --
7637 -------------
7638
7639 function Process (N : Node_Id) return Traverse_Result is
7640 begin
7641 if Nkind (N) not in N_Subexpr then
7642 return Skip;
7643 end if;
7644
7645 Set_Do_Range_Check (N, False);
7646
7647 case Nkind (N) is
7648 when N_And_Then =>
8f6e4fd5 7649 Traverse (Left_Opnd (N));
226494a3 7650 return Skip;
7651
7652 when N_Attribute_Reference =>
226494a3 7653 Set_Do_Overflow_Check (N, False);
7654
226494a3 7655 when N_Function_Call =>
7656 Set_Do_Tag_Check (N, False);
7657
226494a3 7658 when N_Op =>
7659 Set_Do_Overflow_Check (N, False);
7660
7661 case Nkind (N) is
7662 when N_Op_Divide =>
7663 Set_Do_Division_Check (N, False);
7664
7665 when N_Op_And =>
7666 Set_Do_Length_Check (N, False);
7667
7668 when N_Op_Mod =>
7669 Set_Do_Division_Check (N, False);
7670
7671 when N_Op_Or =>
7672 Set_Do_Length_Check (N, False);
7673
7674 when N_Op_Rem =>
7675 Set_Do_Division_Check (N, False);
7676
7677 when N_Op_Xor =>
7678 Set_Do_Length_Check (N, False);
7679
7680 when others =>
7681 null;
7682 end case;
7683
7684 when N_Or_Else =>
8f6e4fd5 7685 Traverse (Left_Opnd (N));
226494a3 7686 return Skip;
7687
7688 when N_Selected_Component =>
226494a3 7689 Set_Do_Discriminant_Check (N, False);
7690
226494a3 7691 when N_Type_Conversion =>
9dfe12ae 7692 Set_Do_Length_Check (N, False);
7693 Set_Do_Tag_Check (N, False);
226494a3 7694 Set_Do_Overflow_Check (N, False);
226494a3 7695
7696 when others =>
7697 null;
7698 end case;
7699
7700 return OK;
7701 end Process;
7702
7703 -- Start of processing for Remove_Checks
7704
7705 begin
8f6e4fd5 7706 Traverse (Expr);
226494a3 7707 end Remove_Checks;
7708
ee6ba406 7709 ----------------------------
7710 -- Selected_Length_Checks --
7711 ----------------------------
7712
7713 function Selected_Length_Checks
7714 (Ck_Node : Node_Id;
7715 Target_Typ : Entity_Id;
7716 Source_Typ : Entity_Id;
314a23b6 7717 Warn_Node : Node_Id) return Check_Result
ee6ba406 7718 is
7719 Loc : constant Source_Ptr := Sloc (Ck_Node);
7720 S_Typ : Entity_Id;
7721 T_Typ : Entity_Id;
7722 Expr_Actual : Node_Id;
7723 Exptyp : Entity_Id;
7724 Cond : Node_Id := Empty;
7725 Do_Access : Boolean := False;
7726 Wnode : Node_Id := Warn_Node;
7727 Ret_Result : Check_Result := (Empty, Empty);
7728 Num_Checks : Natural := 0;
7729
7730 procedure Add_Check (N : Node_Id);
7731 -- Adds the action given to Ret_Result if N is non-Empty
7732
7733 function Get_E_Length (E : Entity_Id; Indx : Nat) return Node_Id;
7734 function Get_N_Length (N : Node_Id; Indx : Nat) return Node_Id;
314a23b6 7735 -- Comments required ???
ee6ba406 7736
7737 function Same_Bounds (L : Node_Id; R : Node_Id) return Boolean;
7738 -- True for equal literals and for nodes that denote the same constant
5f260d20 7739 -- entity, even if its value is not a static constant. This includes the
9dfe12ae 7740 -- case of a discriminal reference within an init proc. Removes some
5f260d20 7741 -- obviously superfluous checks.
ee6ba406 7742
7743 function Length_E_Cond
7744 (Exptyp : Entity_Id;
7745 Typ : Entity_Id;
314a23b6 7746 Indx : Nat) return Node_Id;
ee6ba406 7747 -- Returns expression to compute:
7748 -- Typ'Length /= Exptyp'Length
7749
7750 function Length_N_Cond
7751 (Expr : Node_Id;
7752 Typ : Entity_Id;
314a23b6 7753 Indx : Nat) return Node_Id;
ee6ba406 7754 -- Returns expression to compute:
7755 -- Typ'Length /= Expr'Length
7756
7757 ---------------
7758 -- Add_Check --
7759 ---------------
7760
7761 procedure Add_Check (N : Node_Id) is
7762 begin
7763 if Present (N) then
7764
7765 -- For now, ignore attempt to place more than 2 checks ???
7766
7767 if Num_Checks = 2 then
7768 return;
7769 end if;
7770
7771 pragma Assert (Num_Checks <= 1);
7772 Num_Checks := Num_Checks + 1;
7773 Ret_Result (Num_Checks) := N;
7774 end if;
7775 end Add_Check;
7776
7777 ------------------
7778 -- Get_E_Length --
7779 ------------------
7780
7781 function Get_E_Length (E : Entity_Id; Indx : Nat) return Node_Id is
00c403ee 7782 SE : constant Entity_Id := Scope (E);
ee6ba406 7783 N : Node_Id;
7784 E1 : Entity_Id := E;
ee6ba406 7785
7786 begin
7787 if Ekind (Scope (E)) = E_Record_Type
7788 and then Has_Discriminants (Scope (E))
7789 then
7790 N := Build_Discriminal_Subtype_Of_Component (E);
7791
7792 if Present (N) then
7793 Insert_Action (Ck_Node, N);
7794 E1 := Defining_Identifier (N);
7795 end if;
7796 end if;
7797
7798 if Ekind (E1) = E_String_Literal_Subtype then
7799 return
7800 Make_Integer_Literal (Loc,
7801 Intval => String_Literal_Length (E1));
7802
00c403ee 7803 elsif SE /= Standard_Standard
7804 and then Ekind (Scope (SE)) = E_Protected_Type
7805 and then Has_Discriminants (Scope (SE))
7806 and then Has_Completion (Scope (SE))
ee6ba406 7807 and then not Inside_Init_Proc
7808 then
ee6ba406 7809 -- If the type whose length is needed is a private component
7810 -- constrained by a discriminant, we must expand the 'Length
7811 -- attribute into an explicit computation, using the discriminal
7812 -- of the current protected operation. This is because the actual
7813 -- type of the prival is constructed after the protected opera-
7814 -- tion has been fully expanded.
7815
7816 declare
7817 Indx_Type : Node_Id;
7818 Lo : Node_Id;
7819 Hi : Node_Id;
7820 Do_Expand : Boolean := False;
7821
7822 begin
7823 Indx_Type := First_Index (E);
7824
7825 for J in 1 .. Indx - 1 loop
7826 Next_Index (Indx_Type);
7827 end loop;
7828
2af58f67 7829 Get_Index_Bounds (Indx_Type, Lo, Hi);
ee6ba406 7830
7831 if Nkind (Lo) = N_Identifier
7832 and then Ekind (Entity (Lo)) = E_In_Parameter
7833 then
7834 Lo := Get_Discriminal (E, Lo);
7835 Do_Expand := True;
7836 end if;
7837
7838 if Nkind (Hi) = N_Identifier
7839 and then Ekind (Entity (Hi)) = E_In_Parameter
7840 then
7841 Hi := Get_Discriminal (E, Hi);
7842 Do_Expand := True;
7843 end if;
7844
7845 if Do_Expand then
7846 if not Is_Entity_Name (Lo) then
9dfe12ae 7847 Lo := Duplicate_Subexpr_No_Checks (Lo);
ee6ba406 7848 end if;
7849
7850 if not Is_Entity_Name (Hi) then
9dfe12ae 7851 Lo := Duplicate_Subexpr_No_Checks (Hi);
ee6ba406 7852 end if;
7853
7854 N :=
7855 Make_Op_Add (Loc,
7856 Left_Opnd =>
7857 Make_Op_Subtract (Loc,
7858 Left_Opnd => Hi,
7859 Right_Opnd => Lo),
7860
7861 Right_Opnd => Make_Integer_Literal (Loc, 1));
7862 return N;
7863
7864 else
7865 N :=
7866 Make_Attribute_Reference (Loc,
7867 Attribute_Name => Name_Length,
7868 Prefix =>
7869 New_Occurrence_Of (E1, Loc));
7870
7871 if Indx > 1 then
7872 Set_Expressions (N, New_List (
7873 Make_Integer_Literal (Loc, Indx)));
7874 end if;
7875
7876 return N;
7877 end if;
7878 end;
7879
7880 else
7881 N :=
7882 Make_Attribute_Reference (Loc,
7883 Attribute_Name => Name_Length,
7884 Prefix =>
7885 New_Occurrence_Of (E1, Loc));
7886
7887 if Indx > 1 then
7888 Set_Expressions (N, New_List (
7889 Make_Integer_Literal (Loc, Indx)));
7890 end if;
7891
7892 return N;
ee6ba406 7893 end if;
7894 end Get_E_Length;
7895
7896 ------------------
7897 -- Get_N_Length --
7898 ------------------
7899
7900 function Get_N_Length (N : Node_Id; Indx : Nat) return Node_Id is
7901 begin
7902 return
7903 Make_Attribute_Reference (Loc,
7904 Attribute_Name => Name_Length,
7905 Prefix =>
9dfe12ae 7906 Duplicate_Subexpr_No_Checks (N, Name_Req => True),
ee6ba406 7907 Expressions => New_List (
7908 Make_Integer_Literal (Loc, Indx)));
ee6ba406 7909 end Get_N_Length;
7910
7911 -------------------
7912 -- Length_E_Cond --
7913 -------------------
7914
7915 function Length_E_Cond
7916 (Exptyp : Entity_Id;
7917 Typ : Entity_Id;
314a23b6 7918 Indx : Nat) return Node_Id
ee6ba406 7919 is
7920 begin
7921 return
7922 Make_Op_Ne (Loc,
7923 Left_Opnd => Get_E_Length (Typ, Indx),
7924 Right_Opnd => Get_E_Length (Exptyp, Indx));
ee6ba406 7925 end Length_E_Cond;
7926
7927 -------------------
7928 -- Length_N_Cond --
7929 -------------------
7930
7931 function Length_N_Cond
7932 (Expr : Node_Id;
7933 Typ : Entity_Id;
314a23b6 7934 Indx : Nat) return Node_Id
ee6ba406 7935 is
7936 begin
7937 return
7938 Make_Op_Ne (Loc,
7939 Left_Opnd => Get_E_Length (Typ, Indx),
7940 Right_Opnd => Get_N_Length (Expr, Indx));
ee6ba406 7941 end Length_N_Cond;
7942
feff2f05 7943 -----------------
7944 -- Same_Bounds --
7945 -----------------
7946
ee6ba406 7947 function Same_Bounds (L : Node_Id; R : Node_Id) return Boolean is
7948 begin
7949 return
7950 (Nkind (L) = N_Integer_Literal
7951 and then Nkind (R) = N_Integer_Literal
7952 and then Intval (L) = Intval (R))
7953
7954 or else
7955 (Is_Entity_Name (L)
7956 and then Ekind (Entity (L)) = E_Constant
7957 and then ((Is_Entity_Name (R)
7958 and then Entity (L) = Entity (R))
7959 or else
7960 (Nkind (R) = N_Type_Conversion
7961 and then Is_Entity_Name (Expression (R))
7962 and then Entity (L) = Entity (Expression (R)))))
7963
7964 or else
7965 (Is_Entity_Name (R)
7966 and then Ekind (Entity (R)) = E_Constant
7967 and then Nkind (L) = N_Type_Conversion
7968 and then Is_Entity_Name (Expression (L))
5f260d20 7969 and then Entity (R) = Entity (Expression (L)))
7970
7971 or else
7972 (Is_Entity_Name (L)
7973 and then Is_Entity_Name (R)
7974 and then Entity (L) = Entity (R)
7975 and then Ekind (Entity (L)) = E_In_Parameter
7976 and then Inside_Init_Proc);
ee6ba406 7977 end Same_Bounds;
7978
7979 -- Start of processing for Selected_Length_Checks
7980
7981 begin
6dbcfcd9 7982 if not Full_Expander_Active then
ee6ba406 7983 return Ret_Result;
7984 end if;
7985
7986 if Target_Typ = Any_Type
7987 or else Target_Typ = Any_Composite
7988 or else Raises_Constraint_Error (Ck_Node)
7989 then
7990 return Ret_Result;
7991 end if;
7992
7993 if No (Wnode) then
7994 Wnode := Ck_Node;
7995 end if;
7996
7997 T_Typ := Target_Typ;
7998
7999 if No (Source_Typ) then
8000 S_Typ := Etype (Ck_Node);
8001 else
8002 S_Typ := Source_Typ;
8003 end if;
8004
8005 if S_Typ = Any_Type or else S_Typ = Any_Composite then
8006 return Ret_Result;
8007 end if;
8008
8009 if Is_Access_Type (T_Typ) and then Is_Access_Type (S_Typ) then
8010 S_Typ := Designated_Type (S_Typ);
8011 T_Typ := Designated_Type (T_Typ);
8012 Do_Access := True;
8013
2af58f67 8014 -- A simple optimization for the null case
ee6ba406 8015
2af58f67 8016 if Known_Null (Ck_Node) then
ee6ba406 8017 return Ret_Result;
8018 end if;
8019 end if;
8020
8021 if Is_Array_Type (T_Typ) and then Is_Array_Type (S_Typ) then
8022 if Is_Constrained (T_Typ) then
8023
92f1631f 8024 -- The checking code to be generated will freeze the corresponding
8025 -- array type. However, we must freeze the type now, so that the
8026 -- freeze node does not appear within the generated if expression,
8027 -- but ahead of it.
ee6ba406 8028
8029 Freeze_Before (Ck_Node, T_Typ);
8030
8031 Expr_Actual := Get_Referenced_Object (Ck_Node);
84d0d4a5 8032 Exptyp := Get_Actual_Subtype (Ck_Node);
ee6ba406 8033
8034 if Is_Access_Type (Exptyp) then
8035 Exptyp := Designated_Type (Exptyp);
8036 end if;
8037
8038 -- String_Literal case. This needs to be handled specially be-
8039 -- cause no index types are available for string literals. The
8040 -- condition is simply:
8041
8042 -- T_Typ'Length = string-literal-length
8043
9dfe12ae 8044 if Nkind (Expr_Actual) = N_String_Literal
8045 and then Ekind (Etype (Expr_Actual)) = E_String_Literal_Subtype
8046 then
ee6ba406 8047 Cond :=
8048 Make_Op_Ne (Loc,
8049 Left_Opnd => Get_E_Length (T_Typ, 1),
8050 Right_Opnd =>
8051 Make_Integer_Literal (Loc,
8052 Intval =>
8053 String_Literal_Length (Etype (Expr_Actual))));
8054
8055 -- General array case. Here we have a usable actual subtype for
8056 -- the expression, and the condition is built from the two types
8057 -- (Do_Length):
8058
8059 -- T_Typ'Length /= Exptyp'Length or else
8060 -- T_Typ'Length (2) /= Exptyp'Length (2) or else
8061 -- T_Typ'Length (3) /= Exptyp'Length (3) or else
8062 -- ...
8063
8064 elsif Is_Constrained (Exptyp) then
8065 declare
9dfe12ae 8066 Ndims : constant Nat := Number_Dimensions (T_Typ);
8067
8068 L_Index : Node_Id;
8069 R_Index : Node_Id;
8070 L_Low : Node_Id;
8071 L_High : Node_Id;
8072 R_Low : Node_Id;
8073 R_High : Node_Id;
ee6ba406 8074 L_Length : Uint;
8075 R_Length : Uint;
9dfe12ae 8076 Ref_Node : Node_Id;
ee6ba406 8077
8078 begin
feff2f05 8079 -- At the library level, we need to ensure that the type of
8080 -- the object is elaborated before the check itself is
8081 -- emitted. This is only done if the object is in the
8082 -- current compilation unit, otherwise the type is frozen
8083 -- and elaborated in its unit.
9dfe12ae 8084
8085 if Is_Itype (Exptyp)
8086 and then
8087 Ekind (Cunit_Entity (Current_Sem_Unit)) = E_Package
8088 and then
8089 not In_Package_Body (Cunit_Entity (Current_Sem_Unit))
d66aa9f6 8090 and then In_Open_Scopes (Scope (Exptyp))
9dfe12ae 8091 then
8092 Ref_Node := Make_Itype_Reference (Sloc (Ck_Node));
8093 Set_Itype (Ref_Node, Exptyp);
8094 Insert_Action (Ck_Node, Ref_Node);
8095 end if;
8096
ee6ba406 8097 L_Index := First_Index (T_Typ);
8098 R_Index := First_Index (Exptyp);
8099
8100 for Indx in 1 .. Ndims loop
8101 if not (Nkind (L_Index) = N_Raise_Constraint_Error
f15731c4 8102 or else
8103 Nkind (R_Index) = N_Raise_Constraint_Error)
ee6ba406 8104 then
8105 Get_Index_Bounds (L_Index, L_Low, L_High);
8106 Get_Index_Bounds (R_Index, R_Low, R_High);
8107
8108 -- Deal with compile time length check. Note that we
8109 -- skip this in the access case, because the access
8110 -- value may be null, so we cannot know statically.
8111
8112 if not Do_Access
8113 and then Compile_Time_Known_Value (L_Low)
8114 and then Compile_Time_Known_Value (L_High)
8115 and then Compile_Time_Known_Value (R_Low)
8116 and then Compile_Time_Known_Value (R_High)
8117 then
8118 if Expr_Value (L_High) >= Expr_Value (L_Low) then
8119 L_Length := Expr_Value (L_High) -
8120 Expr_Value (L_Low) + 1;
8121 else
8122 L_Length := UI_From_Int (0);
8123 end if;
8124
8125 if Expr_Value (R_High) >= Expr_Value (R_Low) then
8126 R_Length := Expr_Value (R_High) -
8127 Expr_Value (R_Low) + 1;
8128 else
8129 R_Length := UI_From_Int (0);
8130 end if;
8131
8132 if L_Length > R_Length then
8133 Add_Check
8134 (Compile_Time_Constraint_Error
8135 (Wnode, "too few elements for}?", T_Typ));
8136
8137 elsif L_Length < R_Length then
8138 Add_Check
8139 (Compile_Time_Constraint_Error
8140 (Wnode, "too many elements for}?", T_Typ));
8141 end if;
8142
8143 -- The comparison for an individual index subtype
8144 -- is omitted if the corresponding index subtypes
8145 -- statically match, since the result is known to
8146 -- be true. Note that this test is worth while even
8147 -- though we do static evaluation, because non-static
8148 -- subtypes can statically match.
8149
8150 elsif not
8151 Subtypes_Statically_Match
8152 (Etype (L_Index), Etype (R_Index))
8153
8154 and then not
8155 (Same_Bounds (L_Low, R_Low)
8156 and then Same_Bounds (L_High, R_High))
8157 then
8158 Evolve_Or_Else
8159 (Cond, Length_E_Cond (Exptyp, T_Typ, Indx));
8160 end if;
8161
8162 Next (L_Index);
8163 Next (R_Index);
8164 end if;
8165 end loop;
8166 end;
8167
8168 -- Handle cases where we do not get a usable actual subtype that
8169 -- is constrained. This happens for example in the function call
8170 -- and explicit dereference cases. In these cases, we have to get
8171 -- the length or range from the expression itself, making sure we
8172 -- do not evaluate it more than once.
8173
8174 -- Here Ck_Node is the original expression, or more properly the
feff2f05 8175 -- result of applying Duplicate_Expr to the original tree, forcing
8176 -- the result to be a name.
ee6ba406 8177
8178 else
8179 declare
9dfe12ae 8180 Ndims : constant Nat := Number_Dimensions (T_Typ);
ee6ba406 8181
8182 begin
8183 -- Build the condition for the explicit dereference case
8184
8185 for Indx in 1 .. Ndims loop
8186 Evolve_Or_Else
8187 (Cond, Length_N_Cond (Ck_Node, T_Typ, Indx));
8188 end loop;
8189 end;
8190 end if;
8191 end if;
8192 end if;
8193
8194 -- Construct the test and insert into the tree
8195
8196 if Present (Cond) then
8197 if Do_Access then
8198 Cond := Guard_Access (Cond, Loc, Ck_Node);
8199 end if;
8200
f15731c4 8201 Add_Check
8202 (Make_Raise_Constraint_Error (Loc,
8203 Condition => Cond,
8204 Reason => CE_Length_Check_Failed));
ee6ba406 8205 end if;
8206
8207 return Ret_Result;
ee6ba406 8208 end Selected_Length_Checks;
8209
8210 ---------------------------
8211 -- Selected_Range_Checks --
8212 ---------------------------
8213
8214 function Selected_Range_Checks
8215 (Ck_Node : Node_Id;
8216 Target_Typ : Entity_Id;
8217 Source_Typ : Entity_Id;
314a23b6 8218 Warn_Node : Node_Id) return Check_Result
ee6ba406 8219 is
8220 Loc : constant Source_Ptr := Sloc (Ck_Node);
8221 S_Typ : Entity_Id;
8222 T_Typ : Entity_Id;
8223 Expr_Actual : Node_Id;
8224 Exptyp : Entity_Id;
8225 Cond : Node_Id := Empty;
8226 Do_Access : Boolean := False;
8227 Wnode : Node_Id := Warn_Node;
8228 Ret_Result : Check_Result := (Empty, Empty);
8229 Num_Checks : Integer := 0;
8230
8231 procedure Add_Check (N : Node_Id);
8232 -- Adds the action given to Ret_Result if N is non-Empty
8233
8234 function Discrete_Range_Cond
8235 (Expr : Node_Id;
314a23b6 8236 Typ : Entity_Id) return Node_Id;
ee6ba406 8237 -- Returns expression to compute:
8238 -- Low_Bound (Expr) < Typ'First
8239 -- or else
8240 -- High_Bound (Expr) > Typ'Last
8241
8242 function Discrete_Expr_Cond
8243 (Expr : Node_Id;
314a23b6 8244 Typ : Entity_Id) return Node_Id;
ee6ba406 8245 -- Returns expression to compute:
8246 -- Expr < Typ'First
8247 -- or else
8248 -- Expr > Typ'Last
8249
8250 function Get_E_First_Or_Last
3cb12758 8251 (Loc : Source_Ptr;
8252 E : Entity_Id;
ee6ba406 8253 Indx : Nat;
314a23b6 8254 Nam : Name_Id) return Node_Id;
79212397 8255 -- Returns an attribute reference
ee6ba406 8256 -- E'First or E'Last
79212397 8257 -- with a source location of Loc.
f73ee678 8258 --
79212397 8259 -- Nam is Name_First or Name_Last, according to which attribute is
8260 -- desired. If Indx is non-zero, it is passed as a literal in the
8261 -- Expressions of the attribute reference (identifying the desired
8262 -- array dimension).
ee6ba406 8263
8264 function Get_N_First (N : Node_Id; Indx : Nat) return Node_Id;
8265 function Get_N_Last (N : Node_Id; Indx : Nat) return Node_Id;
8266 -- Returns expression to compute:
9dfe12ae 8267 -- N'First or N'Last using Duplicate_Subexpr_No_Checks
ee6ba406 8268
8269 function Range_E_Cond
8270 (Exptyp : Entity_Id;
8271 Typ : Entity_Id;
8272 Indx : Nat)
8273 return Node_Id;
8274 -- Returns expression to compute:
8275 -- Exptyp'First < Typ'First or else Exptyp'Last > Typ'Last
8276
8277 function Range_Equal_E_Cond
8278 (Exptyp : Entity_Id;
8279 Typ : Entity_Id;
314a23b6 8280 Indx : Nat) return Node_Id;
ee6ba406 8281 -- Returns expression to compute:
8282 -- Exptyp'First /= Typ'First or else Exptyp'Last /= Typ'Last
8283
8284 function Range_N_Cond
8285 (Expr : Node_Id;
8286 Typ : Entity_Id;
314a23b6 8287 Indx : Nat) return Node_Id;
ee6ba406 8288 -- Return expression to compute:
8289 -- Expr'First < Typ'First or else Expr'Last > Typ'Last
8290
8291 ---------------
8292 -- Add_Check --
8293 ---------------
8294
8295 procedure Add_Check (N : Node_Id) is
8296 begin
8297 if Present (N) then
8298
8299 -- For now, ignore attempt to place more than 2 checks ???
8300
8301 if Num_Checks = 2 then
8302 return;
8303 end if;
8304
8305 pragma Assert (Num_Checks <= 1);
8306 Num_Checks := Num_Checks + 1;
8307 Ret_Result (Num_Checks) := N;
8308 end if;
8309 end Add_Check;
8310
8311 -------------------------
8312 -- Discrete_Expr_Cond --
8313 -------------------------
8314
8315 function Discrete_Expr_Cond
8316 (Expr : Node_Id;
314a23b6 8317 Typ : Entity_Id) return Node_Id
ee6ba406 8318 is
8319 begin
8320 return
8321 Make_Or_Else (Loc,
8322 Left_Opnd =>
8323 Make_Op_Lt (Loc,
8324 Left_Opnd =>
9dfe12ae 8325 Convert_To (Base_Type (Typ),
8326 Duplicate_Subexpr_No_Checks (Expr)),
ee6ba406 8327 Right_Opnd =>
8328 Convert_To (Base_Type (Typ),
3cb12758 8329 Get_E_First_Or_Last (Loc, Typ, 0, Name_First))),
ee6ba406 8330
8331 Right_Opnd =>
8332 Make_Op_Gt (Loc,
8333 Left_Opnd =>
9dfe12ae 8334 Convert_To (Base_Type (Typ),
8335 Duplicate_Subexpr_No_Checks (Expr)),
ee6ba406 8336 Right_Opnd =>
8337 Convert_To
8338 (Base_Type (Typ),
3cb12758 8339 Get_E_First_Or_Last (Loc, Typ, 0, Name_Last))));
ee6ba406 8340 end Discrete_Expr_Cond;
8341
8342 -------------------------
8343 -- Discrete_Range_Cond --
8344 -------------------------
8345
8346 function Discrete_Range_Cond
8347 (Expr : Node_Id;
314a23b6 8348 Typ : Entity_Id) return Node_Id
ee6ba406 8349 is
8350 LB : Node_Id := Low_Bound (Expr);
8351 HB : Node_Id := High_Bound (Expr);
8352
8353 Left_Opnd : Node_Id;
8354 Right_Opnd : Node_Id;
8355
8356 begin
8357 if Nkind (LB) = N_Identifier
feff2f05 8358 and then Ekind (Entity (LB)) = E_Discriminant
8359 then
ee6ba406 8360 LB := New_Occurrence_Of (Discriminal (Entity (LB)), Loc);
8361 end if;
8362
ee6ba406 8363 Left_Opnd :=
8364 Make_Op_Lt (Loc,
8365 Left_Opnd =>
8366 Convert_To
9dfe12ae 8367 (Base_Type (Typ), Duplicate_Subexpr_No_Checks (LB)),
ee6ba406 8368
8369 Right_Opnd =>
8370 Convert_To
3cb12758 8371 (Base_Type (Typ),
8372 Get_E_First_Or_Last (Loc, Typ, 0, Name_First)));
ee6ba406 8373
ba9b1a39 8374 if Nkind (HB) = N_Identifier
8375 and then Ekind (Entity (HB)) = E_Discriminant
ee6ba406 8376 then
ba9b1a39 8377 HB := New_Occurrence_Of (Discriminal (Entity (HB)), Loc);
ee6ba406 8378 end if;
8379
8380 Right_Opnd :=
8381 Make_Op_Gt (Loc,
8382 Left_Opnd =>
8383 Convert_To
9dfe12ae 8384 (Base_Type (Typ), Duplicate_Subexpr_No_Checks (HB)),
ee6ba406 8385
8386 Right_Opnd =>
8387 Convert_To
8388 (Base_Type (Typ),
3cb12758 8389 Get_E_First_Or_Last (Loc, Typ, 0, Name_Last)));
ee6ba406 8390
8391 return Make_Or_Else (Loc, Left_Opnd, Right_Opnd);
8392 end Discrete_Range_Cond;
8393
8394 -------------------------
8395 -- Get_E_First_Or_Last --
8396 -------------------------
8397
8398 function Get_E_First_Or_Last
3cb12758 8399 (Loc : Source_Ptr;
8400 E : Entity_Id;
ee6ba406 8401 Indx : Nat;
314a23b6 8402 Nam : Name_Id) return Node_Id
ee6ba406 8403 is
3cb12758 8404 Exprs : List_Id;
ee6ba406 8405 begin
3cb12758 8406 if Indx > 0 then
8407 Exprs := New_List (Make_Integer_Literal (Loc, UI_From_Int (Indx)));
ee6ba406 8408 else
3cb12758 8409 Exprs := No_List;
ee6ba406 8410 end if;
8411
3cb12758 8412 return Make_Attribute_Reference (Loc,
8413 Prefix => New_Occurrence_Of (E, Loc),
8414 Attribute_Name => Nam,
8415 Expressions => Exprs);
ee6ba406 8416 end Get_E_First_Or_Last;
8417
8418 -----------------
8419 -- Get_N_First --
8420 -----------------
8421
8422 function Get_N_First (N : Node_Id; Indx : Nat) return Node_Id is
8423 begin
8424 return
8425 Make_Attribute_Reference (Loc,
8426 Attribute_Name => Name_First,
8427 Prefix =>
9dfe12ae 8428 Duplicate_Subexpr_No_Checks (N, Name_Req => True),
ee6ba406 8429 Expressions => New_List (
8430 Make_Integer_Literal (Loc, Indx)));
ee6ba406 8431 end Get_N_First;
8432
8433 ----------------
8434 -- Get_N_Last --
8435 ----------------
8436
8437 function Get_N_Last (N : Node_Id; Indx : Nat) return Node_Id is
8438 begin
8439 return
8440 Make_Attribute_Reference (Loc,
8441 Attribute_Name => Name_Last,
8442 Prefix =>
9dfe12ae 8443 Duplicate_Subexpr_No_Checks (N, Name_Req => True),
ee6ba406 8444 Expressions => New_List (
8445 Make_Integer_Literal (Loc, Indx)));
ee6ba406 8446 end Get_N_Last;
8447
8448 ------------------
8449 -- Range_E_Cond --
8450 ------------------
8451
8452 function Range_E_Cond
8453 (Exptyp : Entity_Id;
8454 Typ : Entity_Id;
314a23b6 8455 Indx : Nat) return Node_Id
ee6ba406 8456 is
8457 begin
8458 return
8459 Make_Or_Else (Loc,
8460 Left_Opnd =>
8461 Make_Op_Lt (Loc,
3cb12758 8462 Left_Opnd =>
8463 Get_E_First_Or_Last (Loc, Exptyp, Indx, Name_First),
8464 Right_Opnd =>
8465 Get_E_First_Or_Last (Loc, Typ, Indx, Name_First)),
ee6ba406 8466
8467 Right_Opnd =>
8468 Make_Op_Gt (Loc,
3cb12758 8469 Left_Opnd =>
8470 Get_E_First_Or_Last (Loc, Exptyp, Indx, Name_Last),
8471 Right_Opnd =>
8472 Get_E_First_Or_Last (Loc, Typ, Indx, Name_Last)));
ee6ba406 8473 end Range_E_Cond;
8474
8475 ------------------------
8476 -- Range_Equal_E_Cond --
8477 ------------------------
8478
8479 function Range_Equal_E_Cond
8480 (Exptyp : Entity_Id;
8481 Typ : Entity_Id;
314a23b6 8482 Indx : Nat) return Node_Id
ee6ba406 8483 is
8484 begin
8485 return
8486 Make_Or_Else (Loc,
8487 Left_Opnd =>
8488 Make_Op_Ne (Loc,
3cb12758 8489 Left_Opnd =>
8490 Get_E_First_Or_Last (Loc, Exptyp, Indx, Name_First),
8491 Right_Opnd =>
8492 Get_E_First_Or_Last (Loc, Typ, Indx, Name_First)),
8493
ee6ba406 8494 Right_Opnd =>
8495 Make_Op_Ne (Loc,
3cb12758 8496 Left_Opnd =>
8497 Get_E_First_Or_Last (Loc, Exptyp, Indx, Name_Last),
8498 Right_Opnd =>
8499 Get_E_First_Or_Last (Loc, Typ, Indx, Name_Last)));
ee6ba406 8500 end Range_Equal_E_Cond;
8501
8502 ------------------
8503 -- Range_N_Cond --
8504 ------------------
8505
8506 function Range_N_Cond
8507 (Expr : Node_Id;
8508 Typ : Entity_Id;
314a23b6 8509 Indx : Nat) return Node_Id
ee6ba406 8510 is
8511 begin
8512 return
8513 Make_Or_Else (Loc,
8514 Left_Opnd =>
8515 Make_Op_Lt (Loc,
3cb12758 8516 Left_Opnd =>
8517 Get_N_First (Expr, Indx),
8518 Right_Opnd =>
8519 Get_E_First_Or_Last (Loc, Typ, Indx, Name_First)),
ee6ba406 8520
8521 Right_Opnd =>
8522 Make_Op_Gt (Loc,
3cb12758 8523 Left_Opnd =>
8524 Get_N_Last (Expr, Indx),
8525 Right_Opnd =>
8526 Get_E_First_Or_Last (Loc, Typ, Indx, Name_Last)));
ee6ba406 8527 end Range_N_Cond;
8528
8529 -- Start of processing for Selected_Range_Checks
8530
8531 begin
6dbcfcd9 8532 if not Full_Expander_Active then
ee6ba406 8533 return Ret_Result;
8534 end if;
8535
8536 if Target_Typ = Any_Type
8537 or else Target_Typ = Any_Composite
8538 or else Raises_Constraint_Error (Ck_Node)
8539 then
8540 return Ret_Result;
8541 end if;
8542
8543 if No (Wnode) then
8544 Wnode := Ck_Node;
8545 end if;
8546
8547 T_Typ := Target_Typ;
8548
8549 if No (Source_Typ) then
8550 S_Typ := Etype (Ck_Node);
8551 else
8552 S_Typ := Source_Typ;
8553 end if;
8554
8555 if S_Typ = Any_Type or else S_Typ = Any_Composite then
8556 return Ret_Result;
8557 end if;
8558
8559 -- The order of evaluating T_Typ before S_Typ seems to be critical
8560 -- because S_Typ can be derived from Etype (Ck_Node), if it's not passed
8561 -- in, and since Node can be an N_Range node, it might be invalid.
8562 -- Should there be an assert check somewhere for taking the Etype of
8563 -- an N_Range node ???
8564
8565 if Is_Access_Type (T_Typ) and then Is_Access_Type (S_Typ) then
8566 S_Typ := Designated_Type (S_Typ);
8567 T_Typ := Designated_Type (T_Typ);
8568 Do_Access := True;
8569
2af58f67 8570 -- A simple optimization for the null case
ee6ba406 8571
2af58f67 8572 if Known_Null (Ck_Node) then
ee6ba406 8573 return Ret_Result;
8574 end if;
8575 end if;
8576
8577 -- For an N_Range Node, check for a null range and then if not
8578 -- null generate a range check action.
8579
8580 if Nkind (Ck_Node) = N_Range then
8581
8582 -- There's no point in checking a range against itself
8583
8584 if Ck_Node = Scalar_Range (T_Typ) then
8585 return Ret_Result;
8586 end if;
8587
8588 declare
8589 T_LB : constant Node_Id := Type_Low_Bound (T_Typ);
8590 T_HB : constant Node_Id := Type_High_Bound (T_Typ);
eefa141b 8591 Known_T_LB : constant Boolean := Compile_Time_Known_Value (T_LB);
8592 Known_T_HB : constant Boolean := Compile_Time_Known_Value (T_HB);
ee6ba406 8593
eefa141b 8594 LB : Node_Id := Low_Bound (Ck_Node);
8595 HB : Node_Id := High_Bound (Ck_Node);
8596 Known_LB : Boolean;
8597 Known_HB : Boolean;
8598
8599 Null_Range : Boolean;
ee6ba406 8600 Out_Of_Range_L : Boolean;
8601 Out_Of_Range_H : Boolean;
8602
8603 begin
eefa141b 8604 -- Compute what is known at compile time
8605
8606 if Known_T_LB and Known_T_HB then
8607 if Compile_Time_Known_Value (LB) then
8608 Known_LB := True;
8609
8610 -- There's no point in checking that a bound is within its
8611 -- own range so pretend that it is known in this case. First
8612 -- deal with low bound.
8613
8614 elsif Ekind (Etype (LB)) = E_Signed_Integer_Subtype
8615 and then Scalar_Range (Etype (LB)) = Scalar_Range (T_Typ)
8616 then
8617 LB := T_LB;
8618 Known_LB := True;
8619
8620 else
8621 Known_LB := False;
8622 end if;
8623
8624 -- Likewise for the high bound
8625
8626 if Compile_Time_Known_Value (HB) then
8627 Known_HB := True;
8628
8629 elsif Ekind (Etype (HB)) = E_Signed_Integer_Subtype
8630 and then Scalar_Range (Etype (HB)) = Scalar_Range (T_Typ)
8631 then
8632 HB := T_HB;
8633 Known_HB := True;
8634
8635 else
8636 Known_HB := False;
8637 end if;
8638 end if;
8639
8640 -- Check for case where everything is static and we can do the
8641 -- check at compile time. This is skipped if we have an access
8642 -- type, since the access value may be null.
8643
8644 -- ??? This code can be improved since you only need to know that
8645 -- the two respective bounds (LB & T_LB or HB & T_HB) are known at
8646 -- compile time to emit pertinent messages.
8647
8648 if Known_T_LB and Known_T_HB and Known_LB and Known_HB
8649 and not Do_Access
ee6ba406 8650 then
8651 -- Floating-point case
8652
8653 if Is_Floating_Point_Type (S_Typ) then
8654 Null_Range := Expr_Value_R (HB) < Expr_Value_R (LB);
8655 Out_Of_Range_L :=
8656 (Expr_Value_R (LB) < Expr_Value_R (T_LB))
eefa141b 8657 or else
ee6ba406 8658 (Expr_Value_R (LB) > Expr_Value_R (T_HB));
8659
8660 Out_Of_Range_H :=
8661 (Expr_Value_R (HB) > Expr_Value_R (T_HB))
eefa141b 8662 or else
ee6ba406 8663 (Expr_Value_R (HB) < Expr_Value_R (T_LB));
8664
8665 -- Fixed or discrete type case
8666
8667 else
8668 Null_Range := Expr_Value (HB) < Expr_Value (LB);
8669 Out_Of_Range_L :=
8670 (Expr_Value (LB) < Expr_Value (T_LB))
eefa141b 8671 or else
ee6ba406 8672 (Expr_Value (LB) > Expr_Value (T_HB));
8673
8674 Out_Of_Range_H :=
8675 (Expr_Value (HB) > Expr_Value (T_HB))
eefa141b 8676 or else
ee6ba406 8677 (Expr_Value (HB) < Expr_Value (T_LB));
8678 end if;
8679
8680 if not Null_Range then
8681 if Out_Of_Range_L then
8682 if No (Warn_Node) then
8683 Add_Check
8684 (Compile_Time_Constraint_Error
8685 (Low_Bound (Ck_Node),
8686 "static value out of range of}?", T_Typ));
8687
8688 else
8689 Add_Check
8690 (Compile_Time_Constraint_Error
8691 (Wnode,
8692 "static range out of bounds of}?", T_Typ));
8693 end if;
8694 end if;
8695
8696 if Out_Of_Range_H then
8697 if No (Warn_Node) then
8698 Add_Check
8699 (Compile_Time_Constraint_Error
8700 (High_Bound (Ck_Node),
8701 "static value out of range of}?", T_Typ));
8702
8703 else
8704 Add_Check
8705 (Compile_Time_Constraint_Error
8706 (Wnode,
8707 "static range out of bounds of}?", T_Typ));
8708 end if;
8709 end if;
ee6ba406 8710 end if;
8711
8712 else
8713 declare
8714 LB : Node_Id := Low_Bound (Ck_Node);
8715 HB : Node_Id := High_Bound (Ck_Node);
8716
8717 begin
feff2f05 8718 -- If either bound is a discriminant and we are within the
8719 -- record declaration, it is a use of the discriminant in a
8720 -- constraint of a component, and nothing can be checked
8721 -- here. The check will be emitted within the init proc.
8722 -- Before then, the discriminal has no real meaning.
8723 -- Similarly, if the entity is a discriminal, there is no
8724 -- check to perform yet.
8725
8726 -- The same holds within a discriminated synchronized type,
8727 -- where the discriminant may constrain a component or an
8728 -- entry family.
ee6ba406 8729
8730 if Nkind (LB) = N_Identifier
0577b0b1 8731 and then Denotes_Discriminant (LB, True)
ee6ba406 8732 then
0577b0b1 8733 if Current_Scope = Scope (Entity (LB))
8734 or else Is_Concurrent_Type (Current_Scope)
8735 or else Ekind (Entity (LB)) /= E_Discriminant
8736 then
ee6ba406 8737 return Ret_Result;
8738 else
8739 LB :=
8740 New_Occurrence_Of (Discriminal (Entity (LB)), Loc);
8741 end if;
8742 end if;
8743
8744 if Nkind (HB) = N_Identifier
0577b0b1 8745 and then Denotes_Discriminant (HB, True)
ee6ba406 8746 then
0577b0b1 8747 if Current_Scope = Scope (Entity (HB))
8748 or else Is_Concurrent_Type (Current_Scope)
8749 or else Ekind (Entity (HB)) /= E_Discriminant
8750 then
ee6ba406 8751 return Ret_Result;
8752 else
8753 HB :=
8754 New_Occurrence_Of (Discriminal (Entity (HB)), Loc);
8755 end if;
8756 end if;
8757
8758 Cond := Discrete_Range_Cond (Ck_Node, T_Typ);
8759 Set_Paren_Count (Cond, 1);
8760
8761 Cond :=
8762 Make_And_Then (Loc,
8763 Left_Opnd =>
8764 Make_Op_Ge (Loc,
9dfe12ae 8765 Left_Opnd => Duplicate_Subexpr_No_Checks (HB),
8766 Right_Opnd => Duplicate_Subexpr_No_Checks (LB)),
ee6ba406 8767 Right_Opnd => Cond);
8768 end;
ee6ba406 8769 end if;
8770 end;
8771
8772 elsif Is_Scalar_Type (S_Typ) then
8773
8774 -- This somewhat duplicates what Apply_Scalar_Range_Check does,
8775 -- except the above simply sets a flag in the node and lets
8776 -- gigi generate the check base on the Etype of the expression.
8777 -- Sometimes, however we want to do a dynamic check against an
8778 -- arbitrary target type, so we do that here.
8779
8780 if Ekind (Base_Type (S_Typ)) /= Ekind (Base_Type (T_Typ)) then
8781 Cond := Discrete_Expr_Cond (Ck_Node, T_Typ);
8782
8783 -- For literals, we can tell if the constraint error will be
8784 -- raised at compile time, so we never need a dynamic check, but
8785 -- if the exception will be raised, then post the usual warning,
8786 -- and replace the literal with a raise constraint error
8787 -- expression. As usual, skip this for access types
8788
8789 elsif Compile_Time_Known_Value (Ck_Node)
8790 and then not Do_Access
8791 then
8792 declare
8793 LB : constant Node_Id := Type_Low_Bound (T_Typ);
8794 UB : constant Node_Id := Type_High_Bound (T_Typ);
8795
8796 Out_Of_Range : Boolean;
8797 Static_Bounds : constant Boolean :=
b6341c67 8798 Compile_Time_Known_Value (LB)
8799 and Compile_Time_Known_Value (UB);
ee6ba406 8800
8801 begin
8802 -- Following range tests should use Sem_Eval routine ???
8803
8804 if Static_Bounds then
8805 if Is_Floating_Point_Type (S_Typ) then
8806 Out_Of_Range :=
8807 (Expr_Value_R (Ck_Node) < Expr_Value_R (LB))
8808 or else
8809 (Expr_Value_R (Ck_Node) > Expr_Value_R (UB));
8810
eefa141b 8811 -- Fixed or discrete type
8812
8813 else
ee6ba406 8814 Out_Of_Range :=
8815 Expr_Value (Ck_Node) < Expr_Value (LB)
8816 or else
8817 Expr_Value (Ck_Node) > Expr_Value (UB);
8818 end if;
8819
eefa141b 8820 -- Bounds of the type are static and the literal is out of
8821 -- range so output a warning message.
ee6ba406 8822
8823 if Out_Of_Range then
8824 if No (Warn_Node) then
8825 Add_Check
8826 (Compile_Time_Constraint_Error
8827 (Ck_Node,
8828 "static value out of range of}?", T_Typ));
8829
8830 else
8831 Add_Check
8832 (Compile_Time_Constraint_Error
8833 (Wnode,
8834 "static value out of range of}?", T_Typ));
8835 end if;
8836 end if;
8837
8838 else
8839 Cond := Discrete_Expr_Cond (Ck_Node, T_Typ);
8840 end if;
8841 end;
8842
8843 -- Here for the case of a non-static expression, we need a runtime
8844 -- check unless the source type range is guaranteed to be in the
8845 -- range of the target type.
8846
8847 else
7a1dabb3 8848 if not In_Subrange_Of (S_Typ, T_Typ) then
ee6ba406 8849 Cond := Discrete_Expr_Cond (Ck_Node, T_Typ);
8850 end if;
8851 end if;
8852 end if;
8853
8854 if Is_Array_Type (T_Typ) and then Is_Array_Type (S_Typ) then
8855 if Is_Constrained (T_Typ) then
8856
8857 Expr_Actual := Get_Referenced_Object (Ck_Node);
8858 Exptyp := Get_Actual_Subtype (Expr_Actual);
8859
8860 if Is_Access_Type (Exptyp) then
8861 Exptyp := Designated_Type (Exptyp);
8862 end if;
8863
8864 -- String_Literal case. This needs to be handled specially be-
8865 -- cause no index types are available for string literals. The
8866 -- condition is simply:
8867
8868 -- T_Typ'Length = string-literal-length
8869
8870 if Nkind (Expr_Actual) = N_String_Literal then
8871 null;
8872
8873 -- General array case. Here we have a usable actual subtype for
8874 -- the expression, and the condition is built from the two types
8875
8876 -- T_Typ'First < Exptyp'First or else
8877 -- T_Typ'Last > Exptyp'Last or else
8878 -- T_Typ'First(1) < Exptyp'First(1) or else
8879 -- T_Typ'Last(1) > Exptyp'Last(1) or else
8880 -- ...
8881
8882 elsif Is_Constrained (Exptyp) then
8883 declare
9dfe12ae 8884 Ndims : constant Nat := Number_Dimensions (T_Typ);
8885
ee6ba406 8886 L_Index : Node_Id;
8887 R_Index : Node_Id;
ee6ba406 8888
8889 begin
8890 L_Index := First_Index (T_Typ);
8891 R_Index := First_Index (Exptyp);
8892
8893 for Indx in 1 .. Ndims loop
8894 if not (Nkind (L_Index) = N_Raise_Constraint_Error
f15731c4 8895 or else
8896 Nkind (R_Index) = N_Raise_Constraint_Error)
ee6ba406 8897 then
ee6ba406 8898 -- Deal with compile time length check. Note that we
8899 -- skip this in the access case, because the access
8900 -- value may be null, so we cannot know statically.
8901
8902 if not
8903 Subtypes_Statically_Match
8904 (Etype (L_Index), Etype (R_Index))
8905 then
8906 -- If the target type is constrained then we
8907 -- have to check for exact equality of bounds
8908 -- (required for qualified expressions).
8909
8910 if Is_Constrained (T_Typ) then
8911 Evolve_Or_Else
8912 (Cond,
8913 Range_Equal_E_Cond (Exptyp, T_Typ, Indx));
ee6ba406 8914 else
8915 Evolve_Or_Else
8916 (Cond, Range_E_Cond (Exptyp, T_Typ, Indx));
8917 end if;
8918 end if;
8919
8920 Next (L_Index);
8921 Next (R_Index);
ee6ba406 8922 end if;
8923 end loop;
8924 end;
8925
8926 -- Handle cases where we do not get a usable actual subtype that
8927 -- is constrained. This happens for example in the function call
8928 -- and explicit dereference cases. In these cases, we have to get
8929 -- the length or range from the expression itself, making sure we
8930 -- do not evaluate it more than once.
8931
8932 -- Here Ck_Node is the original expression, or more properly the
8933 -- result of applying Duplicate_Expr to the original tree,
8934 -- forcing the result to be a name.
8935
8936 else
8937 declare
9dfe12ae 8938 Ndims : constant Nat := Number_Dimensions (T_Typ);
ee6ba406 8939
8940 begin
8941 -- Build the condition for the explicit dereference case
8942
8943 for Indx in 1 .. Ndims loop
8944 Evolve_Or_Else
8945 (Cond, Range_N_Cond (Ck_Node, T_Typ, Indx));
8946 end loop;
8947 end;
ee6ba406 8948 end if;
8949
8950 else
feff2f05 8951 -- For a conversion to an unconstrained array type, generate an
8952 -- Action to check that the bounds of the source value are within
8953 -- the constraints imposed by the target type (RM 4.6(38)). No
8954 -- check is needed for a conversion to an access to unconstrained
8955 -- array type, as 4.6(24.15/2) requires the designated subtypes
8956 -- of the two access types to statically match.
8957
8958 if Nkind (Parent (Ck_Node)) = N_Type_Conversion
8959 and then not Do_Access
8960 then
ee6ba406 8961 declare
8962 Opnd_Index : Node_Id;
8963 Targ_Index : Node_Id;
00c403ee 8964 Opnd_Range : Node_Id;
ee6ba406 8965
8966 begin
feff2f05 8967 Opnd_Index := First_Index (Get_Actual_Subtype (Ck_Node));
ee6ba406 8968 Targ_Index := First_Index (T_Typ);
00c403ee 8969 while Present (Opnd_Index) loop
8970
8971 -- If the index is a range, use its bounds. If it is an
8972 -- entity (as will be the case if it is a named subtype
8973 -- or an itype created for a slice) retrieve its range.
8974
8975 if Is_Entity_Name (Opnd_Index)
8976 and then Is_Type (Entity (Opnd_Index))
8977 then
8978 Opnd_Range := Scalar_Range (Entity (Opnd_Index));
8979 else
8980 Opnd_Range := Opnd_Index;
8981 end if;
8982
8983 if Nkind (Opnd_Range) = N_Range then
9c486805 8984 if Is_In_Range
8985 (Low_Bound (Opnd_Range), Etype (Targ_Index),
8986 Assume_Valid => True)
ee6ba406 8987 and then
8988 Is_In_Range
9c486805 8989 (High_Bound (Opnd_Range), Etype (Targ_Index),
8990 Assume_Valid => True)
ee6ba406 8991 then
8992 null;
8993
feff2f05 8994 -- If null range, no check needed
f2a06be9 8995
9dfe12ae 8996 elsif
00c403ee 8997 Compile_Time_Known_Value (High_Bound (Opnd_Range))
9dfe12ae 8998 and then
00c403ee 8999 Compile_Time_Known_Value (Low_Bound (Opnd_Range))
9dfe12ae 9000 and then
00c403ee 9001 Expr_Value (High_Bound (Opnd_Range)) <
9002 Expr_Value (Low_Bound (Opnd_Range))
9dfe12ae 9003 then
9004 null;
9005
ee6ba406 9006 elsif Is_Out_Of_Range
9c486805 9007 (Low_Bound (Opnd_Range), Etype (Targ_Index),
9008 Assume_Valid => True)
ee6ba406 9009 or else
9010 Is_Out_Of_Range
9c486805 9011 (High_Bound (Opnd_Range), Etype (Targ_Index),
9012 Assume_Valid => True)
ee6ba406 9013 then
9014 Add_Check
9015 (Compile_Time_Constraint_Error
9016 (Wnode, "value out of range of}?", T_Typ));
9017
9018 else
9019 Evolve_Or_Else
9020 (Cond,
9021 Discrete_Range_Cond
00c403ee 9022 (Opnd_Range, Etype (Targ_Index)));
ee6ba406 9023 end if;
9024 end if;
9025
9026 Next_Index (Opnd_Index);
9027 Next_Index (Targ_Index);
9028 end loop;
9029 end;
9030 end if;
9031 end if;
9032 end if;
9033
9034 -- Construct the test and insert into the tree
9035
9036 if Present (Cond) then
9037 if Do_Access then
9038 Cond := Guard_Access (Cond, Loc, Ck_Node);
9039 end if;
9040
f15731c4 9041 Add_Check
9042 (Make_Raise_Constraint_Error (Loc,
eefa141b 9043 Condition => Cond,
9044 Reason => CE_Range_Check_Failed));
ee6ba406 9045 end if;
9046
9047 return Ret_Result;
ee6ba406 9048 end Selected_Range_Checks;
9049
9050 -------------------------------
9051 -- Storage_Checks_Suppressed --
9052 -------------------------------
9053
9054 function Storage_Checks_Suppressed (E : Entity_Id) return Boolean is
9055 begin
9dfe12ae 9056 if Present (E) and then Checks_May_Be_Suppressed (E) then
9057 return Is_Check_Suppressed (E, Storage_Check);
9058 else
fafc6b97 9059 return Scope_Suppress.Suppress (Storage_Check);
9dfe12ae 9060 end if;
ee6ba406 9061 end Storage_Checks_Suppressed;
9062
9063 ---------------------------
9064 -- Tag_Checks_Suppressed --
9065 ---------------------------
9066
9067 function Tag_Checks_Suppressed (E : Entity_Id) return Boolean is
9068 begin
89f1e35c 9069 if Present (E)
9070 and then Checks_May_Be_Suppressed (E)
9071 then
9072 return Is_Check_Suppressed (E, Tag_Check);
9dfe12ae 9073 end if;
9074
fafc6b97 9075 return Scope_Suppress.Suppress (Tag_Check);
ee6ba406 9076 end Tag_Checks_Suppressed;
9077
0577b0b1 9078 --------------------------
9079 -- Validity_Check_Range --
9080 --------------------------
9081
9082 procedure Validity_Check_Range (N : Node_Id) is
9083 begin
9084 if Validity_Checks_On and Validity_Check_Operands then
9085 if Nkind (N) = N_Range then
9086 Ensure_Valid (Low_Bound (N));
9087 Ensure_Valid (High_Bound (N));
9088 end if;
9089 end if;
9090 end Validity_Check_Range;
9091
9092 --------------------------------
9093 -- Validity_Checks_Suppressed --
9094 --------------------------------
9095
9096 function Validity_Checks_Suppressed (E : Entity_Id) return Boolean is
9097 begin
9098 if Present (E) and then Checks_May_Be_Suppressed (E) then
9099 return Is_Check_Suppressed (E, Validity_Check);
9100 else
fafc6b97 9101 return Scope_Suppress.Suppress (Validity_Check);
0577b0b1 9102 end if;
9103 end Validity_Checks_Suppressed;
9104
ee6ba406 9105end Checks;