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