OSDN Git Service

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