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