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