OSDN Git Service

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