OSDN Git Service

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