OSDN Git Service

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