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