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