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