Branch data Line data Source code
1 : : /* do not edit automatically generated by mc from M2Range. */
2 : : /* M2Range.mod exports procedures which maintain the range checking.
3 : :
4 : : Copyright (C) 2008-2025 Free Software Foundation, Inc.
5 : : Contributed by Gaius Mulley <gaius.mulley@southwales.ac.uk>.
6 : :
7 : : This file is part of GNU Modula-2.
8 : :
9 : : GNU Modula-2 is free software; you can redistribute it and/or modify
10 : : it under the terms of the GNU General Public License as published by
11 : : the Free Software Foundation; either version 3, or (at your option)
12 : : any later version.
13 : :
14 : : GNU Modula-2 is distributed in the hope that it will be useful, but
15 : : WITHOUT ANY WARRANTY; without even the implied warranty of
16 : : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 : : General Public License for more details.
18 : :
19 : : You should have received a copy of the GNU General Public License
20 : : along with GNU Modula-2; see the file COPYING3. If not see
21 : : <http://www.gnu.org/licenses/>. */
22 : :
23 : : #include "config.h"
24 : : #include "system.h"
25 : : #include "gcc-consolidation.h"
26 : :
27 : : #include <stdbool.h>
28 : : # if !defined (PROC_D)
29 : : # define PROC_D
30 : : typedef void (*PROC_t) (void);
31 : : typedef struct { PROC_t proc; } PROC;
32 : : # endif
33 : :
34 : : # if !defined (TRUE)
35 : : # define TRUE (1==1)
36 : : # endif
37 : :
38 : : # if !defined (FALSE)
39 : : # define FALSE (1==0)
40 : : # endif
41 : :
42 : : # include "GStorage.h"
43 : : # include "Gmcrts.h"
44 : : #if defined(__cplusplus)
45 : : # undef NULL
46 : : # define NULL 0
47 : : #endif
48 : : #define _M2Range_C
49 : :
50 : : #include "GM2Range.h"
51 : : # include "GSymbolTable.h"
52 : : # include "GSYSTEM.h"
53 : : # include "Gm2tree.h"
54 : : # include "Gm2linemap.h"
55 : : # include "Gm2type.h"
56 : : # include "Gm2statement.h"
57 : : # include "Gm2expr.h"
58 : : # include "Gm2convert.h"
59 : : # include "Gm2decl.h"
60 : : # include "Gm2builtins.h"
61 : : # include "GM2Debug.h"
62 : : # include "GIndexing.h"
63 : : # include "GStorage.h"
64 : : # include "GM2ALU.h"
65 : : # include "GM2Options.h"
66 : : # include "GM2Error.h"
67 : : # include "GM2ColorString.h"
68 : : # include "GM2MetaError.h"
69 : : # include "GM2LexBuf.h"
70 : : # include "GStrIO.h"
71 : : # include "GNumberIO.h"
72 : : # include "GM2GCCDeclare.h"
73 : : # include "GM2Quads.h"
74 : : # include "GSymbolConversion.h"
75 : : # include "GLists.h"
76 : : # include "GNameKey.h"
77 : : # include "GStdIO.h"
78 : : # include "GDynamicStrings.h"
79 : : # include "GM2GenGCC.h"
80 : : # include "GM2System.h"
81 : : # include "GFormatStrings.h"
82 : : # include "GM2Check.h"
83 : : # include "GM2Base.h"
84 : : # include "GM2CaseList.h"
85 : :
86 : : typedef struct M2Range__T1_r M2Range__T1;
87 : :
88 : : typedef M2Range__T1 *M2Range_Range;
89 : :
90 : : typedef enum {M2Range_assignment, M2Range_returnassignment, M2Range_subrangeassignment, M2Range_inc, M2Range_dec, M2Range_incl, M2Range_excl, M2Range_shift, M2Range_rotate, M2Range_typeindrx, M2Range_typeexpr, M2Range_typeassign, M2Range_typeparam, M2Range_typereturn, M2Range_paramassign, M2Range_staticarraysubscript, M2Range_dynamicarraysubscript, M2Range_forloopbegin, M2Range_forloopto, M2Range_forloopend, M2Range_pointernil, M2Range_noreturn, M2Range_noelse, M2Range_casebounds, M2Range_wholenonposdiv, M2Range_wholenonposmod, M2Range_wholezerodiv, M2Range_wholezerorem, M2Range_none} M2Range_TypeOfRange;
91 : :
92 : : struct M2Range__T1_r {
93 : : M2Range_TypeOfRange type;
94 : : unsigned int des;
95 : : unsigned int expr;
96 : : unsigned int expr2;
97 : : unsigned int byconst;
98 : : unsigned int desLowestType;
99 : : unsigned int exprLowestType;
100 : : unsigned int procedure;
101 : : unsigned int paramNo;
102 : : bool isLeftValue;
103 : : unsigned int dimension;
104 : : unsigned int caseList;
105 : : unsigned int destok;
106 : : unsigned int exprtok;
107 : : unsigned int expr2tok;
108 : : unsigned int byconsttok;
109 : : unsigned int tokenNo;
110 : : unsigned int incrementquad;
111 : : bool errorReported;
112 : : bool strict;
113 : : bool isin;
114 : : bool cancelled;
115 : : unsigned int dependantid;
116 : : };
117 : :
118 : : static unsigned int TopOfRange;
119 : : static Indexing_Index RangeIndex;
120 : : static unsigned int BreakRange;
121 : :
122 : : /*
123 : : InitAssignmentRangeCheck - returns a range check node which
124 : : remembers the information necessary
125 : : so that a range check for des := expr
126 : : can be generated later on.
127 : : */
128 : :
129 : : extern "C" unsigned int M2Range_InitAssignmentRangeCheck (unsigned int tokno, unsigned int des, unsigned int expr, unsigned int destok, unsigned int exprtok);
130 : :
131 : : /*
132 : : InitReturnRangeCheck - returns a range check node which
133 : : remembers the information necessary
134 : : so that a range check for RETURN e
135 : : from procedure, d, can be generated later on.
136 : : */
137 : :
138 : : extern "C" unsigned int M2Range_InitReturnRangeCheck (unsigned int tokno, unsigned int d, unsigned int e);
139 : :
140 : : /*
141 : : InitSubrangeRangeCheck - returns a range check node which
142 : : remembers the information necessary
143 : : so that a range check for d := e
144 : : can be generated later on.
145 : : */
146 : :
147 : : extern "C" unsigned int M2Range_InitSubrangeRangeCheck (unsigned int d, unsigned int e);
148 : :
149 : : /*
150 : : InitStaticArraySubscriptRangeCheck - returns a range check node which
151 : : remembers the information necessary
152 : : so that a range check for d[e]
153 : : can be generated later on.
154 : : */
155 : :
156 : : extern "C" unsigned int M2Range_InitStaticArraySubscriptRangeCheck (unsigned int d, unsigned int e, unsigned int dim);
157 : :
158 : : /*
159 : : InitDynamicArraySubscriptRangeCheck - returns a range check node which
160 : : remembers the information necessary
161 : : so that a range check for d[e]
162 : : can be generated later on.
163 : : */
164 : :
165 : : extern "C" unsigned int M2Range_InitDynamicArraySubscriptRangeCheck (unsigned int d, unsigned int e, unsigned int dim);
166 : :
167 : : /*
168 : : InitIncRangeCheck - returns a range check node which
169 : : remembers the information necessary
170 : : so that a range check for INC(d, e)
171 : : can be generated later on.
172 : : */
173 : :
174 : : extern "C" unsigned int M2Range_InitIncRangeCheck (unsigned int d, unsigned int e);
175 : :
176 : : /*
177 : : InitDecRangeCheck - returns a range check node which
178 : : remembers the information necessary
179 : : so that a range check for DEC(d, e)
180 : : can be generated later on.
181 : : */
182 : :
183 : : extern "C" unsigned int M2Range_InitDecRangeCheck (unsigned int d, unsigned int e);
184 : :
185 : : /*
186 : : InitForLoopBeginRangeCheck - returns a range check node which
187 : : remembers the information necessary
188 : : so that a range check for
189 : : FOR des := expr1 TO expr2 DO
190 : : can be generated later on. expr2 is
191 : : only used to type check with des.
192 : : */
193 : :
194 : : extern "C" unsigned int M2Range_InitForLoopBeginRangeCheck (unsigned int des, unsigned int destok, unsigned int expr1, unsigned int expr1tok, unsigned int expr2, unsigned int expr2tok, unsigned int byconst, unsigned int byconsttok);
195 : :
196 : : /*
197 : : PutRangeForIncrement - places incrementquad into the range record.
198 : : */
199 : :
200 : : extern "C" void M2Range_PutRangeForIncrement (unsigned int range, unsigned int incrementquad);
201 : :
202 : : /*
203 : : InitForLoopToRangeCheck - returns a range check node which
204 : : remembers the information necessary
205 : : so that a range check for FOR d := e TO .. DO
206 : : can be generated later on.
207 : : */
208 : :
209 : : extern "C" unsigned int M2Range_InitForLoopToRangeCheck (unsigned int d, unsigned int e);
210 : :
211 : : /*
212 : : InitForLoopEndRangeCheck - returns a range check node which
213 : : remembers the information necessary
214 : : so that a range check for
215 : : INC or DEC(d, e)
216 : : can be generated later on.
217 : : */
218 : :
219 : : extern "C" unsigned int M2Range_InitForLoopEndRangeCheck (unsigned int d, unsigned int e);
220 : :
221 : : /*
222 : : InitPointerRangeCheck - creates a pointer # NIL check.
223 : : */
224 : :
225 : : extern "C" unsigned int M2Range_InitPointerRangeCheck (unsigned int tokno, unsigned int d, bool isLeft);
226 : :
227 : : /*
228 : : InitNoReturnRangeCheck - creates a check held in the function
229 : : to detect the absence of a RETURN
230 : : statement at runtime.
231 : : */
232 : :
233 : : extern "C" unsigned int M2Range_InitNoReturnRangeCheck (void);
234 : :
235 : : /*
236 : : InitNoElseRangeCheck - creates a check held at the end of
237 : : a CASE statement without an ELSE
238 : : clause to detect its absence
239 : : at runtime.
240 : : */
241 : :
242 : : extern "C" unsigned int M2Range_InitNoElseRangeCheck (void);
243 : :
244 : : /*
245 : : InitWholeNonPosDivCheck - creates a check expression for non positive
246 : : or zero 2nd operand to division.
247 : : */
248 : :
249 : : extern "C" unsigned int M2Range_InitWholeNonPosDivCheck (unsigned int tokno, unsigned int d, unsigned int e);
250 : :
251 : : /*
252 : : InitWholeNonPosModCheck - creates a check expression for non positive
253 : : or zero 2nd operand to modulus.
254 : : */
255 : :
256 : : extern "C" unsigned int M2Range_InitWholeNonPosModCheck (unsigned int tokno, unsigned int d, unsigned int e);
257 : :
258 : : /*
259 : : InitWholeZeroDivisionCheck - creates a check expression for zero 2nd
260 : : operand for division.
261 : : */
262 : :
263 : : extern "C" unsigned int M2Range_InitWholeZeroDivisionCheck (unsigned int tokno, unsigned int d, unsigned int e);
264 : :
265 : : /*
266 : : InitWholeZeroRemainderCheck - creates a check expression for zero 2nd
267 : : operand for remainder.
268 : : */
269 : :
270 : : extern "C" unsigned int M2Range_InitWholeZeroRemainderCheck (unsigned int tokno, unsigned int d, unsigned int e);
271 : :
272 : : /*
273 : : InitInclCheck - checks to see that bit, e, is type compatible with
274 : : e and also in range.
275 : : */
276 : :
277 : : extern "C" unsigned int M2Range_InitInclCheck (unsigned int d, unsigned int e);
278 : :
279 : : /*
280 : : InitExclCheck - checks to see that bit, e, is type compatible with
281 : : e and also in range.
282 : : */
283 : :
284 : : extern "C" unsigned int M2Range_InitExclCheck (unsigned int d, unsigned int e);
285 : :
286 : : /*
287 : : InitShiftCheck - checks to see that bit, e, is type compatible with
288 : : d and also in range.
289 : : */
290 : :
291 : : extern "C" unsigned int M2Range_InitShiftCheck (unsigned int d, unsigned int e);
292 : :
293 : : /*
294 : : InitRotateCheck - checks to see that bit, e, is type compatible with
295 : : d and also in range.
296 : : */
297 : :
298 : : extern "C" unsigned int M2Range_InitRotateCheck (unsigned int d, unsigned int e);
299 : :
300 : : /*
301 : : InitTypesAssignmentCheck - checks to see that the types of d and e
302 : : are assignment compatible.
303 : : */
304 : :
305 : : extern "C" unsigned int M2Range_InitTypesAssignmentCheck (unsigned int tokno, unsigned int d, unsigned int e);
306 : :
307 : : /*
308 : : InitTypesParameterCheck - checks to see that the types of, d,
309 : : and, e, are parameter compatible.
310 : : */
311 : :
312 : : extern "C" unsigned int M2Range_InitTypesParameterCheck (unsigned int tokno, unsigned int proc, unsigned int paramno, unsigned int formal, unsigned int actual, unsigned int depRangeId);
313 : :
314 : : /*
315 : : InitParameterRangeCheck - checks to see that the types of, d, and, e,
316 : : are parameter compatible.
317 : : */
318 : :
319 : : extern "C" unsigned int M2Range_InitParameterRangeCheck (unsigned int tokno, unsigned int proc, unsigned int paramno, unsigned int formal, unsigned int actual, unsigned int parentRangeId);
320 : :
321 : : /*
322 : : InitTypesExpressionCheck - checks to see that the types of, d, and, e,
323 : : are expression compatible.
324 : : */
325 : :
326 : : extern "C" unsigned int M2Range_InitTypesExpressionCheck (unsigned int tokno, unsigned int d, unsigned int e, bool strict, bool isin);
327 : :
328 : : /*
329 : : InitTypesIndrXCheck - checks to see that the types of d and e
330 : : are assignment compatible. The type checking
331 : : will dereference *e during the type check.
332 : : d = *e.
333 : : */
334 : :
335 : : extern "C" unsigned int M2Range_InitTypesIndrXCheck (unsigned int tokno, unsigned int d, unsigned int e);
336 : :
337 : : /*
338 : : InitTypesReturnTypeCheck - checks to see that the types of des and func
339 : : are assignment compatible.
340 : : */
341 : :
342 : : extern "C" unsigned int M2Range_InitTypesReturnTypeCheck (unsigned int tokno, unsigned int func, unsigned int val);
343 : :
344 : : /*
345 : : InitCaseBounds - creates a case bound range check.
346 : : */
347 : :
348 : : extern "C" unsigned int M2Range_InitCaseBounds (unsigned int b);
349 : :
350 : : /*
351 : : CodeRangeCheck - returns a Tree representing the code for a
352 : : range test defined by, r.
353 : : */
354 : :
355 : : extern "C" void M2Range_CodeRangeCheck (unsigned int r, DynamicStrings_String function);
356 : :
357 : : /*
358 : : FoldRangeCheck - attempts to resolve the range check.
359 : : If it evaluates to true then
360 : : it is replaced by an ErrorOp
361 : : elsif it evaluates to false then
362 : : it is removed
363 : : else
364 : : it is left alone
365 : : */
366 : :
367 : : extern "C" void M2Range_FoldRangeCheck (unsigned int tokenno, unsigned int quad, unsigned int range);
368 : :
369 : : /*
370 : : CodeErrorCheck - returns a Tree calling the approprate exception handler.
371 : : */
372 : :
373 : : extern "C" tree M2Range_CodeErrorCheck (unsigned int r, DynamicStrings_String function, DynamicStrings_String message);
374 : :
375 : : /*
376 : : WriteRangeCheck - displays debugging information about range, r.
377 : : */
378 : :
379 : : extern "C" void M2Range_WriteRangeCheck (unsigned int r);
380 : :
381 : : /*
382 : : OverlapsRange - returns TRUE if a1..a2 overlaps with b1..b2.
383 : : */
384 : :
385 : : extern "C" bool M2Range_OverlapsRange (tree a1, tree a2, tree b1, tree b2);
386 : :
387 : : /*
388 : : IsEqual - returns TRUE if a=b.
389 : : */
390 : :
391 : : extern "C" bool M2Range_IsEqual (tree a, tree b);
392 : :
393 : : /*
394 : : IsGreaterOrEqual - returns TRUE if a>=b.
395 : : */
396 : :
397 : : extern "C" bool M2Range_IsGreaterOrEqual (tree a, tree b);
398 : :
399 : : /*
400 : : IsGreater - returns TRUE if a>b.
401 : : */
402 : :
403 : : extern "C" bool M2Range_IsGreater (tree a, tree b);
404 : :
405 : : /*
406 : : BuildIfCallWholeHandlerLoc - return a Tree containing a runtime test whether, condition, is true.
407 : : */
408 : :
409 : : extern "C" tree M2Range_BuildIfCallWholeHandlerLoc (location_t location, tree condition, const char * scope, const char * message);
410 : :
411 : : /*
412 : : BuildIfCallRealHandlerLoc - return a Tree containing a runtime test whether, condition, is true.
413 : : */
414 : :
415 : : extern "C" tree M2Range_BuildIfCallRealHandlerLoc (location_t location, tree condition, const char * scope, const char * message);
416 : :
417 : : /*
418 : : GetMinMax - returns TRUE if we know the max and min of m2type.
419 : : */
420 : :
421 : : extern "C" bool M2Range_GetMinMax (unsigned int tokenno, unsigned int type, tree *min, tree *max);
422 : : static void gdbhook (void);
423 : :
424 : : /*
425 : : BreakWhenRangeCreated - to be called interactively by gdb.
426 : : */
427 : :
428 : : static void BreakWhenRangeCreated (unsigned int r);
429 : :
430 : : /*
431 : : CheckBreak - if sym = BreakRange then call gdbhook.
432 : : */
433 : :
434 : : static void CheckBreak (unsigned int r);
435 : :
436 : : /*
437 : : IsGreaterOrEqualConversion - tests whether t>=e.
438 : : */
439 : :
440 : : static bool IsGreaterOrEqualConversion (location_t location, unsigned int l, unsigned int d, unsigned int e);
441 : :
442 : : /*
443 : : IsEqualConversion - returns TRUE if a=b.
444 : : */
445 : :
446 : : static bool IsEqualConversion (unsigned int l, unsigned int d, unsigned int e);
447 : :
448 : : /*
449 : : lookupExceptionHandler -
450 : : */
451 : :
452 : : static unsigned int lookupExceptionHandler (M2Range_TypeOfRange type);
453 : :
454 : : /*
455 : : InitRange - returns a new range item.
456 : : */
457 : :
458 : : static unsigned int InitRange (void);
459 : :
460 : : /*
461 : : reportedError - returns whether this is the first time this error has been
462 : : reported.
463 : : */
464 : :
465 : : static bool reportedError (unsigned int r);
466 : :
467 : : /*
468 : : setReported - assigns errorReported to TRUE.
469 : : */
470 : :
471 : : static void setReported (unsigned int r);
472 : :
473 : : /*
474 : : PutRange - initializes contents of, p, to
475 : : d, e and their lowest types.
476 : : It also fills in the current token no
477 : : and returns, p.
478 : : */
479 : :
480 : : static M2Range_Range PutRange (unsigned int tokno, M2Range_Range p, M2Range_TypeOfRange t, unsigned int d, unsigned int e);
481 : :
482 : : /*
483 : : PutRangeDesExpr2 - initializes contents of, p, to
484 : : des, expr1 and their lowest types.
485 : : It also fills in the token numbers for
486 : : des, expr, expr2 and returns, p.
487 : : */
488 : :
489 : : static M2Range_Range PutRangeDesExpr2 (M2Range_Range p, M2Range_TypeOfRange t, unsigned int des, unsigned int destok, unsigned int expr1, unsigned int expr1tok, unsigned int expr2, unsigned int expr2tok, unsigned int byconst, unsigned int byconsttok);
490 : :
491 : : /*
492 : : chooseTokenPos - returns, tokenpos, if it is not the unknown location, otherwise
493 : : it returns GetTokenNo.
494 : : */
495 : :
496 : : static unsigned int chooseTokenPos (unsigned int tokenpos);
497 : :
498 : : /*
499 : : PutRangeNoLow - initializes contents of, p. It
500 : : does not set lowest types as they may be
501 : : unknown at this point.
502 : : */
503 : :
504 : : static M2Range_Range PutRangeNoLow (unsigned int tokpos, M2Range_Range p, M2Range_TypeOfRange t, unsigned int d, unsigned int e);
505 : :
506 : : /*
507 : : PutRangeExpr - initializes contents of, p. It
508 : : does not set lowest types as they may be
509 : : unknown at this point.
510 : : */
511 : :
512 : : static M2Range_Range PutRangeExpr (unsigned int tokpos, M2Range_Range p, M2Range_TypeOfRange t, unsigned int d, unsigned int e, bool strict, bool isin);
513 : :
514 : : /*
515 : : PutRangePointer - initializes contents of, p, to
516 : : d, isLeft and their lowest types.
517 : : It also fills in the current token no
518 : : and returns, p.
519 : : */
520 : :
521 : : static M2Range_Range PutRangePointer (unsigned int tokpos, M2Range_Range p, unsigned int d, bool isLeft);
522 : :
523 : : /*
524 : : PutRangeNoEval - initializes contents of, p, to a non evaluation
525 : : runtime check such as a no else clause or
526 : : no return found in function call.
527 : : */
528 : :
529 : : static M2Range_Range PutRangeNoEval (M2Range_Range p, M2Range_TypeOfRange t);
530 : : static M2Range_Range PutRangeUnary (unsigned int tokno, M2Range_Range p, M2Range_TypeOfRange t, unsigned int d, unsigned int e);
531 : :
532 : : /*
533 : : PutRangeParam - initializes contents of, p, to contain the parameter
534 : : type checking information.
535 : : It also fills in the current token no
536 : : and returns, p.
537 : : */
538 : :
539 : : static M2Range_Range PutRangeParam (unsigned int tokno, M2Range_Range p, M2Range_TypeOfRange t, unsigned int proc, unsigned int paramno, unsigned int formal, unsigned int actual, unsigned int depRangeId);
540 : :
541 : : /*
542 : : PutRangeArraySubscript - initializes contents of, p, to
543 : : d, e and their lowest types. It also
544 : : assigns, dim.
545 : : It also fills in the current token no
546 : : and returns, p.
547 : : */
548 : :
549 : : static M2Range_Range PutRangeArraySubscript (M2Range_Range p, M2Range_TypeOfRange t, unsigned int d, unsigned int e, unsigned int dim);
550 : :
551 : : /*
552 : : PutRangeParamAssign - initializes contents of, p, to contain the parameter
553 : : type checking information.
554 : : It also fills in the current token no
555 : : and returns, p.
556 : : */
557 : :
558 : : static M2Range_Range PutRangeParamAssign (unsigned int tokno, M2Range_Range p, M2Range_TypeOfRange t, unsigned int proc, unsigned int i, unsigned int formal, unsigned int actual, unsigned int parentRangeId);
559 : :
560 : : /*
561 : : FoldNil - attempts to fold the pointer against nil comparison.
562 : : */
563 : :
564 : : static void FoldNil (unsigned int tokenno, unsigned int q, unsigned int r);
565 : :
566 : : /*
567 : : OutOfRange - returns TRUE if expr lies outside min..max.
568 : : */
569 : :
570 : : static bool OutOfRange (unsigned int tokenno, tree min, unsigned int expr, tree max, unsigned int type);
571 : :
572 : : /*
573 : : HandlerExists -
574 : : */
575 : :
576 : : static bool HandlerExists (unsigned int r);
577 : :
578 : : /*
579 : : FoldAssignment - attempts to fold the range violation checks.
580 : : It does not issue errors on type violations as that
581 : : is performed by FoldTypeAssign.
582 : : */
583 : :
584 : : static void FoldAssignment (unsigned int tokenno, unsigned int q, unsigned int r);
585 : :
586 : : /*
587 : : IsCancelled - return the cancelled flag associated with range.
588 : : */
589 : :
590 : : static bool IsCancelled (unsigned int range);
591 : :
592 : : /*
593 : : Cancel - set the cancelled flag in range.
594 : : */
595 : :
596 : : static void Cancel (unsigned int range);
597 : :
598 : : /*
599 : : FoldParameterAssign -
600 : : */
601 : :
602 : : static void FoldParameterAssign (unsigned int tokenno, unsigned int q, unsigned int r);
603 : :
604 : : /*
605 : : FoldReturn - do we know this is reachable, if so generate an error message.
606 : : */
607 : :
608 : : static void FoldReturn (unsigned int tokenno, unsigned int q, unsigned int r);
609 : :
610 : : /*
611 : : FoldInc -
612 : : */
613 : :
614 : : static void FoldInc (unsigned int tokenno, unsigned int q, unsigned int r);
615 : :
616 : : /*
617 : : FoldDec -
618 : : */
619 : :
620 : : static void FoldDec (unsigned int tokenno, unsigned int q, unsigned int r);
621 : :
622 : : /*
623 : : CheckSetAndBit - returns TRUE if des is a set type and expr is compatible with des.
624 : : */
625 : :
626 : : static bool CheckSetAndBit (unsigned int tokenno, unsigned int des, unsigned int expr, const char *name_, unsigned int _name_high);
627 : :
628 : : /*
629 : : CheckSet - returns TRUE if des is a set type and expr is compatible with INTEGER.
630 : : */
631 : :
632 : : static bool CheckSet (unsigned int tokenno, unsigned int des, unsigned int expr, const char *name_, unsigned int _name_high);
633 : :
634 : : /*
635 : : FoldIncl - folds an INCL statement if the operands are constant.
636 : : */
637 : :
638 : : static void FoldIncl (unsigned int tokenno, unsigned int q, unsigned int r);
639 : :
640 : : /*
641 : : FoldExcl - folds an EXCL statement if the operands are constant.
642 : : */
643 : :
644 : : static void FoldExcl (unsigned int tokenno, unsigned int q, unsigned int r);
645 : :
646 : : /*
647 : : FoldShift - folds an SHIFT test statement if the operands are constant.
648 : : */
649 : :
650 : : static void FoldShift (unsigned int tokenno, unsigned int q, unsigned int r);
651 : :
652 : : /*
653 : : FoldRotate - folds a ROTATE test statement if the operands are constant.
654 : : */
655 : :
656 : : static void FoldRotate (unsigned int tokenno, unsigned int q, unsigned int r);
657 : :
658 : : /*
659 : : FoldTypeReturnFunc - checks to see that val can be returned from func.
660 : : */
661 : :
662 : : static void FoldTypeReturnFunc (unsigned int q, unsigned int tokenNo, unsigned int func, unsigned int val, unsigned int r);
663 : :
664 : : /*
665 : : FoldTypeAssign -
666 : : */
667 : :
668 : : static void FoldTypeAssign (unsigned int q, unsigned int tokenNo, unsigned int des, unsigned int expr, unsigned int r);
669 : :
670 : : /*
671 : : FoldTypeIndrX - check to see that des = *expr is type compatible.
672 : : */
673 : :
674 : : static void FoldTypeIndrX (unsigned int q, unsigned int tokenNo, unsigned int des, unsigned int expr, unsigned int r);
675 : :
676 : : /*
677 : : FoldTypeParam - performs a parameter check between actual and formal.
678 : : The quad is removed if the check succeeds.
679 : : */
680 : :
681 : : static void FoldTypeParam (unsigned int q, unsigned int tokenNo, unsigned int formal, unsigned int actual, unsigned int procedure, unsigned int paramNo, unsigned int depRangeId);
682 : :
683 : : /*
684 : : FoldTypeExpr -
685 : : */
686 : :
687 : : static void FoldTypeExpr (unsigned int q, unsigned int tokenNo, unsigned int left, unsigned int right, bool strict, bool isin, unsigned int r);
688 : :
689 : : /*
690 : : CodeTypeAssign -
691 : : */
692 : :
693 : : static void CodeTypeAssign (unsigned int tokenNo, unsigned int des, unsigned int expr, unsigned int r);
694 : :
695 : : /*
696 : : CodeTypeReturnFunc -
697 : : */
698 : :
699 : : static void CodeTypeReturnFunc (unsigned int tokenNo, unsigned int func, unsigned int val, unsigned int r);
700 : :
701 : : /*
702 : : CodeTypeIndrX - checks that des = *expr is type compatible and generates an error if they
703 : : are not compatible. It skips over the LValue type so that to allow
704 : : the error messages to pick up the source variable name rather than
705 : : a temporary name or vague name 'expression'.
706 : : */
707 : :
708 : : static void CodeTypeIndrX (unsigned int tokenNo, unsigned int des, unsigned int expr, unsigned int r);
709 : :
710 : : /*
711 : : CodeTypeParam -
712 : : */
713 : :
714 : : static void CodeTypeParam (unsigned int tokenNo, unsigned int formal, unsigned int actual, unsigned int procedure, unsigned int paramNo);
715 : :
716 : : /*
717 : : CodeTypeExpr -
718 : : */
719 : :
720 : : static void CodeTypeExpr (unsigned int tokenNo, unsigned int left, unsigned int right, bool strict, bool isin, unsigned int r);
721 : :
722 : : /*
723 : : FoldTypeCheck - folds a type check. This is a no-op and it used
724 : : for checking types which are resolved post pass 3.
725 : : */
726 : :
727 : : static void FoldTypeCheck (unsigned int tokenno, unsigned int q, unsigned int r);
728 : :
729 : : /*
730 : : CodeTypeCheck - folds a type check. This is a no-op and it used
731 : : for checking types which are resolved post pass 3.
732 : : It does assume that both, des, and, expr, have been
733 : : resolved at this point.
734 : : */
735 : :
736 : : static void CodeTypeCheck (unsigned int tokenno, unsigned int r);
737 : :
738 : : /*
739 : : ForLoopBeginTypeCompatible - check for designator assignment compatibility with
740 : : expr1 and designator expression compatibility with expr2.
741 : : FOR des := expr1 TO expr2 BY byconst DO
742 : : END
743 : : It generates composite tokens if the tokens are on
744 : : the same source line.
745 : : */
746 : :
747 : : static bool ForLoopBeginTypeCompatible (M2Range_Range p);
748 : :
749 : : /*
750 : : FoldForLoopBegin -
751 : : */
752 : :
753 : : static void FoldForLoopBegin (unsigned int tokenno, unsigned int q, unsigned int r);
754 : :
755 : : /*
756 : : FoldForLoopTo -
757 : : */
758 : :
759 : : static void FoldForLoopTo (unsigned int tokenno, unsigned int q, unsigned int r);
760 : :
761 : : /*
762 : : FoldStaticArraySubscript -
763 : : */
764 : :
765 : : static void FoldStaticArraySubscript (unsigned int tokenno, unsigned int q, unsigned int r);
766 : :
767 : : /*
768 : : FoldDynamicArraySubscript -
769 : : */
770 : :
771 : : static void FoldDynamicArraySubscript (unsigned int tokenno, unsigned int q, unsigned int r);
772 : :
773 : : /*
774 : : FoldCaseBounds -
775 : : */
776 : :
777 : : static void FoldCaseBounds (unsigned int tokenno, unsigned int q, unsigned int r);
778 : :
779 : : /*
780 : : CodeCaseBounds - attempts to resolve whether the case bounds are legal.
781 : : This should resolve at compile time as all case bounds
782 : : must be constants. We introduce a CodeCaseBounds as it
783 : : might be possible that constants have just been declared
784 : : during the code generation of this function.
785 : : */
786 : :
787 : : static void CodeCaseBounds (unsigned int tokenno, unsigned int caseList);
788 : :
789 : : /*
790 : : MakeAndDeclareConstLit - creates a constant of value and declares it to GCC.
791 : : */
792 : :
793 : : static unsigned int MakeAndDeclareConstLit (unsigned int tokenno, NameKey_Name value, unsigned int type);
794 : :
795 : : /*
796 : : FoldNonPosDiv - attempts to fold the bound checking for a divide expression.
797 : : */
798 : :
799 : : static void FoldNonPosDiv (unsigned int tokenno, unsigned int q, unsigned int r);
800 : :
801 : : /*
802 : : FoldNonPosMod - attempts to fold the bound checking for a modulus expression.
803 : : */
804 : :
805 : : static void FoldNonPosMod (unsigned int tokenno, unsigned int q, unsigned int r);
806 : :
807 : : /*
808 : : FoldZeroDiv -
809 : : */
810 : :
811 : : static void FoldZeroDiv (unsigned int tokenno, unsigned int q, unsigned int r);
812 : :
813 : : /*
814 : : FoldZeroRem -
815 : : */
816 : :
817 : : static void FoldZeroRem (unsigned int tokenno, unsigned int q, unsigned int r);
818 : :
819 : : /*
820 : : FoldRangeCheckLower - call the appropriate Fold procedure depending upon the type
821 : : of range.
822 : : */
823 : :
824 : : static void FoldRangeCheckLower (unsigned int tokenno, unsigned int quad, unsigned int range);
825 : :
826 : : /*
827 : : DeReferenceLValue - returns a Tree which is either ModGcc(expr)
828 : : or Mod2Gcc ( *expr) depending whether, expr,
829 : : is an LValue.
830 : : */
831 : :
832 : : static tree DeReferenceLValue (unsigned int tokenno, unsigned int expr);
833 : :
834 : : /*
835 : : BuildStringParam - builds a C style string parameter which will be passed
836 : : as an ADDRESS type.
837 : : */
838 : :
839 : : static void BuildStringParam (unsigned int tokenno, DynamicStrings_String s);
840 : :
841 : : /*
842 : : BuildStringParamLoc - builds a C style string parameter which will be passed
843 : : as an ADDRESS type.
844 : : */
845 : :
846 : : static void BuildStringParamLoc (location_t location, DynamicStrings_String s);
847 : :
848 : : /*
849 : : IssueWarning - issue a warning. The compiler knows that this basic block can be reached
850 : : and we are in scope, function.
851 : : */
852 : :
853 : : static void IssueWarning (DynamicStrings_String function, unsigned int r);
854 : :
855 : : /*
856 : : CodeErrorCheckLoc - generate a runtime error message positioned at location
857 : : and in function. If function is NIL then the error scope
858 : : is used.
859 : : */
860 : :
861 : : static tree CodeErrorCheckLoc (location_t location, const char * function, const char * message, unsigned int func);
862 : :
863 : : /*
864 : : IssueWarningLoc -
865 : : */
866 : :
867 : : static void IssueWarningLoc (location_t location, const char * message);
868 : :
869 : : /*
870 : : BuildIfCallHandlerLoc - return a Tree containing a runtime test whether, condition, is true.
871 : : */
872 : :
873 : : static tree BuildIfCallHandlerLoc (location_t location, tree condition, const char * scope, const char * message, unsigned int func);
874 : :
875 : : /*
876 : : BuildIfCallHandler -
877 : : */
878 : :
879 : : static tree BuildIfCallHandler (tree condition, unsigned int r, DynamicStrings_String function, DynamicStrings_String message, bool warning);
880 : :
881 : : /*
882 : : RangeCheckReal -
883 : : */
884 : :
885 : : static void RangeCheckReal (M2Range_Range p, unsigned int r, DynamicStrings_String function, DynamicStrings_String message);
886 : :
887 : : /*
888 : : RangeCheckOrdinal -
889 : : */
890 : :
891 : : static void RangeCheckOrdinal (M2Range_Range p, unsigned int r, DynamicStrings_String function, DynamicStrings_String message);
892 : :
893 : : /*
894 : : DoCodeAssignmentExprType -
895 : : */
896 : :
897 : : static void DoCodeAssignmentExprType (M2Range_Range p, unsigned int r, DynamicStrings_String function, DynamicStrings_String message);
898 : :
899 : : /*
900 : : DoCodeAssignmentWithoutExprType -
901 : : */
902 : :
903 : : static void DoCodeAssignmentWithoutExprType (M2Range_Range p, unsigned int r, DynamicStrings_String function, DynamicStrings_String message);
904 : :
905 : : /*
906 : : DoCodeAssignment -
907 : : */
908 : :
909 : : static void DoCodeAssignment (unsigned int tokenno, unsigned int r, DynamicStrings_String function, DynamicStrings_String message);
910 : :
911 : : /*
912 : : CodeAssignment -
913 : : */
914 : :
915 : : static void CodeAssignment (unsigned int tokenno, unsigned int r, DynamicStrings_String function, DynamicStrings_String message);
916 : :
917 : : /*
918 : : CodeParameterAssign -
919 : : */
920 : :
921 : : static void CodeParameterAssign (unsigned int tokenno, unsigned int r, DynamicStrings_String function, DynamicStrings_String message);
922 : :
923 : : /*
924 : : CodeReturn -
925 : : */
926 : :
927 : : static void CodeReturn (unsigned int tokenno, unsigned int r, DynamicStrings_String function, DynamicStrings_String message);
928 : :
929 : : /*
930 : : IfOutsideLimitsDo -
931 : : */
932 : :
933 : : static void IfOutsideLimitsDo (unsigned int tokenno, tree min, tree expr, tree max, unsigned int r, DynamicStrings_String function, DynamicStrings_String message);
934 : :
935 : : /*
936 : : CodeInc -
937 : : */
938 : :
939 : : static void CodeInc (unsigned int tokenno, unsigned int r, DynamicStrings_String function, DynamicStrings_String message);
940 : :
941 : : /*
942 : : CodeDec -
943 : : */
944 : :
945 : : static void CodeDec (unsigned int tokenno, unsigned int r, DynamicStrings_String function, DynamicStrings_String message);
946 : :
947 : : /*
948 : : CodeInclExcl -
949 : : */
950 : :
951 : : static void CodeInclExcl (unsigned int tokenno, unsigned int r, DynamicStrings_String function, DynamicStrings_String message);
952 : :
953 : : /*
954 : : CodeShiftRotate - ensure that the bit shift is within the range
955 : : -(MAX(set)-MIN(set)+1)..(MAX(set)-MIN(set)+1)
956 : : */
957 : :
958 : : static void CodeShiftRotate (unsigned int tokenno, unsigned int r, DynamicStrings_String function, DynamicStrings_String message);
959 : :
960 : : /*
961 : : CodeStaticArraySubscript -
962 : : */
963 : :
964 : : static void CodeStaticArraySubscript (unsigned int tokenno, unsigned int r, DynamicStrings_String function, DynamicStrings_String message);
965 : :
966 : : /*
967 : : CodeDynamicArraySubscript -
968 : : */
969 : :
970 : : static void CodeDynamicArraySubscript (unsigned int tokenno, unsigned int r, DynamicStrings_String function, DynamicStrings_String message);
971 : :
972 : : /*
973 : : CodeForLoopBegin -
974 : : */
975 : :
976 : : static void CodeForLoopBegin (unsigned int tokenno, unsigned int r, DynamicStrings_String function, DynamicStrings_String message);
977 : :
978 : : /*
979 : : CodeForLoopTo -
980 : : */
981 : :
982 : : static void CodeForLoopTo (unsigned int tokenno, unsigned int r, DynamicStrings_String function, DynamicStrings_String message);
983 : :
984 : : /*
985 : : SameTypesCodeForLoopEnd - the trivial case.
986 : : */
987 : :
988 : : static void SameTypesCodeForLoopEnd (unsigned int tokenNo, unsigned int r, DynamicStrings_String function, DynamicStrings_String message, M2Range_Range p, tree dmax);
989 : : static void DiffTypesCodeForLoopEnd (unsigned int tokenNo, unsigned int r, DynamicStrings_String function, DynamicStrings_String message, M2Range_Range p, tree dmax, tree emin, tree emax);
990 : :
991 : : /*
992 : : CodeForLoopEnd - checks to see that des := des + expr does not overflow.
993 : : This is called at the end of the for loop. It is more complex
994 : : than it initially seems as des and expr might be different types.
995 : : */
996 : :
997 : : static void CodeForLoopEnd (unsigned int tokenno, unsigned int r, DynamicStrings_String function, DynamicStrings_String message);
998 : :
999 : : /*
1000 : : CodeNil -
1001 : : */
1002 : :
1003 : : static void CodeNil (unsigned int r, DynamicStrings_String function, DynamicStrings_String message);
1004 : :
1005 : : /*
1006 : : CodeWholeNonPos - generates range check code for expr<=0.
1007 : : */
1008 : :
1009 : : static void CodeWholeNonPos (unsigned int tokenno, unsigned int r, DynamicStrings_String function, DynamicStrings_String message);
1010 : :
1011 : : /*
1012 : : CodeWholeZero - generates range check code for expr=0.
1013 : : */
1014 : :
1015 : : static void CodeWholeZero (unsigned int tokenno, unsigned int r, DynamicStrings_String function, DynamicStrings_String message);
1016 : :
1017 : : /*
1018 : : FillInParameters -
1019 : : */
1020 : :
1021 : : static DynamicStrings_String FillInParameters (unsigned int r, DynamicStrings_String s);
1022 : :
1023 : : /*
1024 : : GetRangeErrorMessage - returns a specific error message for the range, r.
1025 : : It assumes the 3 parameters to be supplied on the MetaError
1026 : : parameter list are: dest, expr, paramNo or dimension.
1027 : :
1028 : : XYZ
1029 : : 'the initial assignment to {%1a} at the start of the FOR loop will cause a range error, as the type range of {%1taD} does not overlap with {%2tad}')
1030 : : 'the final TO value {%2a} of the FOR loop will cause a range error with the iterator variable {%1a}')
1031 : : */
1032 : :
1033 : : static DynamicStrings_String GetRangeErrorMessage (unsigned int r);
1034 : :
1035 : : /*
1036 : : Init - initializes the modules global variables.
1037 : : */
1038 : :
1039 : : static void Init (void);
1040 : :
1041 : 0 : static void gdbhook (void)
1042 : : {
1043 : 0 : }
1044 : :
1045 : :
1046 : : /*
1047 : : BreakWhenRangeCreated - to be called interactively by gdb.
1048 : : */
1049 : :
1050 : 15506 : static void BreakWhenRangeCreated (unsigned int r)
1051 : : {
1052 : 15506 : BreakRange = r;
1053 : 0 : }
1054 : :
1055 : :
1056 : : /*
1057 : : CheckBreak - if sym = BreakRange then call gdbhook.
1058 : : */
1059 : :
1060 : 0 : static void CheckBreak (unsigned int r)
1061 : : {
1062 : 0 : if (BreakRange == r)
1063 : : {
1064 : 0 : gdbhook ();
1065 : : }
1066 : 0 : }
1067 : :
1068 : :
1069 : : /*
1070 : : IsGreaterOrEqualConversion - tests whether t>=e.
1071 : : */
1072 : :
1073 : 0 : static bool IsGreaterOrEqualConversion (location_t location, unsigned int l, unsigned int d, unsigned int e)
1074 : : {
1075 : 0 : if ((SymbolTable_GetType (d)) == SymbolTable_NulSym)
1076 : : {
1077 : 0 : if ((SymbolTable_GetType (e)) == SymbolTable_NulSym)
1078 : : {
1079 : 0 : return M2Range_IsGreaterOrEqual (SymbolConversion_Mod2Gcc (l), M2GenGCC_LValueToGenericPtr (location, e));
1080 : : }
1081 : : else
1082 : : {
1083 : 0 : return M2Range_IsGreaterOrEqual (m2convert_BuildConvert (location, SymbolConversion_Mod2Gcc (SymbolTable_SkipType (SymbolTable_GetType (e))), SymbolConversion_Mod2Gcc (l), false), M2GenGCC_LValueToGenericPtr (location, e));
1084 : : }
1085 : : }
1086 : : else
1087 : : {
1088 : 0 : return M2Range_IsGreaterOrEqual (m2convert_BuildConvert (location, SymbolConversion_Mod2Gcc (SymbolTable_SkipType (SymbolTable_GetType (d))), SymbolConversion_Mod2Gcc (l), false), M2GenGCC_LValueToGenericPtr (location, e));
1089 : : }
1090 : : /* static analysis guarentees a RETURN statement will be used before here. */
1091 : : __builtin_unreachable ();
1092 : : }
1093 : :
1094 : :
1095 : : /*
1096 : : IsEqualConversion - returns TRUE if a=b.
1097 : : */
1098 : :
1099 : 381086 : static bool IsEqualConversion (unsigned int l, unsigned int d, unsigned int e)
1100 : : {
1101 : 381086 : location_t location;
1102 : :
1103 : 381086 : location = M2LexBuf_TokenToLocation (SymbolTable_GetDeclaredMod (l));
1104 : 381086 : if ((SymbolTable_GetType (d)) == SymbolTable_NulSym)
1105 : : {
1106 : 12 : if ((SymbolTable_GetType (e)) == SymbolTable_NulSym)
1107 : : {
1108 : 0 : return M2Range_IsEqual (SymbolConversion_Mod2Gcc (l), M2GenGCC_LValueToGenericPtr (location, e));
1109 : : }
1110 : : else
1111 : : {
1112 : 12 : return M2Range_IsEqual (m2convert_BuildConvert (location, SymbolConversion_Mod2Gcc (SymbolTable_SkipType (SymbolTable_GetType (e))), SymbolConversion_Mod2Gcc (l), false), M2GenGCC_LValueToGenericPtr (location, e));
1113 : : }
1114 : : }
1115 : : else
1116 : : {
1117 : 381074 : return M2Range_IsEqual (m2convert_BuildConvert (location, SymbolConversion_Mod2Gcc (SymbolTable_SkipType (SymbolTable_GetType (d))), SymbolConversion_Mod2Gcc (l), false), M2GenGCC_LValueToGenericPtr (location, e));
1118 : : }
1119 : : /* static analysis guarentees a RETURN statement will be used before here. */
1120 : : __builtin_unreachable ();
1121 : : }
1122 : :
1123 : :
1124 : : /*
1125 : : lookupExceptionHandler -
1126 : : */
1127 : :
1128 : 12695 : static unsigned int lookupExceptionHandler (M2Range_TypeOfRange type)
1129 : : {
1130 : 12695 : switch (type)
1131 : : {
1132 : 2275 : case M2Range_assignment:
1133 : 2275 : return M2Base_ExceptionAssign;
1134 : 94 : break;
1135 : :
1136 : 94 : case M2Range_returnassignment:
1137 : 94 : return M2Base_ExceptionReturn;
1138 : 0 : break;
1139 : :
1140 : 0 : case M2Range_subrangeassignment:
1141 : 0 : M2Error_InternalError ((const char *) "not expecting this case value", 29);
1142 : 2340 : break;
1143 : :
1144 : 2340 : case M2Range_inc:
1145 : 2340 : return M2Base_ExceptionInc;
1146 : 2052 : break;
1147 : :
1148 : 2052 : case M2Range_dec:
1149 : 2052 : return M2Base_ExceptionDec;
1150 : 0 : break;
1151 : :
1152 : 0 : case M2Range_incl:
1153 : 0 : return M2Base_ExceptionIncl;
1154 : 0 : break;
1155 : :
1156 : 0 : case M2Range_excl:
1157 : 0 : return M2Base_ExceptionExcl;
1158 : 144 : break;
1159 : :
1160 : 144 : case M2Range_shift:
1161 : 144 : return M2Base_ExceptionShift;
1162 : 0 : break;
1163 : :
1164 : 0 : case M2Range_rotate:
1165 : 0 : return M2Base_ExceptionRotate;
1166 : 0 : break;
1167 : :
1168 : 0 : case M2Range_typeassign:
1169 : 0 : case M2Range_typeparam:
1170 : 0 : case M2Range_typeexpr:
1171 : 0 : case M2Range_typeindrx:
1172 : 0 : M2Error_InternalError ((const char *) "not expecting this case value", 29);
1173 : 396 : break;
1174 : :
1175 : 396 : case M2Range_paramassign:
1176 : 396 : return M2Base_ExceptionParameterBounds;
1177 : 816 : break;
1178 : :
1179 : 816 : case M2Range_staticarraysubscript:
1180 : 816 : return M2Base_ExceptionStaticArray;
1181 : 480 : break;
1182 : :
1183 : 480 : case M2Range_dynamicarraysubscript:
1184 : 480 : return M2Base_ExceptionDynamicArray;
1185 : 0 : break;
1186 : :
1187 : 0 : case M2Range_forloopbegin:
1188 : 0 : return M2Base_ExceptionForLoopBegin;
1189 : 0 : break;
1190 : :
1191 : 0 : case M2Range_forloopto:
1192 : 0 : return M2Base_ExceptionForLoopTo;
1193 : 1584 : break;
1194 : :
1195 : 1584 : case M2Range_forloopend:
1196 : 1584 : return M2Base_ExceptionForLoopEnd;
1197 : 792 : break;
1198 : :
1199 : 792 : case M2Range_pointernil:
1200 : 792 : return M2Base_ExceptionPointerNil;
1201 : 12 : break;
1202 : :
1203 : 12 : case M2Range_noreturn:
1204 : 12 : return M2Base_ExceptionNoReturn;
1205 : 104 : break;
1206 : :
1207 : 104 : case M2Range_noelse:
1208 : 104 : return M2Base_ExceptionCase;
1209 : 0 : break;
1210 : :
1211 : 0 : case M2Range_casebounds:
1212 : 0 : M2Error_InternalError ((const char *) "not expecting this case value", 29);
1213 : 0 : break;
1214 : :
1215 : 0 : case M2Range_wholenonposdiv:
1216 : 0 : return M2Base_ExceptionNonPosDiv;
1217 : 0 : break;
1218 : :
1219 : 0 : case M2Range_wholenonposmod:
1220 : 0 : return M2Base_ExceptionNonPosMod;
1221 : 1606 : break;
1222 : :
1223 : 1606 : case M2Range_wholezerodiv:
1224 : 1606 : return M2Base_ExceptionZeroDiv;
1225 : 0 : break;
1226 : :
1227 : 0 : case M2Range_wholezerorem:
1228 : 0 : return M2Base_ExceptionZeroRem;
1229 : 0 : break;
1230 : :
1231 : 0 : case M2Range_none:
1232 : 0 : return M2Base_ExceptionNo;
1233 : 0 : break;
1234 : :
1235 : :
1236 : 0 : default:
1237 : 0 : M2Error_InternalError ((const char *) "enumeration value unknown", 25);
1238 : : break;
1239 : : }
1240 : : ReturnException ("/home/worker/buildworker/tiber-lcov/build/gcc/m2/gm2-compiler/M2Range.def", 20, 1);
1241 : : __builtin_unreachable ();
1242 : : }
1243 : :
1244 : :
1245 : : /*
1246 : : InitRange - returns a new range item.
1247 : : */
1248 : :
1249 : 2085007 : static unsigned int InitRange (void)
1250 : : {
1251 : 2085007 : unsigned int r;
1252 : 2085007 : M2Range_Range p;
1253 : :
1254 : 2085007 : TopOfRange += 1;
1255 : 2085007 : r = TopOfRange;
1256 : 2085007 : Storage_ALLOCATE ((void **) &p, sizeof (M2Range__T1));
1257 : 2085007 : if (p == NULL)
1258 : : {
1259 : 0 : M2Error_InternalError ((const char *) "out of memory error", 19);
1260 : : }
1261 : : else
1262 : : {
1263 : 2085007 : CheckBreak (r);
1264 : 2085007 : p->type = M2Range_none;
1265 : 2085007 : p->des = SymbolTable_NulSym;
1266 : 2085007 : p->expr = SymbolTable_NulSym;
1267 : 2085007 : p->expr2 = SymbolTable_NulSym;
1268 : 2085007 : p->byconst = SymbolTable_NulSym;
1269 : 2085007 : p->desLowestType = SymbolTable_NulSym;
1270 : 2085007 : p->exprLowestType = SymbolTable_NulSym;
1271 : 2085007 : p->isLeftValue = false; /* ignored in all cases other */
1272 : 2085007 : p->dimension = 0; /* ignored in all cases other */
1273 : 2085007 : p->caseList = 0;
1274 : 2085007 : p->tokenNo = M2LexBuf_UnknownTokenNo; /* than pointernil */
1275 : 2085007 : p->destok = M2LexBuf_UnknownTokenNo; /* than pointernil */
1276 : 2085007 : p->exprtok = M2LexBuf_UnknownTokenNo;
1277 : 2085007 : p->expr2tok = M2LexBuf_UnknownTokenNo;
1278 : 2085007 : p->byconsttok = M2LexBuf_UnknownTokenNo;
1279 : 2085007 : p->incrementquad = 0;
1280 : 2085007 : p->errorReported = false;
1281 : 2085007 : p->cancelled = false;
1282 : 2085007 : p->dependantid = 0;
1283 : 2085007 : Indexing_PutIndice (RangeIndex, r, reinterpret_cast <void *> (p));
1284 : : }
1285 : 2085007 : return r;
1286 : : /* static analysis guarentees a RETURN statement will be used before here. */
1287 : : __builtin_unreachable ();
1288 : : }
1289 : :
1290 : :
1291 : : /*
1292 : : reportedError - returns whether this is the first time this error has been
1293 : : reported.
1294 : : */
1295 : :
1296 : 467517 : static bool reportedError (unsigned int r)
1297 : : {
1298 : 467517 : M2Range_Range p;
1299 : :
1300 : 80172 : p = static_cast<M2Range_Range> (Indexing_GetIndice (RangeIndex, r));
1301 : 467517 : return p->errorReported;
1302 : : /* static analysis guarentees a RETURN statement will be used before here. */
1303 : : __builtin_unreachable ();
1304 : : }
1305 : :
1306 : :
1307 : : /*
1308 : : setReported - assigns errorReported to TRUE.
1309 : : */
1310 : :
1311 : 68419 : static void setReported (unsigned int r)
1312 : : {
1313 : 68419 : M2Range_Range p;
1314 : :
1315 : 68419 : p = static_cast<M2Range_Range> (Indexing_GetIndice (RangeIndex, r));
1316 : 68419 : p->errorReported = true;
1317 : 68419 : }
1318 : :
1319 : :
1320 : : /*
1321 : : PutRange - initializes contents of, p, to
1322 : : d, e and their lowest types.
1323 : : It also fills in the current token no
1324 : : and returns, p.
1325 : : */
1326 : :
1327 : 518294 : static M2Range_Range PutRange (unsigned int tokno, M2Range_Range p, M2Range_TypeOfRange t, unsigned int d, unsigned int e)
1328 : : {
1329 : 518294 : p->type = t;
1330 : 518294 : p->des = d;
1331 : 518294 : p->expr = e;
1332 : 518294 : p->desLowestType = SymbolTable_GetLowestType (d);
1333 : 518294 : p->exprLowestType = SymbolTable_GetLowestType (e);
1334 : 518288 : p->tokenNo = tokno;
1335 : 518288 : p->strict = false;
1336 : 518288 : p->isin = false;
1337 : 518288 : return p;
1338 : : /* static analysis guarentees a RETURN statement will be used before here. */
1339 : : __builtin_unreachable ();
1340 : : }
1341 : :
1342 : :
1343 : : /*
1344 : : PutRangeDesExpr2 - initializes contents of, p, to
1345 : : des, expr1 and their lowest types.
1346 : : It also fills in the token numbers for
1347 : : des, expr, expr2 and returns, p.
1348 : : */
1349 : :
1350 : 2610 : static M2Range_Range PutRangeDesExpr2 (M2Range_Range p, M2Range_TypeOfRange t, unsigned int des, unsigned int destok, unsigned int expr1, unsigned int expr1tok, unsigned int expr2, unsigned int expr2tok, unsigned int byconst, unsigned int byconsttok)
1351 : : {
1352 : 2610 : p->des = des;
1353 : 2610 : p->destok = destok;
1354 : 2610 : p->expr = expr1;
1355 : 2610 : p->exprtok = expr1tok;
1356 : 2610 : p->expr2 = expr2;
1357 : 2610 : p->expr2tok = expr2tok;
1358 : 2610 : p->byconst = byconst;
1359 : 2610 : p->byconsttok = byconsttok;
1360 : 2610 : p->type = t;
1361 : 0 : p->desLowestType = SymbolTable_GetLowestType (p->des);
1362 : 2610 : p->exprLowestType = SymbolTable_GetLowestType (expr1);
1363 : 2610 : p->strict = false;
1364 : 2610 : p->isin = false;
1365 : 2610 : return p;
1366 : : /* static analysis guarentees a RETURN statement will be used before here. */
1367 : : __builtin_unreachable ();
1368 : : }
1369 : :
1370 : :
1371 : : /*
1372 : : chooseTokenPos - returns, tokenpos, if it is not the unknown location, otherwise
1373 : : it returns GetTokenNo.
1374 : : */
1375 : :
1376 : 687881 : static unsigned int chooseTokenPos (unsigned int tokenpos)
1377 : : {
1378 : 0 : if (tokenpos == M2LexBuf_UnknownTokenNo)
1379 : : {
1380 : 0 : return M2LexBuf_GetTokenNo ();
1381 : : }
1382 : : else
1383 : : {
1384 : : return tokenpos;
1385 : : }
1386 : : /* static analysis guarentees a RETURN statement will be used before here. */
1387 : : __builtin_unreachable ();
1388 : : }
1389 : :
1390 : :
1391 : : /*
1392 : : PutRangeNoLow - initializes contents of, p. It
1393 : : does not set lowest types as they may be
1394 : : unknown at this point.
1395 : : */
1396 : :
1397 : 527304 : static M2Range_Range PutRangeNoLow (unsigned int tokpos, M2Range_Range p, M2Range_TypeOfRange t, unsigned int d, unsigned int e)
1398 : : {
1399 : 527304 : p->type = t;
1400 : 527304 : p->des = d;
1401 : 527304 : p->expr = e;
1402 : 527304 : p->desLowestType = SymbolTable_NulSym;
1403 : 527304 : p->exprLowestType = SymbolTable_NulSym;
1404 : 527304 : p->isLeftValue = false;
1405 : 0 : p->tokenNo = chooseTokenPos (tokpos);
1406 : 527304 : p->strict = false;
1407 : 527304 : p->isin = false;
1408 : 527304 : return p;
1409 : : /* static analysis guarentees a RETURN statement will be used before here. */
1410 : : __builtin_unreachable ();
1411 : : }
1412 : :
1413 : :
1414 : : /*
1415 : : PutRangeExpr - initializes contents of, p. It
1416 : : does not set lowest types as they may be
1417 : : unknown at this point.
1418 : : */
1419 : :
1420 : 151455 : static M2Range_Range PutRangeExpr (unsigned int tokpos, M2Range_Range p, M2Range_TypeOfRange t, unsigned int d, unsigned int e, bool strict, bool isin)
1421 : : {
1422 : 151455 : p->type = t;
1423 : 151455 : p->des = d;
1424 : 151455 : p->expr = e;
1425 : 151455 : p->desLowestType = SymbolTable_NulSym;
1426 : 151455 : p->exprLowestType = SymbolTable_NulSym;
1427 : 151455 : p->isLeftValue = false;
1428 : 0 : p->tokenNo = chooseTokenPos (tokpos);
1429 : 151455 : p->strict = strict;
1430 : 151455 : p->isin = isin;
1431 : 151455 : return p;
1432 : : /* static analysis guarentees a RETURN statement will be used before here. */
1433 : : __builtin_unreachable ();
1434 : : }
1435 : :
1436 : :
1437 : : /*
1438 : : PutRangePointer - initializes contents of, p, to
1439 : : d, isLeft and their lowest types.
1440 : : It also fills in the current token no
1441 : : and returns, p.
1442 : : */
1443 : :
1444 : 23438 : static M2Range_Range PutRangePointer (unsigned int tokpos, M2Range_Range p, unsigned int d, bool isLeft)
1445 : : {
1446 : 23438 : p->type = M2Range_pointernil;
1447 : 23438 : p->des = d;
1448 : 23438 : p->expr = SymbolTable_NulSym;
1449 : 23438 : p->desLowestType = SymbolTable_GetLowestType (SymbolTable_GetType (d));
1450 : 23438 : p->exprLowestType = SymbolTable_NulSym;
1451 : 23438 : p->isLeftValue = isLeft;
1452 : 23438 : p->tokenNo = tokpos;
1453 : 23438 : p->strict = false;
1454 : 23438 : p->isin = false;
1455 : 23438 : return p;
1456 : : /* static analysis guarentees a RETURN statement will be used before here. */
1457 : : __builtin_unreachable ();
1458 : : }
1459 : :
1460 : :
1461 : : /*
1462 : : PutRangeNoEval - initializes contents of, p, to a non evaluation
1463 : : runtime check such as a no else clause or
1464 : : no return found in function call.
1465 : : */
1466 : :
1467 : 23417 : static M2Range_Range PutRangeNoEval (M2Range_Range p, M2Range_TypeOfRange t)
1468 : : {
1469 : 23417 : p->type = t;
1470 : 0 : p->tokenNo = M2LexBuf_GetTokenNo ();
1471 : 23417 : return p;
1472 : : /* static analysis guarentees a RETURN statement will be used before here. */
1473 : : __builtin_unreachable ();
1474 : : }
1475 : :
1476 : 9122 : static M2Range_Range PutRangeUnary (unsigned int tokno, M2Range_Range p, M2Range_TypeOfRange t, unsigned int d, unsigned int e)
1477 : : {
1478 : : /*
1479 : : PutRange - initializes contents of, p, to
1480 : : d, e and its lowest type.
1481 : : It also fills in the current token no
1482 : : and returns, p.
1483 : : */
1484 : 9122 : p->type = t;
1485 : 9122 : p->des = d;
1486 : 9122 : p->expr = e;
1487 : 9122 : p->desLowestType = SymbolTable_GetLowestType (d);
1488 : 9122 : p->exprLowestType = SymbolTable_NulSym;
1489 : 9122 : p->isLeftValue = false;
1490 : 9122 : p->tokenNo = chooseTokenPos (tokno);
1491 : 9122 : p->strict = false;
1492 : 9122 : p->isin = false;
1493 : 9122 : return p;
1494 : : /* static analysis guarentees a RETURN statement will be used before here. */
1495 : : __builtin_unreachable ();
1496 : : }
1497 : :
1498 : :
1499 : : /*
1500 : : PutRangeParam - initializes contents of, p, to contain the parameter
1501 : : type checking information.
1502 : : It also fills in the current token no
1503 : : and returns, p.
1504 : : */
1505 : :
1506 : 630652 : static M2Range_Range PutRangeParam (unsigned int tokno, M2Range_Range p, M2Range_TypeOfRange t, unsigned int proc, unsigned int paramno, unsigned int formal, unsigned int actual, unsigned int depRangeId)
1507 : : {
1508 : 630652 : p->type = t;
1509 : 630652 : p->des = formal;
1510 : 630652 : p->expr = actual;
1511 : 630652 : p->desLowestType = SymbolTable_NulSym;
1512 : 630652 : p->exprLowestType = SymbolTable_NulSym;
1513 : 630652 : p->procedure = proc;
1514 : 630652 : p->paramNo = paramno;
1515 : 630652 : p->isLeftValue = false;
1516 : 630652 : p->tokenNo = tokno;
1517 : 630652 : p->strict = false;
1518 : 630652 : p->isin = false;
1519 : 630652 : p->dependantid = depRangeId;
1520 : 630652 : return p;
1521 : : /* static analysis guarentees a RETURN statement will be used before here. */
1522 : : __builtin_unreachable ();
1523 : : }
1524 : :
1525 : :
1526 : : /*
1527 : : PutRangeArraySubscript - initializes contents of, p, to
1528 : : d, e and their lowest types. It also
1529 : : assigns, dim.
1530 : : It also fills in the current token no
1531 : : and returns, p.
1532 : : */
1533 : :
1534 : 56720 : static M2Range_Range PutRangeArraySubscript (M2Range_Range p, M2Range_TypeOfRange t, unsigned int d, unsigned int e, unsigned int dim)
1535 : : {
1536 : 56720 : p->type = t;
1537 : 56720 : p->des = d;
1538 : 56720 : p->expr = e;
1539 : 56720 : p->desLowestType = SymbolTable_GetLowestType (d);
1540 : 56720 : p->exprLowestType = SymbolTable_GetLowestType (e);
1541 : 56720 : p->dimension = dim;
1542 : 56720 : p->tokenNo = M2LexBuf_GetTokenNo ();
1543 : 56720 : p->strict = false;
1544 : 56720 : p->isin = false;
1545 : 56720 : return p;
1546 : : /* static analysis guarentees a RETURN statement will be used before here. */
1547 : : __builtin_unreachable ();
1548 : : }
1549 : :
1550 : :
1551 : : /*
1552 : : PutRangeParamAssign - initializes contents of, p, to contain the parameter
1553 : : type checking information.
1554 : : It also fills in the current token no
1555 : : and returns, p.
1556 : : */
1557 : :
1558 : 141995 : static M2Range_Range PutRangeParamAssign (unsigned int tokno, M2Range_Range p, M2Range_TypeOfRange t, unsigned int proc, unsigned int i, unsigned int formal, unsigned int actual, unsigned int parentRangeId)
1559 : : {
1560 : 141995 : p->type = t;
1561 : 141995 : p->des = formal;
1562 : 141995 : p->expr = actual;
1563 : 0 : p->desLowestType = SymbolTable_GetLowestType (p->des);
1564 : 141995 : p->exprLowestType = SymbolTable_GetLowestType (p->expr);
1565 : 141995 : p->procedure = proc;
1566 : 141995 : p->paramNo = i;
1567 : 141995 : p->dimension = i;
1568 : 141995 : p->isLeftValue = false;
1569 : 141995 : p->tokenNo = tokno;
1570 : 141995 : p->dependantid = parentRangeId;
1571 : 141995 : return p;
1572 : : /* static analysis guarentees a RETURN statement will be used before here. */
1573 : : __builtin_unreachable ();
1574 : : }
1575 : :
1576 : :
1577 : : /*
1578 : : FoldNil - attempts to fold the pointer against nil comparison.
1579 : : */
1580 : :
1581 : 122774 : static void FoldNil (unsigned int tokenno, unsigned int q, unsigned int r)
1582 : : {
1583 : 122774 : M2Range_Range p;
1584 : :
1585 : 122774 : p = static_cast<M2Range_Range> (Indexing_GetIndice (RangeIndex, r));
1586 : 122774 : M2GCCDeclare_TryDeclareConstant (tokenno, p->des); /* use quad tokenno, rather than the range tokenNo */
1587 : 122774 : if ((SymbolConversion_GccKnowsAbout (p->des)) && (SymbolTable_IsConst (p->des))) /* use quad tokenno, rather than the range tokenNo */
1588 : : {
1589 : 0 : SymbolTable_PushValue (p->des);
1590 : 0 : SymbolTable_PushValue (M2Base_Nil);
1591 : 0 : if (M2ALU_Equ (tokenno))
1592 : : {
1593 : 0 : M2MetaError_MetaErrorT1 (p->tokenNo, (const char *) "attempting to dereference a pointer {%1Wa} whose value will be NIL", 66, p->des);
1594 : 0 : M2Quads_PutQuad (q, M2Quads_ErrorOp, SymbolTable_NulSym, SymbolTable_NulSym, r);
1595 : : }
1596 : : else
1597 : : {
1598 : 0 : M2Quads_SubQuad (q);
1599 : : }
1600 : : }
1601 : 122774 : }
1602 : :
1603 : :
1604 : : /*
1605 : : OutOfRange - returns TRUE if expr lies outside min..max.
1606 : : */
1607 : :
1608 : 504312 : static bool OutOfRange (unsigned int tokenno, tree min, unsigned int expr, tree max, unsigned int type)
1609 : : {
1610 : 504312 : if (m2expr_TreeOverflow (min))
1611 : : {
1612 : 0 : StrIO_WriteString ((const char *) "overflow detected in min\\n", 26);
1613 : 0 : StrIO_WriteLn ();
1614 : 0 : m2tree_debug_tree (min);
1615 : : }
1616 : 504312 : if (m2expr_TreeOverflow (max))
1617 : : {
1618 : 0 : StrIO_WriteString ((const char *) "overflow detected in max\\n", 26);
1619 : 0 : StrIO_WriteLn ();
1620 : 0 : m2tree_debug_tree (max);
1621 : : }
1622 : 504312 : if (m2expr_TreeOverflow (max))
1623 : : {
1624 : 0 : StrIO_WriteString ((const char *) "overflow detected in expr\\n", 27);
1625 : 0 : StrIO_WriteLn ();
1626 : 0 : m2tree_debug_tree (M2GenGCC_StringToChar (SymbolConversion_Mod2Gcc (expr), type, expr));
1627 : : }
1628 : 504312 : M2ALU_PushIntegerTree (M2GenGCC_StringToChar (SymbolConversion_Mod2Gcc (expr), type, expr));
1629 : 504312 : M2ALU_PushIntegerTree (min);
1630 : 504312 : if (M2ALU_Less (tokenno))
1631 : : {
1632 : : return true;
1633 : : }
1634 : 504252 : M2ALU_PushIntegerTree (M2GenGCC_StringToChar (SymbolConversion_Mod2Gcc (expr), type, expr));
1635 : 504252 : M2ALU_PushIntegerTree (max);
1636 : 504252 : if (M2ALU_Gre (tokenno))
1637 : : {
1638 : : return true;
1639 : : }
1640 : : return false;
1641 : : /* static analysis guarentees a RETURN statement will be used before here. */
1642 : : __builtin_unreachable ();
1643 : : }
1644 : :
1645 : :
1646 : : /*
1647 : : HandlerExists -
1648 : : */
1649 : :
1650 : 115303 : static bool HandlerExists (unsigned int r)
1651 : : {
1652 : 115303 : M2Range_Range p;
1653 : :
1654 : 115303 : p = static_cast<M2Range_Range> (Indexing_GetIndice (RangeIndex, r));
1655 : 115303 : switch (p->type)
1656 : : {
1657 : 11623 : case M2Range_assignment:
1658 : 11623 : return M2Base_ExceptionAssign != SymbolTable_NulSym;
1659 : 3173 : break;
1660 : :
1661 : 3173 : case M2Range_returnassignment:
1662 : 3173 : return M2Base_ExceptionReturn != SymbolTable_NulSym;
1663 : 0 : break;
1664 : :
1665 : 0 : case M2Range_subrangeassignment:
1666 : 0 : M2Error_InternalError ((const char *) "not expecting this case value", 29);
1667 : 2340 : break;
1668 : :
1669 : 2340 : case M2Range_inc:
1670 : 2340 : return M2Base_ExceptionInc != SymbolTable_NulSym;
1671 : 2052 : break;
1672 : :
1673 : 2052 : case M2Range_dec:
1674 : 2052 : return M2Base_ExceptionDec != SymbolTable_NulSym;
1675 : 0 : break;
1676 : :
1677 : 0 : case M2Range_incl:
1678 : 0 : return M2Base_ExceptionIncl != SymbolTable_NulSym;
1679 : 0 : break;
1680 : :
1681 : 0 : case M2Range_excl:
1682 : 0 : return M2Base_ExceptionExcl != SymbolTable_NulSym;
1683 : 588 : break;
1684 : :
1685 : 588 : case M2Range_shift:
1686 : 588 : return M2Base_ExceptionShift != SymbolTable_NulSym;
1687 : 272 : break;
1688 : :
1689 : 272 : case M2Range_rotate:
1690 : 272 : return M2Base_ExceptionRotate != SymbolTable_NulSym;
1691 : : break;
1692 : :
1693 : : case M2Range_typereturn:
1694 : : case M2Range_typeassign:
1695 : : case M2Range_typeparam:
1696 : : case M2Range_typeexpr:
1697 : : case M2Range_typeindrx:
1698 : : return false;
1699 : 13760 : break;
1700 : :
1701 : 13760 : case M2Range_paramassign:
1702 : 13760 : return M2Base_ExceptionParameterBounds != SymbolTable_NulSym;
1703 : 22020 : break;
1704 : :
1705 : 22020 : case M2Range_staticarraysubscript:
1706 : 22020 : return M2Base_ExceptionStaticArray != SymbolTable_NulSym;
1707 : 17412 : break;
1708 : :
1709 : 17412 : case M2Range_dynamicarraysubscript:
1710 : 17412 : return M2Base_ExceptionDynamicArray != SymbolTable_NulSym;
1711 : 56 : break;
1712 : :
1713 : 56 : case M2Range_forloopbegin:
1714 : 56 : return M2Base_ExceptionForLoopBegin != SymbolTable_NulSym;
1715 : 0 : break;
1716 : :
1717 : 0 : case M2Range_forloopto:
1718 : 0 : return M2Base_ExceptionForLoopTo != SymbolTable_NulSym;
1719 : 9540 : break;
1720 : :
1721 : 9540 : case M2Range_forloopend:
1722 : 9540 : return M2Base_ExceptionForLoopEnd != SymbolTable_NulSym;
1723 : 23026 : break;
1724 : :
1725 : 23026 : case M2Range_pointernil:
1726 : 23026 : return M2Base_ExceptionPointerNil != SymbolTable_NulSym;
1727 : 351 : break;
1728 : :
1729 : 351 : case M2Range_noreturn:
1730 : 351 : return M2Base_ExceptionNoReturn != SymbolTable_NulSym;
1731 : 482 : break;
1732 : :
1733 : 482 : case M2Range_noelse:
1734 : 482 : return M2Base_ExceptionCase != SymbolTable_NulSym;
1735 : : break;
1736 : :
1737 : : case M2Range_casebounds:
1738 : : return false;
1739 : 0 : break;
1740 : :
1741 : 0 : case M2Range_wholenonposdiv:
1742 : 0 : return M2Base_ExceptionNonPosDiv != SymbolTable_NulSym;
1743 : 0 : break;
1744 : :
1745 : 0 : case M2Range_wholenonposmod:
1746 : 0 : return M2Base_ExceptionNonPosMod != SymbolTable_NulSym;
1747 : 8464 : break;
1748 : :
1749 : 8464 : case M2Range_wholezerodiv:
1750 : 8464 : return M2Base_ExceptionZeroDiv != SymbolTable_NulSym;
1751 : 96 : break;
1752 : :
1753 : 96 : case M2Range_wholezerorem:
1754 : 96 : return M2Base_ExceptionZeroRem != SymbolTable_NulSym;
1755 : : break;
1756 : :
1757 : : case M2Range_none:
1758 : : return false;
1759 : 0 : break;
1760 : :
1761 : :
1762 : 0 : default:
1763 : 0 : M2Error_InternalError ((const char *) "enumeration value unknown", 25);
1764 : : break;
1765 : : }
1766 : : ReturnException ("/home/worker/buildworker/tiber-lcov/build/gcc/m2/gm2-compiler/M2Range.def", 20, 1);
1767 : : __builtin_unreachable ();
1768 : : }
1769 : :
1770 : :
1771 : : /*
1772 : : FoldAssignment - attempts to fold the range violation checks.
1773 : : It does not issue errors on type violations as that
1774 : : is performed by FoldTypeAssign.
1775 : : */
1776 : :
1777 : 3221519 : static void FoldAssignment (unsigned int tokenno, unsigned int q, unsigned int r)
1778 : : {
1779 : 3221519 : M2Range_Range p;
1780 : 3221519 : tree min;
1781 : 3221519 : tree max;
1782 : :
1783 : 3221519 : p = static_cast<M2Range_Range> (Indexing_GetIndice (RangeIndex, r));
1784 : 3221519 : M2GCCDeclare_TryDeclareConstant (p->exprtok, p->expr);
1785 : 3221519 : if (p->desLowestType != SymbolTable_NulSym)
1786 : : {
1787 : : /* avoid gcc warning by using compound statement even if not strictly necessary. */
1788 : 1773110 : if (M2Check_AssignmentTypeCompatible (tokenno, (const char *) "", 0, p->des, p->expr, false))
1789 : : {
1790 : : /* avoid dangling else. */
1791 : 1772984 : if (((SymbolConversion_GccKnowsAbout (p->expr)) && (SymbolTable_IsConst (p->expr))) && (M2Range_GetMinMax (tokenno, p->desLowestType, &min, &max)))
1792 : : {
1793 : : /* avoid gcc warning by using compound statement even if not strictly necessary. */
1794 : 314004 : if (OutOfRange (tokenno, min, p->expr, max, p->desLowestType))
1795 : : {
1796 : 54 : M2MetaError_MetaErrorT2 (p->tokenNo, (const char *) "attempting to assign a value {%2Wa} to a designator {%1a} which will exceed the range of type {%1tad}", 101, p->des, p->expr);
1797 : 54 : M2Quads_PutQuad (q, M2Quads_ErrorOp, SymbolTable_NulSym, SymbolTable_NulSym, r);
1798 : : }
1799 : : else
1800 : : {
1801 : 313950 : M2Quads_SubQuad (q);
1802 : : }
1803 : : }
1804 : : }
1805 : : else
1806 : : {
1807 : : /* We do not issue an error if these types are incompatible here
1808 : : as this is done by FoldTypeAssign. */
1809 : 126 : M2Quads_SubQuad (q);
1810 : : }
1811 : : }
1812 : 3221519 : }
1813 : :
1814 : :
1815 : : /*
1816 : : IsCancelled - return the cancelled flag associated with range.
1817 : : */
1818 : :
1819 : 15653220 : static bool IsCancelled (unsigned int range)
1820 : : {
1821 : 15653220 : M2Range_Range p;
1822 : :
1823 : 15653220 : p = static_cast<M2Range_Range> (Indexing_GetIndice (RangeIndex, range));
1824 : 15653220 : if (p->cancelled)
1825 : : {
1826 : : return true;
1827 : : }
1828 : 15653094 : if ((p->dependantid != 0) && (IsCancelled (p->dependantid)))
1829 : : {
1830 : 36 : p->cancelled = true;
1831 : : }
1832 : 15653094 : return p->cancelled;
1833 : : /* static analysis guarentees a RETURN statement will be used before here. */
1834 : : __builtin_unreachable ();
1835 : : }
1836 : :
1837 : :
1838 : : /*
1839 : : Cancel - set the cancelled flag in range.
1840 : : */
1841 : :
1842 : 108 : static void Cancel (unsigned int range)
1843 : : {
1844 : 222 : M2Range_Range p;
1845 : :
1846 : 222 : if (range != 0)
1847 : : {
1848 : 114 : p = static_cast<M2Range_Range> (Indexing_GetIndice (RangeIndex, range));
1849 : 114 : if (! p->cancelled)
1850 : : {
1851 : 114 : p->cancelled = true;
1852 : 114 : Cancel (p->dependantid);
1853 : : }
1854 : : }
1855 : 108 : }
1856 : :
1857 : :
1858 : : /*
1859 : : FoldParameterAssign -
1860 : : */
1861 : :
1862 : 1250691 : static void FoldParameterAssign (unsigned int tokenno, unsigned int q, unsigned int r)
1863 : : {
1864 : 1250691 : M2Range_Range p;
1865 : 1250691 : tree min;
1866 : 1250691 : tree max;
1867 : :
1868 : 1250691 : p = static_cast<M2Range_Range> (Indexing_GetIndice (RangeIndex, r));
1869 : 1250691 : M2GCCDeclare_TryDeclareConstant (p->tokenNo, p->expr);
1870 : 1250691 : if (p->desLowestType != SymbolTable_NulSym)
1871 : : {
1872 : 1250691 : if (((SymbolConversion_GccKnowsAbout (p->expr)) && (SymbolTable_IsConst (p->expr))) && (M2Range_GetMinMax (tokenno, p->desLowestType, &min, &max)))
1873 : : {
1874 : : /* avoid gcc warning by using compound statement even if not strictly necessary. */
1875 : 49635 : if (OutOfRange (tokenno, min, p->expr, max, p->desLowestType))
1876 : : {
1877 : : /* this is safer to treat as an error, rather than a warning
1878 : : otherwise the paramater might be widened
1879 : : (if it is a constant). */
1880 : 0 : M2MetaError_MetaErrorT3 (p->tokenNo, (const char *) "the {%3EN} actual parameter {%2a} will exceed the range of formal parameter type {%1tad}", 88, p->des, p->expr, p->dimension);
1881 : 0 : M2Quads_PutQuad (q, M2Quads_ErrorOp, SymbolTable_NulSym, SymbolTable_NulSym, r);
1882 : : }
1883 : : else
1884 : : {
1885 : 49635 : M2Quads_SubQuad (q);
1886 : : }
1887 : : }
1888 : : }
1889 : 1250691 : }
1890 : :
1891 : :
1892 : : /*
1893 : : FoldReturn - do we know this is reachable, if so generate an error message.
1894 : : */
1895 : :
1896 : 81409 : static void FoldReturn (unsigned int tokenno, unsigned int q, unsigned int r)
1897 : : {
1898 : 81409 : M2Range_Range p;
1899 : 81409 : tree min;
1900 : 81409 : tree max;
1901 : :
1902 : 81409 : p = static_cast<M2Range_Range> (Indexing_GetIndice (RangeIndex, r));
1903 : 81409 : M2GCCDeclare_TryDeclareConstant (p->tokenNo, p->expr);
1904 : 81409 : if (p->desLowestType != SymbolTable_NulSym)
1905 : : {
1906 : 81409 : if (((SymbolConversion_GccKnowsAbout (p->expr)) && (SymbolTable_IsConst (p->expr))) && (M2Range_GetMinMax (tokenno, p->desLowestType, &min, &max)))
1907 : : {
1908 : : /* avoid gcc warning by using compound statement even if not strictly necessary. */
1909 : 10981 : if (OutOfRange (tokenno, min, p->expr, max, p->desLowestType))
1910 : : {
1911 : 6 : M2MetaError_MetaErrorT2 (p->tokenNo, (const char *) "attempting to return {%2Wa} from a procedure function {%1a} which will exceed exceed the range of type {%1tad}", 110, p->des, p->expr);
1912 : 6 : M2Quads_PutQuad (q, M2Quads_ErrorOp, SymbolTable_NulSym, SymbolTable_NulSym, r);
1913 : : }
1914 : : else
1915 : : {
1916 : 10975 : M2Quads_SubQuad (q);
1917 : : }
1918 : : }
1919 : : }
1920 : 81409 : }
1921 : :
1922 : :
1923 : : /*
1924 : : FoldInc -
1925 : : */
1926 : :
1927 : 62952 : static void FoldInc (unsigned int tokenno, unsigned int q, unsigned int r)
1928 : : {
1929 : 62952 : M2Range_Range p;
1930 : 62952 : tree t;
1931 : 62952 : tree min;
1932 : 62952 : tree max;
1933 : 62952 : location_t location;
1934 : :
1935 : 62952 : location = M2LexBuf_TokenToLocation (tokenno);
1936 : 62952 : p = static_cast<M2Range_Range> (Indexing_GetIndice (RangeIndex, r));
1937 : 62952 : M2GCCDeclare_TryDeclareConstant (tokenno, p->des); /* use quad tokenno, rather than the range tokenNo */
1938 : 62952 : M2GCCDeclare_TryDeclareConstant (tokenno, p->expr); /* use quad tokenno, rather than the range tokenNo */
1939 : 62952 : if (p->desLowestType != SymbolTable_NulSym) /* use quad tokenno, rather than the range tokenNo */
1940 : : {
1941 : 62952 : if (((SymbolConversion_GccKnowsAbout (p->expr)) && (SymbolTable_IsConst (p->expr))) && (M2Range_GetMinMax (tokenno, p->desLowestType, &min, &max)))
1942 : : {
1943 : : /* avoid gcc warning by using compound statement even if not strictly necessary. */
1944 : 45216 : if (OutOfRange (tokenno, m2expr_GetIntegerZero (location), p->expr, max, p->desLowestType))
1945 : : {
1946 : 0 : M2MetaError_MetaErrorT2 (p->tokenNo, (const char *) "operand to INC {%2Wa} exceeds the range of type {%1ts} of the designator {%1a}", 78, p->des, p->expr);
1947 : 0 : M2Quads_PutQuad (q, M2Quads_ErrorOp, SymbolTable_NulSym, SymbolTable_NulSym, r);
1948 : : }
1949 : 45216 : else if (((SymbolConversion_GccKnowsAbout (p->des)) && (SymbolTable_IsConst (p->des))) && (SymbolConversion_GccKnowsAbout (p->desLowestType)))
1950 : : {
1951 : : /* avoid dangling else. */
1952 : 0 : t = m2expr_BuildSub (location, max, m2convert_BuildConvert (location, SymbolConversion_Mod2Gcc (p->desLowestType), SymbolConversion_Mod2Gcc (p->expr), false), false);
1953 : 0 : M2ALU_PushIntegerTree (SymbolConversion_Mod2Gcc (p->des));
1954 : 0 : M2ALU_PushIntegerTree (t);
1955 : 0 : if (M2ALU_Gre (p->tokenNo))
1956 : : {
1957 : 0 : M2MetaError_MetaErrorT1 (p->tokenNo, (const char *) "the designator to INC {%1Wa} will exceed the range of type {%1ts}", 65, p->des);
1958 : 0 : M2Quads_PutQuad (q, M2Quads_ErrorOp, SymbolTable_NulSym, SymbolTable_NulSym, r);
1959 : : }
1960 : : else
1961 : : {
1962 : : /* range check is unnecessary */
1963 : 0 : M2Quads_SubQuad (q);
1964 : : }
1965 : : }
1966 : : }
1967 : : }
1968 : 62952 : }
1969 : :
1970 : :
1971 : : /*
1972 : : FoldDec -
1973 : : */
1974 : :
1975 : 62508 : static void FoldDec (unsigned int tokenno, unsigned int q, unsigned int r)
1976 : : {
1977 : 62508 : M2Range_Range p;
1978 : 62508 : tree t;
1979 : 62508 : tree min;
1980 : 62508 : tree max;
1981 : 62508 : location_t location;
1982 : :
1983 : 62508 : location = M2LexBuf_TokenToLocation (tokenno);
1984 : 62508 : p = static_cast<M2Range_Range> (Indexing_GetIndice (RangeIndex, r));
1985 : 62508 : M2GCCDeclare_TryDeclareConstant (tokenno, p->des); /* use quad tokenno, rather than the range tokenNo */
1986 : 62508 : M2GCCDeclare_TryDeclareConstant (tokenno, p->expr); /* use quad tokenno, rather than the range tokenNo */
1987 : 62508 : if (p->desLowestType != SymbolTable_NulSym) /* use quad tokenno, rather than the range tokenNo */
1988 : : {
1989 : 62508 : if (((SymbolConversion_GccKnowsAbout (p->expr)) && (SymbolTable_IsConst (p->expr))) && (M2Range_GetMinMax (tokenno, p->desLowestType, &min, &max)))
1990 : : {
1991 : : /* avoid gcc warning by using compound statement even if not strictly necessary. */
1992 : 44748 : if (OutOfRange (tokenno, m2expr_GetIntegerZero (location), p->expr, max, p->desLowestType))
1993 : : {
1994 : 0 : M2MetaError_MetaErrorT2 (p->tokenNo, (const char *) "operand to DEC {%2Wa} exceeds the range of type {%1ts} of the designator {%1a}", 78, p->des, p->expr);
1995 : 0 : M2Quads_PutQuad (q, M2Quads_ErrorOp, SymbolTable_NulSym, SymbolTable_NulSym, r);
1996 : : }
1997 : 44748 : else if (((SymbolConversion_GccKnowsAbout (p->des)) && (SymbolTable_IsConst (p->des))) && (SymbolConversion_GccKnowsAbout (p->desLowestType)))
1998 : : {
1999 : : /* avoid dangling else. */
2000 : 0 : t = m2expr_BuildSub (location, m2convert_BuildConvert (location, SymbolConversion_Mod2Gcc (p->desLowestType), SymbolConversion_Mod2Gcc (p->expr), false), min, false);
2001 : 0 : M2ALU_PushIntegerTree (SymbolConversion_Mod2Gcc (p->des));
2002 : 0 : M2ALU_PushIntegerTree (t);
2003 : 0 : if (M2ALU_Less (p->tokenNo))
2004 : : {
2005 : 0 : M2MetaError_MetaErrorT1 (p->tokenNo, (const char *) "the designator to DEC {%1Wa} will exceed the range of type {%1ts}", 65, p->des);
2006 : 0 : M2Quads_PutQuad (q, M2Quads_ErrorOp, SymbolTable_NulSym, SymbolTable_NulSym, r);
2007 : : }
2008 : : else
2009 : : {
2010 : : /* range check is unnecessary */
2011 : 0 : M2Quads_SubQuad (q);
2012 : : }
2013 : : }
2014 : : }
2015 : : }
2016 : 62508 : }
2017 : :
2018 : :
2019 : : /*
2020 : : CheckSetAndBit - returns TRUE if des is a set type and expr is compatible with des.
2021 : : */
2022 : :
2023 : 38078 : static bool CheckSetAndBit (unsigned int tokenno, unsigned int des, unsigned int expr, const char *name_, unsigned int _name_high)
2024 : : {
2025 : 38078 : DynamicStrings_String s;
2026 : 38078 : char name[_name_high+1];
2027 : :
2028 : : /* make a local copy of each unbounded array. */
2029 : 38078 : memcpy (name, name_, _name_high+1);
2030 : :
2031 : 38078 : if (SymbolTable_IsSet (des))
2032 : : {
2033 : 38078 : if (M2Base_IsExpressionCompatible (SymbolTable_GetType (des), SymbolTable_GetType (expr)))
2034 : : {
2035 : : return true;
2036 : : }
2037 : : else
2038 : : {
2039 : 24 : s = DynamicStrings_ConCat (DynamicStrings_ConCat (DynamicStrings_InitString ((const char *) "operands to ", 12), DynamicStrings_Mark (DynamicStrings_InitString ((const char *) name, _name_high))), DynamicStrings_Mark (DynamicStrings_InitString ((const char *) " {%1Etsd:{%2tsd:{%1tsd} and {%2tsd}}} are incompatible", 54)));
2040 : 24 : M2MetaError_MetaErrorStringT2 (tokenno, s, des, expr);
2041 : 24 : M2Error_FlushErrors ();
2042 : : }
2043 : : }
2044 : : else
2045 : : {
2046 : 0 : s = DynamicStrings_ConCat (DynamicStrings_ConCat (DynamicStrings_InitString ((const char *) "first operand to ", 17), DynamicStrings_Mark (DynamicStrings_InitString ((const char *) name, _name_high))), DynamicStrings_Mark (DynamicStrings_InitString ((const char *) " is not a set {%1Etasd}", 23)));
2047 : 0 : M2MetaError_MetaErrorStringT1 (tokenno, s, des);
2048 : 0 : M2Error_FlushErrors ();
2049 : : }
2050 : : return false;
2051 : : /* static analysis guarentees a RETURN statement will be used before here. */
2052 : : __builtin_unreachable ();
2053 : 38078 : }
2054 : :
2055 : :
2056 : : /*
2057 : : CheckSet - returns TRUE if des is a set type and expr is compatible with INTEGER.
2058 : : */
2059 : :
2060 : 19166 : static bool CheckSet (unsigned int tokenno, unsigned int des, unsigned int expr, const char *name_, unsigned int _name_high)
2061 : : {
2062 : 19166 : DynamicStrings_String s;
2063 : 19166 : char name[_name_high+1];
2064 : :
2065 : : /* make a local copy of each unbounded array. */
2066 : 19166 : memcpy (name, name_, _name_high+1);
2067 : :
2068 : 19166 : if (SymbolTable_IsSet (des))
2069 : : {
2070 : 19166 : if (M2Base_IsParameterCompatible (M2Base_Integer, SymbolTable_GetType (expr)))
2071 : : {
2072 : : return true;
2073 : : }
2074 : : else
2075 : : {
2076 : 0 : s = DynamicStrings_ConCat (DynamicStrings_ConCat (DynamicStrings_InitString ((const char *) "operands to ", 12), DynamicStrings_Mark (DynamicStrings_InitString ((const char *) name, _name_high))), DynamicStrings_Mark (DynamicStrings_InitString ((const char *) " {%1Etsd:{%2tsd:{%1tsd} and {%2tsd}}} are incompatible", 54)));
2077 : 0 : M2MetaError_MetaErrorStringT2 (tokenno, s, des, expr);
2078 : 0 : M2Error_FlushErrors ();
2079 : : }
2080 : : }
2081 : : else
2082 : : {
2083 : 0 : s = DynamicStrings_ConCat (DynamicStrings_ConCat (DynamicStrings_InitString ((const char *) "first operand to ", 17), DynamicStrings_Mark (DynamicStrings_InitString ((const char *) name, _name_high))), DynamicStrings_Mark (DynamicStrings_InitString ((const char *) " is not a set {%1Etasd}", 23)));
2084 : 0 : M2MetaError_MetaErrorStringT1 (tokenno, s, des);
2085 : 0 : M2Error_FlushErrors ();
2086 : : }
2087 : : return false;
2088 : : /* static analysis guarentees a RETURN statement will be used before here. */
2089 : : __builtin_unreachable ();
2090 : 19166 : }
2091 : :
2092 : :
2093 : : /*
2094 : : FoldIncl - folds an INCL statement if the operands are constant.
2095 : : */
2096 : :
2097 : 22478 : static void FoldIncl (unsigned int tokenno, unsigned int q, unsigned int r)
2098 : : {
2099 : 22478 : M2Range_Range p;
2100 : 22478 : tree min;
2101 : 22478 : tree max;
2102 : :
2103 : 22478 : p = static_cast<M2Range_Range> (Indexing_GetIndice (RangeIndex, r));
2104 : 22478 : M2GCCDeclare_TryDeclareConstant (tokenno, p->des); /* use quad tokenno, rather than the range tokenNo */
2105 : 22478 : M2GCCDeclare_TryDeclareConstant (tokenno, p->expr); /* use quad tokenno, rather than the range tokenNo */
2106 : 22478 : p->desLowestType = SymbolTable_SkipType (SymbolTable_GetType (p->des)); /* use quad tokenno, rather than the range tokenNo */
2107 : 22478 : if (p->desLowestType != SymbolTable_NulSym)
2108 : : {
2109 : 22478 : if (CheckSetAndBit (tokenno, p->desLowestType, p->expr, (const char *) "INCL", 4))
2110 : : {
2111 : 22460 : if (((SymbolConversion_GccKnowsAbout (p->expr)) && (SymbolTable_IsConst (p->expr))) && (M2Range_GetMinMax (tokenno, p->desLowestType, &min, &max)))
2112 : : {
2113 : : /* avoid gcc warning by using compound statement even if not strictly necessary. */
2114 : 0 : if (OutOfRange (tokenno, min, p->expr, max, p->desLowestType))
2115 : : {
2116 : 0 : M2MetaError_MetaErrorT2 (p->tokenNo, (const char *) "operand to INCL {%2Wa} exceeds the range of type {%1tasa}", 57, p->des, p->expr);
2117 : 0 : M2Quads_PutQuad (q, M2Quads_ErrorOp, SymbolTable_NulSym, SymbolTable_NulSym, r);
2118 : : }
2119 : : else
2120 : : {
2121 : : /* range check is unnecessary */
2122 : 0 : M2Quads_SubQuad (q);
2123 : : }
2124 : : }
2125 : : }
2126 : : }
2127 : 22460 : }
2128 : :
2129 : :
2130 : : /*
2131 : : FoldExcl - folds an EXCL statement if the operands are constant.
2132 : : */
2133 : :
2134 : 15600 : static void FoldExcl (unsigned int tokenno, unsigned int q, unsigned int r)
2135 : : {
2136 : 15600 : M2Range_Range p;
2137 : 15600 : tree min;
2138 : 15600 : tree max;
2139 : :
2140 : 15600 : p = static_cast<M2Range_Range> (Indexing_GetIndice (RangeIndex, r));
2141 : 15600 : M2GCCDeclare_TryDeclareConstant (tokenno, p->des); /* use quad tokenno, rather than the range tokenNo */
2142 : 15600 : M2GCCDeclare_TryDeclareConstant (tokenno, p->expr); /* use quad tokenno, rather than the range tokenNo */
2143 : 15600 : p->desLowestType = SymbolTable_SkipType (SymbolTable_GetType (p->des)); /* use quad tokenno, rather than the range tokenNo */
2144 : 15600 : if (p->desLowestType != SymbolTable_NulSym)
2145 : : {
2146 : 15600 : if (CheckSetAndBit (tokenno, p->desLowestType, p->expr, (const char *) "EXCL", 4))
2147 : : {
2148 : 15594 : if (((SymbolConversion_GccKnowsAbout (p->expr)) && (SymbolTable_IsConst (p->expr))) && (M2Range_GetMinMax (tokenno, p->desLowestType, &min, &max)))
2149 : : {
2150 : : /* avoid gcc warning by using compound statement even if not strictly necessary. */
2151 : 0 : if (OutOfRange (tokenno, min, p->expr, max, p->desLowestType))
2152 : : {
2153 : 0 : M2MetaError_MetaErrorT2 (p->tokenNo, (const char *) "operand to EXCL {%2Wa} exceeds the range of type {%1tasa}", 57, p->des, p->expr);
2154 : 0 : M2Quads_PutQuad (q, M2Quads_ErrorOp, SymbolTable_NulSym, SymbolTable_NulSym, r);
2155 : : }
2156 : : else
2157 : : {
2158 : : /* range check is unnecessary */
2159 : 0 : M2Quads_SubQuad (q);
2160 : : }
2161 : : }
2162 : : }
2163 : : }
2164 : 15594 : }
2165 : :
2166 : :
2167 : : /*
2168 : : FoldShift - folds an SHIFT test statement if the operands are constant.
2169 : : */
2170 : :
2171 : 7970 : static void FoldShift (unsigned int tokenno, unsigned int q, unsigned int r)
2172 : : {
2173 : 7970 : unsigned int ofType;
2174 : 7970 : M2Range_Range p;
2175 : 7970 : tree shiftMin;
2176 : 7970 : tree shiftMax;
2177 : 7970 : tree min;
2178 : 7970 : tree max;
2179 : 7970 : location_t location;
2180 : :
2181 : 7970 : location = M2LexBuf_TokenToLocation (tokenno);
2182 : 7970 : p = static_cast<M2Range_Range> (Indexing_GetIndice (RangeIndex, r));
2183 : 7970 : M2GCCDeclare_TryDeclareConstant (tokenno, p->des); /* use quad tokenno, rather than the range tokenNo */
2184 : 7970 : M2GCCDeclare_TryDeclareConstant (tokenno, p->expr); /* use quad tokenno, rather than the range tokenNo */
2185 : 7970 : p->desLowestType = SymbolTable_SkipType (SymbolTable_GetType (p->des)); /* use quad tokenno, rather than the range tokenNo */
2186 : 7970 : if (p->desLowestType != SymbolTable_NulSym)
2187 : : {
2188 : 7970 : if (CheckSet (tokenno, p->desLowestType, p->expr, (const char *) "SHIFT", 5))
2189 : : {
2190 : 7970 : ofType = SymbolTable_SkipType (SymbolTable_GetType (p->desLowestType));
2191 : 7970 : if ((((SymbolConversion_GccKnowsAbout (ofType)) && (SymbolConversion_GccKnowsAbout (p->expr))) && (SymbolTable_IsConst (p->expr))) && (M2Range_GetMinMax (tokenno, ofType, &min, &max)))
2192 : : {
2193 : 388 : min = m2convert_BuildConvert (location, m2type_GetIntegerType (), min, false);
2194 : 388 : max = m2convert_BuildConvert (location, m2type_GetIntegerType (), max, false);
2195 : 388 : shiftMax = m2expr_BuildAdd (location, m2expr_BuildSub (location, max, min, false), m2expr_GetIntegerOne (location), false);
2196 : 388 : shiftMin = m2expr_BuildNegate (location, shiftMax, false);
2197 : 388 : if (OutOfRange (tokenno, shiftMin, p->expr, shiftMax, p->desLowestType))
2198 : : {
2199 : 12 : M2MetaError_MetaErrorT2 (p->tokenNo, (const char *) "operand to SHIFT {%2Wa} exceeds the range of type {%1tasa}", 58, p->des, p->expr);
2200 : 12 : M2Quads_PutQuad (q, M2Quads_ErrorOp, SymbolTable_NulSym, SymbolTable_NulSym, r);
2201 : : }
2202 : : else
2203 : : {
2204 : : /* range check is unnecessary */
2205 : 376 : M2Quads_SubQuad (q);
2206 : : }
2207 : : }
2208 : : }
2209 : : }
2210 : 7970 : }
2211 : :
2212 : :
2213 : : /*
2214 : : FoldRotate - folds a ROTATE test statement if the operands are constant.
2215 : : */
2216 : :
2217 : 11196 : static void FoldRotate (unsigned int tokenno, unsigned int q, unsigned int r)
2218 : : {
2219 : 11196 : unsigned int ofType;
2220 : 11196 : M2Range_Range p;
2221 : 11196 : tree rotateMin;
2222 : 11196 : tree rotateMax;
2223 : 11196 : tree min;
2224 : 11196 : tree max;
2225 : 11196 : location_t location;
2226 : :
2227 : 11196 : location = M2LexBuf_TokenToLocation (tokenno);
2228 : 11196 : p = static_cast<M2Range_Range> (Indexing_GetIndice (RangeIndex, r));
2229 : 11196 : M2GCCDeclare_TryDeclareConstant (tokenno, p->des); /* use quad tokenno, rather than the range tokenNo */
2230 : 11196 : M2GCCDeclare_TryDeclareConstant (tokenno, p->expr); /* use quad tokenno, rather than the range tokenNo */
2231 : 11196 : p->desLowestType = SymbolTable_SkipType (SymbolTable_GetType (p->des)); /* use quad tokenno, rather than the range tokenNo */
2232 : 11196 : if (p->desLowestType != SymbolTable_NulSym)
2233 : : {
2234 : 11196 : if (CheckSet (tokenno, p->desLowestType, p->expr, (const char *) "ROTATE", 6))
2235 : : {
2236 : 11196 : ofType = SymbolTable_SkipType (SymbolTable_GetType (p->desLowestType));
2237 : 11196 : if ((((SymbolConversion_GccKnowsAbout (ofType)) && (SymbolConversion_GccKnowsAbout (p->expr))) && (SymbolTable_IsConst (p->expr))) && (M2Range_GetMinMax (tokenno, ofType, &min, &max)))
2238 : : {
2239 : 276 : min = m2convert_BuildConvert (location, m2type_GetIntegerType (), min, false);
2240 : 276 : max = m2convert_BuildConvert (location, m2type_GetIntegerType (), max, false);
2241 : 276 : rotateMax = m2expr_BuildAdd (location, m2expr_BuildSub (location, max, min, false), m2expr_GetIntegerOne (location), false);
2242 : 276 : rotateMin = m2expr_BuildNegate (location, rotateMax, false);
2243 : 276 : if (OutOfRange (tokenno, rotateMin, p->expr, rotateMax, p->desLowestType))
2244 : : {
2245 : 12 : M2MetaError_MetaErrorT2 (p->tokenNo, (const char *) "operand to ROTATE {%2Wa} exceeds the range of type {%1tasa}", 59, p->des, p->expr);
2246 : 12 : M2Quads_PutQuad (q, M2Quads_ErrorOp, SymbolTable_NulSym, SymbolTable_NulSym, r);
2247 : : }
2248 : : else
2249 : : {
2250 : : /* range check is unnecessary */
2251 : 264 : M2Quads_SubQuad (q);
2252 : : }
2253 : : }
2254 : : }
2255 : : }
2256 : 11196 : }
2257 : :
2258 : :
2259 : : /*
2260 : : FoldTypeReturnFunc - checks to see that val can be returned from func.
2261 : : */
2262 : :
2263 : 14933 : static void FoldTypeReturnFunc (unsigned int q, unsigned int tokenNo, unsigned int func, unsigned int val, unsigned int r)
2264 : : {
2265 : 14933 : unsigned int valType;
2266 : 14933 : unsigned int returnType;
2267 : :
2268 : 14933 : returnType = SymbolTable_GetType (func);
2269 : 14933 : if (returnType == SymbolTable_NulSym)
2270 : : {
2271 : : /* avoid dangling else. */
2272 : 0 : if (! (reportedError (r)))
2273 : : {
2274 : 0 : M2MetaError_MetaErrorsT2 (tokenNo, (const char *) "procedure {%1Da} is not a procedure function", 44, (const char *) "{%2ad} cannot be returned from {%1Da}", 37, func, val);
2275 : 0 : M2Quads_SubQuad (q);
2276 : : }
2277 : : }
2278 : : else
2279 : : {
2280 : 14933 : valType = val;
2281 : 14933 : if ((SymbolTable_IsVar (val)) && ((SymbolTable_GetMode (val)) == SymbolTable_LeftValue))
2282 : : {
2283 : 12 : valType = SymbolTable_GetType (val);
2284 : : }
2285 : 14933 : if (M2Check_AssignmentTypeCompatible (tokenNo, (const char *) "", 0, returnType, valType, false))
2286 : : {
2287 : 14927 : M2Quads_SubQuad (q);
2288 : : }
2289 : : else
2290 : : {
2291 : 6 : if (! (reportedError (r)))
2292 : : {
2293 : 6 : M2MetaError_MetaErrorsT2 (tokenNo, (const char *) "the return type {%1Etad} used in procedure {%1Da}", 49, (const char *) "is incompatible with the returned expression {%1ad}}", 52, func, val);
2294 : 6 : setReported (r);
2295 : 6 : M2Error_FlushErrors ();
2296 : : }
2297 : : }
2298 : : }
2299 : 14927 : }
2300 : :
2301 : :
2302 : : /*
2303 : : FoldTypeAssign -
2304 : : */
2305 : :
2306 : 319052 : static void FoldTypeAssign (unsigned int q, unsigned int tokenNo, unsigned int des, unsigned int expr, unsigned int r)
2307 : : {
2308 : 319052 : if (! (reportedError (r)))
2309 : : {
2310 : : /* avoid gcc warning by using compound statement even if not strictly necessary. */
2311 : 319052 : if (M2Check_AssignmentTypeCompatible (tokenNo, (const char *) "assignment designator {%1Ea} {%1ta:of type {%1ta}} cannot be assigned with {%2ad: a {%2td} {%2ad}}{!%2ad: {%2ad} of type {%2tad}}", 129, des, expr, true))
2312 : : {
2313 : 318926 : M2Quads_SubQuad (q);
2314 : : }
2315 : : else
2316 : : {
2317 : 126 : setReported (r);
2318 : 126 : M2Error_FlushErrors ();
2319 : : }
2320 : : }
2321 : 318926 : }
2322 : :
2323 : :
2324 : : /*
2325 : : FoldTypeIndrX - check to see that des = *expr is type compatible.
2326 : : */
2327 : :
2328 : 0 : static void FoldTypeIndrX (unsigned int q, unsigned int tokenNo, unsigned int des, unsigned int expr, unsigned int r)
2329 : : {
2330 : 0 : unsigned int exprType;
2331 : :
2332 : : /* Need to skip over a variable or temporary in des and expr so
2333 : : long as expr is not a procedure. In the case of des = *expr,
2334 : : both expr and des will be variables due to the property of
2335 : : indirection. */
2336 : 0 : if (SymbolTable_IsProcedure (expr))
2337 : : {
2338 : : /* Must not GetType for a procedure as it gives the return type. */
2339 : : exprType = expr;
2340 : : }
2341 : : else
2342 : : {
2343 : 0 : exprType = SymbolTable_GetType (expr);
2344 : : }
2345 : 0 : if (M2Check_AssignmentTypeCompatible (tokenNo, (const char *) "", 0, SymbolTable_GetType (des), SymbolTable_GetType (expr), false))
2346 : : {
2347 : 0 : M2Quads_SubQuad (q);
2348 : : }
2349 : : else
2350 : : {
2351 : 0 : if (! (reportedError (r)))
2352 : : {
2353 : 0 : if (SymbolTable_IsProcedure (des))
2354 : : {
2355 : 0 : M2MetaError_MetaErrorsT2 (tokenNo, (const char *) "the return type {%1Etad} declared in procedure {%1Da}", 53, (const char *) "is incompatible with the returned expression {%2ad}}", 52, des, expr);
2356 : : }
2357 : : else
2358 : : {
2359 : 0 : M2MetaError_MetaErrorT3 (tokenNo, (const char *) "assignment designator {%1Ea} {%1ta:of type {%1ta}} {%1d:is a {%1d}} and expression {%2a} {%3ad:of type {%3ad}} are incompatible", 127, des, expr, exprType);
2360 : : }
2361 : 0 : setReported (r);
2362 : 0 : M2Error_FlushErrors ();
2363 : : }
2364 : : }
2365 : 0 : }
2366 : :
2367 : :
2368 : : /*
2369 : : FoldTypeParam - performs a parameter check between actual and formal.
2370 : : The quad is removed if the check succeeds.
2371 : : */
2372 : :
2373 : 374894 : static void FoldTypeParam (unsigned int q, unsigned int tokenNo, unsigned int formal, unsigned int actual, unsigned int procedure, unsigned int paramNo, unsigned int depRangeId)
2374 : : {
2375 : 374894 : bool compatible;
2376 : :
2377 : 374894 : compatible = false;
2378 : 374894 : if (SymbolTable_IsVarParamAny (procedure, paramNo))
2379 : : {
2380 : : /* Expression type compatibility rules for pass by reference parameters. */
2381 : 10640 : compatible = M2Check_ParameterTypeCompatible (tokenNo, (const char *) "{%4EN} parameter failure due to expression incompatibility between actual parameter {%3ad} and the {%4N} formal {%2ad} parameter in procedure {%1ad}", 148, procedure, formal, actual, paramNo, true);
2382 : : }
2383 : 364254 : else if (M2Options_GetPIM ())
2384 : : {
2385 : : /* avoid dangling else. */
2386 : : /* Assignment type compatibility rules for pass by value PIM parameters. */
2387 : 276630 : compatible = M2Check_ParameterTypeCompatible (tokenNo, (const char *) "{%4EN} parameter failure due to assignment incompatibility between actual parameter {%3ad} and the {%4N} formal {%2ad} parameter in procedure {%1ad}", 148, procedure, formal, actual, paramNo, false);
2388 : : }
2389 : : else
2390 : : {
2391 : : /* avoid dangling else. */
2392 : 87624 : compatible = M2Check_ParameterTypeCompatible (tokenNo, (const char *) "{%4EN} parameter failure due to parameter incompatibility between actual parameter {%3ad} and the {%4N} formal {%2ad} parameter in procedure {%1ad}", 147, procedure, formal, actual, paramNo, false);
2393 : : }
2394 : 374894 : if (compatible)
2395 : : {
2396 : 374786 : M2Quads_SubQuad (q);
2397 : : }
2398 : : else
2399 : : {
2400 : 108 : Cancel (depRangeId);
2401 : : }
2402 : 374894 : }
2403 : :
2404 : :
2405 : : /*
2406 : : FoldTypeExpr -
2407 : : */
2408 : :
2409 : 80172 : static void FoldTypeExpr (unsigned int q, unsigned int tokenNo, unsigned int left, unsigned int right, bool strict, bool isin, unsigned int r)
2410 : : {
2411 : 160344 : if (((left != SymbolTable_NulSym) && (right != SymbolTable_NulSym)) && (! (reportedError (r))))
2412 : : {
2413 : : /* avoid gcc warning by using compound statement even if not strictly necessary. */
2414 : 79890 : if (M2Check_ExpressionTypeCompatible (tokenNo, (const char *) "expression of type {%1Etad} is incompatible with type {%2tad}", 61, left, right, strict, isin))
2415 : : {
2416 : 79788 : M2Quads_SubQuad (q);
2417 : : }
2418 : : else
2419 : : {
2420 : 102 : setReported (r);
2421 : : }
2422 : : }
2423 : 80172 : }
2424 : :
2425 : :
2426 : : /*
2427 : : CodeTypeAssign -
2428 : : */
2429 : :
2430 : 170791 : static void CodeTypeAssign (unsigned int tokenNo, unsigned int des, unsigned int expr, unsigned int r)
2431 : : {
2432 : 170791 : if (! (M2Check_AssignmentTypeCompatible (tokenNo, (const char *) "", 0, des, expr, false)))
2433 : : {
2434 : 12 : if (! (reportedError (r)))
2435 : : {
2436 : 12 : M2MetaError_MetaErrorT2 (tokenNo, (const char *) "assignment designator {%1Ea} {%1ta:of type {%1ta}} {%1d:is a {%1dv}} and expression {%2a} {%2tad:of type {%2tad}} are incompatible", 130, des, expr);
2437 : : }
2438 : 12 : setReported (r);
2439 : : }
2440 : 170791 : }
2441 : :
2442 : :
2443 : : /*
2444 : : CodeTypeReturnFunc -
2445 : : */
2446 : :
2447 : 12688 : static void CodeTypeReturnFunc (unsigned int tokenNo, unsigned int func, unsigned int val, unsigned int r)
2448 : : {
2449 : 12688 : unsigned int valType;
2450 : 12688 : unsigned int returnType;
2451 : :
2452 : 12688 : returnType = SymbolTable_GetType (func);
2453 : 12688 : if (returnType == SymbolTable_NulSym)
2454 : : {
2455 : : /* avoid dangling else. */
2456 : 0 : if (! (reportedError (r)))
2457 : : {
2458 : 0 : M2MetaError_MetaErrorsT2 (tokenNo, (const char *) "procedure {%1Da} is not a procedure function", 44, (const char *) "{%2ad} cannot be returned from {%1Da}", 37, func, val);
2459 : : }
2460 : : }
2461 : : else
2462 : : {
2463 : 12688 : valType = val;
2464 : 12688 : if ((SymbolTable_IsVar (val)) && ((SymbolTable_GetMode (val)) == SymbolTable_LeftValue))
2465 : : {
2466 : 160 : valType = SymbolTable_GetType (val);
2467 : : }
2468 : 12688 : if (! (M2Check_AssignmentTypeCompatible (tokenNo, (const char *) "", 0, returnType, valType, false)))
2469 : : {
2470 : 0 : if (! (reportedError (r)))
2471 : : {
2472 : 0 : M2MetaError_MetaErrorsT2 (tokenNo, (const char *) "the return type {%1Etad} used in procedure function {%1Da}", 58, (const char *) "is incompatible with the returned expression {%2EUa} {%2tad:of type {%2tad}}", 76, func, val);
2473 : : }
2474 : : }
2475 : : }
2476 : 12688 : }
2477 : :
2478 : :
2479 : : /*
2480 : : CodeTypeIndrX - checks that des = *expr is type compatible and generates an error if they
2481 : : are not compatible. It skips over the LValue type so that to allow
2482 : : the error messages to pick up the source variable name rather than
2483 : : a temporary name or vague name 'expression'.
2484 : : */
2485 : :
2486 : 512 : static void CodeTypeIndrX (unsigned int tokenNo, unsigned int des, unsigned int expr, unsigned int r)
2487 : : {
2488 : 512 : if (! (M2Check_AssignmentTypeCompatible (tokenNo, (const char *) "", 0, SymbolTable_GetType (des), SymbolTable_GetType (expr), false)))
2489 : : {
2490 : 6 : if (! (reportedError (r)))
2491 : : {
2492 : 6 : if (SymbolTable_IsProcedure (des))
2493 : : {
2494 : 0 : M2MetaError_MetaErrorsT2 (tokenNo, (const char *) "the return type {%1Etad} declared in procedure {%1Da}", 53, (const char *) "is incompatible with the returned expression {%2EUa} {%2tad:of type {%2tad}}", 76, des, expr);
2495 : : }
2496 : : else
2497 : : {
2498 : 6 : M2MetaError_MetaErrorT2 (tokenNo, (const char *) "assignment designator {%1Ea} {%1ta:of type {%1ta}} {%1d:is a {%1dv}} and expression {%2a} {%2tad:of type {%2tad}} are incompatible", 130, des, expr);
2499 : : }
2500 : 6 : setReported (r);
2501 : : }
2502 : : /* FlushErrors */
2503 : : }
2504 : 512 : }
2505 : :
2506 : :
2507 : : /*
2508 : : CodeTypeParam -
2509 : : */
2510 : :
2511 : 239476 : static void CodeTypeParam (unsigned int tokenNo, unsigned int formal, unsigned int actual, unsigned int procedure, unsigned int paramNo)
2512 : : {
2513 : 239476 : if (! (M2Check_ParameterTypeCompatible (tokenNo, (const char *) "{%4EN} type failure between actual {%3ad} and the formal {%2ad}", 63, procedure, formal, actual, paramNo, SymbolTable_IsVarParamAny (procedure, paramNo))))
2514 : : {} /* empty. */
2515 : 239476 : }
2516 : :
2517 : :
2518 : : /*
2519 : : CodeTypeExpr -
2520 : : */
2521 : :
2522 : 68269 : static void CodeTypeExpr (unsigned int tokenNo, unsigned int left, unsigned int right, bool strict, bool isin, unsigned int r)
2523 : : {
2524 : 68269 : if (! (reportedError (r)))
2525 : : {
2526 : 68185 : if (M2Check_ExpressionTypeCompatible (tokenNo, (const char *) "expression of type {%1Etad} is incompatible with type {%2tad}", 61, left, right, strict, isin))
2527 : : {
2528 : 68167 : setReported (r);
2529 : : }
2530 : : }
2531 : 68269 : }
2532 : :
2533 : :
2534 : : /*
2535 : : FoldTypeCheck - folds a type check. This is a no-op and it used
2536 : : for checking types which are resolved post pass 3.
2537 : : */
2538 : :
2539 : 8769336 : static void FoldTypeCheck (unsigned int tokenno, unsigned int q, unsigned int r)
2540 : : {
2541 : 8769336 : M2Range_Range p;
2542 : :
2543 : 8769336 : p = static_cast<M2Range_Range> (Indexing_GetIndice (RangeIndex, r));
2544 : 8769336 : M2GCCDeclare_TryDeclareConstant (tokenno, p->des); /* use quad tokenno, rather than the range tokenNo */
2545 : 8769336 : M2GCCDeclare_TryDeclareConstant (tokenno, p->expr); /* use quad tokenno, rather than the range tokenNo */
2546 : : /* TryDeclareConstructor(q, expr) ; */
2547 : 8769330 : if (((SymbolConversion_GccKnowsAbout (p->des)) || ((SymbolTable_IsParameter (p->des)) && (SymbolConversion_GccKnowsAbout (SymbolTable_GetType (p->des))))) && (SymbolConversion_GccKnowsAbout (p->expr)))
2548 : : {
2549 : 789051 : switch (p->type)
2550 : : {
2551 : 319052 : case M2Range_typeassign:
2552 : 319052 : FoldTypeAssign (q, p->tokenNo, p->des, p->expr, r);
2553 : 319052 : break;
2554 : :
2555 : 374894 : case M2Range_typeparam:
2556 : 374894 : FoldTypeParam (q, p->tokenNo, p->des, p->expr, p->procedure, p->paramNo, r);
2557 : 374894 : break;
2558 : :
2559 : 80172 : case M2Range_typeexpr:
2560 : 80172 : FoldTypeExpr (q, p->tokenNo, p->des, p->expr, p->strict, p->isin, r);
2561 : 80172 : break;
2562 : :
2563 : 0 : case M2Range_typeindrx:
2564 : 0 : FoldTypeIndrX (q, p->tokenNo, p->des, p->expr, r);
2565 : 0 : break;
2566 : :
2567 : 14933 : case M2Range_typereturn:
2568 : 14933 : FoldTypeReturnFunc (q, p->tokenNo, p->des, p->expr, r);
2569 : 14933 : break;
2570 : :
2571 : :
2572 : 0 : default:
2573 : 0 : M2Error_InternalError ((const char *) "not expecting to reach this point", 33);
2574 : : break;
2575 : : }
2576 : : }
2577 : 8769198 : }
2578 : :
2579 : :
2580 : : /*
2581 : : CodeTypeCheck - folds a type check. This is a no-op and it used
2582 : : for checking types which are resolved post pass 3.
2583 : : It does assume that both, des, and, expr, have been
2584 : : resolved at this point.
2585 : : */
2586 : :
2587 : 491742 : static void CodeTypeCheck (unsigned int tokenno, unsigned int r)
2588 : : {
2589 : 491742 : M2Range_Range p;
2590 : :
2591 : 491742 : p = static_cast<M2Range_Range> (Indexing_GetIndice (RangeIndex, r));
2592 : 491742 : M2GCCDeclare_TryDeclareConstant (tokenno, p->des); /* use quad tokenno, rather than the range tokenNo */
2593 : 491742 : M2GCCDeclare_TryDeclareConstant (tokenno, p->expr); /* use quad tokenno, rather than the range tokenNo */
2594 : : /* TryDeclareConstructor(0, expr) ; */
2595 : 491742 : if (((SymbolConversion_GccKnowsAbout (p->des)) || ((SymbolTable_IsParameter (p->des)) && (SymbolConversion_GccKnowsAbout (SymbolTable_GetType (p->des))))) && (SymbolConversion_GccKnowsAbout (p->expr)))
2596 : : {
2597 : 491736 : switch (p->type)
2598 : : {
2599 : 170791 : case M2Range_typeassign:
2600 : 170791 : CodeTypeAssign (p->tokenNo, p->des, p->expr, r);
2601 : 170791 : break;
2602 : :
2603 : 239476 : case M2Range_typeparam:
2604 : 239476 : CodeTypeParam (p->tokenNo, p->des, p->expr, p->procedure, p->paramNo);
2605 : 239476 : break;
2606 : :
2607 : 68269 : case M2Range_typeexpr:
2608 : 68269 : CodeTypeExpr (p->tokenNo, p->des, p->expr, p->strict, p->isin, r);
2609 : 68269 : break;
2610 : :
2611 : 512 : case M2Range_typeindrx:
2612 : 512 : CodeTypeIndrX (p->tokenNo, p->des, p->expr, r);
2613 : 512 : break;
2614 : :
2615 : 12688 : case M2Range_typereturn:
2616 : 12688 : CodeTypeReturnFunc (p->tokenNo, p->des, p->expr, r);
2617 : 12688 : break;
2618 : :
2619 : :
2620 : 0 : default:
2621 : 0 : M2Error_InternalError ((const char *) "not expecting to reach this point", 33);
2622 : 491736 : break;
2623 : : }
2624 : : }
2625 : : else
2626 : : {
2627 : 6 : M2Error_InternalError ((const char *) "expecting des and expr to be resolved", 37);
2628 : : }
2629 : 491736 : }
2630 : :
2631 : :
2632 : : /*
2633 : : ForLoopBeginTypeCompatible - check for designator assignment compatibility with
2634 : : expr1 and designator expression compatibility with expr2.
2635 : : FOR des := expr1 TO expr2 BY byconst DO
2636 : : END
2637 : : It generates composite tokens if the tokens are on
2638 : : the same source line.
2639 : : */
2640 : :
2641 : 2562 : static bool ForLoopBeginTypeCompatible (M2Range_Range p)
2642 : : {
2643 : 2562 : unsigned int combinedtok;
2644 : 2562 : bool success;
2645 : :
2646 : 2562 : success = true;
2647 : 2562 : combinedtok = M2LexBuf_MakeVirtual2Tok (p->destok, p->exprtok);
2648 : 2562 : if (! (M2Check_AssignmentTypeCompatible (combinedtok, (const char *) "", 0, p->des, p->expr, true)))
2649 : : {
2650 : 0 : M2MetaError_MetaErrorT2 (combinedtok, (const char *) "type incompatibility between {%1Et} and {%2t} detected during the assignment of the designator {%1a} to the first expression {%2a} in the {%kFOR} loop", 150, p->des, p->expr);
2651 : 0 : success = false;
2652 : : }
2653 : 2562 : combinedtok = M2LexBuf_MakeVirtual2Tok (p->destok, p->expr2tok);
2654 : 2562 : if (! (M2Check_ExpressionTypeCompatible (combinedtok, (const char *) "", 0, p->des, p->expr2, true, false)))
2655 : : {
2656 : 14 : M2MetaError_MetaErrorT2 (combinedtok, (const char *) "type expression incompatibility between {%1Et} and {%2t} detected when comparing the designator {%1a} against the second expression {%2a} in the {%kFOR} loop", 157, p->des, p->expr2);
2657 : 14 : success = false;
2658 : : }
2659 : 2562 : combinedtok = M2LexBuf_MakeVirtual2Tok (p->destok, p->byconsttok);
2660 : 2562 : if (! (M2Check_ExpressionTypeCompatible (combinedtok, (const char *) "", 0, p->des, p->byconst, true, false)))
2661 : : {
2662 : 6 : M2MetaError_MetaErrorT2 (combinedtok, (const char *) "type expression incompatibility between {%1Et} and {%2t} detected between the designator {%1a} and the {%kBY} constant expression {%2a} in the {%kFOR} loop", 155, p->des, p->byconst);
2663 : 6 : success = false;
2664 : : }
2665 : 2562 : if (! success && (p->incrementquad != 0))
2666 : : {
2667 : : /* Avoid a subsequent generic type check error. */
2668 : 20 : M2Quads_SubQuad (p->incrementquad);
2669 : : }
2670 : 2562 : return success;
2671 : : /* static analysis guarentees a RETURN statement will be used before here. */
2672 : : __builtin_unreachable ();
2673 : : }
2674 : :
2675 : :
2676 : : /*
2677 : : FoldForLoopBegin -
2678 : : */
2679 : :
2680 : 5464 : static void FoldForLoopBegin (unsigned int tokenno, unsigned int q, unsigned int r)
2681 : : {
2682 : 5464 : M2Range_Range p;
2683 : 5464 : tree min;
2684 : 5464 : tree max;
2685 : :
2686 : 5464 : p = static_cast<M2Range_Range> (Indexing_GetIndice (RangeIndex, r));
2687 : 5464 : M2GCCDeclare_TryDeclareConstant (tokenno, p->expr); /* use quad tokenno, rather than the range tokenNo */
2688 : 5464 : if (p->desLowestType != SymbolTable_NulSym) /* use quad tokenno, rather than the range tokenNo */
2689 : : {
2690 : 5464 : if (((SymbolConversion_GccKnowsAbout (p->expr)) && (SymbolTable_IsConst (p->expr))) && (M2Range_GetMinMax (tokenno, p->desLowestType, &min, &max)))
2691 : : {
2692 : : /* avoid gcc warning by using compound statement even if not strictly necessary. */
2693 : 2422 : if (! (ForLoopBeginTypeCompatible (p)))
2694 : : {
2695 : 20 : M2Quads_SubQuad (q);
2696 : : }
2697 : 2402 : else if (OutOfRange (tokenno, min, p->expr, max, p->desLowestType))
2698 : : {
2699 : : /* avoid dangling else. */
2700 : 0 : M2MetaError_MetaErrorT2 (p->tokenNo, (const char *) "attempting to assign a value {%2Wa} to a FOR loop designator {%1a} which will exceed the range of type {%1tad}", 110, p->des, p->expr);
2701 : 0 : M2Quads_PutQuad (q, M2Quads_ErrorOp, SymbolTable_NulSym, SymbolTable_NulSym, r);
2702 : : }
2703 : : else
2704 : : {
2705 : : /* avoid dangling else. */
2706 : 2402 : M2Quads_SubQuad (q);
2707 : : }
2708 : : }
2709 : : }
2710 : 5464 : }
2711 : :
2712 : :
2713 : : /*
2714 : : FoldForLoopTo -
2715 : : */
2716 : :
2717 : 0 : static void FoldForLoopTo (unsigned int tokenno, unsigned int q, unsigned int r)
2718 : : {
2719 : 0 : M2Range_Range p;
2720 : 0 : tree min;
2721 : 0 : tree max;
2722 : :
2723 : 0 : p = static_cast<M2Range_Range> (Indexing_GetIndice (RangeIndex, r));
2724 : 0 : M2GCCDeclare_TryDeclareConstant (tokenno, p->expr); /* use quad tokenno, rather than the range tokenNo */
2725 : 0 : if (p->desLowestType != SymbolTable_NulSym) /* use quad tokenno, rather than the range tokenNo */
2726 : : {
2727 : 0 : if (((SymbolConversion_GccKnowsAbout (p->expr)) && (SymbolTable_IsConst (p->expr))) && (M2Range_GetMinMax (tokenno, p->desLowestType, &min, &max)))
2728 : : {
2729 : : /* avoid gcc warning by using compound statement even if not strictly necessary. */
2730 : 0 : if (OutOfRange (tokenno, min, p->expr, max, p->desLowestType))
2731 : : {
2732 : 0 : M2MetaError_MetaErrorT2 (p->tokenNo, (const char *) "final value in FOR loop will exceed type range {%1Wtasa} of designator {%2a}", 76, p->des, p->expr);
2733 : 0 : M2Quads_PutQuad (q, M2Quads_ErrorOp, SymbolTable_NulSym, SymbolTable_NulSym, r);
2734 : : }
2735 : : else
2736 : : {
2737 : 0 : M2Quads_SubQuad (q);
2738 : : }
2739 : : }
2740 : : }
2741 : 0 : }
2742 : :
2743 : :
2744 : : /*
2745 : : FoldStaticArraySubscript -
2746 : : */
2747 : :
2748 : 146804 : static void FoldStaticArraySubscript (unsigned int tokenno, unsigned int q, unsigned int r)
2749 : : {
2750 : 146804 : M2Range_Range p;
2751 : 146804 : tree min;
2752 : 146804 : tree max;
2753 : :
2754 : 146804 : p = static_cast<M2Range_Range> (Indexing_GetIndice (RangeIndex, r));
2755 : 146804 : M2GCCDeclare_TryDeclareConstant (tokenno, p->des); /* use quad tokenno, rather than the range tokenNo */
2756 : 146804 : M2GCCDeclare_TryDeclareConstant (tokenno, p->expr); /* use quad tokenno, rather than the range tokenNo */
2757 : 146804 : if (p->desLowestType != SymbolTable_NulSym) /* use quad tokenno, rather than the range tokenNo */
2758 : : {
2759 : 146804 : if (((SymbolConversion_GccKnowsAbout (p->expr)) && (SymbolTable_IsConst (p->expr))) && (M2Range_GetMinMax (tokenno, p->desLowestType, &min, &max)))
2760 : : {
2761 : : /* avoid gcc warning by using compound statement even if not strictly necessary. */
2762 : 36662 : if (OutOfRange (tokenno, min, p->expr, max, p->desLowestType))
2763 : : {
2764 : 0 : M2MetaError_MetaErrorT3 (p->tokenNo, (const char *) "index {%2Wa} out of range found while attempting to access an element of a static array {%1a} in the {%3N} array subscript", 122, p->des, p->expr, p->dimension);
2765 : 0 : M2Quads_PutQuad (q, M2Quads_ErrorOp, SymbolTable_NulSym, SymbolTable_NulSym, r);
2766 : : }
2767 : : else
2768 : : {
2769 : : /* range check is unnecessary */
2770 : 36662 : M2Quads_SubQuad (q);
2771 : : }
2772 : : }
2773 : : }
2774 : 146804 : }
2775 : :
2776 : :
2777 : : /*
2778 : : FoldDynamicArraySubscript -
2779 : : */
2780 : :
2781 : 61134 : static void FoldDynamicArraySubscript (unsigned int tokenno, unsigned int q, unsigned int r)
2782 : : {
2783 : 61134 : M2Range_Range p;
2784 : 61134 : location_t location;
2785 : :
2786 : 61134 : location = M2LexBuf_TokenToLocation (tokenno);
2787 : 61134 : p = static_cast<M2Range_Range> (Indexing_GetIndice (RangeIndex, r));
2788 : 61134 : M2GCCDeclare_TryDeclareConstant (tokenno, p->expr); /* use quad tokenno, rather than the range tokenNo */
2789 : 61134 : if (p->desLowestType != SymbolTable_NulSym) /* use quad tokenno, rather than the range tokenNo */
2790 : : {
2791 : 61134 : if ((SymbolConversion_GccKnowsAbout (p->expr)) && (SymbolTable_IsConst (p->expr)))
2792 : : {
2793 : : /* avoid gcc warning by using compound statement even if not strictly necessary. */
2794 : 3850 : if (M2Range_IsGreater (m2expr_GetIntegerZero (location), m2convert_BuildConvert (location, m2type_GetIntegerType (), SymbolConversion_Mod2Gcc (p->expr), false)))
2795 : : {
2796 : 0 : M2MetaError_MetaErrorT3 (p->tokenNo, (const char *) "index {%2Wa} out of range found while attempting to access an element of a dynamic array {%1a} in the {%3N} array subscript", 123, p->des, p->expr, p->dimension);
2797 : 0 : M2Quads_PutQuad (q, M2Quads_ErrorOp, SymbolTable_NulSym, SymbolTable_NulSym, r);
2798 : : }
2799 : : /* cannot fold high bounds, so leave that for the runtime */
2800 : : }
2801 : : }
2802 : 61134 : }
2803 : :
2804 : :
2805 : : /*
2806 : : FoldCaseBounds -
2807 : : */
2808 : :
2809 : 9660 : static void FoldCaseBounds (unsigned int tokenno, unsigned int q, unsigned int r)
2810 : : {
2811 : 9660 : M2Range_Range p;
2812 : 9660 : bool errorGenerated;
2813 : :
2814 : 9660 : p = static_cast<M2Range_Range> (Indexing_GetIndice (RangeIndex, r));
2815 : 9660 : if (M2CaseList_CaseBoundsResolved (tokenno, p->caseList))
2816 : : {
2817 : 3972 : errorGenerated = false;
2818 : 3972 : if (M2CaseList_TypeCaseBounds (p->caseList))
2819 : : {} /* empty. */
2820 : : /* nothing to do */
2821 : 3972 : if (M2CaseList_OverlappingCaseBounds (p->caseList))
2822 : : {
2823 : 24 : M2Quads_PutQuad (q, M2Quads_ErrorOp, SymbolTable_NulSym, SymbolTable_NulSym, r);
2824 : 24 : errorGenerated = true;
2825 : : }
2826 : 3972 : if (M2Options_VariantValueChecking && (M2CaseList_MissingCaseBounds (tokenno, p->caseList)))
2827 : : {
2828 : 12 : if (! errorGenerated)
2829 : : {
2830 : 6 : M2Quads_PutQuad (q, M2Quads_ErrorOp, SymbolTable_NulSym, SymbolTable_NulSym, r);
2831 : 6 : errorGenerated = true;
2832 : : }
2833 : : }
2834 : 3972 : if (M2Options_CaseEnumChecking && (M2CaseList_MissingCaseStatementBounds (tokenno, p->caseList)))
2835 : : {
2836 : 48 : if (! errorGenerated)
2837 : : {
2838 : 48 : M2Quads_PutQuad (q, M2Quads_ErrorOp, SymbolTable_NulSym, SymbolTable_NulSym, r);
2839 : 48 : errorGenerated = true;
2840 : : }
2841 : : }
2842 : 3972 : if (! errorGenerated)
2843 : : {
2844 : 3894 : M2Quads_SubQuad (q);
2845 : : }
2846 : : }
2847 : 9660 : }
2848 : :
2849 : :
2850 : : /*
2851 : : CodeCaseBounds - attempts to resolve whether the case bounds are legal.
2852 : : This should resolve at compile time as all case bounds
2853 : : must be constants. We introduce a CodeCaseBounds as it
2854 : : might be possible that constants have just been declared
2855 : : during the code generation of this function.
2856 : : */
2857 : :
2858 : 0 : static void CodeCaseBounds (unsigned int tokenno, unsigned int caseList)
2859 : : {
2860 : 0 : if (M2CaseList_CaseBoundsResolved (tokenno, caseList))
2861 : : {
2862 : : /* avoid dangling else. */
2863 : 0 : if (M2CaseList_TypeCaseBounds (caseList))
2864 : : {} /* empty. */
2865 : : /* nothing to do */
2866 : 0 : if (M2CaseList_OverlappingCaseBounds (caseList))
2867 : : {} /* empty. */
2868 : : /* nothing to do */
2869 : 0 : if (M2CaseList_MissingCaseBounds (tokenno, caseList))
2870 : : {} /* empty. */
2871 : : /* nothing to do */
2872 : 0 : if (M2Options_CaseEnumChecking && (M2CaseList_MissingCaseStatementBounds (tokenno, caseList)))
2873 : : {} /* empty. */
2874 : : /* nothing to do */
2875 : : }
2876 : : else
2877 : : {
2878 : 0 : M2MetaError_MetaErrorT0 (tokenno, (const char *) "{%E}the CASE statement ranges must be constants", 47);
2879 : : }
2880 : 0 : }
2881 : :
2882 : :
2883 : : /*
2884 : : MakeAndDeclareConstLit - creates a constant of value and declares it to GCC.
2885 : : */
2886 : :
2887 : 389646 : static unsigned int MakeAndDeclareConstLit (unsigned int tokenno, NameKey_Name value, unsigned int type)
2888 : : {
2889 : 389646 : unsigned int constant;
2890 : :
2891 : 389646 : constant = SymbolTable_MakeConstLit (tokenno, value, type);
2892 : 389646 : M2GCCDeclare_TryDeclareConstant (tokenno, constant); /* use quad tokenno, rather than the range tokenNo */
2893 : 389646 : M2Debug_Assert (SymbolConversion_GccKnowsAbout (constant)); /* use quad tokenno, rather than the range tokenNo */
2894 : 389646 : return constant;
2895 : : /* static analysis guarentees a RETURN statement will be used before here. */
2896 : : __builtin_unreachable ();
2897 : : }
2898 : :
2899 : :
2900 : : /*
2901 : : FoldNonPosDiv - attempts to fold the bound checking for a divide expression.
2902 : : */
2903 : :
2904 : 0 : static void FoldNonPosDiv (unsigned int tokenno, unsigned int q, unsigned int r)
2905 : : {
2906 : 0 : M2Range_Range p;
2907 : 0 : unsigned int zero;
2908 : :
2909 : 0 : p = static_cast<M2Range_Range> (Indexing_GetIndice (RangeIndex, r));
2910 : 0 : M2GCCDeclare_TryDeclareConstant (tokenno, p->expr); /* use quad tokenno, rather than the range tokenNo */
2911 : 0 : if ((SymbolConversion_GccKnowsAbout (p->expr)) && (SymbolTable_IsConst (p->expr))) /* use quad tokenno, rather than the range tokenNo */
2912 : : {
2913 : 0 : zero = MakeAndDeclareConstLit (tokenno, NameKey_MakeKey ((const char *) "0", 1), M2Base_ZType);
2914 : 0 : if (IsGreaterOrEqualConversion (M2LexBuf_TokenToLocation (tokenno), zero, p->des, p->expr))
2915 : : {
2916 : 0 : M2MetaError_MetaErrorT2 (p->tokenNo, (const char *) "the divisor {%2Wa} in this division expression is less than or equal to zero, this will cause an exception to be raised before the result is assigned to the designator {%1a}", 173, p->des, p->expr);
2917 : 0 : M2Quads_PutQuad (q, M2Quads_ErrorOp, SymbolTable_NulSym, SymbolTable_NulSym, r);
2918 : : }
2919 : : }
2920 : 0 : }
2921 : :
2922 : :
2923 : : /*
2924 : : FoldNonPosMod - attempts to fold the bound checking for a modulus expression.
2925 : : */
2926 : :
2927 : 0 : static void FoldNonPosMod (unsigned int tokenno, unsigned int q, unsigned int r)
2928 : : {
2929 : 0 : M2Range_Range p;
2930 : 0 : unsigned int zero;
2931 : :
2932 : 0 : p = static_cast<M2Range_Range> (Indexing_GetIndice (RangeIndex, r));
2933 : 0 : M2GCCDeclare_TryDeclareConstant (tokenno, p->expr); /* use quad tokenno, rather than the range tokenNo */
2934 : 0 : if ((SymbolConversion_GccKnowsAbout (p->expr)) && (SymbolTable_IsConst (p->expr))) /* use quad tokenno, rather than the range tokenNo */
2935 : : {
2936 : 0 : zero = MakeAndDeclareConstLit (tokenno, NameKey_MakeKey ((const char *) "0", 1), M2Base_ZType);
2937 : 0 : if (IsGreaterOrEqualConversion (M2LexBuf_TokenToLocation (tokenno), zero, p->des, p->expr))
2938 : : {
2939 : 0 : M2MetaError_MetaErrorT2 (p->tokenNo, (const char *) "the divisor {%2Wa} in this modulus expression is less than or equal to zero, this will cause an exception to be raised before the result is assigned to the designator {%1a}", 172, p->des, p->expr);
2940 : 0 : M2Quads_PutQuad (q, M2Quads_ErrorOp, SymbolTable_NulSym, SymbolTable_NulSym, r);
2941 : : }
2942 : : }
2943 : 0 : }
2944 : :
2945 : :
2946 : : /*
2947 : : FoldZeroDiv -
2948 : : */
2949 : :
2950 : 379642 : static void FoldZeroDiv (unsigned int tokenno, unsigned int q, unsigned int r)
2951 : : {
2952 : 379642 : M2Range_Range p;
2953 : 379642 : unsigned int zero;
2954 : :
2955 : 379642 : p = static_cast<M2Range_Range> (Indexing_GetIndice (RangeIndex, r));
2956 : 379642 : M2GCCDeclare_TryDeclareConstant (tokenno, p->expr); /* use quad tokenno, rather than the range tokenNo */
2957 : 379642 : if ((SymbolConversion_GccKnowsAbout (p->expr)) && (SymbolTable_IsConst (p->expr))) /* use quad tokenno, rather than the range tokenNo */
2958 : : {
2959 : 371678 : zero = MakeAndDeclareConstLit (tokenno, NameKey_MakeKey ((const char *) "0", 1), M2Base_ZType);
2960 : 371678 : if (IsEqualConversion (zero, p->des, p->expr))
2961 : : {
2962 : 0 : M2MetaError_MetaErrorT2 (p->tokenNo, (const char *) "the divisor {%2Wa} in this division expression is equal to zero, this will cause an exception to be raised before the result is assigned to the designator {%1a}", 160, p->des, p->expr);
2963 : 0 : M2Quads_PutQuad (q, M2Quads_ErrorOp, SymbolTable_NulSym, SymbolTable_NulSym, r);
2964 : : }
2965 : : }
2966 : 379642 : }
2967 : :
2968 : :
2969 : : /*
2970 : : FoldZeroRem -
2971 : : */
2972 : :
2973 : 9408 : static void FoldZeroRem (unsigned int tokenno, unsigned int q, unsigned int r)
2974 : : {
2975 : 9408 : M2Range_Range p;
2976 : 9408 : unsigned int zero;
2977 : :
2978 : 9408 : p = static_cast<M2Range_Range> (Indexing_GetIndice (RangeIndex, r));
2979 : 9408 : M2GCCDeclare_TryDeclareConstant (tokenno, p->expr); /* use quad tokenno, rather than the range tokenNo */
2980 : 9408 : if ((SymbolConversion_GccKnowsAbout (p->expr)) && (SymbolTable_IsConst (p->expr))) /* use quad tokenno, rather than the range tokenNo */
2981 : : {
2982 : 9408 : zero = MakeAndDeclareConstLit (tokenno, NameKey_MakeKey ((const char *) "0", 1), M2Base_ZType);
2983 : 9408 : if (IsEqualConversion (zero, p->des, p->expr))
2984 : : {
2985 : 0 : M2MetaError_MetaErrorT2 (p->tokenNo, (const char *) "the divisor {%2Wa} in this remainder expression is equal to zero, this will cause an exception to be raised before the result is assigned to the designator {%1a}", 161, p->des, p->expr);
2986 : 0 : M2Quads_PutQuad (q, M2Quads_ErrorOp, SymbolTable_NulSym, SymbolTable_NulSym, r);
2987 : : }
2988 : : }
2989 : 9408 : }
2990 : :
2991 : :
2992 : : /*
2993 : : FoldRangeCheckLower - call the appropriate Fold procedure depending upon the type
2994 : : of range.
2995 : : */
2996 : :
2997 : 14312179 : static void FoldRangeCheckLower (unsigned int tokenno, unsigned int quad, unsigned int range)
2998 : : {
2999 : 14312179 : M2Range_Range p;
3000 : :
3001 : 14312179 : p = static_cast<M2Range_Range> (Indexing_GetIndice (RangeIndex, range));
3002 : 14312179 : switch (p->type)
3003 : : {
3004 : 3221519 : case M2Range_assignment:
3005 : 3221519 : FoldAssignment (tokenno, quad, range);
3006 : 3221519 : break;
3007 : :
3008 : 81409 : case M2Range_returnassignment:
3009 : 81409 : FoldReturn (tokenno, quad, range);
3010 : 81409 : break;
3011 : :
3012 : 62952 : case M2Range_inc:
3013 : : /* subrangeassignment : | unused currently */
3014 : 62952 : FoldInc (tokenno, quad, range);
3015 : 62952 : break;
3016 : :
3017 : 62508 : case M2Range_dec:
3018 : 62508 : FoldDec (tokenno, quad, range);
3019 : 62508 : break;
3020 : :
3021 : 22478 : case M2Range_incl:
3022 : 22478 : FoldIncl (tokenno, quad, range);
3023 : 22478 : break;
3024 : :
3025 : 15600 : case M2Range_excl:
3026 : 15600 : FoldExcl (tokenno, quad, range);
3027 : 15600 : break;
3028 : :
3029 : 7970 : case M2Range_shift:
3030 : 7970 : FoldShift (tokenno, quad, range);
3031 : 7970 : break;
3032 : :
3033 : 11196 : case M2Range_rotate:
3034 : 11196 : FoldRotate (tokenno, quad, range);
3035 : 11196 : break;
3036 : :
3037 : 8769336 : case M2Range_typereturn:
3038 : 8769336 : case M2Range_typeassign:
3039 : 8769336 : case M2Range_typeparam:
3040 : 8769336 : case M2Range_typeexpr:
3041 : 8769336 : case M2Range_typeindrx:
3042 : 8769336 : FoldTypeCheck (tokenno, quad, range);
3043 : 8769336 : break;
3044 : :
3045 : 1250691 : case M2Range_paramassign:
3046 : 1250691 : FoldParameterAssign (tokenno, quad, range);
3047 : 1250691 : break;
3048 : :
3049 : 146804 : case M2Range_staticarraysubscript:
3050 : 146804 : FoldStaticArraySubscript (tokenno, quad, range);
3051 : 146804 : break;
3052 : :
3053 : 61134 : case M2Range_dynamicarraysubscript:
3054 : 61134 : FoldDynamicArraySubscript (tokenno, quad, range);
3055 : 61134 : break;
3056 : :
3057 : 5464 : case M2Range_forloopbegin:
3058 : 5464 : FoldForLoopBegin (tokenno, quad, range);
3059 : 5464 : break;
3060 : :
3061 : 0 : case M2Range_forloopto:
3062 : 0 : FoldForLoopTo (tokenno, quad, range);
3063 : 0 : break;
3064 : :
3065 : : case M2Range_forloopend:
3066 : : return; /* unable to fold anything at this point, des, will be variable */
3067 : 122774 : break;
3068 : :
3069 : 122774 : case M2Range_pointernil:
3070 : 122774 : FoldNil (tokenno, quad, range);
3071 : 122774 : break;
3072 : :
3073 : : case M2Range_noreturn:
3074 : : return; /* nothing to fold */
3075 : : break;
3076 : :
3077 : : case M2Range_noelse:
3078 : : return; /* nothing to fold */
3079 : 9660 : break;
3080 : :
3081 : 9660 : case M2Range_casebounds:
3082 : 9660 : FoldCaseBounds (tokenno, quad, range);
3083 : 9660 : break;
3084 : :
3085 : 0 : case M2Range_wholenonposdiv:
3086 : 0 : FoldNonPosDiv (tokenno, quad, range);
3087 : 0 : break;
3088 : :
3089 : 0 : case M2Range_wholenonposmod:
3090 : 0 : FoldNonPosMod (tokenno, quad, range);
3091 : 0 : break;
3092 : :
3093 : 379642 : case M2Range_wholezerodiv:
3094 : 379642 : FoldZeroDiv (tokenno, quad, range);
3095 : 379642 : break;
3096 : :
3097 : 9408 : case M2Range_wholezerorem:
3098 : 9408 : FoldZeroRem (tokenno, quad, range);
3099 : 9408 : break;
3100 : :
3101 : 0 : case M2Range_none:
3102 : 0 : M2Quads_SubQuad (quad);
3103 : 0 : break;
3104 : :
3105 : :
3106 : 0 : default:
3107 : 0 : M2Error_InternalError ((const char *) "unexpected case", 15);
3108 : 14312017 : break;
3109 : : }
3110 : : }
3111 : :
3112 : :
3113 : : /*
3114 : : DeReferenceLValue - returns a Tree which is either ModGcc(expr)
3115 : : or Mod2Gcc ( *expr) depending whether, expr,
3116 : : is an LValue.
3117 : : */
3118 : :
3119 : 52718 : static tree DeReferenceLValue (unsigned int tokenno, unsigned int expr)
3120 : : {
3121 : 52718 : tree e;
3122 : 52718 : location_t location;
3123 : :
3124 : 52718 : location = M2LexBuf_TokenToLocation (tokenno);
3125 : 52718 : e = SymbolConversion_Mod2Gcc (expr);
3126 : 52718 : if ((SymbolTable_GetMode (expr)) == SymbolTable_LeftValue)
3127 : : {
3128 : 314 : e = m2expr_BuildIndirect (location, e, SymbolConversion_Mod2Gcc (SymbolTable_GetType (expr)));
3129 : : }
3130 : 52718 : return e;
3131 : : /* static analysis guarentees a RETURN statement will be used before here. */
3132 : : __builtin_unreachable ();
3133 : : }
3134 : :
3135 : :
3136 : : /*
3137 : : BuildStringParam - builds a C style string parameter which will be passed
3138 : : as an ADDRESS type.
3139 : : */
3140 : :
3141 : 38085 : static void BuildStringParam (unsigned int tokenno, DynamicStrings_String s)
3142 : : {
3143 : 38085 : BuildStringParamLoc (M2LexBuf_TokenToLocation (tokenno), s);
3144 : 38085 : }
3145 : :
3146 : :
3147 : : /*
3148 : : BuildStringParamLoc - builds a C style string parameter which will be passed
3149 : : as an ADDRESS type.
3150 : : */
3151 : :
3152 : 49689 : static void BuildStringParamLoc (location_t location, DynamicStrings_String s)
3153 : : {
3154 : 49689 : m2statement_BuildParam (location, m2convert_BuildConvert (location, SymbolConversion_Mod2Gcc (M2System_Address), m2expr_BuildAddr (location, m2decl_BuildStringConstant (const_cast <const char * > (static_cast <char * > (DynamicStrings_string (s))), static_cast<int> (DynamicStrings_Length (s))), false), false));
3155 : 49689 : }
3156 : :
3157 : :
3158 : : /*
3159 : : IssueWarning - issue a warning. The compiler knows that this basic block can be reached
3160 : : and we are in scope, function.
3161 : : */
3162 : :
3163 : 0 : static void IssueWarning (DynamicStrings_String function, unsigned int r)
3164 : : {
3165 : 0 : M2Range_Range p;
3166 : 0 : DynamicStrings_String s;
3167 : :
3168 : 0 : p = static_cast<M2Range_Range> (Indexing_GetIndice (RangeIndex, r));
3169 : 0 : switch (p->type)
3170 : : {
3171 : 0 : case M2Range_assignment:
3172 : 0 : s = DynamicStrings_InitString ((const char *) "if the assignment is ever executed then the designator {%1Wa} will exceed the type range {%1ts:of {%1ts}}", 105);
3173 : 0 : break;
3174 : :
3175 : 0 : case M2Range_returnassignment:
3176 : 0 : s = DynamicStrings_InitString ((const char *) "if the value {%2Wa} is returned from procedure function {%1Wa} then it will exceed the type range {%1ts:of {%1ts}}", 114);
3177 : 0 : break;
3178 : :
3179 : 0 : case M2Range_subrangeassignment:
3180 : 0 : M2Error_InternalError ((const char *) "not expecting this case value", 29);
3181 : 0 : break;
3182 : :
3183 : 0 : case M2Range_inc:
3184 : 0 : s = DynamicStrings_InitString ((const char *) "if the INC is ever executed the expression {%2Wa} will cause an overflow error for the designator {%1a} as it exceeds the type range {%1ts:of {%1ts}}", 149);
3185 : 0 : break;
3186 : :
3187 : 0 : case M2Range_dec:
3188 : 0 : s = DynamicStrings_InitString ((const char *) "if the DEC is ever executed the expression {%2Wa} will cause an underflow error for the designator {%1a} as it exceeds the type range {%1ts:of {%1ts}}", 150);
3189 : 0 : break;
3190 : :
3191 : 0 : case M2Range_incl:
3192 : 0 : s = DynamicStrings_InitString ((const char *) "the expression {%2Wa} given in the INCL exceeds the type range {%1ts} of the designator {%1a}", 93);
3193 : 0 : break;
3194 : :
3195 : 0 : case M2Range_excl:
3196 : 0 : s = DynamicStrings_InitString ((const char *) "the expression {%2Wa} given in the EXCL exceeds the type range {%1ts} of the designator {%1a}", 93);
3197 : 0 : break;
3198 : :
3199 : 0 : case M2Range_shift:
3200 : 0 : s = DynamicStrings_InitString ((const char *) "the expression {%2Wa} given in the second parameter to SHIFT exceeds the type range {%1ts} of the first parameter {%1a}", 119);
3201 : 0 : break;
3202 : :
3203 : 0 : case M2Range_rotate:
3204 : 0 : s = DynamicStrings_InitString ((const char *) "the expression {%2Wa} given in the second parameter to ROTATE exceeds the type range {%1ts} of the first parameter {%1a}", 120);
3205 : 0 : break;
3206 : :
3207 : 0 : case M2Range_typeassign:
3208 : 0 : s = DynamicStrings_InitString ((const char *) "", 0);
3209 : 0 : break;
3210 : :
3211 : 0 : case M2Range_typeparam:
3212 : 0 : s = DynamicStrings_InitString ((const char *) "", 0);
3213 : 0 : break;
3214 : :
3215 : 0 : case M2Range_typeexpr:
3216 : 0 : s = DynamicStrings_InitString ((const char *) "", 0);
3217 : 0 : break;
3218 : :
3219 : 0 : case M2Range_paramassign:
3220 : 0 : s = DynamicStrings_InitString ((const char *) "if this call is executed then the actual parameter {%2Wa} will be out of range of the {%3N} formal parameter {%1a}", 114);
3221 : 0 : break;
3222 : :
3223 : 0 : case M2Range_staticarraysubscript:
3224 : 0 : s = DynamicStrings_InitString ((const char *) "if this access to the static array {%1Wa:{%2a:{%1a}[{%2a}]}} is ever made then the index will be out of bounds in the {%3N} array subscript", 139);
3225 : 0 : break;
3226 : :
3227 : 0 : case M2Range_dynamicarraysubscript:
3228 : 0 : s = DynamicStrings_InitString ((const char *) "if this access to the dynamic array {%1Wa:{%2a:{%1a}[{%2a}]}} is ever made then the index will be out of bounds in the {%3N} array subscript", 140);
3229 : 0 : break;
3230 : :
3231 : 0 : case M2Range_forloopbegin:
3232 : 0 : s = DynamicStrings_InitString ((const char *) "if the assignment in this FOR loop is ever executed then the designator {%1Wa} will be exceed the type range {%1ts:of {%1ts}}", 125);
3233 : 0 : break;
3234 : :
3235 : 0 : case M2Range_forloopto:
3236 : 0 : s = DynamicStrings_InitString ((const char *) "the final value {%2Wa} in this FOR loop will be out of bounds {%1ts:of type {%1ts}} if ever executed", 100);
3237 : 0 : break;
3238 : :
3239 : 0 : case M2Range_forloopend:
3240 : 0 : s = DynamicStrings_InitString ((const char *) "the FOR loop will cause the designator {%1Wa} to be out of bounds when the BY value {%2a} is added", 98);
3241 : 0 : break;
3242 : :
3243 : 0 : case M2Range_pointernil:
3244 : 0 : s = DynamicStrings_InitString ((const char *) "if this pointer value {%1Wa} is ever dereferenced it will cause an exception", 76);
3245 : 0 : break;
3246 : :
3247 : 0 : case M2Range_noreturn:
3248 : 0 : s = DynamicStrings_InitString ((const char *) "{%1W:}this function will exit without executing a RETURN statement", 66);
3249 : 0 : break;
3250 : :
3251 : 0 : case M2Range_noelse:
3252 : 0 : s = DynamicStrings_InitString ((const char *) "{%1W:}this CASE statement does not have an ELSE statement", 57);
3253 : 0 : break;
3254 : :
3255 : 0 : case M2Range_casebounds:
3256 : 0 : s = DynamicStrings_InitString ((const char *) "{%1W:}this CASE statement has overlapping ranges", 48);
3257 : 0 : break;
3258 : :
3259 : 0 : case M2Range_wholenonposdiv:
3260 : 0 : s = DynamicStrings_InitString ((const char *) "this division expression {%2Wa} will cause an exception as this divisor is less than or equal to zero", 101);
3261 : 0 : break;
3262 : :
3263 : 0 : case M2Range_wholenonposmod:
3264 : 0 : s = DynamicStrings_InitString ((const char *) "this modulus expression {%2Wa} will cause an exception as this divisor is less than or equal to zero", 100);
3265 : 0 : break;
3266 : :
3267 : 0 : case M2Range_wholezerodiv:
3268 : 0 : s = DynamicStrings_InitString ((const char *) "this division expression {%2Wa} will cause an exception as the divisor is zero", 78);
3269 : 0 : break;
3270 : :
3271 : 0 : case M2Range_wholezerorem:
3272 : 0 : s = DynamicStrings_InitString ((const char *) "this remainder expression {%2Wa} will cause an exception as the divisor is zero", 79);
3273 : 0 : break;
3274 : :
3275 : 0 : case M2Range_none:
3276 : 0 : M2Error_InternalError ((const char *) "unexpected value", 16);
3277 : 0 : break;
3278 : :
3279 : :
3280 : 0 : default:
3281 : 0 : M2Error_InternalError ((const char *) "enumeration value unknown", 25);
3282 : 0 : break;
3283 : : }
3284 : 0 : s = DynamicStrings_ConCat (s, DynamicStrings_Mark (DynamicStrings_InitString ((const char *) " in (", 5)));
3285 : 0 : s = DynamicStrings_ConCat (s, function);
3286 : 0 : s = DynamicStrings_ConCatChar (s, ')');
3287 : 0 : M2MetaError_MetaErrorStringT3 (p->tokenNo, s, p->des, p->expr, p->dimension);
3288 : 0 : }
3289 : :
3290 : :
3291 : : /*
3292 : : CodeErrorCheckLoc - generate a runtime error message positioned at location
3293 : : and in function. If function is NIL then the error scope
3294 : : is used.
3295 : : */
3296 : :
3297 : 3868 : static tree CodeErrorCheckLoc (location_t location, const char * function, const char * message, unsigned int func)
3298 : : {
3299 : 3868 : DynamicStrings_String scope;
3300 : 3868 : DynamicStrings_String errorMessage;
3301 : 3868 : tree t;
3302 : 3868 : DynamicStrings_String filename;
3303 : 3868 : unsigned int line;
3304 : 3868 : unsigned int column;
3305 : :
3306 : 3868 : if (func == SymbolTable_NulSym)
3307 : : {
3308 : : return NULL;
3309 : : }
3310 : : else
3311 : : {
3312 : 3868 : t = SymbolConversion_Mod2Gcc (func);
3313 : 3868 : if (t != NULL)
3314 : : {
3315 : 3868 : filename = DynamicStrings_InitStringCharStar (m2linemap_GetFilenameFromLocation (location));
3316 : 3868 : M2Debug_Assert (message != NULL);
3317 : 3868 : errorMessage = DynamicStrings_InitStringCharStar (static_cast <void *> (const_cast <char * > (message)));
3318 : 3868 : column = m2linemap_GetColumnNoFromLocation (location);
3319 : 3868 : line = m2linemap_GetLineNoFromLocation (location);
3320 : 3868 : BuildStringParamLoc (location, errorMessage);
3321 : 3868 : if (function == NULL)
3322 : : {
3323 : 0 : scope = M2Error_GetAnnounceScope (filename, static_cast<DynamicStrings_String> (NULL));
3324 : : }
3325 : : else
3326 : : {
3327 : 3868 : scope = M2ColorString_quoteOpen (DynamicStrings_InitString ((const char *) "", 0));
3328 : 3868 : scope = DynamicStrings_ConCat (scope, DynamicStrings_Mark (DynamicStrings_InitStringCharStar (static_cast <void *> (const_cast <char * > (function)))));
3329 : 3868 : scope = DynamicStrings_ConCat (DynamicStrings_InitString ((const char *) "procedure ", 10), M2ColorString_quoteClose (scope));
3330 : : }
3331 : 3868 : BuildStringParamLoc (location, scope);
3332 : 3868 : m2statement_BuildParam (location, m2decl_BuildIntegerConstant (static_cast<int> (column)));
3333 : 3868 : m2statement_BuildParam (location, m2decl_BuildIntegerConstant (static_cast<int> (line)));
3334 : 3868 : BuildStringParamLoc (location, filename);
3335 : 3868 : t = m2statement_BuildProcedureCallTree (location, t, NULL);
3336 : : }
3337 : : /*
3338 : : filename := KillString (filename) ;
3339 : : scope := KillString (scope) ;
3340 : : errorMessage := KillString (errorMessage)
3341 : : */
3342 : 3868 : return t;
3343 : : }
3344 : : /* static analysis guarentees a RETURN statement will be used before here. */
3345 : : __builtin_unreachable ();
3346 : : }
3347 : :
3348 : :
3349 : : /*
3350 : : IssueWarningLoc -
3351 : : */
3352 : :
3353 : 0 : static void IssueWarningLoc (location_t location, const char * message)
3354 : : {
3355 : 0 : DynamicStrings_String s;
3356 : :
3357 : 0 : s = DynamicStrings_InitString ((const char *) "numerical overflow detected when performing ", 44);
3358 : 0 : s = DynamicStrings_ConCat (s, DynamicStrings_Mark (DynamicStrings_InitStringCharStar (static_cast <void *> (const_cast <char * > (message)))));
3359 : 0 : m2linemap_ErrorAt (location, DynamicStrings_string (s));
3360 : 0 : s = DynamicStrings_KillString (s);
3361 : 0 : }
3362 : :
3363 : :
3364 : : /*
3365 : : BuildIfCallHandlerLoc - return a Tree containing a runtime test whether, condition, is true.
3366 : : */
3367 : :
3368 : 3868 : static tree BuildIfCallHandlerLoc (location_t location, tree condition, const char * scope, const char * message, unsigned int func)
3369 : : {
3370 : 3868 : if (m2expr_IsTrue (condition))
3371 : : {
3372 : 0 : IssueWarningLoc (location, message);
3373 : : }
3374 : 3868 : return m2statement_BuildIfThenDoEnd (condition, CodeErrorCheckLoc (location, scope, message, func));
3375 : : /* static analysis guarentees a RETURN statement will be used before here. */
3376 : : __builtin_unreachable ();
3377 : : }
3378 : :
3379 : :
3380 : : /*
3381 : : BuildIfCallHandler -
3382 : : */
3383 : :
3384 : 61118 : static tree BuildIfCallHandler (tree condition, unsigned int r, DynamicStrings_String function, DynamicStrings_String message, bool warning)
3385 : : {
3386 : 61118 : if (warning && (m2expr_IsTrue (condition)))
3387 : : {
3388 : 0 : IssueWarning (function, r);
3389 : : }
3390 : 61118 : return m2statement_BuildIfThenDoEnd (condition, M2Range_CodeErrorCheck (r, function, message));
3391 : : /* static analysis guarentees a RETURN statement will be used before here. */
3392 : : __builtin_unreachable ();
3393 : : }
3394 : :
3395 : :
3396 : : /*
3397 : : RangeCheckReal -
3398 : : */
3399 : :
3400 : 4544 : static void RangeCheckReal (M2Range_Range p, unsigned int r, DynamicStrings_String function, DynamicStrings_String message)
3401 : : {
3402 : 4544 : tree e;
3403 : 4544 : tree condition;
3404 : 4544 : location_t location;
3405 : :
3406 : 4544 : location = M2LexBuf_TokenToLocation (p->tokenNo);
3407 : 4544 : e = DeReferenceLValue (p->tokenNo, p->expr);
3408 : 4544 : condition = m2expr_BuildEqualTo (location, m2builtins_BuiltInIsfinite (location, e), m2expr_GetIntegerZero (location));
3409 : 4544 : m2type_AddStatement (location, BuildIfCallHandler (condition, r, function, message, true));
3410 : 4544 : }
3411 : :
3412 : :
3413 : : /*
3414 : : RangeCheckOrdinal -
3415 : : */
3416 : :
3417 : 171394 : static void RangeCheckOrdinal (M2Range_Range p, unsigned int r, DynamicStrings_String function, DynamicStrings_String message)
3418 : : {
3419 : 171394 : tree condition;
3420 : 171394 : tree desMin;
3421 : 171394 : tree desMax;
3422 : 171394 : tree exprMin;
3423 : 171394 : tree exprMax;
3424 : 171394 : location_t location;
3425 : :
3426 : 171394 : location = M2LexBuf_TokenToLocation (p->tokenNo);
3427 : 171394 : if ((M2Range_GetMinMax (p->tokenNo, p->exprLowestType, &exprMin, &exprMax)) && (M2Range_GetMinMax (p->tokenNo, p->desLowestType, &desMin, &desMax)))
3428 : : {
3429 : : /* avoid gcc warning by using compound statement even if not strictly necessary. */
3430 : 140408 : if (M2Range_OverlapsRange (desMin, desMax, exprMin, exprMax))
3431 : : {
3432 : : /* avoid dangling else. */
3433 : 140408 : if (M2Range_IsGreater (desMin, exprMin))
3434 : : {
3435 : 3335 : condition = m2expr_BuildLessThan (location, DeReferenceLValue (p->tokenNo, p->expr), m2convert_BuildConvert (location, SymbolConversion_Mod2Gcc (p->exprLowestType), desMin, false));
3436 : 3335 : m2type_AddStatement (location, BuildIfCallHandler (condition, r, function, message, true));
3437 : : }
3438 : 140408 : if (M2Range_IsGreater (exprMax, desMax))
3439 : : {
3440 : 4817 : condition = m2expr_BuildGreaterThan (location, DeReferenceLValue (p->tokenNo, p->expr), m2convert_BuildConvert (location, SymbolConversion_Mod2Gcc (p->exprLowestType), desMax, false));
3441 : 4817 : m2type_AddStatement (location, BuildIfCallHandler (condition, r, function, message, true));
3442 : : }
3443 : : }
3444 : : else
3445 : : {
3446 : 0 : M2MetaError_MetaErrorStringT3 (p->tokenNo, message, p->des, p->expr, p->paramNo);
3447 : : }
3448 : : }
3449 : 171394 : }
3450 : :
3451 : :
3452 : : /*
3453 : : DoCodeAssignmentExprType -
3454 : : */
3455 : :
3456 : 175938 : static void DoCodeAssignmentExprType (M2Range_Range p, unsigned int r, DynamicStrings_String function, DynamicStrings_String message)
3457 : : {
3458 : 175938 : if ((SymbolConversion_GccKnowsAbout (p->desLowestType)) && (SymbolConversion_GccKnowsAbout (p->exprLowestType)))
3459 : : {
3460 : 175938 : if ((M2Base_IsRealType (p->desLowestType)) && (M2Base_IsRealType (p->exprLowestType)))
3461 : : {
3462 : 4544 : RangeCheckReal (p, r, function, message);
3463 : : }
3464 : : else
3465 : : {
3466 : 171394 : RangeCheckOrdinal (p, r, function, message);
3467 : : }
3468 : : }
3469 : : else
3470 : : {
3471 : 0 : M2Error_InternalError ((const char *) "should have resolved these types", 32);
3472 : : }
3473 : 175938 : }
3474 : :
3475 : :
3476 : : /*
3477 : : DoCodeAssignmentWithoutExprType -
3478 : : */
3479 : :
3480 : 42672 : static void DoCodeAssignmentWithoutExprType (M2Range_Range p, unsigned int r, DynamicStrings_String function, DynamicStrings_String message)
3481 : : {
3482 : 42672 : tree condition;
3483 : 42672 : tree desMin;
3484 : 42672 : tree desMax;
3485 : 42672 : location_t location;
3486 : :
3487 : 42672 : location = M2LexBuf_TokenToLocation (p->tokenNo);
3488 : 42672 : if (SymbolConversion_GccKnowsAbout (p->desLowestType))
3489 : : {
3490 : : /* avoid dangling else. */
3491 : 42672 : if (M2Range_GetMinMax (p->tokenNo, p->desLowestType, &desMin, &desMax))
3492 : : {
3493 : 7928 : condition = m2expr_BuildLessThan (location, m2convert_BuildConvert (location, SymbolConversion_Mod2Gcc (p->desLowestType), DeReferenceLValue (p->tokenNo, p->expr), false), desMin);
3494 : 7928 : m2type_AddStatement (location, BuildIfCallHandler (condition, r, function, message, true));
3495 : 7928 : condition = m2expr_BuildGreaterThan (location, m2convert_BuildConvert (location, SymbolConversion_Mod2Gcc (p->desLowestType), DeReferenceLValue (p->tokenNo, p->expr), false), desMax);
3496 : 7928 : m2type_AddStatement (location, BuildIfCallHandler (condition, r, function, message, true));
3497 : : }
3498 : : }
3499 : : else
3500 : : {
3501 : 0 : M2Error_InternalError ((const char *) "should have resolved this type", 30);
3502 : : }
3503 : 42672 : }
3504 : :
3505 : :
3506 : : /*
3507 : : DoCodeAssignment -
3508 : : */
3509 : :
3510 : 274467 : static void DoCodeAssignment (unsigned int tokenno, unsigned int r, DynamicStrings_String function, DynamicStrings_String message)
3511 : : {
3512 : 274467 : M2Range_Range p;
3513 : :
3514 : 274467 : p = static_cast<M2Range_Range> (Indexing_GetIndice (RangeIndex, r));
3515 : 274467 : M2GCCDeclare_TryDeclareConstant (p->tokenNo, p->des);
3516 : 274467 : M2GCCDeclare_TryDeclareConstant (p->tokenNo, p->expr);
3517 : 274467 : M2GCCDeclare_DeclareConstructor (tokenno, 0, p->expr);
3518 : 274467 : if (p->desLowestType != SymbolTable_NulSym)
3519 : : {
3520 : 218610 : M2Debug_Assert (SymbolConversion_GccKnowsAbout (p->expr));
3521 : 218610 : if (p->exprLowestType == SymbolTable_NulSym)
3522 : : {
3523 : 42672 : DoCodeAssignmentWithoutExprType (p, r, function, message);
3524 : : }
3525 : : else
3526 : : {
3527 : 175938 : DoCodeAssignmentExprType (p, r, function, message);
3528 : : }
3529 : : }
3530 : 274467 : }
3531 : :
3532 : :
3533 : : /*
3534 : : CodeAssignment -
3535 : : */
3536 : :
3537 : 166437 : static void CodeAssignment (unsigned int tokenno, unsigned int r, DynamicStrings_String function, DynamicStrings_String message)
3538 : : {
3539 : 0 : DoCodeAssignment (tokenno, r, function, message);
3540 : 166437 : }
3541 : :
3542 : :
3543 : : /*
3544 : : CodeParameterAssign -
3545 : : */
3546 : :
3547 : 91368 : static void CodeParameterAssign (unsigned int tokenno, unsigned int r, DynamicStrings_String function, DynamicStrings_String message)
3548 : : {
3549 : 0 : DoCodeAssignment (tokenno, r, function, message);
3550 : 91368 : }
3551 : :
3552 : :
3553 : : /*
3554 : : CodeReturn -
3555 : : */
3556 : :
3557 : 16522 : static void CodeReturn (unsigned int tokenno, unsigned int r, DynamicStrings_String function, DynamicStrings_String message)
3558 : : {
3559 : 0 : DoCodeAssignment (tokenno, r, function, message);
3560 : 16522 : }
3561 : :
3562 : :
3563 : : /*
3564 : : IfOutsideLimitsDo -
3565 : : */
3566 : :
3567 : 21598 : static void IfOutsideLimitsDo (unsigned int tokenno, tree min, tree expr, tree max, unsigned int r, DynamicStrings_String function, DynamicStrings_String message)
3568 : : {
3569 : 21598 : tree condition;
3570 : 21598 : location_t location;
3571 : :
3572 : 21598 : location = M2LexBuf_TokenToLocation (tokenno);
3573 : 21598 : condition = m2expr_BuildGreaterThan (location, min, expr);
3574 : 21598 : m2type_AddStatement (location, m2statement_BuildIfThenDoEnd (condition, M2Range_CodeErrorCheck (r, function, message)));
3575 : 21598 : condition = m2expr_BuildLessThan (location, max, expr);
3576 : 21598 : m2type_AddStatement (location, m2statement_BuildIfThenDoEnd (condition, M2Range_CodeErrorCheck (r, function, message)));
3577 : 21598 : }
3578 : :
3579 : :
3580 : : /*
3581 : : CodeInc -
3582 : : */
3583 : :
3584 : 792 : static void CodeInc (unsigned int tokenno, unsigned int r, DynamicStrings_String function, DynamicStrings_String message)
3585 : : {
3586 : 792 : M2Range_Range p;
3587 : 792 : tree t;
3588 : 792 : tree condition;
3589 : 792 : tree e;
3590 : 792 : tree desMin;
3591 : 792 : tree desMax;
3592 : 792 : location_t location;
3593 : :
3594 : 792 : location = M2LexBuf_TokenToLocation (tokenno);
3595 : 792 : p = static_cast<M2Range_Range> (Indexing_GetIndice (RangeIndex, r));
3596 : 792 : M2GCCDeclare_TryDeclareConstant (p->tokenNo, p->des);
3597 : 792 : M2GCCDeclare_TryDeclareConstant (p->tokenNo, p->expr);
3598 : 792 : if (p->desLowestType != SymbolTable_NulSym)
3599 : : {
3600 : : /* avoid gcc warning by using compound statement even if not strictly necessary. */
3601 : 792 : if ((SymbolConversion_GccKnowsAbout (p->expr)) && (SymbolConversion_GccKnowsAbout (p->desLowestType)))
3602 : : {
3603 : : /* avoid dangling else. */
3604 : 792 : if (M2Range_GetMinMax (tokenno, p->desLowestType, &desMin, &desMax))
3605 : : {
3606 : 780 : e = m2convert_BuildConvert (location, m2type_GetTreeType (desMin), DeReferenceLValue (tokenno, p->expr), false);
3607 : 780 : IfOutsideLimitsDo (p->tokenNo, m2convert_BuildConvert (location, m2type_GetTreeType (desMin), m2expr_GetIntegerZero (location), false), e, desMax, r, function, message);
3608 : 780 : t = m2expr_BuildSub (location, desMax, m2convert_BuildConvert (location, SymbolConversion_Mod2Gcc (p->desLowestType), e, false), false);
3609 : 780 : condition = m2expr_BuildGreaterThan (location, SymbolConversion_Mod2Gcc (p->des), t);
3610 : 780 : m2type_AddStatement (location, m2statement_BuildIfThenDoEnd (condition, M2Range_CodeErrorCheck (r, function, message)));
3611 : : }
3612 : : }
3613 : : else
3614 : : {
3615 : 0 : M2Error_InternalError ((const char *) "should have resolved these types", 32);
3616 : : }
3617 : : }
3618 : 792 : }
3619 : :
3620 : :
3621 : : /*
3622 : : CodeDec -
3623 : : */
3624 : :
3625 : 684 : static void CodeDec (unsigned int tokenno, unsigned int r, DynamicStrings_String function, DynamicStrings_String message)
3626 : : {
3627 : 684 : M2Range_Range p;
3628 : 684 : tree t;
3629 : 684 : tree condition;
3630 : 684 : tree e;
3631 : 684 : tree desMin;
3632 : 684 : tree desMax;
3633 : 684 : location_t location;
3634 : :
3635 : 684 : location = M2LexBuf_TokenToLocation (tokenno);
3636 : 684 : p = static_cast<M2Range_Range> (Indexing_GetIndice (RangeIndex, r));
3637 : 684 : M2GCCDeclare_TryDeclareConstant (p->tokenNo, p->des);
3638 : 684 : M2GCCDeclare_TryDeclareConstant (p->tokenNo, p->expr);
3639 : 684 : if (p->desLowestType != SymbolTable_NulSym)
3640 : : {
3641 : : /* avoid gcc warning by using compound statement even if not strictly necessary. */
3642 : 684 : if ((SymbolConversion_GccKnowsAbout (p->expr)) && (SymbolConversion_GccKnowsAbout (p->desLowestType)))
3643 : : {
3644 : : /* avoid dangling else. */
3645 : 684 : if (M2Range_GetMinMax (tokenno, p->desLowestType, &desMin, &desMax))
3646 : : {
3647 : 684 : e = m2convert_BuildConvert (location, m2type_GetTreeType (desMin), DeReferenceLValue (tokenno, p->expr), false);
3648 : 684 : IfOutsideLimitsDo (p->tokenNo, m2convert_BuildConvert (location, m2type_GetTreeType (desMin), m2expr_GetIntegerZero (location), false), e, desMax, r, function, message);
3649 : 684 : t = m2expr_BuildSub (location, m2convert_BuildConvert (location, SymbolConversion_Mod2Gcc (p->desLowestType), e, false), desMin, false);
3650 : 684 : condition = m2expr_BuildLessThan (location, SymbolConversion_Mod2Gcc (p->des), t);
3651 : 684 : m2type_AddStatement (location, m2statement_BuildIfThenDoEnd (condition, M2Range_CodeErrorCheck (r, function, message)));
3652 : : }
3653 : : }
3654 : : else
3655 : : {
3656 : 0 : M2Error_InternalError ((const char *) "should have resolved these types", 32);
3657 : : }
3658 : : }
3659 : 684 : }
3660 : :
3661 : :
3662 : : /*
3663 : : CodeInclExcl -
3664 : : */
3665 : :
3666 : 1856 : static void CodeInclExcl (unsigned int tokenno, unsigned int r, DynamicStrings_String function, DynamicStrings_String message)
3667 : : {
3668 : 1856 : M2Range_Range p;
3669 : 1856 : tree e;
3670 : 1856 : tree desMin;
3671 : 1856 : tree desMax;
3672 : 1856 : location_t location;
3673 : :
3674 : 1856 : location = M2LexBuf_TokenToLocation (tokenno);
3675 : 1856 : p = static_cast<M2Range_Range> (Indexing_GetIndice (RangeIndex, r));
3676 : 1856 : M2GCCDeclare_TryDeclareConstant (p->tokenNo, p->des);
3677 : 1856 : M2GCCDeclare_TryDeclareConstant (p->tokenNo, p->expr);
3678 : 1856 : p->desLowestType = SymbolTable_SkipType (SymbolTable_GetType (p->des));
3679 : 1856 : if (p->desLowestType != SymbolTable_NulSym)
3680 : : {
3681 : : /* avoid gcc warning by using compound statement even if not strictly necessary. */
3682 : 1856 : if ((SymbolConversion_GccKnowsAbout (p->expr)) && (SymbolConversion_GccKnowsAbout (p->desLowestType)))
3683 : : {
3684 : : /* avoid dangling else. */
3685 : 1856 : if (M2Range_GetMinMax (tokenno, p->desLowestType, &desMin, &desMax))
3686 : : {
3687 : 0 : e = m2convert_BuildConvert (location, m2type_GetTreeType (desMin), DeReferenceLValue (tokenno, p->expr), false);
3688 : : /* this should not be used for incl/excl as des is a set type
3689 : : t := BuildSub(location,
3690 : : desMax,
3691 : : BuildConvert(location, Mod2Gcc(desLowestType), e, FALSE),
3692 : : FALSE) ;
3693 : : condition := BuildGreaterThan(Mod2Gcc(des), t) ;
3694 : : AddStatement(location, BuildIfThenDoEnd(condition, CodeErrorCheck(r, function, message)))
3695 : : */
3696 : 0 : IfOutsideLimitsDo (p->tokenNo, desMin, e, desMax, r, function, message);
3697 : : }
3698 : : }
3699 : : else
3700 : : {
3701 : 0 : M2Error_InternalError ((const char *) "should have resolved these types", 32);
3702 : : }
3703 : : }
3704 : 1856 : }
3705 : :
3706 : :
3707 : : /*
3708 : : CodeShiftRotate - ensure that the bit shift is within the range
3709 : : -(MAX(set)-MIN(set)+1)..(MAX(set)-MIN(set)+1)
3710 : : */
3711 : :
3712 : 418 : static void CodeShiftRotate (unsigned int tokenno, unsigned int r, DynamicStrings_String function, DynamicStrings_String message)
3713 : : {
3714 : 418 : unsigned int ofType;
3715 : 418 : M2Range_Range p;
3716 : 418 : tree e;
3717 : 418 : tree shiftMin;
3718 : 418 : tree shiftMax;
3719 : 418 : tree desMin;
3720 : 418 : tree desMax;
3721 : 418 : location_t location;
3722 : :
3723 : 418 : p = static_cast<M2Range_Range> (Indexing_GetIndice (RangeIndex, r));
3724 : 418 : M2GCCDeclare_TryDeclareConstant (p->tokenNo, p->des);
3725 : 418 : M2GCCDeclare_TryDeclareConstant (p->tokenNo, p->expr);
3726 : 418 : p->desLowestType = SymbolTable_SkipType (SymbolTable_GetType (p->des));
3727 : 418 : if (p->desLowestType != SymbolTable_NulSym)
3728 : : {
3729 : 418 : ofType = SymbolTable_SkipType (SymbolTable_GetType (p->desLowestType));
3730 : 418 : if ((SymbolConversion_GccKnowsAbout (p->expr)) && (SymbolConversion_GccKnowsAbout (ofType)))
3731 : : {
3732 : : /* avoid dangling else. */
3733 : 418 : if (M2Range_GetMinMax (tokenno, ofType, &desMin, &desMax))
3734 : : {
3735 : 418 : location = M2LexBuf_TokenToLocation (p->tokenNo);
3736 : 418 : desMin = m2convert_BuildConvert (location, m2type_GetIntegerType (), desMin, false);
3737 : 418 : desMax = m2convert_BuildConvert (location, m2type_GetIntegerType (), desMax, false);
3738 : 418 : shiftMax = m2expr_BuildAdd (location, m2expr_BuildSub (location, desMax, desMin, false), m2expr_GetIntegerOne (location), false);
3739 : 418 : shiftMin = m2expr_BuildNegate (location, shiftMax, false);
3740 : 418 : e = m2convert_BuildConvert (location, m2type_GetIntegerType (), DeReferenceLValue (tokenno, p->expr), false);
3741 : 418 : IfOutsideLimitsDo (p->tokenNo, shiftMin, e, shiftMax, r, function, message);
3742 : : }
3743 : : }
3744 : : else
3745 : : {
3746 : 0 : M2Error_InternalError ((const char *) "should have resolved these types", 32);
3747 : : }
3748 : : }
3749 : 418 : }
3750 : :
3751 : :
3752 : : /*
3753 : : CodeStaticArraySubscript -
3754 : : */
3755 : :
3756 : 11010 : static void CodeStaticArraySubscript (unsigned int tokenno, unsigned int r, DynamicStrings_String function, DynamicStrings_String message)
3757 : : {
3758 : 11010 : M2Range_Range p;
3759 : 11010 : tree desMin;
3760 : 11010 : tree desMax;
3761 : 11010 : location_t location;
3762 : :
3763 : 11010 : location = M2LexBuf_TokenToLocation (tokenno);
3764 : 11010 : p = static_cast<M2Range_Range> (Indexing_GetIndice (RangeIndex, r));
3765 : 11010 : M2GCCDeclare_TryDeclareConstant (p->tokenNo, p->expr);
3766 : 11010 : if ((SymbolConversion_GccKnowsAbout (p->expr)) && (SymbolConversion_GccKnowsAbout (p->desLowestType)))
3767 : : {
3768 : 11010 : if (M2Range_GetMinMax (tokenno, p->desLowestType, &desMin, &desMax))
3769 : : {
3770 : 11010 : IfOutsideLimitsDo (tokenno, desMin, m2convert_BuildConvert (location, m2type_GetTreeType (desMin), DeReferenceLValue (tokenno, p->expr), false), desMax, r, function, message);
3771 : : }
3772 : : else
3773 : : {
3774 : 0 : M2Error_InternalError ((const char *) "should have resolved the bounds of the static array", 51);
3775 : : }
3776 : : }
3777 : : else
3778 : : {
3779 : 0 : M2Error_InternalError ((const char *) "should have resolved these types", 32);
3780 : : }
3781 : 11010 : }
3782 : :
3783 : :
3784 : : /*
3785 : : CodeDynamicArraySubscript -
3786 : : */
3787 : :
3788 : 8706 : static void CodeDynamicArraySubscript (unsigned int tokenno, unsigned int r, DynamicStrings_String function, DynamicStrings_String message)
3789 : : {
3790 : 8706 : unsigned int UnboundedType;
3791 : 8706 : M2Range_Range p;
3792 : 8706 : tree high;
3793 : 8706 : tree e;
3794 : 8706 : location_t location;
3795 : :
3796 : 8706 : location = M2LexBuf_TokenToLocation (tokenno);
3797 : 8706 : p = static_cast<M2Range_Range> (Indexing_GetIndice (RangeIndex, r));
3798 : 8706 : M2GCCDeclare_TryDeclareConstant (p->tokenNo, p->expr);
3799 : 8706 : M2Debug_Assert (SymbolTable_IsVar (p->des));
3800 : 8706 : if ((SymbolConversion_GccKnowsAbout (p->expr)) && (SymbolConversion_GccKnowsAbout (p->des)))
3801 : : {
3802 : 8706 : UnboundedType = SymbolTable_GetType (p->des);
3803 : 8706 : M2Debug_Assert (SymbolTable_IsUnbounded (UnboundedType));
3804 : 8706 : high = m2convert_BuildConvert (location, m2type_GetIntegerType (), M2GenGCC_GetHighFromUnbounded (location, p->dimension, p->des), false);
3805 : 8706 : e = m2convert_BuildConvert (location, m2type_GetIntegerType (), DeReferenceLValue (tokenno, p->expr), false);
3806 : 8706 : IfOutsideLimitsDo (p->tokenNo, m2expr_GetIntegerZero (location), e, high, r, function, message);
3807 : : }
3808 : : else
3809 : : {
3810 : 0 : M2Error_InternalError ((const char *) "should have resolved these types", 32);
3811 : : }
3812 : 8706 : }
3813 : :
3814 : :
3815 : : /*
3816 : : CodeForLoopBegin -
3817 : : */
3818 : :
3819 : 140 : static void CodeForLoopBegin (unsigned int tokenno, unsigned int r, DynamicStrings_String function, DynamicStrings_String message)
3820 : : {
3821 : 140 : if (ForLoopBeginTypeCompatible (reinterpret_cast <M2Range_Range> (Indexing_GetIndice (RangeIndex, r))))
3822 : : {
3823 : 140 : DoCodeAssignment (tokenno, r, function, message);
3824 : : }
3825 : 140 : }
3826 : :
3827 : :
3828 : : /*
3829 : : CodeForLoopTo -
3830 : : */
3831 : :
3832 : 0 : static void CodeForLoopTo (unsigned int tokenno, unsigned int r, DynamicStrings_String function, DynamicStrings_String message)
3833 : : {
3834 : 0 : DoCodeAssignment (tokenno, r, function, message);
3835 : 0 : }
3836 : :
3837 : :
3838 : : /*
3839 : : SameTypesCodeForLoopEnd - the trivial case.
3840 : : */
3841 : :
3842 : 244 : static void SameTypesCodeForLoopEnd (unsigned int tokenNo, unsigned int r, DynamicStrings_String function, DynamicStrings_String message, M2Range_Range p, tree dmax)
3843 : : {
3844 : 244 : tree inc;
3845 : 244 : tree room;
3846 : 244 : tree statement;
3847 : 244 : tree condition;
3848 : 244 : location_t location;
3849 : :
3850 : 244 : location = M2LexBuf_TokenToLocation (tokenNo);
3851 : 244 : inc = DeReferenceLValue (p->tokenNo, p->expr);
3852 : 244 : room = m2expr_BuildSub (location, dmax, SymbolConversion_Mod2Gcc (p->des), false);
3853 : 244 : condition = m2expr_BuildLessThan (location, room, inc);
3854 : 244 : statement = BuildIfCallHandler (condition, r, function, message, m2expr_IsTrue (condition));
3855 : 244 : m2type_AddStatement (location, statement);
3856 : 244 : }
3857 : :
3858 : 2324 : static void DiffTypesCodeForLoopEnd (unsigned int tokenNo, unsigned int r, DynamicStrings_String function, DynamicStrings_String message, M2Range_Range p, tree dmax, tree emin, tree emax)
3859 : : {
3860 : 2324 : location_t location;
3861 : 2324 : tree desoftypee;
3862 : 2324 : tree inc;
3863 : 2324 : tree room;
3864 : 2324 : tree c1;
3865 : 2324 : tree c2;
3866 : 2324 : tree c3;
3867 : 2324 : tree c4;
3868 : 2324 : tree c5;
3869 : 2324 : tree c6;
3870 : 2324 : tree c7;
3871 : 2324 : tree c8;
3872 : 2324 : tree s1;
3873 : 2324 : tree s2;
3874 : 2324 : tree s3;
3875 : 2324 : tree s4;
3876 : 2324 : tree s5;
3877 : 2324 : tree s6;
3878 : 2324 : tree s7;
3879 : 2324 : tree s8;
3880 : 2324 : tree lg1;
3881 : 2324 : tree lg2;
3882 : 2324 : tree dz;
3883 : 2324 : tree ez;
3884 : :
3885 : : /*
3886 : : DiffTypesSameForLoopEnd - remember that lowestType will map onto an int, or unsigned int
3887 : : of appropriate size.
3888 : : */
3889 : 2324 : location = M2LexBuf_TokenToLocation (tokenNo);
3890 : 2324 : inc = DeReferenceLValue (p->tokenNo, p->expr);
3891 : 2324 : ez = m2convert_BuildConvert (location, SymbolConversion_Mod2Gcc (p->exprLowestType), m2expr_GetIntegerZero (location), false);
3892 : 2324 : dz = m2convert_BuildConvert (location, SymbolConversion_Mod2Gcc (p->desLowestType), m2expr_GetIntegerZero (location), false);
3893 : 2324 : c1 = m2expr_BuildGreaterThanOrEqual (location, inc, ez);
3894 : : /* if (inc >= 0) [c1] */
3895 : 2324 : c2 = m2expr_BuildGreaterThanOrEqual (location, SymbolConversion_Mod2Gcc (p->des), dz);
3896 : : /* if (des >= 0) [c2] */
3897 : 2324 : lg1 = m2convert_BuildConvert (location, SymbolConversion_Mod2Gcc (p->desLowestType), inc, false);
3898 : 2324 : room = m2expr_BuildSub (location, dmax, SymbolConversion_Mod2Gcc (p->des), false);
3899 : 2324 : c3 = m2expr_BuildGreaterThan (location, lg1, room); /* [c3] */
3900 : : /* WarnIf(IsTrue(c1) AND IsTrue(c2) AND IsTrue(c3), function, message) ; --implement me-- */
3901 : 2324 : s3 = BuildIfCallHandler (c3, r, function, message, false);
3902 : 2324 : s2 = m2statement_BuildIfThenDoEnd (c2, s3);
3903 : : /* if (des <= val(desLowestType, emax) [c4] */
3904 : 2324 : c4 = m2expr_BuildLessThanOrEqual (location, SymbolConversion_Mod2Gcc (p->des), m2convert_BuildConvert (location, SymbolConversion_Mod2Gcc (p->desLowestType), emax, false));
3905 : : /* des <= MAX(exprLowestType) */
3906 : 2324 : desoftypee = m2convert_BuildConvert (location, SymbolConversion_Mod2Gcc (p->exprLowestType), SymbolConversion_Mod2Gcc (p->des), false);
3907 : 2324 : c5 = m2expr_BuildEqualTo (location, desoftypee, emin); /* [c5] */
3908 : 2324 : s5 = BuildIfCallHandler (c5, r, function, message, false);
3909 : : /* end */
3910 : 2324 : c6 = m2expr_BuildEqualTo (location, inc, emin); /* [c6] */
3911 : : /* if des = 0 [c7] */
3912 : 2324 : c7 = m2expr_BuildEqualTo (location, SymbolConversion_Mod2Gcc (p->des), dz);
3913 : 2324 : s7 = BuildIfCallHandler (c7, r, function, message, false);
3914 : : /* lg2 = VAL(desLowestType, -inc) [s8] */
3915 : 2324 : lg2 = m2convert_BuildConvert (location, SymbolConversion_Mod2Gcc (p->desLowestType), m2expr_BuildNegate (location, inc, false), false);
3916 : : /* error */
3917 : 2324 : c8 = m2expr_BuildGreaterThan (location, lg2, SymbolConversion_Mod2Gcc (p->des));
3918 : 2324 : s8 = BuildIfCallHandler (c8, r, function, message, false);
3919 : : /* end */
3920 : 2324 : s6 = m2statement_BuildIfThenElseEnd (c6, s7, s8);
3921 : 2324 : s4 = m2statement_BuildIfThenElseEnd (c4, s5, s6);
3922 : 2324 : s1 = m2statement_BuildIfThenElseEnd (c1, s2, s4);
3923 : 2324 : m2type_AddStatement (location, s1);
3924 : 2324 : }
3925 : :
3926 : :
3927 : : /*
3928 : : CodeForLoopEnd - checks to see that des := des + expr does not overflow.
3929 : : This is called at the end of the for loop. It is more complex
3930 : : than it initially seems as des and expr might be different types.
3931 : : */
3932 : :
3933 : 2568 : static void CodeForLoopEnd (unsigned int tokenno, unsigned int r, DynamicStrings_String function, DynamicStrings_String message)
3934 : : {
3935 : 2568 : bool isCard;
3936 : 2568 : M2Range_Range p;
3937 : 2568 : tree dmin;
3938 : 2568 : tree dmax;
3939 : 2568 : tree emin;
3940 : 2568 : tree emax;
3941 : :
3942 : 2568 : p = static_cast<M2Range_Range> (Indexing_GetIndice (RangeIndex, r));
3943 : 2568 : M2GCCDeclare_TryDeclareConstant (tokenno, p->des); /* use quad tokenno, rather than the range tokenNo */
3944 : 2568 : M2GCCDeclare_TryDeclareConstant (tokenno, p->expr); /* use quad tokenno, rather than the range tokenNo */
3945 : 2568 : if (p->desLowestType != SymbolTable_NulSym) /* use quad tokenno, rather than the range tokenNo */
3946 : : {
3947 : 2568 : M2Debug_Assert (SymbolConversion_GccKnowsAbout (p->expr));
3948 : 2568 : if ((((SymbolConversion_GccKnowsAbout (p->desLowestType)) && (M2Range_GetMinMax (tokenno, p->desLowestType, &dmin, &dmax))) && (SymbolConversion_GccKnowsAbout (p->exprLowestType))) && (M2Range_GetMinMax (tokenno, p->exprLowestType, &emin, &emax)))
3949 : : {
3950 : 2568 : M2ALU_PushIntegerTree (dmin);
3951 : 2568 : M2ALU_PushInt (0);
3952 : 2568 : isCard = M2ALU_GreEqu (tokenno);
3953 : 2568 : if ((p->desLowestType == p->exprLowestType) && isCard)
3954 : : {
3955 : 244 : SameTypesCodeForLoopEnd (tokenno, r, function, message, p, dmax);
3956 : : }
3957 : : else
3958 : : {
3959 : 2324 : DiffTypesCodeForLoopEnd (tokenno, r, function, message, p, dmax, emin, emax);
3960 : : }
3961 : : }
3962 : : }
3963 : 2568 : }
3964 : :
3965 : :
3966 : : /*
3967 : : CodeNil -
3968 : : */
3969 : :
3970 : 23026 : static void CodeNil (unsigned int r, DynamicStrings_String function, DynamicStrings_String message)
3971 : : {
3972 : 23026 : M2Range_Range p;
3973 : 23026 : tree condition;
3974 : 23026 : tree t;
3975 : 23026 : location_t location;
3976 : :
3977 : 23026 : p = static_cast<M2Range_Range> (Indexing_GetIndice (RangeIndex, r));
3978 : 23026 : M2GCCDeclare_TryDeclareConstant (p->tokenNo, p->des);
3979 : : /*
3980 : : IF GetMode(des)=LeftValue
3981 : : THEN
3982 : : t := BuildIndirect(Mod2Gcc(des), Mod2Gcc(GetType(des)))
3983 : : ELSE
3984 : : t := Mod2Gcc(des)
3985 : : END ;
3986 : : */
3987 : 23026 : t = SymbolConversion_Mod2Gcc (p->des);
3988 : 23026 : location = M2LexBuf_TokenToLocation (p->tokenNo);
3989 : 23026 : condition = m2expr_BuildEqualTo (location, m2convert_BuildConvert (location, m2type_GetPointerType (), t, false), m2expr_GetPointerZero (location));
3990 : 23026 : m2type_AddStatement (location, BuildIfCallHandler (condition, r, function, message, true));
3991 : 23026 : }
3992 : :
3993 : :
3994 : : /*
3995 : : CodeWholeNonPos - generates range check code for expr<=0.
3996 : : */
3997 : :
3998 : 0 : static void CodeWholeNonPos (unsigned int tokenno, unsigned int r, DynamicStrings_String function, DynamicStrings_String message)
3999 : : {
4000 : 0 : unsigned int zero;
4001 : 0 : M2Range_Range p;
4002 : 0 : tree condition;
4003 : 0 : tree e;
4004 : 0 : location_t location;
4005 : :
4006 : 0 : p = static_cast<M2Range_Range> (Indexing_GetIndice (RangeIndex, r));
4007 : 0 : M2GCCDeclare_TryDeclareConstant (p->tokenNo, p->expr);
4008 : 0 : if (SymbolConversion_GccKnowsAbout (p->expr))
4009 : : {
4010 : 0 : location = M2LexBuf_TokenToLocation (tokenno);
4011 : 0 : e = M2GenGCC_ZConstToTypedConst (M2GenGCC_LValueToGenericPtr (location, p->expr), p->expr, p->des);
4012 : 0 : zero = MakeAndDeclareConstLit (tokenno, NameKey_MakeKey ((const char *) "0", 1), M2Base_ZType);
4013 : 0 : condition = m2expr_BuildLessThanOrEqual (location, e, SymbolConversion_Mod2Gcc (zero));
4014 : 0 : m2type_AddStatement (location, m2statement_BuildIfThenDoEnd (condition, M2Range_CodeErrorCheck (r, function, message)));
4015 : : }
4016 : : else
4017 : : {
4018 : 0 : M2Error_InternalError ((const char *) "should have resolved expr", 25);
4019 : : }
4020 : 0 : }
4021 : :
4022 : :
4023 : : /*
4024 : : CodeWholeZero - generates range check code for expr=0.
4025 : : */
4026 : :
4027 : 8560 : static void CodeWholeZero (unsigned int tokenno, unsigned int r, DynamicStrings_String function, DynamicStrings_String message)
4028 : : {
4029 : 8560 : unsigned int zero;
4030 : 8560 : M2Range_Range p;
4031 : 8560 : tree condition;
4032 : 8560 : tree e;
4033 : 8560 : location_t location;
4034 : :
4035 : 8560 : p = static_cast<M2Range_Range> (Indexing_GetIndice (RangeIndex, r));
4036 : 8560 : M2GCCDeclare_TryDeclareConstant (p->tokenNo, p->expr);
4037 : 8560 : if (SymbolConversion_GccKnowsAbout (p->expr))
4038 : : {
4039 : 8560 : location = M2LexBuf_TokenToLocation (tokenno);
4040 : 8560 : e = M2GenGCC_ZConstToTypedConst (M2GenGCC_LValueToGenericPtr (location, p->expr), p->expr, p->des);
4041 : 8560 : zero = MakeAndDeclareConstLit (tokenno, NameKey_MakeKey ((const char *) "0", 1), M2Base_ZType);
4042 : 8560 : condition = m2expr_BuildEqualTo (location, e, m2convert_BuildConvert (location, m2type_GetTreeType (e), SymbolConversion_Mod2Gcc (zero), false));
4043 : 8560 : m2type_AddStatement (location, m2statement_BuildIfThenDoEnd (condition, M2Range_CodeErrorCheck (r, function, message)));
4044 : : }
4045 : : else
4046 : : {
4047 : 0 : M2Error_InternalError ((const char *) "should have resolved expr", 25);
4048 : : }
4049 : 8560 : }
4050 : :
4051 : :
4052 : : /*
4053 : : FillInParameters -
4054 : : */
4055 : :
4056 : 12695 : static DynamicStrings_String FillInParameters (unsigned int r, DynamicStrings_String s)
4057 : : {
4058 : 12695 : M2Range_Range p;
4059 : :
4060 : 12695 : p = static_cast<M2Range_Range> (Indexing_GetIndice (RangeIndex, r));
4061 : 12695 : switch (p->type)
4062 : : {
4063 : 2275 : case M2Range_assignment:
4064 : 2275 : s = M2MetaError_MetaString3 (s, p->des, p->expr, p->dimension);
4065 : 2275 : break;
4066 : :
4067 : 94 : case M2Range_returnassignment:
4068 : 94 : s = M2MetaError_MetaString3 (s, p->des, p->expr, p->dimension);
4069 : 94 : break;
4070 : :
4071 : 0 : case M2Range_subrangeassignment:
4072 : 0 : M2Error_InternalError ((const char *) "unexpected case", 15);
4073 : 2340 : break;
4074 : :
4075 : 2340 : case M2Range_inc:
4076 : 2340 : s = M2MetaError_MetaString3 (s, p->des, p->expr, p->dimension);
4077 : 2340 : break;
4078 : :
4079 : 2052 : case M2Range_dec:
4080 : 2052 : s = M2MetaError_MetaString3 (s, p->des, p->expr, p->dimension);
4081 : 2052 : break;
4082 : :
4083 : 0 : case M2Range_incl:
4084 : 0 : s = M2MetaError_MetaString3 (s, p->des, p->expr, p->dimension);
4085 : 0 : break;
4086 : :
4087 : 0 : case M2Range_excl:
4088 : 0 : s = M2MetaError_MetaString3 (s, p->des, p->expr, p->dimension);
4089 : 0 : break;
4090 : :
4091 : 144 : case M2Range_shift:
4092 : 144 : s = M2MetaError_MetaString3 (s, p->des, p->expr, p->dimension);
4093 : 144 : break;
4094 : :
4095 : 0 : case M2Range_rotate:
4096 : 0 : s = M2MetaError_MetaString3 (s, p->des, p->expr, p->dimension);
4097 : 0 : break;
4098 : :
4099 : : case M2Range_typeassign:
4100 : : break;
4101 : :
4102 : : case M2Range_typeparam:
4103 : : break;
4104 : :
4105 : : case M2Range_typeexpr:
4106 : : break;
4107 : :
4108 : 396 : case M2Range_paramassign:
4109 : 396 : s = M2MetaError_MetaString3 (s, p->des, p->expr, p->paramNo);
4110 : 396 : break;
4111 : :
4112 : 816 : case M2Range_staticarraysubscript:
4113 : 816 : s = M2MetaError_MetaString3 (s, p->des, p->expr, p->dimension);
4114 : 816 : break;
4115 : :
4116 : 480 : case M2Range_dynamicarraysubscript:
4117 : 480 : s = M2MetaError_MetaString3 (s, p->des, p->expr, p->dimension);
4118 : 480 : break;
4119 : :
4120 : 0 : case M2Range_forloopbegin:
4121 : 0 : s = M2MetaError_MetaString3 (s, p->des, p->expr, p->dimension);
4122 : 0 : break;
4123 : :
4124 : 0 : case M2Range_forloopto:
4125 : 0 : s = M2MetaError_MetaString3 (s, p->des, p->expr, p->dimension);
4126 : 0 : break;
4127 : :
4128 : 1584 : case M2Range_forloopend:
4129 : 1584 : s = M2MetaError_MetaString3 (s, p->des, p->expr, p->dimension);
4130 : 1584 : break;
4131 : :
4132 : 792 : case M2Range_pointernil:
4133 : 792 : s = M2MetaError_MetaString3 (s, p->des, p->expr, p->dimension);
4134 : 792 : break;
4135 : :
4136 : 12 : case M2Range_noreturn:
4137 : 12 : s = M2MetaError_MetaString3 (s, p->des, p->expr, p->dimension);
4138 : 12 : break;
4139 : :
4140 : 104 : case M2Range_noelse:
4141 : 104 : s = M2MetaError_MetaString3 (s, p->des, p->expr, p->dimension);
4142 : 104 : break;
4143 : :
4144 : 0 : case M2Range_casebounds:
4145 : 0 : s = M2MetaError_MetaString3 (s, p->des, p->expr, p->dimension);
4146 : 0 : break;
4147 : :
4148 : 0 : case M2Range_wholenonposdiv:
4149 : 0 : s = M2MetaError_MetaString3 (s, p->des, p->expr, p->dimension);
4150 : 0 : break;
4151 : :
4152 : 0 : case M2Range_wholenonposmod:
4153 : 0 : s = M2MetaError_MetaString3 (s, p->des, p->expr, p->dimension);
4154 : 0 : break;
4155 : :
4156 : 1606 : case M2Range_wholezerodiv:
4157 : 1606 : s = M2MetaError_MetaString3 (s, p->des, p->expr, p->dimension);
4158 : 1606 : break;
4159 : :
4160 : 0 : case M2Range_wholezerorem:
4161 : 0 : s = M2MetaError_MetaString3 (s, p->des, p->expr, p->dimension);
4162 : 0 : break;
4163 : :
4164 : : case M2Range_none:
4165 : : break;
4166 : :
4167 : :
4168 : 0 : default:
4169 : 0 : M2Error_InternalError ((const char *) "unexpected case", 15);
4170 : 12695 : break;
4171 : : }
4172 : 12695 : return s;
4173 : : /* static analysis guarentees a RETURN statement will be used before here. */
4174 : : __builtin_unreachable ();
4175 : : }
4176 : :
4177 : :
4178 : : /*
4179 : : GetRangeErrorMessage - returns a specific error message for the range, r.
4180 : : It assumes the 3 parameters to be supplied on the MetaError
4181 : : parameter list are: dest, expr, paramNo or dimension.
4182 : :
4183 : : XYZ
4184 : : 'the initial assignment to {%1a} at the start of the FOR loop will cause a range error, as the type range of {%1taD} does not overlap with {%2tad}')
4185 : : 'the final TO value {%2a} of the FOR loop will cause a range error with the iterator variable {%1a}')
4186 : : */
4187 : :
4188 : 823945 : static DynamicStrings_String GetRangeErrorMessage (unsigned int r)
4189 : : {
4190 : 823945 : M2Range_Range p;
4191 : 823945 : DynamicStrings_String s;
4192 : :
4193 : 823945 : p = static_cast<M2Range_Range> (Indexing_GetIndice (RangeIndex, r));
4194 : 823945 : switch (p->type)
4195 : : {
4196 : 166437 : case M2Range_assignment:
4197 : 166437 : s = DynamicStrings_InitString ((const char *) "assignment will cause a range error, as the runtime instance value of {%1tad} does not overlap with the type {%2tad}", 116);
4198 : 166437 : break;
4199 : :
4200 : 16522 : case M2Range_returnassignment:
4201 : 16522 : s = DynamicStrings_InitString ((const char *) "attempting to return {%2Wa} from a procedure function {%1a} which will exceed exceed the range of type {%1tad}", 110);
4202 : 16522 : break;
4203 : :
4204 : 0 : case M2Range_subrangeassignment:
4205 : 0 : M2Error_InternalError ((const char *) "unexpected case", 15);
4206 : 792 : break;
4207 : :
4208 : 792 : case M2Range_inc:
4209 : 792 : s = DynamicStrings_InitString ((const char *) "if the INC is ever executed the expression {%2Wa} will cause an overflow error for the designator {%1a} as it exceeds the type range {%1ts:of {%1ts}}", 149);
4210 : 792 : break;
4211 : :
4212 : 684 : case M2Range_dec:
4213 : 684 : s = DynamicStrings_InitString ((const char *) "if the DEC is ever executed the expression {%2Wa} will cause an underflow error for the designator {%1a} as it exceeds the type range {%1ts:of {%1ts}}", 150);
4214 : 684 : break;
4215 : :
4216 : 1092 : case M2Range_incl:
4217 : 1092 : s = DynamicStrings_InitString ((const char *) "the expression {%2Wa} given in the INCL exceeds the type range {%1ts} of the designator {%1a}", 93);
4218 : 1092 : break;
4219 : :
4220 : 764 : case M2Range_excl:
4221 : 764 : s = DynamicStrings_InitString ((const char *) "the expression {%2Wa} given in the EXCL exceeds the type range {%1ts} of the designator {%1a}", 93);
4222 : 764 : break;
4223 : :
4224 : 288 : case M2Range_shift:
4225 : 288 : s = DynamicStrings_InitString ((const char *) "the expression {%2Wa} given in the second parameter to SHIFT exceeds the type range {%1ts} of the first parameter {%1a}", 119);
4226 : 288 : break;
4227 : :
4228 : 130 : case M2Range_rotate:
4229 : 130 : s = DynamicStrings_InitString ((const char *) "the expression {%2Wa} given in the second parameter to ROTATE exceeds the type range {%1ts} of the first parameter {%1a}", 120);
4230 : 130 : break;
4231 : :
4232 : : case M2Range_typeassign:
4233 : : s = static_cast<DynamicStrings_String> (NULL);
4234 : : break;
4235 : :
4236 : : case M2Range_typeparam:
4237 : : s = static_cast<DynamicStrings_String> (NULL);
4238 : : break;
4239 : :
4240 : : case M2Range_typeexpr:
4241 : : s = static_cast<DynamicStrings_String> (NULL);
4242 : : break;
4243 : :
4244 : 512 : case M2Range_typeindrx:
4245 : 512 : s = DynamicStrings_InitString ((const char *) "assignment between designator {%1ad} and {%2ad} is incompatible", 63);
4246 : 512 : break;
4247 : :
4248 : 12688 : case M2Range_typereturn:
4249 : 12688 : s = DynamicStrings_InitString ((const char *) "the value {%2ad} returned from procedure function {%1a} is type incompatible, expecting {%1tad} rather than a {%2tad}", 117);
4250 : 12688 : break;
4251 : :
4252 : 91368 : case M2Range_paramassign:
4253 : 91368 : s = DynamicStrings_InitString ((const char *) "if this call is executed then the actual parameter {%2Wa} will be out of range of the {%3N} formal parameter {%1a}", 114);
4254 : 91368 : break;
4255 : :
4256 : 11010 : case M2Range_staticarraysubscript:
4257 : 11010 : s = DynamicStrings_InitString ((const char *) "if this access to the static array {%1Wa:{%2a:{%1a}[{%2a}]}} is ever made then the index will be out of bounds in the {%3N} array subscript", 139);
4258 : 11010 : break;
4259 : :
4260 : 8706 : case M2Range_dynamicarraysubscript:
4261 : 8706 : s = DynamicStrings_InitString ((const char *) "if this access to the dynamic array {%1Wa:{%2a:{%1a}[{%2a}]}} is ever made then the index will be out of bounds in the {%3N} array subscript", 140);
4262 : 8706 : break;
4263 : :
4264 : 140 : case M2Range_forloopbegin:
4265 : 140 : s = DynamicStrings_InitString ((const char *) "if the assignment in this FOR loop is ever executed then the designator {%1Wa} will be exceed the type range {%1ts:of {%1ts}}", 125);
4266 : 140 : break;
4267 : :
4268 : 0 : case M2Range_forloopto:
4269 : 0 : s = DynamicStrings_InitString ((const char *) "the final value {%2Wa} in this FOR loop will be out of bounds {%1ts:of type {%1ts}} if ever executed", 100);
4270 : 0 : break;
4271 : :
4272 : 2568 : case M2Range_forloopend:
4273 : 2568 : s = DynamicStrings_InitString ((const char *) "the FOR loop will cause the designator {%1Wa} to be out of bounds when the BY value {%2a} is added", 98);
4274 : 2568 : break;
4275 : :
4276 : 23026 : case M2Range_pointernil:
4277 : 23026 : s = DynamicStrings_InitString ((const char *) "if this pointer value {%1Wa} is ever dereferenced it will cause an exception", 76);
4278 : 23026 : break;
4279 : :
4280 : 12 : case M2Range_noreturn:
4281 : 12 : s = DynamicStrings_InitString ((const char *) "{%1W:}this function will exit without executing a RETURN statement", 66);
4282 : 12 : break;
4283 : :
4284 : 104 : case M2Range_noelse:
4285 : 104 : s = DynamicStrings_InitString ((const char *) "{%1W:}this CASE statement does not have an ELSE statement", 57);
4286 : 104 : break;
4287 : :
4288 : 0 : case M2Range_casebounds:
4289 : 0 : s = DynamicStrings_InitString ((const char *) "{%1W:}this CASE statement has overlapping ranges", 48);
4290 : 0 : break;
4291 : :
4292 : 0 : case M2Range_wholenonposdiv:
4293 : 0 : s = DynamicStrings_InitString ((const char *) "this division expression {%2Wa} will cause an exception as this divisor is less than or equal to zero", 101);
4294 : 0 : break;
4295 : :
4296 : 0 : case M2Range_wholenonposmod:
4297 : 0 : s = DynamicStrings_InitString ((const char *) "this modulus expression {%2Wa} will cause an exception as this divisor is less than or equal to zero", 100);
4298 : 0 : break;
4299 : :
4300 : 8464 : case M2Range_wholezerodiv:
4301 : 8464 : s = DynamicStrings_InitString ((const char *) "this division expression {%2Wa} will cause an exception as the divisor is zero", 78);
4302 : 8464 : break;
4303 : :
4304 : 96 : case M2Range_wholezerorem:
4305 : 96 : s = DynamicStrings_InitString ((const char *) "this remainder expression {%2Wa} will cause an exception as the divisor is zero", 79);
4306 : 96 : break;
4307 : :
4308 : : case M2Range_none:
4309 : : s = static_cast<DynamicStrings_String> (NULL);
4310 : : break;
4311 : :
4312 : :
4313 : 0 : default:
4314 : 0 : M2Error_InternalError ((const char *) "unexpected case", 15);
4315 : 823945 : break;
4316 : : }
4317 : 823945 : return s;
4318 : : /* static analysis guarentees a RETURN statement will be used before here. */
4319 : : __builtin_unreachable ();
4320 : : }
4321 : :
4322 : :
4323 : : /*
4324 : : Init - initializes the modules global variables.
4325 : : */
4326 : :
4327 : 15506 : static void Init (void)
4328 : : {
4329 : 15506 : TopOfRange = 0;
4330 : 15506 : RangeIndex = Indexing_InitIndex (1);
4331 : 15506 : BreakWhenRangeCreated (0); /* Disable the intereactive range watch. */
4332 : : /* To examine the range when it is created run cc1gm2 from gdb
4333 : : and set a break point on gdbhook.
4334 : : (gdb) break gdbhook
4335 : : (gdb) run
4336 : : Now below interactively call BreakWhenRangeCreated with the symbol
4337 : : under investigation. */
4338 : 15506 : gdbhook ();
4339 : 15506 : }
4340 : :
4341 : :
4342 : : /*
4343 : : InitAssignmentRangeCheck - returns a range check node which
4344 : : remembers the information necessary
4345 : : so that a range check for des := expr
4346 : : can be generated later on.
4347 : : */
4348 : :
4349 : 486535 : extern "C" unsigned int M2Range_InitAssignmentRangeCheck (unsigned int tokno, unsigned int des, unsigned int expr, unsigned int destok, unsigned int exprtok)
4350 : : {
4351 : 486535 : unsigned int r;
4352 : 486535 : M2Range_Range p;
4353 : :
4354 : 486535 : r = InitRange ();
4355 : 486535 : p = static_cast<M2Range_Range> (Indexing_GetIndice (RangeIndex, r));
4356 : 486535 : M2Debug_Assert ((PutRange (tokno, p, M2Range_assignment, des, expr)) != NULL);
4357 : 486529 : p->destok = destok;
4358 : 486529 : p->exprtok = exprtok;
4359 : 486529 : return r;
4360 : : /* static analysis guarentees a RETURN statement will be used before here. */
4361 : : __builtin_unreachable ();
4362 : : }
4363 : :
4364 : :
4365 : : /*
4366 : : InitReturnRangeCheck - returns a range check node which
4367 : : remembers the information necessary
4368 : : so that a range check for RETURN e
4369 : : from procedure, d, can be generated later on.
4370 : : */
4371 : :
4372 : 27679 : extern "C" unsigned int M2Range_InitReturnRangeCheck (unsigned int tokno, unsigned int d, unsigned int e)
4373 : : {
4374 : 27679 : unsigned int r;
4375 : :
4376 : 27679 : r = InitRange ();
4377 : 27679 : M2Debug_Assert ((PutRange (tokno, reinterpret_cast <M2Range_Range> (Indexing_GetIndice (RangeIndex, r)), M2Range_returnassignment, d, e)) != NULL);
4378 : 27679 : return r;
4379 : : /* static analysis guarentees a RETURN statement will be used before here. */
4380 : : __builtin_unreachable ();
4381 : : }
4382 : :
4383 : :
4384 : : /*
4385 : : InitSubrangeRangeCheck - returns a range check node which
4386 : : remembers the information necessary
4387 : : so that a range check for d := e
4388 : : can be generated later on.
4389 : : */
4390 : :
4391 : 0 : extern "C" unsigned int M2Range_InitSubrangeRangeCheck (unsigned int d, unsigned int e)
4392 : : {
4393 : 0 : unsigned int r;
4394 : :
4395 : 0 : r = InitRange ();
4396 : 0 : M2Debug_Assert ((PutRange (M2LexBuf_GetTokenNo (), reinterpret_cast <M2Range_Range> (Indexing_GetIndice (RangeIndex, r)), M2Range_subrangeassignment, d, e)) != NULL);
4397 : 0 : return r;
4398 : : /* static analysis guarentees a RETURN statement will be used before here. */
4399 : : __builtin_unreachable ();
4400 : : }
4401 : :
4402 : :
4403 : : /*
4404 : : InitStaticArraySubscriptRangeCheck - returns a range check node which
4405 : : remembers the information necessary
4406 : : so that a range check for d[e]
4407 : : can be generated later on.
4408 : : */
4409 : :
4410 : 47726 : extern "C" unsigned int M2Range_InitStaticArraySubscriptRangeCheck (unsigned int d, unsigned int e, unsigned int dim)
4411 : : {
4412 : 47726 : unsigned int r;
4413 : :
4414 : 47726 : r = InitRange ();
4415 : 47726 : M2Debug_Assert ((PutRangeArraySubscript (reinterpret_cast <M2Range_Range> (Indexing_GetIndice (RangeIndex, r)), M2Range_staticarraysubscript, d, e, dim)) != NULL);
4416 : 47726 : return r;
4417 : : /* static analysis guarentees a RETURN statement will be used before here. */
4418 : : __builtin_unreachable ();
4419 : : }
4420 : :
4421 : :
4422 : : /*
4423 : : InitDynamicArraySubscriptRangeCheck - returns a range check node which
4424 : : remembers the information necessary
4425 : : so that a range check for d[e]
4426 : : can be generated later on.
4427 : : */
4428 : :
4429 : 8994 : extern "C" unsigned int M2Range_InitDynamicArraySubscriptRangeCheck (unsigned int d, unsigned int e, unsigned int dim)
4430 : : {
4431 : 8994 : unsigned int r;
4432 : :
4433 : 8994 : r = InitRange ();
4434 : 8994 : M2Debug_Assert ((PutRangeArraySubscript (reinterpret_cast <M2Range_Range> (Indexing_GetIndice (RangeIndex, r)), M2Range_dynamicarraysubscript, d, e, dim)) != NULL);
4435 : 8994 : return r;
4436 : : /* static analysis guarentees a RETURN statement will be used before here. */
4437 : : __builtin_unreachable ();
4438 : : }
4439 : :
4440 : :
4441 : : /*
4442 : : InitIncRangeCheck - returns a range check node which
4443 : : remembers the information necessary
4444 : : so that a range check for INC(d, e)
4445 : : can be generated later on.
4446 : : */
4447 : :
4448 : 792 : extern "C" unsigned int M2Range_InitIncRangeCheck (unsigned int d, unsigned int e)
4449 : : {
4450 : 792 : unsigned int r;
4451 : :
4452 : 792 : r = InitRange ();
4453 : 792 : M2Debug_Assert ((PutRange (M2LexBuf_GetTokenNo (), reinterpret_cast <M2Range_Range> (Indexing_GetIndice (RangeIndex, r)), M2Range_inc, d, e)) != NULL);
4454 : 792 : return r;
4455 : : /* static analysis guarentees a RETURN statement will be used before here. */
4456 : : __builtin_unreachable ();
4457 : : }
4458 : :
4459 : :
4460 : : /*
4461 : : InitDecRangeCheck - returns a range check node which
4462 : : remembers the information necessary
4463 : : so that a range check for DEC(d, e)
4464 : : can be generated later on.
4465 : : */
4466 : :
4467 : 684 : extern "C" unsigned int M2Range_InitDecRangeCheck (unsigned int d, unsigned int e)
4468 : : {
4469 : 684 : unsigned int r;
4470 : :
4471 : 684 : r = InitRange ();
4472 : 684 : M2Debug_Assert ((PutRange (M2LexBuf_GetTokenNo (), reinterpret_cast <M2Range_Range> (Indexing_GetIndice (RangeIndex, r)), M2Range_dec, d, e)) != NULL);
4473 : 684 : return r;
4474 : : /* static analysis guarentees a RETURN statement will be used before here. */
4475 : : __builtin_unreachable ();
4476 : : }
4477 : :
4478 : :
4479 : : /*
4480 : : InitForLoopBeginRangeCheck - returns a range check node which
4481 : : remembers the information necessary
4482 : : so that a range check for
4483 : : FOR des := expr1 TO expr2 DO
4484 : : can be generated later on. expr2 is
4485 : : only used to type check with des.
4486 : : */
4487 : :
4488 : 2610 : extern "C" unsigned int M2Range_InitForLoopBeginRangeCheck (unsigned int des, unsigned int destok, unsigned int expr1, unsigned int expr1tok, unsigned int expr2, unsigned int expr2tok, unsigned int byconst, unsigned int byconsttok)
4489 : : {
4490 : 2610 : unsigned int r;
4491 : :
4492 : 2610 : r = InitRange ();
4493 : 5220 : M2Debug_Assert ((PutRangeDesExpr2 (reinterpret_cast <M2Range_Range> (Indexing_GetIndice (RangeIndex, r)), M2Range_forloopbegin, des, destok, expr1, expr1tok, expr2, expr2tok, byconst, byconsttok)) != NULL);
4494 : 2610 : return r;
4495 : : /* static analysis guarentees a RETURN statement will be used before here. */
4496 : : __builtin_unreachable ();
4497 : : }
4498 : :
4499 : :
4500 : : /*
4501 : : PutRangeForIncrement - places incrementquad into the range record.
4502 : : */
4503 : :
4504 : 2604 : extern "C" void M2Range_PutRangeForIncrement (unsigned int range, unsigned int incrementquad)
4505 : : {
4506 : 2604 : M2Range_Range p;
4507 : :
4508 : 2604 : p = static_cast<M2Range_Range> (Indexing_GetIndice (RangeIndex, range));
4509 : 2604 : p->incrementquad = incrementquad;
4510 : 2604 : }
4511 : :
4512 : :
4513 : : /*
4514 : : InitForLoopToRangeCheck - returns a range check node which
4515 : : remembers the information necessary
4516 : : so that a range check for FOR d := e TO .. DO
4517 : : can be generated later on.
4518 : : */
4519 : :
4520 : 0 : extern "C" unsigned int M2Range_InitForLoopToRangeCheck (unsigned int d, unsigned int e)
4521 : : {
4522 : 0 : unsigned int r;
4523 : :
4524 : 0 : r = InitRange ();
4525 : 0 : M2Debug_Assert ((PutRange (M2LexBuf_GetTokenNo (), reinterpret_cast <M2Range_Range> (Indexing_GetIndice (RangeIndex, r)), M2Range_forloopto, d, e)) != NULL);
4526 : 0 : return r;
4527 : : /* static analysis guarentees a RETURN statement will be used before here. */
4528 : : __builtin_unreachable ();
4529 : : }
4530 : :
4531 : :
4532 : : /*
4533 : : InitForLoopEndRangeCheck - returns a range check node which
4534 : : remembers the information necessary
4535 : : so that a range check for
4536 : : INC or DEC(d, e)
4537 : : can be generated later on.
4538 : : */
4539 : :
4540 : 2604 : extern "C" unsigned int M2Range_InitForLoopEndRangeCheck (unsigned int d, unsigned int e)
4541 : : {
4542 : 2604 : unsigned int r;
4543 : :
4544 : 2604 : r = InitRange ();
4545 : 2604 : M2Debug_Assert ((PutRange (M2LexBuf_GetTokenNo (), reinterpret_cast <M2Range_Range> (Indexing_GetIndice (RangeIndex, r)), M2Range_forloopend, d, e)) != NULL);
4546 : 2604 : return r;
4547 : : /* static analysis guarentees a RETURN statement will be used before here. */
4548 : : __builtin_unreachable ();
4549 : : }
4550 : :
4551 : :
4552 : : /*
4553 : : InitPointerRangeCheck - creates a pointer # NIL check.
4554 : : */
4555 : :
4556 : 23438 : extern "C" unsigned int M2Range_InitPointerRangeCheck (unsigned int tokno, unsigned int d, bool isLeft)
4557 : : {
4558 : 23438 : unsigned int r;
4559 : :
4560 : 23438 : r = InitRange ();
4561 : 23438 : M2Debug_Assert ((PutRangePointer (tokno, reinterpret_cast <M2Range_Range> (Indexing_GetIndice (RangeIndex, r)), d, isLeft)) != NULL);
4562 : 23438 : return r;
4563 : : /* static analysis guarentees a RETURN statement will be used before here. */
4564 : : __builtin_unreachable ();
4565 : : }
4566 : :
4567 : :
4568 : : /*
4569 : : InitNoReturnRangeCheck - creates a check held in the function
4570 : : to detect the absence of a RETURN
4571 : : statement at runtime.
4572 : : */
4573 : :
4574 : 18963 : extern "C" unsigned int M2Range_InitNoReturnRangeCheck (void)
4575 : : {
4576 : 18963 : unsigned int r;
4577 : :
4578 : 18963 : r = InitRange ();
4579 : 18963 : M2Debug_Assert ((PutRangeNoEval (reinterpret_cast <M2Range_Range> (Indexing_GetIndice (RangeIndex, r)), M2Range_noreturn)) != NULL);
4580 : 18963 : return r;
4581 : : /* static analysis guarentees a RETURN statement will be used before here. */
4582 : : __builtin_unreachable ();
4583 : : }
4584 : :
4585 : :
4586 : : /*
4587 : : InitNoElseRangeCheck - creates a check held at the end of
4588 : : a CASE statement without an ELSE
4589 : : clause to detect its absence
4590 : : at runtime.
4591 : : */
4592 : :
4593 : 482 : extern "C" unsigned int M2Range_InitNoElseRangeCheck (void)
4594 : : {
4595 : 482 : unsigned int r;
4596 : :
4597 : 482 : r = InitRange ();
4598 : 482 : M2Debug_Assert ((PutRangeNoEval (reinterpret_cast <M2Range_Range> (Indexing_GetIndice (RangeIndex, r)), M2Range_noelse)) != NULL);
4599 : 482 : return r;
4600 : : /* static analysis guarentees a RETURN statement will be used before here. */
4601 : : __builtin_unreachable ();
4602 : : }
4603 : :
4604 : :
4605 : : /*
4606 : : InitWholeNonPosDivCheck - creates a check expression for non positive
4607 : : or zero 2nd operand to division.
4608 : : */
4609 : :
4610 : 0 : extern "C" unsigned int M2Range_InitWholeNonPosDivCheck (unsigned int tokno, unsigned int d, unsigned int e)
4611 : : {
4612 : 0 : unsigned int r;
4613 : :
4614 : 0 : r = InitRange ();
4615 : 0 : M2Debug_Assert ((PutRangeUnary (tokno, reinterpret_cast <M2Range_Range> (Indexing_GetIndice (RangeIndex, r)), M2Range_wholenonposdiv, d, e)) != NULL);
4616 : 0 : return r;
4617 : : /* static analysis guarentees a RETURN statement will be used before here. */
4618 : : __builtin_unreachable ();
4619 : : }
4620 : :
4621 : :
4622 : : /*
4623 : : InitWholeNonPosModCheck - creates a check expression for non positive
4624 : : or zero 2nd operand to modulus.
4625 : : */
4626 : :
4627 : 0 : extern "C" unsigned int M2Range_InitWholeNonPosModCheck (unsigned int tokno, unsigned int d, unsigned int e)
4628 : : {
4629 : 0 : unsigned int r;
4630 : :
4631 : 0 : r = InitRange ();
4632 : 0 : M2Debug_Assert ((PutRangeUnary (tokno, reinterpret_cast <M2Range_Range> (Indexing_GetIndice (RangeIndex, r)), M2Range_wholenonposmod, d, e)) != NULL);
4633 : 0 : return r;
4634 : : /* static analysis guarentees a RETURN statement will be used before here. */
4635 : : __builtin_unreachable ();
4636 : : }
4637 : :
4638 : :
4639 : : /*
4640 : : InitWholeZeroDivisionCheck - creates a check expression for zero 2nd
4641 : : operand for division.
4642 : : */
4643 : :
4644 : 9026 : extern "C" unsigned int M2Range_InitWholeZeroDivisionCheck (unsigned int tokno, unsigned int d, unsigned int e)
4645 : : {
4646 : 9026 : unsigned int r;
4647 : :
4648 : 9026 : r = InitRange ();
4649 : 9026 : M2Debug_Assert ((PutRangeUnary (tokno, reinterpret_cast <M2Range_Range> (Indexing_GetIndice (RangeIndex, r)), M2Range_wholezerodiv, d, e)) != NULL);
4650 : 9026 : return r;
4651 : : /* static analysis guarentees a RETURN statement will be used before here. */
4652 : : __builtin_unreachable ();
4653 : : }
4654 : :
4655 : :
4656 : : /*
4657 : : InitWholeZeroRemainderCheck - creates a check expression for zero 2nd
4658 : : operand for remainder.
4659 : : */
4660 : :
4661 : 96 : extern "C" unsigned int M2Range_InitWholeZeroRemainderCheck (unsigned int tokno, unsigned int d, unsigned int e)
4662 : : {
4663 : 96 : unsigned int r;
4664 : :
4665 : 96 : r = InitRange ();
4666 : 96 : M2Debug_Assert ((PutRangeUnary (tokno, reinterpret_cast <M2Range_Range> (Indexing_GetIndice (RangeIndex, r)), M2Range_wholezerorem, d, e)) != NULL);
4667 : 96 : return r;
4668 : : /* static analysis guarentees a RETURN statement will be used before here. */
4669 : : __builtin_unreachable ();
4670 : : }
4671 : :
4672 : :
4673 : : /*
4674 : : InitInclCheck - checks to see that bit, e, is type compatible with
4675 : : e and also in range.
4676 : : */
4677 : :
4678 : 1116 : extern "C" unsigned int M2Range_InitInclCheck (unsigned int d, unsigned int e)
4679 : : {
4680 : 1116 : unsigned int r;
4681 : :
4682 : 1116 : r = InitRange ();
4683 : 1116 : M2Debug_Assert ((PutRangeNoLow (M2LexBuf_GetTokenNo (), reinterpret_cast <M2Range_Range> (Indexing_GetIndice (RangeIndex, r)), M2Range_incl, d, e)) != NULL);
4684 : 1116 : return r;
4685 : : /* static analysis guarentees a RETURN statement will be used before here. */
4686 : : __builtin_unreachable ();
4687 : : }
4688 : :
4689 : :
4690 : : /*
4691 : : InitExclCheck - checks to see that bit, e, is type compatible with
4692 : : e and also in range.
4693 : : */
4694 : :
4695 : 770 : extern "C" unsigned int M2Range_InitExclCheck (unsigned int d, unsigned int e)
4696 : : {
4697 : 770 : unsigned int r;
4698 : :
4699 : 770 : r = InitRange ();
4700 : 770 : M2Debug_Assert ((PutRangeNoLow (M2LexBuf_GetTokenNo (), reinterpret_cast <M2Range_Range> (Indexing_GetIndice (RangeIndex, r)), M2Range_excl, d, e)) != NULL);
4701 : 770 : return r;
4702 : : /* static analysis guarentees a RETURN statement will be used before here. */
4703 : : __builtin_unreachable ();
4704 : : }
4705 : :
4706 : :
4707 : : /*
4708 : : InitShiftCheck - checks to see that bit, e, is type compatible with
4709 : : d and also in range.
4710 : : */
4711 : :
4712 : 682 : extern "C" unsigned int M2Range_InitShiftCheck (unsigned int d, unsigned int e)
4713 : : {
4714 : 682 : unsigned int r;
4715 : :
4716 : 682 : r = InitRange ();
4717 : 682 : M2Debug_Assert ((PutRangeNoLow (M2LexBuf_GetTokenNo (), reinterpret_cast <M2Range_Range> (Indexing_GetIndice (RangeIndex, r)), M2Range_shift, d, e)) != NULL);
4718 : 682 : return r;
4719 : : /* static analysis guarentees a RETURN statement will be used before here. */
4720 : : __builtin_unreachable ();
4721 : : }
4722 : :
4723 : :
4724 : : /*
4725 : : InitRotateCheck - checks to see that bit, e, is type compatible with
4726 : : d and also in range.
4727 : : */
4728 : :
4729 : 406 : extern "C" unsigned int M2Range_InitRotateCheck (unsigned int d, unsigned int e)
4730 : : {
4731 : 406 : unsigned int r;
4732 : :
4733 : 406 : r = InitRange ();
4734 : 406 : M2Debug_Assert ((PutRangeNoLow (M2LexBuf_GetTokenNo (), reinterpret_cast <M2Range_Range> (Indexing_GetIndice (RangeIndex, r)), M2Range_rotate, d, e)) != NULL);
4735 : 406 : return r;
4736 : : /* static analysis guarentees a RETURN statement will be used before here. */
4737 : : __builtin_unreachable ();
4738 : : }
4739 : :
4740 : :
4741 : : /*
4742 : : InitTypesAssignmentCheck - checks to see that the types of d and e
4743 : : are assignment compatible.
4744 : : */
4745 : :
4746 : 496133 : extern "C" unsigned int M2Range_InitTypesAssignmentCheck (unsigned int tokno, unsigned int d, unsigned int e)
4747 : : {
4748 : 496133 : unsigned int r;
4749 : :
4750 : 496133 : r = InitRange ();
4751 : 496133 : M2Debug_Assert ((PutRangeNoLow (tokno, reinterpret_cast <M2Range_Range> (Indexing_GetIndice (RangeIndex, r)), M2Range_typeassign, d, e)) != NULL);
4752 : 496133 : return r;
4753 : : /* static analysis guarentees a RETURN statement will be used before here. */
4754 : : __builtin_unreachable ();
4755 : : }
4756 : :
4757 : :
4758 : : /*
4759 : : InitTypesParameterCheck - checks to see that the types of, d,
4760 : : and, e, are parameter compatible.
4761 : : */
4762 : :
4763 : 630652 : extern "C" unsigned int M2Range_InitTypesParameterCheck (unsigned int tokno, unsigned int proc, unsigned int paramno, unsigned int formal, unsigned int actual, unsigned int depRangeId)
4764 : : {
4765 : 630652 : unsigned int r;
4766 : :
4767 : 630652 : r = InitRange ();
4768 : 630652 : M2Debug_Assert ((PutRangeParam (tokno, reinterpret_cast <M2Range_Range> (Indexing_GetIndice (RangeIndex, r)), M2Range_typeparam, proc, paramno, formal, actual, depRangeId)) != NULL);
4769 : 630652 : return r;
4770 : : /* static analysis guarentees a RETURN statement will be used before here. */
4771 : : __builtin_unreachable ();
4772 : : }
4773 : :
4774 : :
4775 : : /*
4776 : : InitParameterRangeCheck - checks to see that the types of, d, and, e,
4777 : : are parameter compatible.
4778 : : */
4779 : :
4780 : 141995 : extern "C" unsigned int M2Range_InitParameterRangeCheck (unsigned int tokno, unsigned int proc, unsigned int paramno, unsigned int formal, unsigned int actual, unsigned int parentRangeId)
4781 : : {
4782 : 141995 : unsigned int r;
4783 : :
4784 : 141995 : r = InitRange ();
4785 : 283990 : M2Debug_Assert ((PutRangeParamAssign (tokno, reinterpret_cast <M2Range_Range> (Indexing_GetIndice (RangeIndex, r)), M2Range_paramassign, proc, paramno, formal, actual, parentRangeId)) != NULL);
4786 : 141995 : return r;
4787 : : /* static analysis guarentees a RETURN statement will be used before here. */
4788 : : __builtin_unreachable ();
4789 : : }
4790 : :
4791 : :
4792 : : /*
4793 : : InitTypesExpressionCheck - checks to see that the types of, d, and, e,
4794 : : are expression compatible.
4795 : : */
4796 : :
4797 : 151455 : extern "C" unsigned int M2Range_InitTypesExpressionCheck (unsigned int tokno, unsigned int d, unsigned int e, bool strict, bool isin)
4798 : : {
4799 : 151455 : unsigned int r;
4800 : :
4801 : 151455 : r = InitRange ();
4802 : 151455 : M2Debug_Assert ((PutRangeExpr (tokno, reinterpret_cast <M2Range_Range> (Indexing_GetIndice (RangeIndex, r)), M2Range_typeexpr, d, e, strict, isin)) != NULL);
4803 : 151455 : return r;
4804 : : /* static analysis guarentees a RETURN statement will be used before here. */
4805 : : __builtin_unreachable ();
4806 : : }
4807 : :
4808 : :
4809 : : /*
4810 : : InitTypesIndrXCheck - checks to see that the types of d and e
4811 : : are assignment compatible. The type checking
4812 : : will dereference *e during the type check.
4813 : : d = *e.
4814 : : */
4815 : :
4816 : 518 : extern "C" unsigned int M2Range_InitTypesIndrXCheck (unsigned int tokno, unsigned int d, unsigned int e)
4817 : : {
4818 : 518 : unsigned int r;
4819 : :
4820 : 518 : r = InitRange ();
4821 : 518 : M2Debug_Assert ((PutRangeNoLow (tokno, reinterpret_cast <M2Range_Range> (Indexing_GetIndice (RangeIndex, r)), M2Range_typeindrx, d, e)) != NULL);
4822 : 518 : return r;
4823 : : /* static analysis guarentees a RETURN statement will be used before here. */
4824 : : __builtin_unreachable ();
4825 : : }
4826 : :
4827 : :
4828 : : /*
4829 : : InitTypesReturnTypeCheck - checks to see that the types of des and func
4830 : : are assignment compatible.
4831 : : */
4832 : :
4833 : 27679 : extern "C" unsigned int M2Range_InitTypesReturnTypeCheck (unsigned int tokno, unsigned int func, unsigned int val)
4834 : : {
4835 : 27679 : unsigned int r;
4836 : :
4837 : 27679 : r = InitRange ();
4838 : 27679 : M2Debug_Assert ((PutRangeNoLow (tokno, reinterpret_cast <M2Range_Range> (Indexing_GetIndice (RangeIndex, r)), M2Range_typereturn, func, val)) != NULL);
4839 : 27679 : return r;
4840 : : /* static analysis guarentees a RETURN statement will be used before here. */
4841 : : __builtin_unreachable ();
4842 : : }
4843 : :
4844 : :
4845 : : /*
4846 : : InitCaseBounds - creates a case bound range check.
4847 : : */
4848 : :
4849 : 3972 : extern "C" unsigned int M2Range_InitCaseBounds (unsigned int b)
4850 : : {
4851 : 3972 : M2Range_Range p;
4852 : 3972 : unsigned int r;
4853 : :
4854 : 3972 : r = InitRange ();
4855 : 3972 : p = PutRangeNoEval (reinterpret_cast <M2Range_Range> (Indexing_GetIndice (RangeIndex, r)), M2Range_casebounds);
4856 : 3972 : p->caseList = b;
4857 : 3972 : return r;
4858 : : /* static analysis guarentees a RETURN statement will be used before here. */
4859 : : __builtin_unreachable ();
4860 : : }
4861 : :
4862 : :
4863 : : /*
4864 : : CodeRangeCheck - returns a Tree representing the code for a
4865 : : range test defined by, r.
4866 : : */
4867 : :
4868 : 823829 : extern "C" void M2Range_CodeRangeCheck (unsigned int r, DynamicStrings_String function)
4869 : : {
4870 : 823829 : M2Range_Range p;
4871 : 823829 : DynamicStrings_String message;
4872 : :
4873 : 823829 : p = static_cast<M2Range_Range> (Indexing_GetIndice (RangeIndex, r));
4874 : 823829 : message = GetRangeErrorMessage (r);
4875 : 823829 : switch (p->type)
4876 : : {
4877 : 166437 : case M2Range_assignment:
4878 : 166437 : CodeAssignment (p->tokenNo, r, function, message);
4879 : 166437 : break;
4880 : :
4881 : 16522 : case M2Range_returnassignment:
4882 : 16522 : CodeReturn (p->tokenNo, r, function, message);
4883 : 16522 : break;
4884 : :
4885 : 0 : case M2Range_subrangeassignment:
4886 : 0 : M2Error_InternalError ((const char *) "unexpected case", 15);
4887 : 792 : break;
4888 : :
4889 : 792 : case M2Range_inc:
4890 : 792 : CodeInc (p->tokenNo, r, function, message);
4891 : 792 : break;
4892 : :
4893 : 684 : case M2Range_dec:
4894 : 684 : CodeDec (p->tokenNo, r, function, message);
4895 : 684 : break;
4896 : :
4897 : 1856 : case M2Range_incl:
4898 : 1856 : case M2Range_excl:
4899 : 1856 : CodeInclExcl (p->tokenNo, r, function, message);
4900 : 1856 : break;
4901 : :
4902 : 418 : case M2Range_shift:
4903 : 418 : case M2Range_rotate:
4904 : 418 : CodeShiftRotate (p->tokenNo, r, function, message);
4905 : 418 : break;
4906 : :
4907 : 491742 : case M2Range_typeassign:
4908 : 491742 : case M2Range_typeparam:
4909 : 491742 : case M2Range_typeexpr:
4910 : 491742 : case M2Range_typeindrx:
4911 : 491742 : case M2Range_typereturn:
4912 : 491742 : CodeTypeCheck (p->tokenNo, r);
4913 : 491742 : break;
4914 : :
4915 : 11010 : case M2Range_staticarraysubscript:
4916 : 11010 : CodeStaticArraySubscript (p->tokenNo, r, function, message);
4917 : 11010 : break;
4918 : :
4919 : 8706 : case M2Range_dynamicarraysubscript:
4920 : 8706 : CodeDynamicArraySubscript (p->tokenNo, r, function, message);
4921 : 8706 : break;
4922 : :
4923 : 140 : case M2Range_forloopbegin:
4924 : 140 : CodeForLoopBegin (p->tokenNo, r, function, message);
4925 : 140 : break;
4926 : :
4927 : 0 : case M2Range_forloopto:
4928 : 0 : CodeForLoopTo (p->tokenNo, r, function, message);
4929 : 0 : break;
4930 : :
4931 : 2568 : case M2Range_forloopend:
4932 : 2568 : CodeForLoopEnd (p->tokenNo, r, function, message);
4933 : 2568 : break;
4934 : :
4935 : 23026 : case M2Range_pointernil:
4936 : 23026 : CodeNil (r, function, message);
4937 : 23026 : break;
4938 : :
4939 : 0 : case M2Range_noreturn:
4940 : 0 : m2type_AddStatement (M2LexBuf_TokenToLocation (p->tokenNo), M2Range_CodeErrorCheck (r, function, message));
4941 : 0 : break;
4942 : :
4943 : 0 : case M2Range_noelse:
4944 : 0 : m2type_AddStatement (M2LexBuf_TokenToLocation (p->tokenNo), M2Range_CodeErrorCheck (r, function, message));
4945 : 0 : break;
4946 : :
4947 : 0 : case M2Range_casebounds:
4948 : 0 : CodeCaseBounds (p->tokenNo, p->caseList);
4949 : 0 : break;
4950 : :
4951 : 0 : case M2Range_wholenonposdiv:
4952 : 0 : CodeWholeNonPos (p->tokenNo, r, function, message);
4953 : 0 : break;
4954 : :
4955 : 0 : case M2Range_wholenonposmod:
4956 : 0 : CodeWholeNonPos (p->tokenNo, r, function, message);
4957 : 0 : break;
4958 : :
4959 : 8464 : case M2Range_wholezerodiv:
4960 : 8464 : CodeWholeZero (p->tokenNo, r, function, message);
4961 : 8464 : break;
4962 : :
4963 : 96 : case M2Range_wholezerorem:
4964 : 96 : CodeWholeZero (p->tokenNo, r, function, message);
4965 : 96 : break;
4966 : :
4967 : 91368 : case M2Range_paramassign:
4968 : 91368 : CodeParameterAssign (p->tokenNo, r, function, message);
4969 : 91368 : break;
4970 : :
4971 : : case M2Range_none:
4972 : : break;
4973 : :
4974 : :
4975 : 0 : default:
4976 : 0 : M2Error_InternalError ((const char *) "unexpected case", 15);
4977 : 823823 : break;
4978 : : }
4979 : 823823 : }
4980 : :
4981 : :
4982 : : /*
4983 : : FoldRangeCheck - attempts to resolve the range check.
4984 : : If it evaluates to true then
4985 : : it is replaced by an ErrorOp
4986 : : elsif it evaluates to false then
4987 : : it is removed
4988 : : else
4989 : : it is left alone
4990 : : */
4991 : :
4992 : 14312305 : extern "C" void M2Range_FoldRangeCheck (unsigned int tokenno, unsigned int quad, unsigned int range)
4993 : : {
4994 : 14312305 : if (IsCancelled (range))
4995 : : {
4996 : 126 : M2Quads_SubQuad (quad);
4997 : : }
4998 : : else
4999 : : {
5000 : 14312179 : FoldRangeCheckLower (tokenno, quad, range);
5001 : : }
5002 : 14312143 : }
5003 : :
5004 : :
5005 : : /*
5006 : : CodeErrorCheck - returns a Tree calling the approprate exception handler.
5007 : : */
5008 : :
5009 : 115303 : extern "C" tree M2Range_CodeErrorCheck (unsigned int r, DynamicStrings_String function, DynamicStrings_String message)
5010 : : {
5011 : 115303 : DynamicStrings_String filename;
5012 : 115303 : unsigned int line;
5013 : 115303 : unsigned int column;
5014 : 115303 : M2Range_Range p;
5015 : 115303 : tree f;
5016 : 115303 : location_t location;
5017 : :
5018 : 115303 : if (HandlerExists (r))
5019 : : {
5020 : 12695 : if (message == NULL)
5021 : : {
5022 : 116 : message = GetRangeErrorMessage (r);
5023 : : }
5024 : 12695 : message = FillInParameters (r, message);
5025 : 12695 : p = static_cast<M2Range_Range> (Indexing_GetIndice (RangeIndex, r));
5026 : 12695 : filename = M2LexBuf_FindFileNameFromToken (p->tokenNo, 0);
5027 : 12695 : line = M2LexBuf_TokenToLineNo (p->tokenNo, 0);
5028 : 12695 : column = M2LexBuf_TokenToColumnNo (p->tokenNo, 0);
5029 : 12695 : location = M2LexBuf_TokenToLocation (p->tokenNo);
5030 : 12695 : f = SymbolConversion_Mod2Gcc (lookupExceptionHandler (p->type));
5031 : 12695 : BuildStringParam (p->tokenNo, message);
5032 : 12695 : BuildStringParam (p->tokenNo, function);
5033 : 12695 : m2statement_BuildParam (location, m2decl_BuildIntegerConstant (static_cast<int> (column)));
5034 : 12695 : m2statement_BuildParam (location, m2decl_BuildIntegerConstant (static_cast<int> (line)));
5035 : 12695 : BuildStringParam (p->tokenNo, filename);
5036 : 12695 : return m2statement_BuildProcedureCallTree (location, f, NULL);
5037 : : }
5038 : : else
5039 : : {
5040 : : return NULL;
5041 : : }
5042 : : /* static analysis guarentees a RETURN statement will be used before here. */
5043 : : __builtin_unreachable ();
5044 : : }
5045 : :
5046 : :
5047 : : /*
5048 : : WriteRangeCheck - displays debugging information about range, r.
5049 : : */
5050 : :
5051 : 0 : extern "C" void M2Range_WriteRangeCheck (unsigned int r)
5052 : : {
5053 : 0 : M2Range_Range p;
5054 : :
5055 : 0 : p = static_cast<M2Range_Range> (Indexing_GetIndice (RangeIndex, r));
5056 : 0 : StrIO_WriteString ((const char *) "range ", 6);
5057 : 0 : NumberIO_WriteCard (r, 0);
5058 : 0 : StrIO_WriteString ((const char *) " ", 1);
5059 : 0 : if (p->cancelled)
5060 : : {
5061 : 0 : StrIO_WriteString ((const char *) "cancelled ", 10);
5062 : : }
5063 : 0 : if (p->dependantid != 0)
5064 : : {
5065 : 0 : StrIO_WriteString ((const char *) "dep ", 4);
5066 : 0 : NumberIO_WriteCard (p->dependantid, 0);
5067 : 0 : StrIO_WriteString ((const char *) " ", 1);
5068 : : }
5069 : 0 : switch (p->type)
5070 : : {
5071 : 0 : case M2Range_assignment:
5072 : 0 : StrIO_WriteString ((const char *) "assignment (", 12);
5073 : 0 : M2Quads_WriteOperand (p->des);
5074 : 0 : StrIO_WriteString ((const char *) ", ", 2);
5075 : 0 : M2Quads_WriteOperand (p->expr);
5076 : 0 : break;
5077 : :
5078 : 0 : case M2Range_returnassignment:
5079 : 0 : StrIO_WriteString ((const char *) "returnassignment (", 18);
5080 : 0 : M2Quads_WriteOperand (p->des);
5081 : 0 : StrIO_WriteString ((const char *) ", ", 2);
5082 : 0 : M2Quads_WriteOperand (p->expr);
5083 : 0 : break;
5084 : :
5085 : 0 : case M2Range_subrangeassignment:
5086 : 0 : StrIO_WriteString ((const char *) "subrangeassignment(", 19);
5087 : 0 : M2Quads_WriteOperand (p->des);
5088 : 0 : StrIO_WriteString ((const char *) ", ", 2);
5089 : 0 : M2Quads_WriteOperand (p->expr);
5090 : 0 : break;
5091 : :
5092 : 0 : case M2Range_inc:
5093 : 0 : StrIO_WriteString ((const char *) "inc(", 4);
5094 : 0 : M2Quads_WriteOperand (p->des);
5095 : 0 : StrIO_WriteString ((const char *) ", ", 2);
5096 : 0 : M2Quads_WriteOperand (p->expr);
5097 : 0 : break;
5098 : :
5099 : 0 : case M2Range_dec:
5100 : 0 : StrIO_WriteString ((const char *) "dec(", 4);
5101 : 0 : M2Quads_WriteOperand (p->des);
5102 : 0 : StrIO_WriteString ((const char *) ", ", 2);
5103 : 0 : M2Quads_WriteOperand (p->expr);
5104 : 0 : break;
5105 : :
5106 : 0 : case M2Range_incl:
5107 : 0 : StrIO_WriteString ((const char *) "incl(", 5);
5108 : 0 : M2Quads_WriteOperand (p->des);
5109 : 0 : StrIO_WriteString ((const char *) ", ", 2);
5110 : 0 : M2Quads_WriteOperand (p->expr);
5111 : 0 : break;
5112 : :
5113 : 0 : case M2Range_excl:
5114 : 0 : StrIO_WriteString ((const char *) "excl(", 5);
5115 : 0 : M2Quads_WriteOperand (p->des);
5116 : 0 : StrIO_WriteString ((const char *) ", ", 2);
5117 : 0 : M2Quads_WriteOperand (p->expr);
5118 : 0 : break;
5119 : :
5120 : 0 : case M2Range_shift:
5121 : 0 : StrIO_WriteString ((const char *) "shift(", 6);
5122 : 0 : M2Quads_WriteOperand (p->des);
5123 : 0 : StrIO_WriteString ((const char *) ", ", 2);
5124 : 0 : M2Quads_WriteOperand (p->expr);
5125 : 0 : break;
5126 : :
5127 : 0 : case M2Range_rotate:
5128 : 0 : StrIO_WriteString ((const char *) "rotate(", 7);
5129 : 0 : M2Quads_WriteOperand (p->des);
5130 : 0 : StrIO_WriteString ((const char *) ", ", 2);
5131 : 0 : M2Quads_WriteOperand (p->expr);
5132 : 0 : break;
5133 : :
5134 : 0 : case M2Range_typeexpr:
5135 : 0 : StrIO_WriteString ((const char *) "expr compatible (", 17);
5136 : 0 : M2Quads_WriteOperand (p->des);
5137 : 0 : StrIO_WriteString ((const char *) ", ", 2);
5138 : 0 : M2Quads_WriteOperand (p->expr);
5139 : 0 : break;
5140 : :
5141 : 0 : case M2Range_typeassign:
5142 : 0 : StrIO_WriteString ((const char *) "assignment compatible (", 23);
5143 : 0 : M2Quads_WriteOperand (p->des);
5144 : 0 : StrIO_WriteString ((const char *) ", ", 2);
5145 : 0 : M2Quads_WriteOperand (p->expr);
5146 : 0 : break;
5147 : :
5148 : 0 : case M2Range_typeindrx:
5149 : 0 : StrIO_WriteString ((const char *) "indrx compatible (", 18);
5150 : 0 : M2Quads_WriteOperand (p->des);
5151 : 0 : StrIO_WriteString ((const char *) ", ", 2);
5152 : 0 : M2Quads_WriteOperand (p->expr);
5153 : 0 : break;
5154 : :
5155 : 0 : case M2Range_typereturn:
5156 : 0 : StrIO_WriteString ((const char *) "return compatible (", 19);
5157 : 0 : M2Quads_WriteOperand (p->des);
5158 : 0 : StrIO_WriteString ((const char *) ", ", 2);
5159 : 0 : M2Quads_WriteOperand (p->expr);
5160 : 0 : break;
5161 : :
5162 : 0 : case M2Range_typeparam:
5163 : 0 : StrIO_WriteString ((const char *) "parameter compatible (", 22);
5164 : 0 : M2Quads_WriteOperand (p->des);
5165 : 0 : StrIO_WriteString ((const char *) ", ", 2);
5166 : 0 : M2Quads_WriteOperand (p->expr);
5167 : 0 : break;
5168 : :
5169 : 0 : case M2Range_paramassign:
5170 : 0 : StrIO_WriteString ((const char *) "parameter range (", 17);
5171 : 0 : M2Quads_WriteOperand (p->des);
5172 : 0 : StrIO_WriteString ((const char *) ", ", 2);
5173 : 0 : M2Quads_WriteOperand (p->expr);
5174 : 0 : break;
5175 : :
5176 : 0 : case M2Range_staticarraysubscript:
5177 : 0 : StrIO_WriteString ((const char *) "staticarraysubscript(", 21);
5178 : 0 : M2Quads_WriteOperand (p->des);
5179 : 0 : StrIO_WriteString ((const char *) ", ", 2);
5180 : 0 : M2Quads_WriteOperand (p->expr);
5181 : 0 : break;
5182 : :
5183 : 0 : case M2Range_dynamicarraysubscript:
5184 : 0 : StrIO_WriteString ((const char *) "dynamicarraysubscript(", 22);
5185 : 0 : M2Quads_WriteOperand (p->des);
5186 : 0 : StrIO_WriteString ((const char *) ", ", 2);
5187 : 0 : M2Quads_WriteOperand (p->expr);
5188 : 0 : break;
5189 : :
5190 : 0 : case M2Range_forloopbegin:
5191 : 0 : StrIO_WriteString ((const char *) "forloopbegin(", 13);
5192 : 0 : M2Quads_WriteOperand (p->des);
5193 : 0 : StrIO_WriteString ((const char *) ", ", 2);
5194 : 0 : M2Quads_WriteOperand (p->expr);
5195 : 0 : break;
5196 : :
5197 : 0 : case M2Range_forloopto:
5198 : 0 : StrIO_WriteString ((const char *) "forloopto(", 10);
5199 : 0 : M2Quads_WriteOperand (p->des);
5200 : 0 : StrIO_WriteString ((const char *) ", ", 2);
5201 : 0 : M2Quads_WriteOperand (p->expr);
5202 : 0 : break;
5203 : :
5204 : 0 : case M2Range_forloopend:
5205 : 0 : StrIO_WriteString ((const char *) "forloopend(", 11);
5206 : 0 : M2Quads_WriteOperand (p->des);
5207 : 0 : StrIO_WriteString ((const char *) ", ", 2);
5208 : 0 : M2Quads_WriteOperand (p->expr);
5209 : 0 : break;
5210 : :
5211 : 0 : case M2Range_pointernil:
5212 : 0 : StrIO_WriteString ((const char *) "pointernil(", 11);
5213 : 0 : M2Quads_WriteOperand (p->des);
5214 : 0 : break;
5215 : :
5216 : 0 : case M2Range_noreturn:
5217 : 0 : StrIO_WriteString ((const char *) "noreturn(", 9);
5218 : 0 : break;
5219 : :
5220 : 0 : case M2Range_noelse:
5221 : 0 : StrIO_WriteString ((const char *) "noelse(", 7);
5222 : 0 : break;
5223 : :
5224 : 0 : case M2Range_casebounds:
5225 : 0 : StrIO_WriteString ((const char *) "casebounds(", 11);
5226 : 0 : M2CaseList_WriteCase (p->caseList);
5227 : 0 : break;
5228 : :
5229 : 0 : case M2Range_wholenonposdiv:
5230 : 0 : StrIO_WriteString ((const char *) "wholenonposdiv(", 15);
5231 : 0 : M2Quads_WriteOperand (p->expr);
5232 : 0 : break;
5233 : :
5234 : 0 : case M2Range_wholenonposmod:
5235 : 0 : StrIO_WriteString ((const char *) "wholenonposmod(", 15);
5236 : 0 : M2Quads_WriteOperand (p->expr);
5237 : 0 : break;
5238 : :
5239 : 0 : case M2Range_wholezerodiv:
5240 : 0 : StrIO_WriteString ((const char *) "wholezerodiv(", 13);
5241 : 0 : M2Quads_WriteOperand (p->expr);
5242 : 0 : break;
5243 : :
5244 : 0 : case M2Range_wholezerorem:
5245 : 0 : StrIO_WriteString ((const char *) "wholezerorem(", 13);
5246 : 0 : M2Quads_WriteOperand (p->expr);
5247 : 0 : break;
5248 : :
5249 : 0 : case M2Range_none:
5250 : 0 : StrIO_WriteString ((const char *) "none(", 5);
5251 : 0 : break;
5252 : :
5253 : :
5254 : 0 : default:
5255 : 0 : M2Error_InternalError ((const char *) "unknown case", 12);
5256 : 0 : break;
5257 : : }
5258 : 0 : StdIO_Write (')');
5259 : 0 : }
5260 : :
5261 : :
5262 : : /*
5263 : : OverlapsRange - returns TRUE if a1..a2 overlaps with b1..b2.
5264 : : */
5265 : :
5266 : 211692 : extern "C" bool M2Range_OverlapsRange (tree a1, tree a2, tree b1, tree b2)
5267 : : {
5268 : : /* RETURN( ((a1<=b2) AND (a2>=b1)) ) */
5269 : 211692 : return ((m2expr_CompareTrees (a1, b2)) <= 0) && ((m2expr_CompareTrees (a2, b1)) >= 0);
5270 : : /* static analysis guarentees a RETURN statement will be used before here. */
5271 : : __builtin_unreachable ();
5272 : : }
5273 : :
5274 : :
5275 : : /*
5276 : : IsEqual - returns TRUE if a=b.
5277 : : */
5278 : :
5279 : 392494 : extern "C" bool M2Range_IsEqual (tree a, tree b)
5280 : : {
5281 : 392494 : return (m2expr_CompareTrees (a, b)) == 0;
5282 : : /* static analysis guarentees a RETURN statement will be used before here. */
5283 : : __builtin_unreachable ();
5284 : : }
5285 : :
5286 : :
5287 : : /*
5288 : : IsGreaterOrEqual - returns TRUE if a>=b.
5289 : : */
5290 : :
5291 : 0 : extern "C" bool M2Range_IsGreaterOrEqual (tree a, tree b)
5292 : : {
5293 : 0 : return (m2expr_CompareTrees (a, b)) >= 0;
5294 : : /* static analysis guarentees a RETURN statement will be used before here. */
5295 : : __builtin_unreachable ();
5296 : : }
5297 : :
5298 : :
5299 : : /*
5300 : : IsGreater - returns TRUE if a>b.
5301 : : */
5302 : :
5303 : 287732 : extern "C" bool M2Range_IsGreater (tree a, tree b)
5304 : : {
5305 : 287732 : return (m2expr_CompareTrees (a, b)) > 0;
5306 : : /* static analysis guarentees a RETURN statement will be used before here. */
5307 : : __builtin_unreachable ();
5308 : : }
5309 : :
5310 : :
5311 : : /*
5312 : : BuildIfCallWholeHandlerLoc - return a Tree containing a runtime test whether, condition, is true.
5313 : : */
5314 : :
5315 : 3844 : extern "C" tree M2Range_BuildIfCallWholeHandlerLoc (location_t location, tree condition, const char * scope, const char * message)
5316 : : {
5317 : 3844 : return BuildIfCallHandlerLoc (location, condition, scope, message, M2Base_ExceptionWholeValue);
5318 : : /* static analysis guarentees a RETURN statement will be used before here. */
5319 : : __builtin_unreachable ();
5320 : : }
5321 : :
5322 : :
5323 : : /*
5324 : : BuildIfCallRealHandlerLoc - return a Tree containing a runtime test whether, condition, is true.
5325 : : */
5326 : :
5327 : 24 : extern "C" tree M2Range_BuildIfCallRealHandlerLoc (location_t location, tree condition, const char * scope, const char * message)
5328 : : {
5329 : 24 : return BuildIfCallHandlerLoc (location, condition, scope, message, M2Base_ExceptionRealValue);
5330 : : /* static analysis guarentees a RETURN statement will be used before here. */
5331 : : __builtin_unreachable ();
5332 : : }
5333 : :
5334 : :
5335 : : /*
5336 : : GetMinMax - returns TRUE if we know the max and min of m2type.
5337 : : */
5338 : :
5339 : 1405874 : extern "C" bool M2Range_GetMinMax (unsigned int tokenno, unsigned int type, tree *min, tree *max)
5340 : : {
5341 : 1405874 : unsigned int minC;
5342 : 1405874 : unsigned int maxC;
5343 : 1405874 : location_t location;
5344 : :
5345 : 1405874 : location = M2LexBuf_TokenToLocation (tokenno);
5346 : 1405874 : M2Debug_Assert (SymbolTable_IsAModula2Type (type));
5347 : 1405874 : if (((((((((((((((((SymbolConversion_GccKnowsAbout (type)) && (! (SymbolTable_IsPointer (type)))) && (! (SymbolTable_IsArray (type)))) && (! (SymbolTable_IsRecord (type)))) && (! (SymbolTable_IsRecord (type)))) && (! (SymbolTable_IsUnbounded (type)))) && (! (SymbolTable_IsProcType (type)))) && (! (M2Base_IsRealType (type)))) && (! (M2System_IsRealN (type)))) && (! (M2Base_IsComplexType (type)))) && (! (M2System_IsComplexN (type)))) && (type != M2System_Address)) && (! (SymbolTable_IsSet (type)))) && (type != M2System_Word)) && (type != M2System_Loc)) && (type != M2System_Byte)) && (! (M2System_IsWordN (type))))
5348 : : {
5349 : 858538 : if (SymbolTable_IsSubrange (type))
5350 : : {
5351 : 49414 : SymbolTable_GetSubrange (type, &maxC, &minC);
5352 : 49414 : (*max) = SymbolConversion_Mod2Gcc (maxC);
5353 : 49414 : (*min) = SymbolConversion_Mod2Gcc (minC);
5354 : : }
5355 : 809124 : else if (SymbolTable_IsEnumeration (type))
5356 : : {
5357 : : /* avoid dangling else. */
5358 : 92403 : M2Base_GetBaseTypeMinMax (type, &minC, &maxC);
5359 : 92403 : (*max) = SymbolConversion_Mod2Gcc (maxC);
5360 : 92403 : (*min) = SymbolConversion_Mod2Gcc (minC);
5361 : : }
5362 : : else
5363 : : {
5364 : : /* avoid dangling else. */
5365 : 716721 : (*max) = m2type_GetMaxFrom (location, SymbolConversion_Mod2Gcc (type));
5366 : 716721 : (*min) = m2type_GetMinFrom (location, SymbolConversion_Mod2Gcc (type));
5367 : : }
5368 : 858538 : (*max) = m2convert_BuildConvert (location, SymbolConversion_Mod2Gcc (type), (*max), false);
5369 : 858538 : M2Debug_Assert (! (m2expr_TreeOverflow ((*max))));
5370 : 858538 : (*min) = m2convert_BuildConvert (location, SymbolConversion_Mod2Gcc (type), (*min), false);
5371 : 858538 : M2Debug_Assert (! (m2expr_TreeOverflow ((*min))));
5372 : 858538 : return true;
5373 : : }
5374 : : else
5375 : : {
5376 : 547336 : return false;
5377 : : }
5378 : : /* static analysis guarentees a RETURN statement will be used before here. */
5379 : : __builtin_unreachable ();
5380 : : }
5381 : :
5382 : 15506 : extern "C" void _M2_M2Range_init (__attribute__((unused)) int argc, __attribute__((unused)) char *argv[], __attribute__((unused)) char *envp[])
5383 : : {
5384 : : /* Now is the time to interactively call gdb, for example:
5385 : : (gdb) print BreakWhenRangeCreated (1234)
5386 : : (gdb) cont
5387 : : and you will arrive at gdbhook when this symbol is created. */
5388 : 15506 : Init ();
5389 : 15506 : }
5390 : :
5391 : 0 : extern "C" void _M2_M2Range_fini (__attribute__((unused)) int argc, __attribute__((unused)) char *argv[], __attribute__((unused)) char *envp[])
5392 : : {
5393 : 0 : }
|