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