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