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