Branch data Line data Source code
1 : : /* do not edit automatically generated by mc from M2Check. */
2 : : /* M2Check.mod perform rigerous type checking for fully declared symbols.
3 : :
4 : : Copyright (C) 2020-2024 Free Software Foundation, Inc.
5 : : Contributed by Gaius Mulley <gaius.mulley@southwales.ac.uk>.
6 : :
7 : : This file is part of GNU Modula-2.
8 : :
9 : : GNU Modula-2 is free software; you can redistribute it and/or modify
10 : : it under the terms of the GNU General Public License as published by
11 : : the Free Software Foundation; either version 3, or (at your option)
12 : : any later version.
13 : :
14 : : GNU Modula-2 is distributed in the hope that it will be useful, but
15 : : WITHOUT ANY WARRANTY; without even the implied warranty of
16 : : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 : : General Public License for more details.
18 : :
19 : : You should have received a copy of the GNU General Public License
20 : : along with GNU Modula-2; see the file COPYING3. If not see
21 : : <http://www.gnu.org/licenses/>. */
22 : :
23 : : #include "config.h"
24 : : #include "system.h"
25 : : #include <stdbool.h>
26 : : # if !defined (PROC_D)
27 : : # define PROC_D
28 : : typedef void (*PROC_t) (void);
29 : : typedef struct { PROC_t proc; } PROC;
30 : : # endif
31 : :
32 : : # if !defined (TRUE)
33 : : # define TRUE (1==1)
34 : : # endif
35 : :
36 : : # if !defined (FALSE)
37 : : # define FALSE (1==0)
38 : : # endif
39 : :
40 : : # include "GStorage.h"
41 : : # include "Gmcrts.h"
42 : : #if defined(__cplusplus)
43 : : # undef NULL
44 : : # define NULL 0
45 : : #endif
46 : : #define _M2Check_H
47 : : #define _M2Check_C
48 : :
49 : : # include "GM2System.h"
50 : : # include "GM2Base.h"
51 : : # include "GIndexing.h"
52 : : # include "GM2Error.h"
53 : : # include "GM2MetaError.h"
54 : : # include "GStrLib.h"
55 : : # include "GM2Debug.h"
56 : : # include "GSymbolTable.h"
57 : : # include "GM2GCCDeclare.h"
58 : : # include "GM2ALU.h"
59 : : # include "Gm2expr.h"
60 : : # include "GSymbolConversion.h"
61 : : # include "GDynamicStrings.h"
62 : : # include "GM2LexBuf.h"
63 : : # include "GStorage.h"
64 : : # include "GSYSTEM.h"
65 : : # include "Glibc.h"
66 : :
67 : : # define debugging false
68 : : typedef struct M2Check_typeCheckFunction_p M2Check_typeCheckFunction;
69 : :
70 : : typedef struct M2Check__T1_r M2Check__T1;
71 : :
72 : : typedef M2Check__T1 *M2Check_errorSig;
73 : :
74 : : typedef struct M2Check__T2_r M2Check__T2;
75 : :
76 : : typedef M2Check__T2 *M2Check_pair;
77 : :
78 : : typedef struct M2Check__T3_r M2Check__T3;
79 : :
80 : : typedef M2Check__T3 *M2Check_tInfo;
81 : :
82 : : typedef enum {M2Check_parameter, M2Check_assignment, M2Check_expression} M2Check_checkType;
83 : :
84 : : typedef enum {M2Check_true, M2Check_false, M2Check_unknown, M2Check_visited, M2Check_unused} M2Check_status;
85 : :
86 : : typedef M2Check_status (*M2Check_typeCheckFunction_t) (M2Check_status, M2Check_tInfo, unsigned int, unsigned int);
87 : : struct M2Check_typeCheckFunction_p { M2Check_typeCheckFunction_t proc; };
88 : :
89 : : struct M2Check__T1_r {
90 : : unsigned int token;
91 : : unsigned int left;
92 : : unsigned int right;
93 : : };
94 : :
95 : : struct M2Check__T2_r {
96 : : unsigned int left;
97 : : unsigned int right;
98 : : M2Check_status pairStatus;
99 : : M2Check_pair next;
100 : : };
101 : :
102 : : struct M2Check__T3_r {
103 : : DynamicStrings_String format;
104 : : M2Check_checkType kind;
105 : : unsigned int token;
106 : : unsigned int actual;
107 : : unsigned int formal;
108 : : unsigned int left;
109 : : unsigned int right;
110 : : unsigned int procedure;
111 : : unsigned int nth;
112 : : bool isvar;
113 : : bool strict;
114 : : bool isin;
115 : : M2Error_Error error;
116 : : M2Check_typeCheckFunction checkFunc;
117 : : Indexing_Index visited;
118 : : Indexing_Index resolved;
119 : : Indexing_Index unresolved;
120 : : M2Check_tInfo next;
121 : : };
122 : :
123 : : static M2Check_pair pairFreeList;
124 : : static M2Check_tInfo tinfoFreeList;
125 : : static Indexing_Index errors;
126 : :
127 : : /*
128 : : ParameterTypeCompatible - returns TRUE if the nth procedure parameter formal
129 : : is compatible with actual.
130 : : */
131 : :
132 : : extern "C" bool M2Check_ParameterTypeCompatible (unsigned int token, const char *format_, unsigned int _format_high, unsigned int procedure, unsigned int formal, unsigned int actual, unsigned int nth, bool isvar);
133 : :
134 : : /*
135 : : AssignmentTypeCompatible - returns TRUE if the des and the expr are assignment compatible.
136 : : */
137 : :
138 : : extern "C" bool M2Check_AssignmentTypeCompatible (unsigned int token, const char *format_, unsigned int _format_high, unsigned int des, unsigned int expr);
139 : :
140 : : /*
141 : : ExpressionTypeCompatible - returns TRUE if the expressions, left and right,
142 : : are expression compatible.
143 : : */
144 : :
145 : : extern "C" bool M2Check_ExpressionTypeCompatible (unsigned int token, const char *format_, unsigned int _format_high, unsigned int left, unsigned int right, bool strict, bool isin);
146 : :
147 : : /*
148 : : dumpIndice -
149 : : */
150 : :
151 : : static void dumpIndice (M2Check_pair ptr);
152 : :
153 : : /*
154 : : dumpIndex -
155 : : */
156 : :
157 : : static void dumpIndex (const char *name_, unsigned int _name_high, Indexing_Index index);
158 : :
159 : : /*
160 : : dumptInfo -
161 : : */
162 : :
163 : : static void dumptInfo (M2Check_tInfo t);
164 : :
165 : : /*
166 : : isKnown - returns BOOLEAN:TRUE if result is status:true or status:false.
167 : : */
168 : :
169 : : static bool isKnown (M2Check_status result);
170 : :
171 : : /*
172 : : isFalse - returns BOOLEAN:TRUE if result is status:false
173 : : */
174 : :
175 : : static bool isFalse (M2Check_status result);
176 : :
177 : : /*
178 : : checkTypeEquivalence - returns TRUE if left and right can be skipped and found to be equal.
179 : : */
180 : :
181 : : static M2Check_status checkTypeEquivalence (M2Check_status result, unsigned int left, unsigned int right);
182 : :
183 : : /*
184 : : checkSubrange - check to see if subrange types left and right have the same limits.
185 : : */
186 : :
187 : : static M2Check_status checkSubrange (M2Check_status result, M2Check_tInfo tinfo, unsigned int left, unsigned int right);
188 : :
189 : : /*
190 : : checkUnbounded - check to see if the unbounded is type compatible with right.
191 : : This is only allowed during parameter passing.
192 : : */
193 : :
194 : : static M2Check_status checkUnbounded (M2Check_status result, M2Check_tInfo tinfo, unsigned int unbounded, unsigned int right);
195 : :
196 : : /*
197 : : checkArrayTypeEquivalence - check array and unbounded array type equivalence.
198 : : */
199 : :
200 : : static M2Check_status checkArrayTypeEquivalence (M2Check_status result, M2Check_tInfo tinfo, unsigned int left, unsigned int right);
201 : :
202 : : /*
203 : : checkGenericTypeEquivalence - check left and right for generic equivalence.
204 : : */
205 : :
206 : : static M2Check_status checkGenericTypeEquivalence (M2Check_status result, unsigned int left, unsigned int right);
207 : :
208 : : /*
209 : : firstTime - returns TRUE if the triple (token, left, right) has not been seen before.
210 : : */
211 : :
212 : : static bool firstTime (unsigned int token, unsigned int left, unsigned int right);
213 : :
214 : : /*
215 : : buildError4 - generate a MetaString4 error. This is only used when checking
216 : : parameter compatibility.
217 : : */
218 : :
219 : : static void buildError4 (M2Check_tInfo tinfo, unsigned int left, unsigned int right);
220 : :
221 : : /*
222 : : buildError2 - generate a MetaString2 error. This is called by all three kinds of errors.
223 : : */
224 : :
225 : : static void buildError2 (M2Check_tInfo tinfo, unsigned int left, unsigned int right);
226 : :
227 : : /*
228 : : issueError -
229 : : */
230 : :
231 : : static M2Check_status issueError (bool result, M2Check_tInfo tinfo, unsigned int left, unsigned int right);
232 : :
233 : : /*
234 : : checkBaseEquivalence - the catch all check for types not specifically
235 : : handled by this module.
236 : : */
237 : :
238 : : static M2Check_status checkBaseEquivalence (M2Check_status result, M2Check_tInfo tinfo, unsigned int left, unsigned int right);
239 : :
240 : : /*
241 : : checkPair -
242 : : */
243 : :
244 : : static M2Check_status checkPair (M2Check_status result, M2Check_tInfo tinfo, unsigned int left, unsigned int right);
245 : :
246 : : /*
247 : : useBaseCheck -
248 : : */
249 : :
250 : : static bool useBaseCheck (unsigned int sym);
251 : :
252 : : /*
253 : : checkBaseTypeEquivalence -
254 : : */
255 : :
256 : : static M2Check_status checkBaseTypeEquivalence (M2Check_status result, M2Check_tInfo tinfo, unsigned int left, unsigned int right);
257 : :
258 : : /*
259 : : IsTyped - returns TRUE if sym will have a type.
260 : : */
261 : :
262 : : static bool IsTyped (unsigned int sym);
263 : :
264 : : /*
265 : : isLValue -
266 : : */
267 : :
268 : : static bool isLValue (unsigned int sym);
269 : :
270 : : /*
271 : : checkVarEquivalence - this test must be done early as it checks the symbol mode.
272 : : An LValue is treated as a pointer during assignment and the
273 : : LValue is attached to a variable. This function skips the variable
274 : : and checks the types - after it has considered a possible LValue.
275 : : */
276 : :
277 : : static M2Check_status checkVarEquivalence (M2Check_status result, M2Check_tInfo tinfo, unsigned int left, unsigned int right);
278 : :
279 : : /*
280 : : checkConstMeta - performs a very course grained check against
281 : : obviously incompatible type kinds.
282 : : If left is a const string then it checks right against char.
283 : : */
284 : :
285 : : static M2Check_status checkConstMeta (M2Check_status result, M2Check_tInfo tinfo, unsigned int left, unsigned int right);
286 : :
287 : : /*
288 : : checkConstEquivalence - this check can be done first as it checks symbols which
289 : : may have no type. Ie constant strings. These constants
290 : : will likely have their type set during quadruple folding.
291 : : But we can check the meta type for obvious mismatches
292 : : early on. For example adding a string to an enum or set.
293 : : */
294 : :
295 : : static M2Check_status checkConstEquivalence (M2Check_status result, M2Check_tInfo tinfo, unsigned int left, unsigned int right);
296 : :
297 : : /*
298 : : checkSubrangeTypeEquivalence -
299 : : */
300 : :
301 : : static M2Check_status checkSubrangeTypeEquivalence (M2Check_status result, M2Check_tInfo tinfo, unsigned int left, unsigned int right);
302 : :
303 : : /*
304 : : isZRC -
305 : : */
306 : :
307 : : static bool isZRC (unsigned int zrc, unsigned int sym);
308 : :
309 : : /*
310 : : isSameSizeConst -
311 : :
312 : : */
313 : :
314 : : static bool isSameSizeConst (unsigned int a, unsigned int b);
315 : :
316 : : /*
317 : : isSameSize - should only be called if either a or b are WORD, BYTE, etc.
318 : : */
319 : :
320 : : static bool isSameSize (unsigned int a, unsigned int b);
321 : :
322 : : /*
323 : : checkSystemEquivalence - check whether left and right are system types and whether they have the same size.
324 : : */
325 : :
326 : : static M2Check_status checkSystemEquivalence (M2Check_status result, unsigned int left, unsigned int right);
327 : :
328 : : /*
329 : : checkTypeKindViolation - returns false if one operand left or right is
330 : : a set, record or array.
331 : : */
332 : :
333 : : static M2Check_status checkTypeKindViolation (M2Check_status result, M2Check_tInfo tinfo, unsigned int left, unsigned int right);
334 : :
335 : : /*
336 : : doCheckPair -
337 : : */
338 : :
339 : : static M2Check_status doCheckPair (M2Check_status result, M2Check_tInfo tinfo, unsigned int left, unsigned int right);
340 : :
341 : : /*
342 : : checkProcType -
343 : : */
344 : :
345 : : static M2Check_status checkProcType (M2Check_status result, M2Check_tInfo tinfo, unsigned int left, unsigned int right);
346 : :
347 : : /*
348 : : checkProcedureProcType -
349 : : */
350 : :
351 : : static M2Check_status checkProcedureProcType (M2Check_status result, M2Check_tInfo tinfo, unsigned int left, unsigned int right);
352 : :
353 : : /*
354 : : checkProcedure -
355 : : */
356 : :
357 : : static M2Check_status checkProcedure (M2Check_status result, M2Check_tInfo tinfo, unsigned int left, unsigned int right);
358 : :
359 : : /*
360 : : checkEnumerationEquivalence -
361 : : */
362 : :
363 : : static M2Check_status checkEnumerationEquivalence (M2Check_status result, unsigned int left, unsigned int right);
364 : :
365 : : /*
366 : : checkPointerType - check whether left and right are equal or are of type ADDRESS.
367 : : */
368 : :
369 : : static M2Check_status checkPointerType (M2Check_status result, unsigned int left, unsigned int right);
370 : :
371 : : /*
372 : : checkProcTypeEquivalence - allow proctype to be compared against another
373 : : proctype or procedure. It is legal to be compared
374 : : against an address.
375 : : */
376 : :
377 : : static M2Check_status checkProcTypeEquivalence (M2Check_status result, M2Check_tInfo tinfo, unsigned int left, unsigned int right);
378 : :
379 : : /*
380 : : checkTypeKindEquivalence -
381 : : */
382 : :
383 : : static M2Check_status checkTypeKindEquivalence (M2Check_status result, M2Check_tInfo tinfo, unsigned int left, unsigned int right);
384 : :
385 : : /*
386 : : isSkipEquivalence -
387 : : */
388 : :
389 : : static bool isSkipEquivalence (unsigned int left, unsigned int right);
390 : :
391 : : /*
392 : : checkValueEquivalence - check to see if left and right values are the same.
393 : : */
394 : :
395 : : static M2Check_status checkValueEquivalence (M2Check_status result, unsigned int left, unsigned int right);
396 : :
397 : : /*
398 : : and -
399 : : */
400 : :
401 : : static M2Check_status and_ (M2Check_status left, M2Check_status right);
402 : :
403 : : /*
404 : : checkTypeRangeEquivalence -
405 : : */
406 : :
407 : : static M2Check_status checkTypeRangeEquivalence (M2Check_status result, M2Check_tInfo tinfo, unsigned int left, unsigned int right);
408 : :
409 : : /*
410 : : include - include pair left:right into pairs with status, s.
411 : : */
412 : :
413 : : static void include (Indexing_Index pairs, unsigned int left, unsigned int right, M2Check_status s);
414 : :
415 : : /*
416 : : exclude - exclude pair left:right from pairs.
417 : : */
418 : :
419 : : static void exclude (Indexing_Index pairs, unsigned int left, unsigned int right);
420 : :
421 : : /*
422 : : getStatus -
423 : : */
424 : :
425 : : static M2Check_status getStatus (Indexing_Index pairs, unsigned int left, unsigned int right);
426 : :
427 : : /*
428 : : return -
429 : : */
430 : :
431 : : static M2Check_status return_ (M2Check_status result, M2Check_tInfo tinfo, unsigned int left, unsigned int right);
432 : :
433 : : /*
434 : : checkSkipEquivalence - return true if left right are equivalent.
435 : : */
436 : :
437 : : static M2Check_status checkSkipEquivalence (M2Check_status result, unsigned int left, unsigned int right);
438 : :
439 : : /*
440 : : checkSetEquivalent - compares set types, left and right.
441 : : */
442 : :
443 : : static M2Check_status checkSetEquivalent (M2Check_status result, M2Check_tInfo tinfo, unsigned int left, unsigned int right);
444 : :
445 : : /*
446 : : checkRecordEquivalence - compares record types, left and right.
447 : : */
448 : :
449 : : static M2Check_status checkRecordEquivalence (M2Check_status result, unsigned int left, unsigned int right);
450 : :
451 : : /*
452 : : getType - only returns the type of symbol providing it is not a procedure.
453 : : */
454 : :
455 : : static unsigned int getType (unsigned int sym);
456 : :
457 : : /*
458 : : getSType -
459 : : */
460 : :
461 : : static unsigned int getSType (unsigned int sym);
462 : :
463 : : /*
464 : : determineCompatible - check for compatibility by checking
465 : : equivalence, array, generic and type kind.
466 : : */
467 : :
468 : : static M2Check_status determineCompatible (M2Check_status result, M2Check_tInfo tinfo, unsigned int left, unsigned int right);
469 : :
470 : : /*
471 : : get -
472 : : */
473 : :
474 : : static bool get (Indexing_Index pairs, unsigned int *left, unsigned int *right, M2Check_status s);
475 : :
476 : : /*
477 : : isInternal - return TRUE if sym is a constant lit which was declared
478 : : as internal.
479 : : */
480 : :
481 : : static bool isInternal (unsigned int sym);
482 : :
483 : : /*
484 : : doCheck - keep obtaining an unresolved pair and check for the
485 : : type compatibility. This is the main check routine used by
486 : : parameter, assignment and expression compatibility.
487 : : It tests all unknown pairs and calls the appropriate
488 : : check function
489 : : */
490 : :
491 : : static bool doCheck (M2Check_tInfo tinfo);
492 : :
493 : : /*
494 : : in - returns TRUE if the pair is in the list.
495 : : */
496 : :
497 : : static bool in (Indexing_Index pairs, unsigned int left, unsigned int right);
498 : :
499 : : /*
500 : : newPair -
501 : : */
502 : :
503 : : static M2Check_pair newPair (void);
504 : :
505 : : /*
506 : : disposePair - adds pair, p, to the free list.
507 : : */
508 : :
509 : : static void disposePair (M2Check_pair p);
510 : :
511 : : /*
512 : : deconstructIndex -
513 : : */
514 : :
515 : : static Indexing_Index deconstructIndex (Indexing_Index pairs);
516 : :
517 : : /*
518 : : deconstruct - deallocate the List data structure.
519 : : */
520 : :
521 : : static void deconstruct (M2Check_tInfo tinfo);
522 : :
523 : : /*
524 : : newtInfo -
525 : : */
526 : :
527 : : static M2Check_tInfo newtInfo (void);
528 : :
529 : : /*
530 : : collapseString - if the string, a, is "" then return NIL otherwise create
531 : : and return a dynamic string.
532 : : */
533 : :
534 : : static DynamicStrings_String collapseString (const char *a_, unsigned int _a_high);
535 : :
536 : : /*
537 : : doExpressionTypeCompatible -
538 : : */
539 : :
540 : : static bool doExpressionTypeCompatible (unsigned int token, const char *format_, unsigned int _format_high, unsigned int left, unsigned int right, bool strict);
541 : :
542 : : /*
543 : : init - initialise all global data structures for this module.
544 : : */
545 : :
546 : : static void init (void);
547 : :
548 : :
549 : : /*
550 : : dumpIndice -
551 : : */
552 : :
553 : 0 : static void dumpIndice (M2Check_pair ptr)
554 : : {
555 : 0 : libc_printf ((const char *) " left (%d), right (%d), status ", 31, ptr->left, ptr->right);
556 : 0 : switch (ptr->pairStatus)
557 : : {
558 : 0 : case M2Check_true:
559 : 0 : libc_printf ((const char *) "true", 4);
560 : 0 : break;
561 : :
562 : 0 : case M2Check_false:
563 : 0 : libc_printf ((const char *) "false", 5);
564 : 0 : break;
565 : :
566 : 0 : case M2Check_unknown:
567 : 0 : libc_printf ((const char *) "unknown", 7);
568 : 0 : break;
569 : :
570 : 0 : case M2Check_visited:
571 : 0 : libc_printf ((const char *) "visited", 7);
572 : 0 : break;
573 : :
574 : 0 : case M2Check_unused:
575 : 0 : libc_printf ((const char *) "unused", 6);
576 : 0 : break;
577 : :
578 : :
579 : 0 : default:
580 : 0 : CaseException ("/home/worker/buildworker/tiber-lcov/build/gcc/m2/gm2-compiler/M2Check.def", 20, 1);
581 : 0 : __builtin_unreachable ();
582 : : }
583 : 0 : libc_printf ((const char *) "\\n", 2);
584 : 0 : }
585 : :
586 : :
587 : : /*
588 : : dumpIndex -
589 : : */
590 : :
591 : 0 : static void dumpIndex (const char *name_, unsigned int _name_high, Indexing_Index index)
592 : : {
593 : 0 : char name[_name_high+1];
594 : :
595 : : /* make a local copy of each unbounded array. */
596 : 0 : memcpy (name, name_, _name_high+1);
597 : :
598 : 0 : libc_printf ((const char *) "status: %s\\n", 12, &name);
599 : 0 : Indexing_ForeachIndiceInIndexDo (index, (Indexing_IndexProcedure) {(Indexing_IndexProcedure_t) dumpIndice});
600 : 0 : }
601 : :
602 : :
603 : : /*
604 : : dumptInfo -
605 : : */
606 : :
607 : 0 : static void dumptInfo (M2Check_tInfo t)
608 : : {
609 : 0 : libc_printf ((const char *) "actual (%d), formal (%d), left (%d), right (%d), procedure (%d)\\n", 65, t->actual, t->formal, t->left, t->right, t->procedure);
610 : 0 : dumpIndex ((const char *) "visited", 7, t->visited);
611 : 0 : dumpIndex ((const char *) "resolved", 8, t->resolved);
612 : 0 : dumpIndex ((const char *) "unresolved", 10, t->unresolved);
613 : 0 : }
614 : :
615 : :
616 : : /*
617 : : isKnown - returns BOOLEAN:TRUE if result is status:true or status:false.
618 : : */
619 : :
620 : 21399602 : static bool isKnown (M2Check_status result)
621 : : {
622 : 21399602 : return ((result == M2Check_true) || (result == M2Check_false)) || (result == M2Check_visited);
623 : : /* static analysis guarentees a RETURN statement will be used before here. */
624 : : __builtin_unreachable ();
625 : : }
626 : :
627 : :
628 : : /*
629 : : isFalse - returns BOOLEAN:TRUE if result is status:false
630 : : */
631 : :
632 : 0 : static bool isFalse (M2Check_status result)
633 : : {
634 : 0 : return result == M2Check_false;
635 : : /* static analysis guarentees a RETURN statement will be used before here. */
636 : : __builtin_unreachable ();
637 : : }
638 : :
639 : :
640 : : /*
641 : : checkTypeEquivalence - returns TRUE if left and right can be skipped and found to be equal.
642 : : */
643 : :
644 : 239167 : static M2Check_status checkTypeEquivalence (M2Check_status result, unsigned int left, unsigned int right)
645 : : {
646 : 239167 : unsigned int leftT;
647 : 239167 : unsigned int rightT;
648 : :
649 : : /* firstly check to see if we already have resolved this as false. */
650 : 239167 : if (isFalse (result))
651 : : {
652 : : return result;
653 : : }
654 : : else
655 : : {
656 : : /* check to see if we dont care about left or right. */
657 : 239167 : if ((left == SymbolTable_NulSym) || (right == SymbolTable_NulSym))
658 : : {
659 : : return M2Check_true;
660 : : }
661 : : else
662 : : {
663 : 239167 : leftT = SymbolTable_SkipType (left);
664 : 239167 : rightT = SymbolTable_SkipType (right);
665 : 239167 : if (leftT == rightT)
666 : : {
667 : : return M2Check_true;
668 : : }
669 : 239043 : else if ((SymbolTable_IsType (leftT)) && (SymbolTable_IsType (rightT)))
670 : : {
671 : : /* avoid dangling else. */
672 : : /* the fundamental types are definitely different. */
673 : : return M2Check_false;
674 : : }
675 : : }
676 : : }
677 : : return result;
678 : : /* static analysis guarentees a RETURN statement will be used before here. */
679 : : __builtin_unreachable ();
680 : : }
681 : :
682 : :
683 : : /*
684 : : checkSubrange - check to see if subrange types left and right have the same limits.
685 : : */
686 : :
687 : 48 : static M2Check_status checkSubrange (M2Check_status result, M2Check_tInfo tinfo, unsigned int left, unsigned int right)
688 : : {
689 : 48 : unsigned int lLow;
690 : 48 : unsigned int rLow;
691 : 48 : unsigned int lHigh;
692 : 48 : unsigned int rHigh;
693 : :
694 : : /* firstly check to see if we already have resolved this as false. */
695 : 48 : if (isFalse (result))
696 : : {
697 : : return result;
698 : : }
699 : : else
700 : : {
701 : 48 : M2Debug_Assert (SymbolTable_IsSubrange (left));
702 : 48 : M2Debug_Assert (SymbolTable_IsSubrange (right));
703 : 48 : lLow = M2GCCDeclare_GetTypeMin (left);
704 : 48 : lHigh = M2GCCDeclare_GetTypeMax (left);
705 : 48 : rLow = M2GCCDeclare_GetTypeMin (right);
706 : 48 : rHigh = M2GCCDeclare_GetTypeMax (right);
707 : 48 : M2ALU_PushIntegerTree (SymbolConversion_Mod2Gcc (lLow));
708 : 48 : M2ALU_PushIntegerTree (SymbolConversion_Mod2Gcc (rLow));
709 : 48 : if (! (M2ALU_Equ (tinfo->token)))
710 : : {
711 : : return M2Check_false;
712 : : }
713 : 48 : M2ALU_PushIntegerTree (SymbolConversion_Mod2Gcc (lHigh));
714 : 48 : M2ALU_PushIntegerTree (SymbolConversion_Mod2Gcc (rHigh));
715 : 48 : if (! (M2ALU_Equ (tinfo->token)))
716 : : {
717 : : return M2Check_false;
718 : : }
719 : : }
720 : : return M2Check_true;
721 : : /* static analysis guarentees a RETURN statement will be used before here. */
722 : : __builtin_unreachable ();
723 : : }
724 : :
725 : :
726 : : /*
727 : : checkUnbounded - check to see if the unbounded is type compatible with right.
728 : : This is only allowed during parameter passing.
729 : : */
730 : :
731 : 7911 : static M2Check_status checkUnbounded (M2Check_status result, M2Check_tInfo tinfo, unsigned int unbounded, unsigned int right)
732 : : {
733 : 7911 : unsigned int lLow;
734 : 7911 : unsigned int rLow;
735 : 7911 : unsigned int lHigh;
736 : 7911 : unsigned int rHigh;
737 : :
738 : : /* Firstly check to see if we have resolved this as false. */
739 : 7911 : if (isFalse (result))
740 : : {
741 : : return result;
742 : : }
743 : : else
744 : : {
745 : 7911 : M2Debug_Assert (SymbolTable_IsUnbounded (unbounded));
746 : 7911 : if (tinfo->kind == M2Check_parameter)
747 : : {
748 : : /* --fixme-- we should check the unbounded data type against the type of right. */
749 : : return M2Check_true;
750 : : }
751 : : else
752 : : {
753 : : /* Not allowed to use an unbounded symbol (type) in an expression or assignment. */
754 : : return M2Check_false;
755 : : }
756 : : }
757 : : /* static analysis guarentees a RETURN statement will be used before here. */
758 : : __builtin_unreachable ();
759 : : }
760 : :
761 : :
762 : : /*
763 : : checkArrayTypeEquivalence - check array and unbounded array type equivalence.
764 : : */
765 : :
766 : 238983 : static M2Check_status checkArrayTypeEquivalence (M2Check_status result, M2Check_tInfo tinfo, unsigned int left, unsigned int right)
767 : : {
768 : 238983 : unsigned int lSub;
769 : 238983 : unsigned int rSub;
770 : :
771 : 238983 : if (isFalse (result))
772 : : {
773 : : return result;
774 : : }
775 : 238983 : else if ((SymbolTable_IsArray (left)) && (SymbolTable_IsArray (right)))
776 : : {
777 : : /* avoid dangling else. */
778 : 48 : lSub = SymbolTable_GetArraySubscript (left);
779 : 48 : rSub = SymbolTable_GetArraySubscript (right);
780 : 48 : result = checkPair (result, tinfo, SymbolTable_GetSType (left), SymbolTable_GetSType (right));
781 : 48 : if ((lSub != SymbolTable_NulSym) && (rSub != SymbolTable_NulSym))
782 : : {
783 : 48 : result = checkSubrange (result, tinfo, getSType (lSub), getSType (rSub));
784 : : }
785 : : }
786 : 238935 : else if ((SymbolTable_IsUnbounded (left)) && ((SymbolTable_IsArray (right)) || (SymbolTable_IsUnbounded (right))))
787 : : {
788 : : /* avoid dangling else. */
789 : 36 : if ((M2System_IsGenericSystemType (getSType (left))) || (M2System_IsGenericSystemType (getSType (right))))
790 : : {
791 : 24 : return M2Check_true;
792 : : }
793 : : else
794 : : {
795 : 12 : result = checkUnbounded (result, tinfo, left, right);
796 : : }
797 : : }
798 : 238899 : else if ((SymbolTable_IsUnbounded (right)) && ((SymbolTable_IsArray (left)) || (SymbolTable_IsUnbounded (left))))
799 : : {
800 : : /* avoid dangling else. */
801 : 7911 : if ((M2System_IsGenericSystemType (getSType (right))) || (M2System_IsGenericSystemType (getSType (left))))
802 : : {
803 : 12 : return M2Check_true;
804 : : }
805 : : else
806 : : {
807 : 7899 : result = checkUnbounded (result, tinfo, right, left);
808 : : }
809 : : }
810 : 230988 : else if ((SymbolTable_IsArray (left)) && (SymbolTable_IsConst (right)))
811 : : {
812 : : /* avoid dangling else. */
813 : 0 : result = checkPair (result, tinfo, SymbolTable_GetType (left), SymbolTable_GetType (right));
814 : : }
815 : 230988 : else if ((SymbolTable_IsArray (right)) && (SymbolTable_IsConst (left)))
816 : : {
817 : : /* avoid dangling else. */
818 : 0 : result = checkPair (result, tinfo, SymbolTable_GetType (left), SymbolTable_GetType (right));
819 : : }
820 : : return result;
821 : : /* static analysis guarentees a RETURN statement will be used before here. */
822 : : __builtin_unreachable ();
823 : : }
824 : :
825 : :
826 : : /*
827 : : checkGenericTypeEquivalence - check left and right for generic equivalence.
828 : : */
829 : :
830 : 0 : static M2Check_status checkGenericTypeEquivalence (M2Check_status result, unsigned int left, unsigned int right)
831 : : {
832 : 0 : if (isFalse (result))
833 : : {
834 : : return result;
835 : : }
836 : 0 : else if (left == right)
837 : : {
838 : : /* avoid dangling else. */
839 : : return M2Check_true;
840 : : }
841 : : else
842 : : {
843 : : /* avoid dangling else. */
844 : 0 : return result;
845 : : }
846 : : /* static analysis guarentees a RETURN statement will be used before here. */
847 : : __builtin_unreachable ();
848 : : }
849 : :
850 : :
851 : : /*
852 : : firstTime - returns TRUE if the triple (token, left, right) has not been seen before.
853 : : */
854 : :
855 : 462 : static bool firstTime (unsigned int token, unsigned int left, unsigned int right)
856 : : {
857 : 462 : M2Check_errorSig p;
858 : 462 : unsigned int i;
859 : 462 : unsigned int n;
860 : :
861 : 462 : i = 1;
862 : 462 : n = Indexing_HighIndice (errors);
863 : 1020 : while (i <= n)
864 : : {
865 : 420 : p = static_cast<M2Check_errorSig> (Indexing_GetIndice (errors, i));
866 : 420 : if (((p->token == token) && (p->left == left)) && (p->right == right))
867 : : {
868 : : return false;
869 : : }
870 : 96 : i += 1;
871 : : }
872 : 138 : Storage_ALLOCATE ((void **) &p, sizeof (M2Check__T1));
873 : 138 : p->token = token;
874 : 138 : p->left = left;
875 : 138 : p->right = right;
876 : 138 : Indexing_IncludeIndiceIntoIndex (errors, reinterpret_cast<void *> (p));
877 : 138 : return true;
878 : : /* static analysis guarentees a RETURN statement will be used before here. */
879 : : __builtin_unreachable ();
880 : : }
881 : :
882 : :
883 : : /*
884 : : buildError4 - generate a MetaString4 error. This is only used when checking
885 : : parameter compatibility.
886 : : */
887 : :
888 : 90 : static void buildError4 (M2Check_tInfo tinfo, unsigned int left, unsigned int right)
889 : : {
890 : 90 : DynamicStrings_String s;
891 : :
892 : 90 : if (firstTime (tinfo->token, left, right))
893 : : {
894 : 30 : if (tinfo->error == NULL)
895 : : {
896 : : /* need to create top level error message first. */
897 : 30 : tinfo->error = M2Error_NewError (tinfo->token);
898 : : /* The parameters to MetaString4 in buildError4 must match the order
899 : : of paramters passed to ParameterTypeCompatible. */
900 : 30 : s = M2MetaError_MetaString4 (tinfo->format, tinfo->procedure, tinfo->formal, tinfo->actual, tinfo->nth);
901 : 30 : M2Error_ErrorString (tinfo->error, s);
902 : : }
903 : : /* and also generate a sub error containing detail. */
904 : 30 : if ((left != tinfo->left) || (right != tinfo->right))
905 : : {
906 : 30 : tinfo->error = M2Error_ChainError (tinfo->token, tinfo->error);
907 : 30 : s = M2MetaError_MetaString2 (DynamicStrings_InitString ((const char *) "{%1Ead} and {%2ad} are incompatible as formal and actual procedure parameters", 77), left, right);
908 : 30 : M2Error_ErrorString (tinfo->error, s);
909 : : }
910 : : }
911 : 90 : }
912 : :
913 : :
914 : : /*
915 : : buildError2 - generate a MetaString2 error. This is called by all three kinds of errors.
916 : : */
917 : :
918 : 372 : static void buildError2 (M2Check_tInfo tinfo, unsigned int left, unsigned int right)
919 : : {
920 : 372 : DynamicStrings_String s;
921 : :
922 : 372 : if (firstTime (tinfo->token, left, right))
923 : : {
924 : 108 : if (tinfo->error == NULL)
925 : : {
926 : : /* Need to create top level error message first. */
927 : 108 : tinfo->error = M2Error_NewError (tinfo->token);
928 : 108 : s = M2MetaError_MetaString2 (tinfo->format, tinfo->left, tinfo->right);
929 : 108 : M2Error_ErrorString (tinfo->error, s);
930 : : }
931 : : /* Also generate a sub error containing detail. */
932 : 108 : if ((left != tinfo->left) || (right != tinfo->right))
933 : : {
934 : 108 : tinfo->error = M2Error_ChainError (tinfo->token, tinfo->error);
935 : 108 : switch (tinfo->kind)
936 : : {
937 : 0 : case M2Check_parameter:
938 : 0 : s = M2MetaError_MetaString2 (DynamicStrings_InitString ((const char *) "{%1Ead} and {%2ad} are incompatible as formal and actual procedure parameters", 77), left, right);
939 : 0 : break;
940 : :
941 : 0 : case M2Check_assignment:
942 : 0 : s = M2MetaError_MetaString2 (DynamicStrings_InitString ((const char *) "{%1Ead} and {%2ad} are assignment incompatible", 46), left, right);
943 : 0 : break;
944 : :
945 : 108 : case M2Check_expression:
946 : 108 : s = M2MetaError_MetaString2 (DynamicStrings_InitString ((const char *) "{%1Ead} and {%2ad} are expression incompatible", 46), left, right);
947 : 108 : break;
948 : :
949 : :
950 : 0 : default:
951 : 0 : CaseException ("/home/worker/buildworker/tiber-lcov/build/gcc/m2/gm2-compiler/M2Check.def", 20, 1);
952 : 0 : __builtin_unreachable ();
953 : : }
954 : 108 : M2Error_ErrorString (tinfo->error, s);
955 : : }
956 : : }
957 : 372 : }
958 : :
959 : :
960 : : /*
961 : : issueError -
962 : : */
963 : :
964 : 322401 : static M2Check_status issueError (bool result, M2Check_tInfo tinfo, unsigned int left, unsigned int right)
965 : : {
966 : 322401 : if (result)
967 : : {
968 : : return M2Check_true;
969 : : }
970 : : else
971 : : {
972 : : /* check whether errors are required. */
973 : 4208 : if (tinfo->format != NULL)
974 : : {
975 : 462 : switch (tinfo->kind)
976 : : {
977 : 90 : case M2Check_parameter:
978 : 90 : buildError4 (tinfo, left, right);
979 : 90 : break;
980 : :
981 : 0 : case M2Check_assignment:
982 : 0 : buildError2 (tinfo, left, right);
983 : 0 : break;
984 : :
985 : 372 : case M2Check_expression:
986 : 372 : buildError2 (tinfo, left, right);
987 : 372 : break;
988 : :
989 : :
990 : 0 : default:
991 : 0 : CaseException ("/home/worker/buildworker/tiber-lcov/build/gcc/m2/gm2-compiler/M2Check.def", 20, 1);
992 : 0 : __builtin_unreachable ();
993 : : }
994 : 462 : tinfo->format = static_cast<DynamicStrings_String> (NULL); /* string is used by MetaError now. */
995 : : }
996 : 4208 : return M2Check_false;
997 : : }
998 : : /* static analysis guarentees a RETURN statement will be used before here. */
999 : : __builtin_unreachable ();
1000 : : }
1001 : :
1002 : :
1003 : : /*
1004 : : checkBaseEquivalence - the catch all check for types not specifically
1005 : : handled by this module.
1006 : : */
1007 : :
1008 : 318458 : static M2Check_status checkBaseEquivalence (M2Check_status result, M2Check_tInfo tinfo, unsigned int left, unsigned int right)
1009 : : {
1010 : 318458 : if (isKnown (result))
1011 : : {
1012 : : return result;
1013 : : }
1014 : : else
1015 : : {
1016 : 318458 : switch (tinfo->kind)
1017 : : {
1018 : 110362 : case M2Check_parameter:
1019 : 110362 : if (tinfo->isvar)
1020 : : {
1021 : 24 : return issueError (M2Base_IsExpressionCompatible (left, right), tinfo, left, right);
1022 : : }
1023 : : else
1024 : : {
1025 : 110338 : return issueError (M2Base_IsAssignmentCompatible (left, right), tinfo, left, right);
1026 : : }
1027 : 146720 : break;
1028 : :
1029 : 146720 : case M2Check_assignment:
1030 : 146720 : return issueError (M2Base_IsAssignmentCompatible (left, right), tinfo, left, right);
1031 : 61376 : break;
1032 : :
1033 : 61376 : case M2Check_expression:
1034 : 61376 : if (tinfo->isin)
1035 : : {
1036 : 0 : if ((SymbolTable_IsVar (right)) || (SymbolTable_IsConst (right)))
1037 : : {
1038 : 0 : right = getSType (right);
1039 : : }
1040 : : }
1041 : 61376 : if (tinfo->strict)
1042 : : {
1043 : 47112 : return issueError (M2Base_IsComparisonCompatible (left, right), tinfo, left, right);
1044 : : }
1045 : : else
1046 : : {
1047 : 14264 : return issueError (M2Base_IsExpressionCompatible (left, right), tinfo, left, right);
1048 : : }
1049 : 0 : break;
1050 : :
1051 : :
1052 : 0 : default:
1053 : 0 : M2Error_InternalError ((const char *) "unexpected kind value", 21);
1054 : : break;
1055 : : }
1056 : : }
1057 : : /* should never reach here. */
1058 : : ReturnException ("/home/worker/buildworker/tiber-lcov/build/gcc/m2/gm2-compiler/M2Check.def", 20, 1);
1059 : : __builtin_unreachable ();
1060 : : }
1061 : :
1062 : :
1063 : : /*
1064 : : checkPair -
1065 : : */
1066 : :
1067 : 3037503 : static M2Check_status checkPair (M2Check_status result, M2Check_tInfo tinfo, unsigned int left, unsigned int right)
1068 : : {
1069 : 3037503 : if (isFalse (result))
1070 : : {
1071 : 0 : exclude (tinfo->visited, left, right);
1072 : 0 : return result;
1073 : : }
1074 : : else
1075 : : {
1076 : 3037503 : if (in (tinfo->resolved, left, right))
1077 : : {
1078 : 128 : exclude (tinfo->visited, left, right);
1079 : 128 : return getStatus (tinfo->resolved, left, right);
1080 : : }
1081 : 3037375 : else if (in (tinfo->visited, left, right))
1082 : : {
1083 : : /* avoid dangling else. */
1084 : : return M2Check_visited;
1085 : : }
1086 : : else
1087 : : {
1088 : : /* avoid dangling else. */
1089 : 2991555 : if (debugging)
1090 : : {
1091 : : libc_printf ((const char *) " marked as visited (%d, %d)\\n", 31, left, right);
1092 : : }
1093 : 2991555 : include (tinfo->visited, left, right, M2Check_unknown);
1094 : 2991555 : include (tinfo->unresolved, left, right, M2Check_unknown);
1095 : : }
1096 : 2991555 : return doCheckPair (result, tinfo, left, right);
1097 : : }
1098 : : /* static analysis guarentees a RETURN statement will be used before here. */
1099 : : __builtin_unreachable ();
1100 : : }
1101 : :
1102 : :
1103 : : /*
1104 : : useBaseCheck -
1105 : : */
1106 : :
1107 : 958701 : static bool useBaseCheck (unsigned int sym)
1108 : : {
1109 : 958701 : return (((M2Base_IsBaseType (sym)) || (M2System_IsSystemType (sym))) || (M2Base_IsMathType (sym))) || (M2Base_IsComplexType (sym));
1110 : : /* static analysis guarentees a RETURN statement will be used before here. */
1111 : : __builtin_unreachable ();
1112 : : }
1113 : :
1114 : :
1115 : : /*
1116 : : checkBaseTypeEquivalence -
1117 : : */
1118 : :
1119 : 557625 : static M2Check_status checkBaseTypeEquivalence (M2Check_status result, M2Check_tInfo tinfo, unsigned int left, unsigned int right)
1120 : : {
1121 : 557625 : if (isFalse (result))
1122 : : {
1123 : : return result;
1124 : : }
1125 : 557625 : else if ((useBaseCheck (left)) && (useBaseCheck (right)))
1126 : : {
1127 : : /* avoid dangling else. */
1128 : 318458 : return checkBaseEquivalence (result, tinfo, left, right);
1129 : : }
1130 : : else
1131 : : {
1132 : : /* avoid dangling else. */
1133 : 239167 : return result;
1134 : : }
1135 : : /* static analysis guarentees a RETURN statement will be used before here. */
1136 : : __builtin_unreachable ();
1137 : : }
1138 : :
1139 : :
1140 : : /*
1141 : : IsTyped - returns TRUE if sym will have a type.
1142 : : */
1143 : :
1144 : 9754587 : static bool IsTyped (unsigned int sym)
1145 : : {
1146 : 9754587 : return (((((SymbolTable_IsVar (sym)) || (SymbolTable_IsParameter (sym))) || (SymbolTable_IsConstructor (sym))) || ((SymbolTable_IsConst (sym)) && (SymbolTable_IsConstructor (sym)))) || (SymbolTable_IsParameter (sym))) || ((SymbolTable_IsConst (sym)) && ((SymbolTable_GetType (sym)) != SymbolTable_NulSym));
1147 : : /* static analysis guarentees a RETURN statement will be used before here. */
1148 : : __builtin_unreachable ();
1149 : : }
1150 : :
1151 : :
1152 : : /*
1153 : : isLValue -
1154 : : */
1155 : :
1156 : 3233013 : static bool isLValue (unsigned int sym)
1157 : : {
1158 : 3233013 : return (SymbolTable_IsVar (sym)) && ((SymbolTable_GetMode (sym)) == SymbolTable_LeftValue);
1159 : : /* static analysis guarentees a RETURN statement will be used before here. */
1160 : : __builtin_unreachable ();
1161 : : }
1162 : :
1163 : :
1164 : : /*
1165 : : checkVarEquivalence - this test must be done early as it checks the symbol mode.
1166 : : An LValue is treated as a pointer during assignment and the
1167 : : LValue is attached to a variable. This function skips the variable
1168 : : and checks the types - after it has considered a possible LValue.
1169 : : */
1170 : :
1171 : 3478241 : static M2Check_status checkVarEquivalence (M2Check_status result, M2Check_tInfo tinfo, unsigned int left, unsigned int right)
1172 : : {
1173 : 3478241 : if (isFalse (result))
1174 : : {
1175 : : return result;
1176 : : }
1177 : 3478241 : else if ((IsTyped (left)) || (IsTyped (right)))
1178 : : {
1179 : : /* avoid dangling else. */
1180 : 2954404 : if (tinfo->kind == M2Check_assignment)
1181 : : {
1182 : : /* avoid gcc warning by using compound statement even if not strictly necessary. */
1183 : : /* LValues are only relevant during assignment. */
1184 : 1590483 : if ((isLValue (left)) && (! (isLValue (right))))
1185 : : {
1186 : : /* avoid dangling else. */
1187 : 264150 : if ((SymbolTable_SkipType (getType (right))) == M2System_Address)
1188 : : {
1189 : : return M2Check_true;
1190 : : }
1191 : 50218 : else if (SymbolTable_IsPointer (SymbolTable_SkipType (getType (right))))
1192 : : {
1193 : : /* avoid dangling else. */
1194 : 15100 : right = SymbolTable_GetDType (SymbolTable_SkipType (getType (right)));
1195 : : }
1196 : : }
1197 : 1326333 : else if ((isLValue (right)) && (! (isLValue (left))))
1198 : : {
1199 : : /* avoid dangling else. */
1200 : 18257 : if ((SymbolTable_SkipType (getType (left))) == M2System_Address)
1201 : : {
1202 : : return M2Check_true;
1203 : : }
1204 : 18257 : else if (SymbolTable_IsPointer (SymbolTable_SkipType (getType (left))))
1205 : : {
1206 : : /* avoid dangling else. */
1207 : 300 : left = SymbolTable_GetDType (SymbolTable_SkipType (getType (left)));
1208 : : }
1209 : : }
1210 : : }
1211 : 2740472 : return doCheckPair (result, tinfo, getType (left), getType (right));
1212 : : }
1213 : : else
1214 : : {
1215 : : /* avoid dangling else. */
1216 : : return result;
1217 : : }
1218 : : /* static analysis guarentees a RETURN statement will be used before here. */
1219 : : __builtin_unreachable ();
1220 : : }
1221 : :
1222 : :
1223 : : /*
1224 : : checkConstMeta - performs a very course grained check against
1225 : : obviously incompatible type kinds.
1226 : : If left is a const string then it checks right against char.
1227 : : */
1228 : :
1229 : 1026356 : static M2Check_status checkConstMeta (M2Check_status result, M2Check_tInfo tinfo, unsigned int left, unsigned int right)
1230 : : {
1231 : 1026356 : unsigned int typeRight;
1232 : :
1233 : 1026356 : M2Debug_Assert (SymbolTable_IsConst (left));
1234 : 1026356 : if (isFalse (result))
1235 : : {
1236 : : return result;
1237 : : }
1238 : 1026356 : else if (SymbolTable_IsConstString (left))
1239 : : {
1240 : : /* avoid dangling else. */
1241 : 88843 : if (SymbolTable_IsConstString (right))
1242 : : {
1243 : : return M2Check_true;
1244 : : }
1245 : 86347 : else if (IsTyped (right))
1246 : : {
1247 : : /* avoid dangling else. */
1248 : 53459 : typeRight = SymbolTable_GetDType (right);
1249 : 53459 : if (typeRight == SymbolTable_NulSym)
1250 : : {
1251 : : return result;
1252 : : }
1253 : 53459 : else if ((((SymbolTable_IsSet (typeRight)) || (SymbolTable_IsEnumeration (typeRight))) || (SymbolTable_IsProcedure (typeRight))) || (SymbolTable_IsRecord (typeRight)))
1254 : : {
1255 : : /* avoid dangling else. */
1256 : 36 : return M2Check_false;
1257 : : }
1258 : 53423 : else if (SymbolTable_IsArray (typeRight))
1259 : : {
1260 : : /* avoid dangling else. */
1261 : 5394 : return doCheckPair (result, tinfo, M2Base_Char, SymbolTable_GetType (typeRight));
1262 : : }
1263 : 48029 : else if ((SymbolTable_GetStringLength (tinfo->token, left)) == 1)
1264 : : {
1265 : : /* avoid dangling else. */
1266 : 15141 : return doCheckPair (result, tinfo, M2Base_Char, typeRight);
1267 : : }
1268 : : }
1269 : : }
1270 : : return result;
1271 : : /* static analysis guarentees a RETURN statement will be used before here. */
1272 : : __builtin_unreachable ();
1273 : : }
1274 : :
1275 : :
1276 : : /*
1277 : : checkConstEquivalence - this check can be done first as it checks symbols which
1278 : : may have no type. Ie constant strings. These constants
1279 : : will likely have their type set during quadruple folding.
1280 : : But we can check the meta type for obvious mismatches
1281 : : early on. For example adding a string to an enum or set.
1282 : : */
1283 : :
1284 : 3499836 : static M2Check_status checkConstEquivalence (M2Check_status result, M2Check_tInfo tinfo, unsigned int left, unsigned int right)
1285 : : {
1286 : 3499836 : if (isFalse (result))
1287 : : {
1288 : : return result;
1289 : : }
1290 : 3499836 : else if ((left == SymbolTable_NulSym) || (right == SymbolTable_NulSym))
1291 : : {
1292 : : /* avoid dangling else. */
1293 : : /* No option but to return true. */
1294 : : return M2Check_true;
1295 : : }
1296 : 3499720 : else if (SymbolTable_IsConst (left))
1297 : : {
1298 : : /* avoid dangling else. */
1299 : 769797 : return checkConstMeta (result, tinfo, left, right);
1300 : : }
1301 : 2729923 : else if (SymbolTable_IsConst (right))
1302 : : {
1303 : : /* avoid dangling else. */
1304 : 256559 : return checkConstMeta (result, tinfo, right, left);
1305 : : }
1306 : : return result;
1307 : : /* static analysis guarentees a RETURN statement will be used before here. */
1308 : : __builtin_unreachable ();
1309 : : }
1310 : :
1311 : :
1312 : : /*
1313 : : checkSubrangeTypeEquivalence -
1314 : : */
1315 : :
1316 : 567707 : static M2Check_status checkSubrangeTypeEquivalence (M2Check_status result, M2Check_tInfo tinfo, unsigned int left, unsigned int right)
1317 : : {
1318 : 567707 : if (isFalse (result))
1319 : : {
1320 : : return result;
1321 : : }
1322 : : else
1323 : : {
1324 : 567707 : if (SymbolTable_IsSubrange (left))
1325 : : {
1326 : 8190 : return doCheckPair (result, tinfo, SymbolTable_GetDType (left), right);
1327 : : }
1328 : 559517 : if (SymbolTable_IsSubrange (right))
1329 : : {
1330 : 4390 : return doCheckPair (result, tinfo, left, SymbolTable_GetDType (right));
1331 : : }
1332 : 555127 : if (left == right)
1333 : : {
1334 : : return M2Check_true;
1335 : : }
1336 : : else
1337 : : {
1338 : 555127 : return result;
1339 : : }
1340 : : }
1341 : : /* static analysis guarentees a RETURN statement will be used before here. */
1342 : : __builtin_unreachable ();
1343 : : }
1344 : :
1345 : :
1346 : : /*
1347 : : isZRC -
1348 : : */
1349 : :
1350 : 0 : static bool isZRC (unsigned int zrc, unsigned int sym)
1351 : : {
1352 : 0 : if (SymbolTable_IsConst (sym))
1353 : : {
1354 : 0 : sym = SymbolTable_SkipType (SymbolTable_GetType (sym));
1355 : : }
1356 : 0 : if ((zrc == M2Base_CType) && ((M2System_IsComplexN (sym)) || (M2Base_IsComplexType (sym))))
1357 : : {
1358 : 0 : return true;
1359 : : }
1360 : 0 : return (zrc == sym) || ((zrc == M2Base_ZType) || ((zrc == M2Base_RType) && (! (SymbolTable_IsComposite (sym)))));
1361 : : /* static analysis guarentees a RETURN statement will be used before here. */
1362 : : __builtin_unreachable ();
1363 : : }
1364 : :
1365 : :
1366 : : /*
1367 : : isSameSizeConst -
1368 : :
1369 : : */
1370 : :
1371 : 2318 : static bool isSameSizeConst (unsigned int a, unsigned int b)
1372 : : {
1373 : 2318 : if (SymbolTable_IsConst (a))
1374 : : {
1375 : 0 : a = SymbolTable_SkipType (SymbolTable_GetType (a));
1376 : 0 : return ((isZRC (a, b)) || (a == b)) || ((a != SymbolTable_NulSym) && (isSameSize (a, b)));
1377 : : }
1378 : 2318 : else if (SymbolTable_IsConst (b))
1379 : : {
1380 : : /* avoid dangling else. */
1381 : 0 : b = SymbolTable_SkipType (SymbolTable_GetType (b));
1382 : 0 : return ((isZRC (b, a)) || (a == b)) || ((b != SymbolTable_NulSym) && (isSameSize (a, b)));
1383 : : }
1384 : : return false;
1385 : : /* static analysis guarentees a RETURN statement will be used before here. */
1386 : : __builtin_unreachable ();
1387 : : }
1388 : :
1389 : :
1390 : : /*
1391 : : isSameSize - should only be called if either a or b are WORD, BYTE, etc.
1392 : : */
1393 : :
1394 : 2318 : static bool isSameSize (unsigned int a, unsigned int b)
1395 : : {
1396 : 2318 : return (isSameSizeConst (a, b)) || (M2System_IsSameSize (a, b));
1397 : : /* static analysis guarentees a RETURN statement will be used before here. */
1398 : : __builtin_unreachable ();
1399 : : }
1400 : :
1401 : :
1402 : : /*
1403 : : checkSystemEquivalence - check whether left and right are system types and whether they have the same size.
1404 : : */
1405 : :
1406 : 569613 : static M2Check_status checkSystemEquivalence (M2Check_status result, unsigned int left, unsigned int right)
1407 : : {
1408 : 569613 : if ((isFalse (result)) || (result == M2Check_visited))
1409 : : {
1410 : : return result;
1411 : : }
1412 : : else
1413 : : {
1414 : 569613 : if (((M2System_IsGenericSystemType (left)) || (M2System_IsGenericSystemType (right))) && (isSameSize (left, right)))
1415 : : {
1416 : : return M2Check_true;
1417 : : }
1418 : : }
1419 : : return result;
1420 : : /* static analysis guarentees a RETURN statement will be used before here. */
1421 : : __builtin_unreachable ();
1422 : : }
1423 : :
1424 : :
1425 : : /*
1426 : : checkTypeKindViolation - returns false if one operand left or right is
1427 : : a set, record or array.
1428 : : */
1429 : :
1430 : 96328 : static M2Check_status checkTypeKindViolation (M2Check_status result, M2Check_tInfo tinfo, unsigned int left, unsigned int right)
1431 : : {
1432 : 96328 : if ((isFalse (result)) || (result == M2Check_visited))
1433 : : {
1434 : : return result;
1435 : : }
1436 : : else
1437 : : {
1438 : : /* We have checked IsSet (left) and IsSet (right) etc in doCheckPair. */
1439 : 96328 : if ((((SymbolTable_IsSet (left)) || (SymbolTable_IsSet (right))) || ((SymbolTable_IsRecord (left)) || (SymbolTable_IsRecord (right)))) || ((SymbolTable_IsArray (left)) || (SymbolTable_IsArray (right))))
1440 : : {
1441 : 646 : return M2Check_false;
1442 : : }
1443 : : }
1444 : : return result;
1445 : : /* static analysis guarentees a RETURN statement will be used before here. */
1446 : : __builtin_unreachable ();
1447 : : }
1448 : :
1449 : :
1450 : : /*
1451 : : doCheckPair -
1452 : : */
1453 : :
1454 : 5765142 : static M2Check_status doCheckPair (M2Check_status result, M2Check_tInfo tinfo, unsigned int left, unsigned int right)
1455 : : {
1456 : 5765142 : if ((isFalse (result)) || (result == M2Check_visited))
1457 : : {
1458 : 0 : return return_ (result, tinfo, left, right);
1459 : : }
1460 : 5765142 : else if (left == right)
1461 : : {
1462 : : /* avoid dangling else. */
1463 : 2265306 : return return_ (M2Check_true, tinfo, left, right);
1464 : : }
1465 : : else
1466 : : {
1467 : : /* avoid dangling else. */
1468 : 3499836 : result = checkConstEquivalence (M2Check_unknown, tinfo, left, right);
1469 : 3499836 : if (! (isKnown (result)))
1470 : : {
1471 : 3478241 : result = checkVarEquivalence (M2Check_unknown, tinfo, left, right);
1472 : 3478241 : if (! (isKnown (result)))
1473 : : {
1474 : 569613 : result = checkSystemEquivalence (M2Check_unknown, left, right);
1475 : 569613 : if (! (isKnown (result)))
1476 : : {
1477 : 567707 : result = checkSubrangeTypeEquivalence (M2Check_unknown, tinfo, left, right);
1478 : 567707 : if (! (isKnown (result)))
1479 : : {
1480 : 557625 : result = checkBaseTypeEquivalence (M2Check_unknown, tinfo, left, right);
1481 : 557625 : if (! (isKnown (result)))
1482 : : {
1483 : 239167 : result = checkTypeEquivalence (M2Check_unknown, left, right);
1484 : 239167 : if (! (isKnown (result)))
1485 : : {
1486 : 238983 : result = checkArrayTypeEquivalence (result, tinfo, left, right);
1487 : 238983 : if (! (isKnown (result)))
1488 : : {
1489 : 230988 : result = checkGenericTypeEquivalence (result, left, right);
1490 : 230988 : if (! (isKnown (result)))
1491 : : {
1492 : 230988 : result = checkTypeKindEquivalence (result, tinfo, left, right);
1493 : 230988 : if (! (isKnown (result)))
1494 : : {
1495 : 96328 : result = checkTypeKindViolation (result, tinfo, left, right);
1496 : : }
1497 : : }
1498 : : }
1499 : : }
1500 : : }
1501 : : }
1502 : : }
1503 : : }
1504 : : }
1505 : : }
1506 : 3499836 : return return_ (result, tinfo, left, right);
1507 : : /* static analysis guarentees a RETURN statement will be used before here. */
1508 : : __builtin_unreachable ();
1509 : : }
1510 : :
1511 : :
1512 : : /*
1513 : : checkProcType -
1514 : : */
1515 : :
1516 : 134 : static M2Check_status checkProcType (M2Check_status result, M2Check_tInfo tinfo, unsigned int left, unsigned int right)
1517 : : {
1518 : 134 : unsigned int i;
1519 : 134 : unsigned int n;
1520 : 134 : unsigned int lt;
1521 : 134 : unsigned int rt;
1522 : :
1523 : 134 : M2Debug_Assert (SymbolTable_IsProcType (right));
1524 : 134 : M2Debug_Assert (SymbolTable_IsProcType (left));
1525 : 134 : if (isFalse (result))
1526 : : {
1527 : : return result;
1528 : : }
1529 : : else
1530 : : {
1531 : 134 : lt = SymbolTable_GetDType (left);
1532 : 134 : rt = SymbolTable_GetDType (right);
1533 : 134 : if ((lt == SymbolTable_NulSym) && (rt == SymbolTable_NulSym))
1534 : : {
1535 : : result = M2Check_unknown;
1536 : : }
1537 : 0 : else if (lt == SymbolTable_NulSym)
1538 : : {
1539 : : /* avoid dangling else. */
1540 : 0 : if (tinfo->format != NULL)
1541 : : {
1542 : 0 : M2MetaError_MetaErrorStringT3 (tinfo->token, DynamicStrings_InitString ((const char *) "procedure type {%1a} does not have a {%kRETURN} type whereas procedure type {%2ad} has a {%kRETURN} type {%3ad}", 111), left, right, rt);
1543 : : }
1544 : 0 : return return_ (M2Check_false, tinfo, left, right);
1545 : : }
1546 : 0 : else if (rt == SymbolTable_NulSym)
1547 : : {
1548 : : /* avoid dangling else. */
1549 : 0 : if (tinfo->format != NULL)
1550 : : {
1551 : 0 : M2MetaError_MetaErrorStringT3 (tinfo->token, DynamicStrings_InitString ((const char *) "procedure type {%1a} does not have a {%kRETURN} type whereas procedure type {%2ad} has a {%kRETURN} type {%3ad}", 111), right, left, lt);
1552 : : }
1553 : 0 : return return_ (M2Check_false, tinfo, left, right);
1554 : : }
1555 : : else
1556 : : {
1557 : : /* avoid dangling else. */
1558 : : /* two return type seen so we check them. */
1559 : 0 : result = checkPair (M2Check_unknown, tinfo, lt, rt);
1560 : : }
1561 : 134 : if ((SymbolTable_NoOfParam (left)) != (SymbolTable_NoOfParam (right)))
1562 : : {
1563 : 0 : if (tinfo->format != NULL)
1564 : : {
1565 : 0 : M2MetaError_MetaErrorStringT2 (tinfo->token, DynamicStrings_InitString ((const char *) "procedure type {%1a} has a different number of parameters from procedure type {%2ad}", 84), right, left);
1566 : : }
1567 : 0 : return return_ (M2Check_false, tinfo, left, right);
1568 : : }
1569 : 134 : i = 1;
1570 : 134 : n = SymbolTable_NoOfParam (left);
1571 : 658 : while (i <= n)
1572 : : {
1573 : 390 : if ((SymbolTable_IsVarParam (left, i)) != (SymbolTable_IsVarParam (right, i)))
1574 : : {
1575 : 0 : if (SymbolTable_IsVarParam (left, i))
1576 : : {
1577 : : /* avoid dangling else. */
1578 : 0 : if (tinfo->format != NULL)
1579 : : {
1580 : 0 : M2MetaError_MetaErrorStringT3 (tinfo->token, DynamicStrings_InitString ((const char *) "procedure type {%2a} {%3n} parameter was declared as a {%kVAR} whereas procedure type {%1ad} {%3n} parameter was not", 116), right, left, i);
1581 : : }
1582 : : }
1583 : : else
1584 : : {
1585 : 0 : if (tinfo->format != NULL)
1586 : : {
1587 : 0 : M2MetaError_MetaErrorStringT3 (tinfo->token, DynamicStrings_InitString ((const char *) "procedure type {%1a} {%3n} parameter was declared as a {%kVAR} whereas procedure type {%2ad} {%3n} parameter was not", 116), right, left, i);
1588 : : }
1589 : : }
1590 : 0 : return return_ (M2Check_false, tinfo, left, right);
1591 : : }
1592 : 390 : result = checkPair (result, tinfo, SymbolTable_GetDType (SymbolTable_GetNthParam (left, i)), SymbolTable_GetDType (SymbolTable_GetNthParam (right, i)));
1593 : 390 : i += 1;
1594 : : }
1595 : : }
1596 : 134 : return return_ (result, tinfo, left, right);
1597 : : /* static analysis guarentees a RETURN statement will be used before here. */
1598 : : __builtin_unreachable ();
1599 : : }
1600 : :
1601 : :
1602 : : /*
1603 : : checkProcedureProcType -
1604 : : */
1605 : :
1606 : 0 : static M2Check_status checkProcedureProcType (M2Check_status result, M2Check_tInfo tinfo, unsigned int left, unsigned int right)
1607 : : {
1608 : 0 : unsigned int i;
1609 : 0 : unsigned int n;
1610 : 0 : unsigned int lt;
1611 : 0 : unsigned int rt;
1612 : :
1613 : 0 : M2Debug_Assert (SymbolTable_IsProcedure (right));
1614 : 0 : M2Debug_Assert (SymbolTable_IsProcType (left));
1615 : 0 : if (! (isFalse (result)))
1616 : : {
1617 : 0 : lt = SymbolTable_GetDType (left);
1618 : 0 : rt = SymbolTable_GetDType (right);
1619 : 0 : if ((lt == SymbolTable_NulSym) && (rt == SymbolTable_NulSym))
1620 : : {} /* empty. */
1621 : 0 : else if (lt == SymbolTable_NulSym)
1622 : : {
1623 : : /* avoid dangling else. */
1624 : 0 : if (tinfo->format != NULL)
1625 : : {
1626 : 0 : M2MetaError_MetaErrorStringT3 (tinfo->token, DynamicStrings_InitString ((const char *) "procedure type {%1a} does not have a {%kRETURN} type whereas procedure {%2ad} has a {%kRETURN} type {%3ad}", 106), left, right, rt);
1627 : : }
1628 : 0 : return return_ (M2Check_false, tinfo, left, right);
1629 : : }
1630 : 0 : else if (rt == SymbolTable_NulSym)
1631 : : {
1632 : : /* avoid dangling else. */
1633 : 0 : if (tinfo->format != NULL)
1634 : : {
1635 : 0 : M2MetaError_MetaErrorStringT3 (tinfo->token, DynamicStrings_InitString ((const char *) "procedure {%1a} does not have a {%kRETURN} type whereas procedure type {%2ad} has a {%kRETURN} type {%3ad}", 106), right, left, lt);
1636 : : }
1637 : 0 : return return_ (M2Check_false, tinfo, left, right);
1638 : : }
1639 : : else
1640 : : {
1641 : : /* avoid dangling else. */
1642 : : /* two return type seen so we check them. */
1643 : 0 : result = checkPair (result, tinfo, lt, rt);
1644 : : }
1645 : 0 : if ((SymbolTable_NoOfParam (left)) != (SymbolTable_NoOfParam (right)))
1646 : : {
1647 : 0 : if (tinfo->format != NULL)
1648 : : {
1649 : 0 : M2MetaError_MetaErrorStringT2 (tinfo->token, DynamicStrings_InitString ((const char *) "procedure {%1a} has a different number of parameters from procedure type {%2ad}", 79), right, left);
1650 : : }
1651 : 0 : return return_ (M2Check_false, tinfo, left, right);
1652 : : }
1653 : 0 : i = 1;
1654 : 0 : n = SymbolTable_NoOfParam (left);
1655 : 0 : while (i <= n)
1656 : : {
1657 : 0 : if ((SymbolTable_IsVarParam (left, i)) != (SymbolTable_IsVarParam (right, i)))
1658 : : {
1659 : 0 : if (SymbolTable_IsVarParam (left, i))
1660 : : {
1661 : : /* avoid dangling else. */
1662 : 0 : if (tinfo->format != NULL)
1663 : : {
1664 : 0 : M2MetaError_MetaErrorStringT3 (tinfo->token, DynamicStrings_InitString ((const char *) "procedure type {%2a} {%3n} parameter was declared as a {%kVAR} whereas procedure {%1ad} {%3n} parameter was not", 111), right, left, i);
1665 : : }
1666 : : }
1667 : : else
1668 : : {
1669 : 0 : if (tinfo->format != NULL)
1670 : : {
1671 : 0 : M2MetaError_MetaErrorStringT3 (tinfo->token, DynamicStrings_InitString ((const char *) "procedure {%1a} {%3n} parameter was declared as a {%kVAR} whereas procedure type {%2ad} {%3n} parameter was not", 111), right, left, i);
1672 : : }
1673 : : }
1674 : 0 : return return_ (M2Check_false, tinfo, left, right);
1675 : : }
1676 : 0 : result = checkPair (result, tinfo, SymbolTable_GetDType (SymbolTable_GetNthParam (left, i)), SymbolTable_GetDType (SymbolTable_GetNthParam (right, i)));
1677 : 0 : i += 1;
1678 : : }
1679 : : }
1680 : 0 : return return_ (result, tinfo, left, right);
1681 : : /* static analysis guarentees a RETURN statement will be used before here. */
1682 : : __builtin_unreachable ();
1683 : : }
1684 : :
1685 : :
1686 : : /*
1687 : : checkProcedure -
1688 : : */
1689 : :
1690 : 0 : static M2Check_status checkProcedure (M2Check_status result, M2Check_tInfo tinfo, unsigned int left, unsigned int right)
1691 : : {
1692 : 0 : M2Debug_Assert (SymbolTable_IsProcedure (right));
1693 : 0 : if (isFalse (result))
1694 : : {
1695 : : return result;
1696 : : }
1697 : 0 : else if (SymbolTable_IsVar (left))
1698 : : {
1699 : : /* avoid dangling else. */
1700 : 0 : return checkProcedure (result, tinfo, SymbolTable_GetDType (left), right);
1701 : : }
1702 : 0 : else if (left == M2System_Address)
1703 : : {
1704 : : /* avoid dangling else. */
1705 : : return M2Check_true;
1706 : : }
1707 : 0 : else if (SymbolTable_IsProcType (left))
1708 : : {
1709 : : /* avoid dangling else. */
1710 : 0 : return checkProcedureProcType (result, tinfo, left, right);
1711 : : }
1712 : : else
1713 : : {
1714 : : /* avoid dangling else. */
1715 : : return result;
1716 : : }
1717 : : /* static analysis guarentees a RETURN statement will be used before here. */
1718 : : __builtin_unreachable ();
1719 : : }
1720 : :
1721 : :
1722 : : /*
1723 : : checkEnumerationEquivalence -
1724 : : */
1725 : :
1726 : 0 : static M2Check_status checkEnumerationEquivalence (M2Check_status result, unsigned int left, unsigned int right)
1727 : : {
1728 : 0 : if (isFalse (result))
1729 : : {
1730 : : return result;
1731 : : }
1732 : 0 : else if (left == right)
1733 : : {
1734 : : /* avoid dangling else. */
1735 : : return M2Check_true;
1736 : : }
1737 : : else
1738 : : {
1739 : : /* avoid dangling else. */
1740 : 0 : return M2Check_false;
1741 : : }
1742 : : /* static analysis guarentees a RETURN statement will be used before here. */
1743 : : __builtin_unreachable ();
1744 : : }
1745 : :
1746 : :
1747 : : /*
1748 : : checkPointerType - check whether left and right are equal or are of type ADDRESS.
1749 : : */
1750 : :
1751 : 64138 : static M2Check_status checkPointerType (M2Check_status result, unsigned int left, unsigned int right)
1752 : : {
1753 : 0 : if (isFalse (result))
1754 : : {
1755 : : return result;
1756 : : }
1757 : 64138 : else if (((left == right) || (left == M2System_Address)) || (right == M2System_Address))
1758 : : {
1759 : : /* avoid dangling else. */
1760 : : return M2Check_true;
1761 : : }
1762 : : else
1763 : : {
1764 : : /* avoid dangling else. */
1765 : 0 : return M2Check_false;
1766 : : }
1767 : : /* static analysis guarentees a RETURN statement will be used before here. */
1768 : : __builtin_unreachable ();
1769 : : }
1770 : :
1771 : :
1772 : : /*
1773 : : checkProcTypeEquivalence - allow proctype to be compared against another
1774 : : proctype or procedure. It is legal to be compared
1775 : : against an address.
1776 : : */
1777 : :
1778 : 70342 : static M2Check_status checkProcTypeEquivalence (M2Check_status result, M2Check_tInfo tinfo, unsigned int left, unsigned int right)
1779 : : {
1780 : 70342 : if (isFalse (result))
1781 : : {
1782 : : return result;
1783 : : }
1784 : 70342 : else if ((SymbolTable_IsProcedure (left)) && (SymbolTable_IsProcType (right)))
1785 : : {
1786 : : /* avoid dangling else. */
1787 : 0 : return checkProcedure (result, tinfo, right, left);
1788 : : }
1789 : 70342 : else if ((SymbolTable_IsProcType (left)) && (SymbolTable_IsProcedure (right)))
1790 : : {
1791 : : /* avoid dangling else. */
1792 : 0 : return checkProcedure (result, tinfo, left, right);
1793 : : }
1794 : 70342 : else if ((SymbolTable_IsProcType (left)) && (SymbolTable_IsProcType (right)))
1795 : : {
1796 : : /* avoid dangling else. */
1797 : 134 : return checkProcType (result, tinfo, left, right);
1798 : : }
1799 : 70208 : else if ((left == M2System_Address) || (right == M2System_Address))
1800 : : {
1801 : : /* avoid dangling else. */
1802 : : return M2Check_true;
1803 : : }
1804 : : else
1805 : : {
1806 : : /* avoid dangling else. */
1807 : : return M2Check_false;
1808 : : }
1809 : : /* static analysis guarentees a RETURN statement will be used before here. */
1810 : : __builtin_unreachable ();
1811 : : }
1812 : :
1813 : :
1814 : : /*
1815 : : checkTypeKindEquivalence -
1816 : : */
1817 : :
1818 : 231168 : static M2Check_status checkTypeKindEquivalence (M2Check_status result, M2Check_tInfo tinfo, unsigned int left, unsigned int right)
1819 : : {
1820 : 231168 : if (isFalse (result))
1821 : : {
1822 : : return result;
1823 : : }
1824 : 231168 : else if ((left == SymbolTable_NulSym) || (right == SymbolTable_NulSym))
1825 : : {
1826 : : /* avoid dangling else. */
1827 : : return M2Check_true;
1828 : : }
1829 : : else
1830 : : {
1831 : : /* avoid dangling else. */
1832 : : /* Long cascade of all type kinds. */
1833 : 231168 : if ((SymbolTable_IsSet (left)) && (SymbolTable_IsSet (right)))
1834 : : {
1835 : 180 : return checkSetEquivalent (result, tinfo, left, right);
1836 : : }
1837 : 230988 : else if ((SymbolTable_IsArray (left)) && (SymbolTable_IsArray (right)))
1838 : : {
1839 : : /* avoid dangling else. */
1840 : 0 : return checkArrayTypeEquivalence (result, tinfo, left, right);
1841 : : }
1842 : 230988 : else if ((SymbolTable_IsRecord (left)) && (SymbolTable_IsRecord (right)))
1843 : : {
1844 : : /* avoid dangling else. */
1845 : 231168 : return checkRecordEquivalence (result, left, right);
1846 : : }
1847 : 230988 : else if ((SymbolTable_IsEnumeration (left)) && (SymbolTable_IsEnumeration (right)))
1848 : : {
1849 : : /* avoid dangling else. */
1850 : 0 : return checkEnumerationEquivalence (result, left, right);
1851 : : }
1852 : 230988 : else if ((SymbolTable_IsProcType (left)) || (SymbolTable_IsProcType (right)))
1853 : : {
1854 : : /* avoid dangling else. */
1855 : 70342 : return checkProcTypeEquivalence (result, tinfo, right, left);
1856 : : }
1857 : 160646 : else if ((SymbolTable_IsReallyPointer (left)) && (SymbolTable_IsReallyPointer (right)))
1858 : : {
1859 : : /* avoid dangling else. */
1860 : 64138 : return checkPointerType (result, left, right);
1861 : : }
1862 : : else
1863 : : {
1864 : : /* avoid dangling else. */
1865 : 96508 : return result;
1866 : : }
1867 : : }
1868 : : /* static analysis guarentees a RETURN statement will be used before here. */
1869 : : __builtin_unreachable ();
1870 : : }
1871 : :
1872 : :
1873 : : /*
1874 : : isSkipEquivalence -
1875 : : */
1876 : :
1877 : 360 : static bool isSkipEquivalence (unsigned int left, unsigned int right)
1878 : : {
1879 : 360 : return (SymbolTable_SkipType (left)) == (SymbolTable_SkipType (right));
1880 : : /* static analysis guarentees a RETURN statement will be used before here. */
1881 : : __builtin_unreachable ();
1882 : : }
1883 : :
1884 : :
1885 : : /*
1886 : : checkValueEquivalence - check to see if left and right values are the same.
1887 : : */
1888 : :
1889 : 360 : static M2Check_status checkValueEquivalence (M2Check_status result, unsigned int left, unsigned int right)
1890 : : {
1891 : 360 : if (isKnown (result))
1892 : : {
1893 : : return result;
1894 : : }
1895 : 360 : else if (left == right)
1896 : : {
1897 : : /* avoid dangling else. */
1898 : : return M2Check_true;
1899 : : }
1900 : : else
1901 : : {
1902 : : /* avoid dangling else. */
1903 : 360 : if (m2expr_AreConstantsEqual (SymbolConversion_Mod2Gcc (left), SymbolConversion_Mod2Gcc (right)))
1904 : : {
1905 : : return M2Check_true;
1906 : : }
1907 : : else
1908 : : {
1909 : : return M2Check_false;
1910 : : }
1911 : : }
1912 : : /* static analysis guarentees a RETURN statement will be used before here. */
1913 : : __builtin_unreachable ();
1914 : : }
1915 : :
1916 : :
1917 : : /*
1918 : : and -
1919 : : */
1920 : :
1921 : 180 : static M2Check_status and_ (M2Check_status left, M2Check_status right)
1922 : : {
1923 : 0 : if ((left == M2Check_true) && (right == M2Check_true))
1924 : : {
1925 : : return M2Check_true;
1926 : : }
1927 : : else
1928 : : {
1929 : 174 : return M2Check_false;
1930 : : }
1931 : : /* static analysis guarentees a RETURN statement will be used before here. */
1932 : : __builtin_unreachable ();
1933 : : }
1934 : :
1935 : :
1936 : : /*
1937 : : checkTypeRangeEquivalence -
1938 : : */
1939 : :
1940 : 180 : static M2Check_status checkTypeRangeEquivalence (M2Check_status result, M2Check_tInfo tinfo, unsigned int left, unsigned int right)
1941 : : {
1942 : 180 : M2Check_status result2;
1943 : 180 : M2Check_status result3;
1944 : :
1945 : 180 : result = checkSkipEquivalence (result, left, right);
1946 : 180 : result2 = checkValueEquivalence (result, M2GCCDeclare_GetTypeMin (left), M2GCCDeclare_GetTypeMin (right));
1947 : 180 : result3 = checkValueEquivalence (result, M2GCCDeclare_GetTypeMax (left), M2GCCDeclare_GetTypeMax (right));
1948 : 354 : return return_ (and_ (result2, result3), tinfo, left, right);
1949 : : /* static analysis guarentees a RETURN statement will be used before here. */
1950 : : __builtin_unreachable ();
1951 : : }
1952 : :
1953 : :
1954 : : /*
1955 : : include - include pair left:right into pairs with status, s.
1956 : : */
1957 : :
1958 : 20630595 : static void include (Indexing_Index pairs, unsigned int left, unsigned int right, M2Check_status s)
1959 : : {
1960 : 20630595 : M2Check_pair p;
1961 : :
1962 : 20630595 : p = newPair ();
1963 : 20630595 : p->left = left;
1964 : 20630595 : p->right = right;
1965 : 20630595 : p->pairStatus = s;
1966 : 20630595 : p->next = NULL;
1967 : 20630595 : Indexing_IncludeIndiceIntoIndex (pairs, reinterpret_cast<void *> (p));
1968 : 20630595 : }
1969 : :
1970 : :
1971 : : /*
1972 : : exclude - exclude pair left:right from pairs.
1973 : : */
1974 : :
1975 : 20313771 : static void exclude (Indexing_Index pairs, unsigned int left, unsigned int right)
1976 : : {
1977 : 20313771 : M2Check_pair p;
1978 : 20313771 : unsigned int i;
1979 : 20313771 : unsigned int n;
1980 : :
1981 : 20313771 : i = 1;
1982 : 20313771 : n = Indexing_HighIndice (pairs);
1983 : 60631053 : while (i <= n)
1984 : : {
1985 : 28977866 : p = static_cast<M2Check_pair> (Indexing_GetIndice (pairs, i));
1986 : 28977866 : if (((p != NULL) && (p->left == left)) && (p->right == right))
1987 : : {
1988 : 8974355 : Indexing_PutIndice (pairs, i, NULL);
1989 : 8974355 : disposePair (p);
1990 : 8974355 : return ;
1991 : : }
1992 : 20003511 : i += 1;
1993 : : }
1994 : : }
1995 : :
1996 : :
1997 : : /*
1998 : : getStatus -
1999 : : */
2000 : :
2001 : 128 : static M2Check_status getStatus (Indexing_Index pairs, unsigned int left, unsigned int right)
2002 : : {
2003 : 128 : M2Check_pair p;
2004 : 128 : unsigned int i;
2005 : 128 : unsigned int n;
2006 : :
2007 : 128 : i = 1;
2008 : 128 : n = Indexing_HighIndice (pairs);
2009 : 384 : while (i <= n)
2010 : : {
2011 : 256 : p = static_cast<M2Check_pair> (Indexing_GetIndice (pairs, i));
2012 : 256 : if (((p != NULL) && (p->left == left)) && (p->right == right))
2013 : : {
2014 : 128 : return p->pairStatus;
2015 : : }
2016 : 128 : i += 1;
2017 : : }
2018 : : return M2Check_unknown;
2019 : : /* static analysis guarentees a RETURN statement will be used before here. */
2020 : : __builtin_unreachable ();
2021 : : }
2022 : :
2023 : :
2024 : : /*
2025 : : return -
2026 : : */
2027 : :
2028 : 8802701 : static M2Check_status return_ (M2Check_status result, M2Check_tInfo tinfo, unsigned int left, unsigned int right)
2029 : : {
2030 : 8802701 : if (result != M2Check_unknown)
2031 : : {
2032 : 8661199 : if (isKnown (result))
2033 : : {
2034 : 8661199 : include (tinfo->resolved, left, right, result);
2035 : 8661199 : exclude (tinfo->unresolved, left, right);
2036 : 8661199 : exclude (tinfo->visited, left, right); /* no longer visiting as it is resolved. */
2037 : : }
2038 : : }
2039 : 8661199 : if (result == M2Check_false)
2040 : : {
2041 : 3943 : return issueError (false, tinfo, left, right);
2042 : : }
2043 : : return result;
2044 : : /* static analysis guarentees a RETURN statement will be used before here. */
2045 : : __builtin_unreachable ();
2046 : : }
2047 : :
2048 : :
2049 : : /*
2050 : : checkSkipEquivalence - return true if left right are equivalent.
2051 : : */
2052 : :
2053 : 360 : static M2Check_status checkSkipEquivalence (M2Check_status result, unsigned int left, unsigned int right)
2054 : : {
2055 : 360 : if (isKnown (result))
2056 : : {
2057 : : return result;
2058 : : }
2059 : 360 : else if (isSkipEquivalence (left, right))
2060 : : {
2061 : : /* avoid dangling else. */
2062 : : return M2Check_true;
2063 : : }
2064 : : else
2065 : : {
2066 : : /* avoid dangling else. */
2067 : : return result;
2068 : : }
2069 : : /* static analysis guarentees a RETURN statement will be used before here. */
2070 : : __builtin_unreachable ();
2071 : : }
2072 : :
2073 : :
2074 : : /*
2075 : : checkSetEquivalent - compares set types, left and right.
2076 : : */
2077 : :
2078 : 180 : static M2Check_status checkSetEquivalent (M2Check_status result, M2Check_tInfo tinfo, unsigned int left, unsigned int right)
2079 : : {
2080 : 180 : result = checkSkipEquivalence (result, left, right);
2081 : 180 : result = checkTypeKindEquivalence (result, tinfo, SymbolTable_GetDType (left), SymbolTable_GetDType (right));
2082 : 180 : result = checkTypeRangeEquivalence (result, tinfo, SymbolTable_GetDType (left), SymbolTable_GetDType (right));
2083 : 180 : return return_ (result, tinfo, left, right);
2084 : : /* static analysis guarentees a RETURN statement will be used before here. */
2085 : : __builtin_unreachable ();
2086 : : }
2087 : :
2088 : :
2089 : : /*
2090 : : checkRecordEquivalence - compares record types, left and right.
2091 : : */
2092 : :
2093 : 0 : static M2Check_status checkRecordEquivalence (M2Check_status result, unsigned int left, unsigned int right)
2094 : : {
2095 : 0 : if (isFalse (result))
2096 : : {
2097 : : return result;
2098 : : }
2099 : 0 : else if (left == right)
2100 : : {
2101 : : /* avoid dangling else. */
2102 : : return M2Check_true;
2103 : : }
2104 : : else
2105 : : {
2106 : : /* avoid dangling else. */
2107 : 0 : return M2Check_false;
2108 : : }
2109 : : /* static analysis guarentees a RETURN statement will be used before here. */
2110 : : __builtin_unreachable ();
2111 : : }
2112 : :
2113 : :
2114 : : /*
2115 : : getType - only returns the type of symbol providing it is not a procedure.
2116 : : */
2117 : :
2118 : 5847226 : static unsigned int getType (unsigned int sym)
2119 : : {
2120 : 5847226 : if ((sym != SymbolTable_NulSym) && (SymbolTable_IsProcedure (sym)))
2121 : : {
2122 : 315746 : return M2System_Address;
2123 : : }
2124 : 5531480 : else if (IsTyped (sym))
2125 : : {
2126 : : /* avoid dangling else. */
2127 : 5476532 : return SymbolTable_GetDType (sym);
2128 : : }
2129 : : else
2130 : : {
2131 : : /* avoid dangling else. */
2132 : : return sym;
2133 : : }
2134 : : /* static analysis guarentees a RETURN statement will be used before here. */
2135 : : __builtin_unreachable ();
2136 : : }
2137 : :
2138 : :
2139 : : /*
2140 : : getSType -
2141 : : */
2142 : :
2143 : 2347400 : static unsigned int getSType (unsigned int sym)
2144 : : {
2145 : 2347400 : if (SymbolTable_IsProcedure (sym))
2146 : : {
2147 : 101824 : return M2System_Address;
2148 : : }
2149 : : else
2150 : : {
2151 : 2245576 : return SymbolTable_GetSType (sym);
2152 : : }
2153 : : /* static analysis guarentees a RETURN statement will be used before here. */
2154 : : __builtin_unreachable ();
2155 : : }
2156 : :
2157 : :
2158 : : /*
2159 : : determineCompatible - check for compatibility by checking
2160 : : equivalence, array, generic and type kind.
2161 : : */
2162 : :
2163 : 3037065 : static M2Check_status determineCompatible (M2Check_status result, M2Check_tInfo tinfo, unsigned int left, unsigned int right)
2164 : : {
2165 : 3037065 : result = checkPair (result, tinfo, left, right);
2166 : 3037065 : return return_ (result, tinfo, left, right);
2167 : : /* static analysis guarentees a RETURN statement will be used before here. */
2168 : : __builtin_unreachable ();
2169 : : }
2170 : :
2171 : :
2172 : : /*
2173 : : get -
2174 : : */
2175 : :
2176 : 6030893 : static bool get (Indexing_Index pairs, unsigned int *left, unsigned int *right, M2Check_status s)
2177 : : {
2178 : 6030893 : unsigned int i;
2179 : 6030893 : unsigned int n;
2180 : 6030893 : M2Check_pair p;
2181 : :
2182 : 6030893 : i = 1;
2183 : 6030893 : n = Indexing_HighIndice (pairs);
2184 : 18042160 : while (i <= n)
2185 : : {
2186 : 9021235 : p = static_cast<M2Check_pair> (Indexing_GetIndice (pairs, i));
2187 : 9021235 : if ((p != NULL) && (p->pairStatus == s))
2188 : : {
2189 : 3040861 : (*left) = p->left;
2190 : 3040861 : (*right) = p->right;
2191 : 3040861 : return true;
2192 : : }
2193 : 5980374 : i += 1;
2194 : : }
2195 : : return false;
2196 : : /* static analysis guarentees a RETURN statement will be used before here. */
2197 : : __builtin_unreachable ();
2198 : : }
2199 : :
2200 : :
2201 : : /*
2202 : : isInternal - return TRUE if sym is a constant lit which was declared
2203 : : as internal.
2204 : : */
2205 : :
2206 : 6079830 : static bool isInternal (unsigned int sym)
2207 : : {
2208 : 6079830 : return (SymbolTable_IsConstLit (sym)) && (SymbolTable_IsConstLitInternal (sym));
2209 : : /* static analysis guarentees a RETURN statement will be used before here. */
2210 : : __builtin_unreachable ();
2211 : : }
2212 : :
2213 : :
2214 : : /*
2215 : : doCheck - keep obtaining an unresolved pair and check for the
2216 : : type compatibility. This is the main check routine used by
2217 : : parameter, assignment and expression compatibility.
2218 : : It tests all unknown pairs and calls the appropriate
2219 : : check function
2220 : : */
2221 : :
2222 : 2995041 : static bool doCheck (M2Check_tInfo tinfo)
2223 : : {
2224 : 2995041 : M2Check_status result;
2225 : 2995041 : unsigned int left;
2226 : 2995041 : unsigned int right;
2227 : :
2228 : 2995041 : if (debugging)
2229 : : {
2230 : : dumptInfo (tinfo);
2231 : : }
2232 : 9025934 : while (get (tinfo->unresolved, &left, &right, M2Check_unknown))
2233 : : {
2234 : 3040861 : if (debugging)
2235 : : {
2236 : : libc_printf ((const char *) "doCheck (%d, %d)\\n", 18, left, right);
2237 : : dumptInfo (tinfo);
2238 : : }
2239 : 3040861 : if ((isInternal (left)) || (isInternal (right)))
2240 : : {
2241 : : /* Do not check constants which have been generated internally.
2242 : : Currently these are generated by the default BY constant value
2243 : : in a FOR loop. */
2244 : 3784 : return true;
2245 : : }
2246 : : /*
2247 : : IF in (tinfo^.visited, left, right)
2248 : : THEN
2249 : : IF debugging
2250 : : THEN
2251 : : printf (" already visited (%d, %d)
2252 : : ", left, right)
2253 : : END ;
2254 : : ELSE
2255 : : IF debugging
2256 : : THEN
2257 : : printf (" not visited (%d, %d)
2258 : : ", left, right)
2259 : : END ;
2260 : : */
2261 : 3037065 : result = static_cast<M2Check_status> ((*tinfo->checkFunc.proc) (M2Check_unknown, tinfo, left, right));
2262 : 3037065 : if (isKnown (result))
2263 : : {
2264 : : /* remove this pair from the unresolved list. */
2265 : 2991245 : exclude (tinfo->unresolved, left, right);
2266 : : /* add it to the resolved list. */
2267 : 2991245 : include (tinfo->resolved, left, right, result);
2268 : 2991245 : if (result == M2Check_false)
2269 : : {
2270 : : if (debugging)
2271 : : {
2272 : : libc_printf ((const char *) " known (%d, %d) false\\n", 26, left, right);
2273 : : }
2274 : : return false;
2275 : : }
2276 : : else
2277 : : {
2278 : : if (debugging)
2279 : : {
2280 : : libc_printf ((const char *) " known (%d, %d) true\\n", 25, left, right);
2281 : : }
2282 : : }
2283 : : }
2284 : : }
2285 : : return true;
2286 : : /* static analysis guarentees a RETURN statement will be used before here. */
2287 : : __builtin_unreachable ();
2288 : : }
2289 : :
2290 : :
2291 : : /*
2292 : : in - returns TRUE if the pair is in the list.
2293 : : */
2294 : :
2295 : 6074878 : static bool in (Indexing_Index pairs, unsigned int left, unsigned int right)
2296 : : {
2297 : 6074878 : unsigned int i;
2298 : 6074878 : unsigned int n;
2299 : 6074878 : M2Check_pair p;
2300 : :
2301 : 6074878 : i = 1;
2302 : 6074878 : n = Indexing_HighIndice (pairs);
2303 : 12150450 : while (i <= n)
2304 : : {
2305 : 46642 : p = static_cast<M2Check_pair> (Indexing_GetIndice (pairs, i));
2306 : 46642 : if (((p != NULL) && (p->left == left)) && (p->right == right))
2307 : : {
2308 : : return true;
2309 : : }
2310 : 694 : i += 1;
2311 : : }
2312 : : return false;
2313 : : /* static analysis guarentees a RETURN statement will be used before here. */
2314 : : __builtin_unreachable ();
2315 : : }
2316 : :
2317 : :
2318 : : /*
2319 : : newPair -
2320 : : */
2321 : :
2322 : 20630595 : static M2Check_pair newPair (void)
2323 : : {
2324 : 20630595 : M2Check_pair p;
2325 : :
2326 : 20630595 : if (pairFreeList == NULL)
2327 : : {
2328 : 84837 : Storage_ALLOCATE ((void **) &p, sizeof (M2Check__T2));
2329 : : }
2330 : : else
2331 : : {
2332 : 20545758 : p = pairFreeList;
2333 : 20545758 : pairFreeList = p->next;
2334 : : }
2335 : 20630595 : M2Debug_Assert (p != NULL);
2336 : 20630595 : return p;
2337 : : /* static analysis guarentees a RETURN statement will be used before here. */
2338 : : __builtin_unreachable ();
2339 : : }
2340 : :
2341 : :
2342 : : /*
2343 : : disposePair - adds pair, p, to the free list.
2344 : : */
2345 : :
2346 : 20630583 : static void disposePair (M2Check_pair p)
2347 : : {
2348 : 20630583 : p->next = pairFreeList;
2349 : 8974355 : pairFreeList = p;
2350 : 11656228 : }
2351 : :
2352 : :
2353 : : /*
2354 : : deconstructIndex -
2355 : : */
2356 : :
2357 : 8985087 : static Indexing_Index deconstructIndex (Indexing_Index pairs)
2358 : : {
2359 : 8985087 : M2Check_pair p;
2360 : 8985087 : unsigned int i;
2361 : 8985087 : unsigned int n;
2362 : :
2363 : 8985087 : i = 1;
2364 : 8985087 : n = Indexing_HighIndice (pairs);
2365 : 38600757 : while (i <= n)
2366 : : {
2367 : 20630583 : p = static_cast<M2Check_pair> (Indexing_GetIndice (pairs, i));
2368 : 20630583 : if (p != NULL)
2369 : : {
2370 : 11656228 : disposePair (p);
2371 : : }
2372 : 20630583 : i += 1;
2373 : : }
2374 : 8985087 : return Indexing_KillIndex (pairs);
2375 : : /* static analysis guarentees a RETURN statement will be used before here. */
2376 : : __builtin_unreachable ();
2377 : : }
2378 : :
2379 : :
2380 : : /*
2381 : : deconstruct - deallocate the List data structure.
2382 : : */
2383 : :
2384 : 2995029 : static void deconstruct (M2Check_tInfo tinfo)
2385 : : {
2386 : 2995029 : tinfo->format = DynamicStrings_KillString (tinfo->format);
2387 : 2995029 : tinfo->visited = deconstructIndex (tinfo->visited);
2388 : 2995029 : tinfo->resolved = deconstructIndex (tinfo->resolved);
2389 : 2995029 : tinfo->unresolved = deconstructIndex (tinfo->unresolved);
2390 : 2995029 : }
2391 : :
2392 : :
2393 : : /*
2394 : : newtInfo -
2395 : : */
2396 : :
2397 : 2995041 : static M2Check_tInfo newtInfo (void)
2398 : : {
2399 : 2995041 : M2Check_tInfo tinfo;
2400 : :
2401 : 2995041 : if (tinfoFreeList == NULL)
2402 : : {
2403 : 2995041 : Storage_ALLOCATE ((void **) &tinfo, sizeof (M2Check__T3));
2404 : : }
2405 : : else
2406 : : {
2407 : 0 : tinfo = tinfoFreeList;
2408 : 0 : tinfoFreeList = tinfoFreeList->next;
2409 : : }
2410 : 2995041 : return tinfo;
2411 : : /* static analysis guarentees a RETURN statement will be used before here. */
2412 : : __builtin_unreachable ();
2413 : : }
2414 : :
2415 : :
2416 : : /*
2417 : : collapseString - if the string, a, is "" then return NIL otherwise create
2418 : : and return a dynamic string.
2419 : : */
2420 : :
2421 : 2995041 : static DynamicStrings_String collapseString (const char *a_, unsigned int _a_high)
2422 : : {
2423 : 2995041 : char a[_a_high+1];
2424 : :
2425 : : /* make a local copy of each unbounded array. */
2426 : 2995041 : memcpy (a, a_, _a_high+1);
2427 : :
2428 : 2995041 : if (StrLib_StrEqual ((const char *) a, _a_high, (const char *) "", 0))
2429 : : {
2430 : : return static_cast<DynamicStrings_String> (NULL);
2431 : : }
2432 : : else
2433 : : {
2434 : 1294314 : return DynamicStrings_InitString ((const char *) a, _a_high);
2435 : : }
2436 : : /* static analysis guarentees a RETURN statement will be used before here. */
2437 : : __builtin_unreachable ();
2438 : 2995041 : }
2439 : :
2440 : :
2441 : : /*
2442 : : doExpressionTypeCompatible -
2443 : : */
2444 : :
2445 : 234417 : static bool doExpressionTypeCompatible (unsigned int token, const char *format_, unsigned int _format_high, unsigned int left, unsigned int right, bool strict)
2446 : : {
2447 : 234417 : M2Check_tInfo tinfo;
2448 : 234417 : char format[_format_high+1];
2449 : :
2450 : : /* make a local copy of each unbounded array. */
2451 : 234417 : memcpy (format, format_, _format_high+1);
2452 : :
2453 : 468834 : tinfo = newtInfo ();
2454 : 234417 : tinfo->format = collapseString ((const char *) format, _format_high);
2455 : 234417 : tinfo->token = token;
2456 : 234417 : tinfo->kind = M2Check_expression;
2457 : 234417 : tinfo->actual = SymbolTable_NulSym;
2458 : 234417 : tinfo->formal = SymbolTable_NulSym;
2459 : 234417 : tinfo->procedure = SymbolTable_NulSym;
2460 : 234417 : tinfo->nth = 0;
2461 : 234417 : tinfo->isvar = false;
2462 : 234417 : tinfo->error = static_cast<M2Error_Error> (NULL);
2463 : 234417 : tinfo->left = left;
2464 : 234417 : tinfo->right = right;
2465 : 234417 : tinfo->checkFunc.proc = static_cast<M2Check_typeCheckFunction_t> (determineCompatible);
2466 : 234417 : tinfo->visited = Indexing_InitIndex (1);
2467 : 234417 : tinfo->resolved = Indexing_InitIndex (1);
2468 : 234417 : tinfo->unresolved = Indexing_InitIndex (1);
2469 : 234417 : tinfo->strict = strict;
2470 : 234417 : tinfo->isin = false;
2471 : 234417 : include (tinfo->unresolved, left, right, M2Check_unknown);
2472 : 234417 : if (doCheck (tinfo))
2473 : : {
2474 : 233948 : deconstruct (tinfo);
2475 : 233948 : return true;
2476 : : }
2477 : : else
2478 : : {
2479 : 457 : deconstruct (tinfo);
2480 : 457 : return false;
2481 : : }
2482 : : /* static analysis guarentees a RETURN statement will be used before here. */
2483 : : __builtin_unreachable ();
2484 : 234417 : }
2485 : :
2486 : :
2487 : : /*
2488 : : init - initialise all global data structures for this module.
2489 : : */
2490 : :
2491 : 16817 : static void init (void)
2492 : : {
2493 : 16817 : pairFreeList = NULL;
2494 : 16817 : tinfoFreeList = NULL;
2495 : 16817 : errors = Indexing_InitIndex (1);
2496 : 16817 : }
2497 : :
2498 : :
2499 : : /*
2500 : : ParameterTypeCompatible - returns TRUE if the nth procedure parameter formal
2501 : : is compatible with actual.
2502 : : */
2503 : :
2504 : 1160804 : extern "C" bool M2Check_ParameterTypeCompatible (unsigned int token, const char *format_, unsigned int _format_high, unsigned int procedure, unsigned int formal, unsigned int actual, unsigned int nth, bool isvar)
2505 : : {
2506 : 1160804 : unsigned int formalT;
2507 : 1160804 : unsigned int actualT;
2508 : 1160804 : M2Check_tInfo tinfo;
2509 : 1160804 : char format[_format_high+1];
2510 : :
2511 : : /* make a local copy of each unbounded array. */
2512 : 1160804 : memcpy (format, format_, _format_high+1);
2513 : :
2514 : 2321608 : tinfo = newtInfo ();
2515 : 1160804 : formalT = getSType (formal);
2516 : 1160804 : actualT = getSType (actual);
2517 : 1160804 : tinfo->format = collapseString ((const char *) format, _format_high);
2518 : 1160804 : tinfo->token = token;
2519 : 1160804 : tinfo->kind = M2Check_parameter;
2520 : 1160804 : tinfo->actual = actual;
2521 : 1160804 : tinfo->formal = formal;
2522 : 1160804 : tinfo->procedure = procedure;
2523 : 1160804 : tinfo->nth = nth;
2524 : 1160804 : tinfo->isvar = isvar;
2525 : 1160804 : tinfo->error = static_cast<M2Error_Error> (NULL);
2526 : 1160804 : tinfo->left = formalT;
2527 : 1160804 : tinfo->right = actualT;
2528 : 1160804 : tinfo->checkFunc.proc = static_cast<M2Check_typeCheckFunction_t> (determineCompatible);
2529 : 1160804 : tinfo->visited = Indexing_InitIndex (1);
2530 : 1160804 : tinfo->resolved = Indexing_InitIndex (1);
2531 : 1160804 : tinfo->unresolved = Indexing_InitIndex (1);
2532 : 1160804 : tinfo->strict = false;
2533 : 1160804 : tinfo->isin = false;
2534 : 1160804 : include (tinfo->unresolved, actual, formal, M2Check_unknown);
2535 : 1160804 : if (debugging)
2536 : : {
2537 : : dumptInfo (tinfo);
2538 : : }
2539 : 1160804 : if (doCheck (tinfo))
2540 : : {
2541 : 1160714 : deconstruct (tinfo);
2542 : 1160714 : return true;
2543 : : }
2544 : : else
2545 : : {
2546 : 90 : deconstruct (tinfo);
2547 : 90 : return false;
2548 : : }
2549 : : /* static analysis guarentees a RETURN statement will be used before here. */
2550 : : __builtin_unreachable ();
2551 : 1160804 : }
2552 : :
2553 : :
2554 : : /*
2555 : : AssignmentTypeCompatible - returns TRUE if the des and the expr are assignment compatible.
2556 : : */
2557 : :
2558 : 1599820 : extern "C" bool M2Check_AssignmentTypeCompatible (unsigned int token, const char *format_, unsigned int _format_high, unsigned int des, unsigned int expr)
2559 : : {
2560 : 1599820 : M2Check_tInfo tinfo;
2561 : 1599820 : char format[_format_high+1];
2562 : :
2563 : : /* make a local copy of each unbounded array. */
2564 : 1599820 : memcpy (format, format_, _format_high+1);
2565 : :
2566 : 3199640 : tinfo = newtInfo ();
2567 : 1599820 : tinfo->format = collapseString ((const char *) format, _format_high);
2568 : 1599820 : tinfo->token = token;
2569 : 1599820 : tinfo->kind = M2Check_assignment;
2570 : 1599820 : tinfo->actual = SymbolTable_NulSym;
2571 : 1599820 : tinfo->formal = SymbolTable_NulSym;
2572 : 1599820 : tinfo->procedure = SymbolTable_NulSym;
2573 : 1599820 : tinfo->nth = 0;
2574 : 1599820 : tinfo->isvar = false;
2575 : 1599820 : tinfo->error = static_cast<M2Error_Error> (NULL);
2576 : 1599820 : tinfo->left = des;
2577 : 1599820 : tinfo->right = expr;
2578 : 1599820 : tinfo->checkFunc.proc = static_cast<M2Check_typeCheckFunction_t> (determineCompatible);
2579 : 1599820 : tinfo->visited = Indexing_InitIndex (1);
2580 : 1599820 : tinfo->resolved = Indexing_InitIndex (1);
2581 : 1599820 : tinfo->unresolved = Indexing_InitIndex (1);
2582 : 1599820 : include (tinfo->unresolved, des, expr, M2Check_unknown);
2583 : 1599820 : tinfo->strict = false;
2584 : 1599820 : tinfo->isin = false;
2585 : 1599820 : if (doCheck (tinfo))
2586 : : {
2587 : 1599154 : deconstruct (tinfo);
2588 : 1599154 : return true;
2589 : : }
2590 : : else
2591 : : {
2592 : 666 : deconstruct (tinfo);
2593 : 666 : return false;
2594 : : }
2595 : : /* static analysis guarentees a RETURN statement will be used before here. */
2596 : : __builtin_unreachable ();
2597 : 1599820 : }
2598 : :
2599 : :
2600 : : /*
2601 : : ExpressionTypeCompatible - returns TRUE if the expressions, left and right,
2602 : : are expression compatible.
2603 : : */
2604 : :
2605 : 234417 : extern "C" bool M2Check_ExpressionTypeCompatible (unsigned int token, const char *format_, unsigned int _format_high, unsigned int left, unsigned int right, bool strict, bool isin)
2606 : : {
2607 : 234417 : char format[_format_high+1];
2608 : :
2609 : : /* make a local copy of each unbounded array. */
2610 : 234417 : memcpy (format, format_, _format_high+1);
2611 : :
2612 : 234417 : if ((left != SymbolTable_NulSym) && (right != SymbolTable_NulSym))
2613 : : {
2614 : 234405 : if (isin)
2615 : : {
2616 : 5976 : if ((SymbolTable_IsConst (right)) || (SymbolTable_IsVar (right)))
2617 : : {
2618 : 3994 : right = getSType (right);
2619 : : }
2620 : 5976 : if (SymbolTable_IsSet (right))
2621 : : {
2622 : 5820 : right = getSType (right);
2623 : : }
2624 : : }
2625 : : }
2626 : 234417 : return doExpressionTypeCompatible (token, (const char *) format, _format_high, left, right, strict);
2627 : : /* static analysis guarentees a RETURN statement will be used before here. */
2628 : : __builtin_unreachable ();
2629 : 234417 : }
2630 : :
2631 : 16817 : extern "C" void _M2_M2Check_init (__attribute__((unused)) int argc,__attribute__((unused)) char *argv[],__attribute__((unused)) char *envp[])
2632 : : {
2633 : 16817 : init ();
2634 : 16817 : }
2635 : :
2636 : 0 : extern "C" void _M2_M2Check_fini (__attribute__((unused)) int argc,__attribute__((unused)) char *argv[],__attribute__((unused)) char *envp[])
2637 : : {
2638 : 0 : }
|