Branch data Line data Source code
1 : : /* do not edit automatically generated by mc from M2SymInit. */
2 : : /* M2SymInit.mod records initialization state for variables.
3 : :
4 : : Copyright (C) 2001-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 _M2SymInit_H
47 : : #define _M2SymInit_C
48 : :
49 : : # include "GStorage.h"
50 : : # include "GM2Debug.h"
51 : : # include "GM2Printf.h"
52 : : # include "Glibc.h"
53 : : # include "GNameKey.h"
54 : : # include "GM2Base.h"
55 : : # include "GM2Options.h"
56 : : # include "GM2MetaError.h"
57 : : # include "GM2LexBuf.h"
58 : : # include "GDynamicStrings.h"
59 : : # include "GM2Error.h"
60 : : # include "GM2BasicBlock.h"
61 : : # include "GIndexing.h"
62 : : # include "GLists.h"
63 : : # include "GSymbolTable.h"
64 : : # include "GM2Quads.h"
65 : : # include "GM2GCCDeclare.h"
66 : :
67 : : # define Debugging false
68 : : typedef struct M2SymInit_recordDesc_r M2SymInit_recordDesc;
69 : :
70 : : typedef struct M2SymInit__T1_r M2SymInit__T1;
71 : :
72 : : typedef struct M2SymInit__T2_r M2SymInit__T2;
73 : :
74 : : typedef M2SymInit__T2 *M2SymInit_symAlias;
75 : :
76 : : typedef struct M2SymInit__T3_r M2SymInit__T3;
77 : :
78 : : typedef M2SymInit__T3 *M2SymInit_bbEntry;
79 : :
80 : : typedef enum {M2SymInit_scalar, M2SymInit_record} M2SymInit_descType;
81 : :
82 : : typedef M2SymInit__T1 *M2SymInit_InitDesc;
83 : :
84 : : struct M2SymInit_recordDesc_r {
85 : : Indexing_Index fieldDesc;
86 : : };
87 : :
88 : : struct M2SymInit__T2_r {
89 : : unsigned int keySym;
90 : : unsigned int alias;
91 : : M2SymInit_symAlias next;
92 : : };
93 : :
94 : : struct M2SymInit__T3_r {
95 : : unsigned int start;
96 : : unsigned int end;
97 : : bool first;
98 : : bool endCall;
99 : : bool endGoto;
100 : : bool endCond;
101 : : bool topOfLoop;
102 : : unsigned int trashQuad;
103 : : unsigned int indexBB;
104 : : unsigned int nextQuad;
105 : : unsigned int condQuad;
106 : : unsigned int nextBB;
107 : : unsigned int condBB;
108 : : M2SymInit_bbEntry next;
109 : : };
110 : :
111 : : struct M2SymInit__T1_r {
112 : : unsigned int sym;
113 : : unsigned int type;
114 : : bool initialized;
115 : : M2SymInit_descType kind; /* case tag */
116 : : union {
117 : : M2SymInit_recordDesc rec;
118 : : };
119 : : };
120 : :
121 : : static Indexing_Index IndirectArray;
122 : : static Indexing_Index LArray;
123 : : static M2SymInit_symAlias freeList;
124 : : static Indexing_Index bbArray;
125 : : static M2SymInit_bbEntry bbFreeList;
126 : : static Lists_List ignoreList;
127 : : static Lists_List errorList;
128 : :
129 : : /*
130 : : PrintSymInit -
131 : : */
132 : :
133 : : extern "C" M2SymInit_InitDesc M2SymInit_InitSymInit (void);
134 : :
135 : : /*
136 : : PrintSymInit -
137 : : */
138 : :
139 : : extern "C" void M2SymInit_KillSymInit (M2SymInit_InitDesc *desc);
140 : :
141 : : /*
142 : : PrintSymInit -
143 : : */
144 : :
145 : : extern "C" void M2SymInit_ConfigSymInit (M2SymInit_InitDesc desc, unsigned int sym);
146 : :
147 : : /*
148 : : PopulateFields -
149 : : */
150 : :
151 : : extern "C" void M2SymInit_SetInitialized (M2SymInit_InitDesc desc);
152 : :
153 : : /*
154 : : PopulateFields -
155 : : */
156 : :
157 : : extern "C" bool M2SymInit_GetInitialized (M2SymInit_InitDesc desc);
158 : :
159 : : /*
160 : : PopulateFields -
161 : : */
162 : :
163 : : extern "C" M2SymInit_InitDesc M2SymInit_GetFieldDesc (M2SymInit_InitDesc desc, unsigned int field);
164 : :
165 : : /*
166 : : PopulateFields -
167 : : */
168 : :
169 : : extern "C" bool M2SymInit_SetFieldInitialized (M2SymInit_InitDesc desc, Lists_List fieldlist);
170 : :
171 : : /*
172 : : SetFieldInitializedNo -
173 : : */
174 : :
175 : : extern "C" bool M2SymInit_GetFieldInitialized (M2SymInit_InitDesc desc, Lists_List fieldlist);
176 : :
177 : : /*
178 : : ScopeBlockVariableAnalysis - checks to see whether a variable is
179 : : read before it has been initialized.
180 : : */
181 : :
182 : : extern "C" void M2SymInit_ScopeBlockVariableAnalysis (unsigned int Scope, unsigned int Start, unsigned int End);
183 : :
184 : : /*
185 : : PrintSymInit -
186 : : */
187 : :
188 : : extern "C" void M2SymInit_PrintSymInit (M2SymInit_InitDesc desc);
189 : :
190 : : /*
191 : : KillFieldDesc -
192 : : */
193 : :
194 : : static void KillFieldDesc (Indexing_Index *fielddesc);
195 : :
196 : : /*
197 : : PopulateFields -
198 : : */
199 : :
200 : : static void PopulateFields (M2SymInit_InitDesc desc, unsigned int recsym);
201 : :
202 : : /*
203 : : TrySetInitialized -
204 : : */
205 : :
206 : : static void TrySetInitialized (M2SymInit_InitDesc desc);
207 : :
208 : : /*
209 : : SetFieldInitializedNo -
210 : : */
211 : :
212 : : static bool SetFieldInitializedNo (M2SymInit_InitDesc desc, Lists_List fieldlist, unsigned int level);
213 : :
214 : : /*
215 : : SetFieldInitializedNo -
216 : : */
217 : :
218 : : static bool GetFieldInitializedNo (M2SymInit_InitDesc desc, Lists_List fieldlist, unsigned int level);
219 : :
220 : : /*
221 : : IsGlobalVar -
222 : : */
223 : :
224 : : static bool IsGlobalVar (unsigned int sym);
225 : :
226 : : /*
227 : : RecordFieldContainsVarient -
228 : : */
229 : :
230 : : static bool RecordFieldContainsVarient (unsigned int sym, Lists_List visited);
231 : :
232 : : /*
233 : : RecordContainsVarient -
234 : : */
235 : :
236 : : static bool RecordContainsVarient (unsigned int sym, Lists_List visited);
237 : :
238 : : /*
239 : : VarContainsVarient -
240 : : */
241 : :
242 : : static bool VarContainsVarient (unsigned int sym, Lists_List visited);
243 : :
244 : : /*
245 : : TypeContainsVarient -
246 : : */
247 : :
248 : : static bool TypeContainsVarient (unsigned int sym, Lists_List visited);
249 : :
250 : : /*
251 : : ArrayContainsVarient -
252 : : */
253 : :
254 : : static bool ArrayContainsVarient (unsigned int sym, Lists_List visited);
255 : :
256 : : /*
257 : : PointerContainsVarient -
258 : : */
259 : :
260 : : static bool PointerContainsVarient (unsigned int sym, Lists_List visited);
261 : :
262 : : /*
263 : : doContainsVariant -
264 : : */
265 : :
266 : : static bool doContainsVariant (unsigned int sym, Lists_List visited);
267 : :
268 : : /*
269 : : ContainsVariant - returns TRUE if type sym contains a variant record.
270 : : */
271 : :
272 : : static bool ContainsVariant (unsigned int sym);
273 : :
274 : : /*
275 : : IssueConditional -
276 : : */
277 : :
278 : : static void IssueConditional (unsigned int quad, bool conditional);
279 : :
280 : : /*
281 : : GenerateNoteFlow -
282 : : */
283 : :
284 : : static void GenerateNoteFlow (unsigned int n, bool warning);
285 : :
286 : : /*
287 : : IssueWarning - issue a warning or note at tok location.
288 : : */
289 : :
290 : : static void IssueWarning (unsigned int tok, const char *before_, unsigned int _before_high, const char *after_, unsigned int _after_high, unsigned int sym, bool warning);
291 : :
292 : : /*
293 : : IsUniqueWarning - return TRUE if a warning has not been issued at tok.
294 : : It remembers tok and subsequent calls will always return FALSE.
295 : : */
296 : :
297 : : static bool IsUniqueWarning (unsigned int tok);
298 : :
299 : : /*
300 : : CheckDeferredRecordAccess -
301 : : */
302 : :
303 : : static void CheckDeferredRecordAccess (unsigned int tok, unsigned int sym, bool canDereference, bool warning, unsigned int i);
304 : :
305 : : /*
306 : : SetVarUninitialized - resets variable init state.
307 : : */
308 : :
309 : : static void SetVarUninitialized (unsigned int sym);
310 : :
311 : : /*
312 : : ComponentFindVar -
313 : : */
314 : :
315 : : static unsigned int ComponentFindVar (unsigned int sym, bool *lvalue, unsigned int tok);
316 : :
317 : : /*
318 : : ComponentCreateFieldList - builds a list of fields accessed by the component var.
319 : : Each item in the list will be a field of incremental levels
320 : : though a nested record. It is not a list of fields
321 : : at the same level.
322 : :
323 : : foo = RECORD
324 : : v: RECORD
325 : : x, y: CARDINAL ;
326 : : END ;
327 : : w: CARDINAL ;
328 : : END ;
329 : :
330 : : { v, x } for example and not { v, w }
331 : : */
332 : :
333 : : static Lists_List ComponentCreateFieldList (unsigned int sym);
334 : :
335 : : /*
336 : : ComponentCreateFieldList - builds a list of fields accessed by the component var.
337 : : Each item in the list will be a field of incremental levels
338 : : though a nested record. It is not a list of fields
339 : : at the same level.
340 : :
341 : : foo = RECORD
342 : : v: RECORD
343 : : x, y: CARDINAL ;
344 : : END ;
345 : : w: CARDINAL ;
346 : : END ;
347 : :
348 : : { v, x } for example and not { v, w }
349 : : */
350 : :
351 : : static void ComponentBuildFieldList (Lists_List lst, unsigned int sym);
352 : :
353 : : /*
354 : : deRefComponent -
355 : : */
356 : :
357 : : static unsigned int deRefComponent (unsigned int component, bool lvalue, unsigned int sym, unsigned int tok);
358 : :
359 : : /*
360 : : SetVarComponentInitialized -
361 : : */
362 : :
363 : : static void SetVarComponentInitialized (unsigned int sym, unsigned int tok);
364 : :
365 : : /*
366 : : GetVarComponentInitialized -
367 : : */
368 : :
369 : : static bool GetVarComponentInitialized (unsigned int sym, unsigned int tok);
370 : :
371 : : /*
372 : : Trace -
373 : : */
374 : :
375 : : static void Trace (const char *message_, unsigned int _message_high, unsigned int sym);
376 : :
377 : : /*
378 : : SetVarInitialized - if the variable has a left mode and can be dereferenced
379 : : then set the left and right initialization state.
380 : : */
381 : :
382 : : static void SetVarInitialized (unsigned int sym, bool canDereference, unsigned int tok);
383 : :
384 : : /*
385 : : doGetVarInitialized -
386 : : */
387 : :
388 : : static bool doGetVarInitialized (unsigned int sym, unsigned int tok);
389 : :
390 : : /*
391 : : GetVarInitialized -
392 : : */
393 : :
394 : : static bool GetVarInitialized (unsigned int sym, unsigned int tok);
395 : :
396 : : /*
397 : : IsExempt - returns TRUE if sym is a global variable or a parameter or
398 : : a variable with a variant record type.
399 : : */
400 : :
401 : : static bool IsExempt (unsigned int sym);
402 : :
403 : : /*
404 : : CheckBinary -
405 : : */
406 : :
407 : : static void CheckBinary (unsigned int op1tok, unsigned int op1, unsigned int op2tok, unsigned int op2, unsigned int op3tok, unsigned int op3, bool warning, unsigned int i);
408 : :
409 : : /*
410 : : CheckUnary -
411 : : */
412 : :
413 : : static void CheckUnary (unsigned int lhstok, unsigned int lhs, unsigned int rhstok, unsigned int rhs, bool warning, unsigned int i);
414 : :
415 : : /*
416 : : CheckXIndr -
417 : : */
418 : :
419 : : static void CheckXIndr (unsigned int lhstok, unsigned int lhs, unsigned int type, unsigned int rhstok, unsigned int rhs, bool warning, unsigned int i);
420 : :
421 : : /*
422 : : CheckIndrX -
423 : : */
424 : :
425 : : static void CheckIndrX (unsigned int lhstok, unsigned int lhs, unsigned int rhstok, unsigned int rhs, bool warning, unsigned int i);
426 : :
427 : : /*
428 : : CheckRecordField -
429 : : */
430 : :
431 : : static void CheckRecordField (unsigned int op1);
432 : :
433 : : /*
434 : : CheckBecomes -
435 : : */
436 : :
437 : : static void CheckBecomes (unsigned int destok, unsigned int des, unsigned int exprtok, unsigned int expr, bool warning, unsigned int i);
438 : :
439 : : /*
440 : : CheckComparison -
441 : : */
442 : :
443 : : static void CheckComparison (unsigned int op1tok, unsigned int op1, unsigned int op2tok, unsigned int op2, bool warning, unsigned int i);
444 : :
445 : : /*
446 : : CheckAddr -
447 : : */
448 : :
449 : : static void CheckAddr (unsigned int ptrtok, unsigned int ptr, unsigned int contenttok, unsigned int content);
450 : :
451 : : /*
452 : : DefaultTokPos -
453 : : */
454 : :
455 : : static unsigned int DefaultTokPos (unsigned int preferredPos, unsigned int defaultPos);
456 : :
457 : : /*
458 : : stop -
459 : : */
460 : :
461 : : static void stop (void);
462 : :
463 : : /*
464 : : CheckReadBeforeInitQuad -
465 : : */
466 : :
467 : : static bool CheckReadBeforeInitQuad (unsigned int procSym, unsigned int quad, bool warning, unsigned int i);
468 : :
469 : : /*
470 : : FilterCheckReadBeforeInitQuad -
471 : : */
472 : :
473 : : static bool FilterCheckReadBeforeInitQuad (unsigned int procSym, unsigned int start, bool warning, unsigned int i);
474 : :
475 : : /*
476 : : CheckReadBeforeInitFirstBasicBlock -
477 : : */
478 : :
479 : : static void CheckReadBeforeInitFirstBasicBlock (unsigned int procSym, unsigned int start, unsigned int end, bool warning, unsigned int i);
480 : :
481 : : /*
482 : : bbArrayKill -
483 : : */
484 : :
485 : : static void bbArrayKill (void);
486 : :
487 : : /*
488 : : DumpBBEntry -
489 : : */
490 : :
491 : : static void DumpBBEntry (M2SymInit_bbEntry bbPtr, unsigned int procSym);
492 : :
493 : : /*
494 : : DumpBBArray -
495 : : */
496 : :
497 : : static void DumpBBArray (unsigned int procSym);
498 : :
499 : : /*
500 : : DumpBBSequence -
501 : : */
502 : :
503 : : static void DumpBBSequence (Lists_List lst);
504 : :
505 : : /*
506 : : trashParam -
507 : : */
508 : :
509 : : static void trashParam (unsigned int trashQuad);
510 : :
511 : : /*
512 : : SetVarLRInitialized - this sets up an alias between the parameter
513 : : value and the pointer for the case:
514 : :
515 : : procedure foo (var shadow: PtrToType) ;
516 : :
517 : : which allows shadow to be statically analyzed
518 : : once it is re-assigned.
519 : : */
520 : :
521 : : static void SetVarLRInitialized (unsigned int param);
522 : :
523 : : /*
524 : : TestBBSequence -
525 : : */
526 : :
527 : : static void TestBBSequence (unsigned int procSym, Lists_List lst);
528 : :
529 : : /*
530 : : CreateBBPermultations -
531 : : */
532 : :
533 : : static void CreateBBPermultations (unsigned int procSym, unsigned int i, Lists_List lst);
534 : :
535 : : /*
536 : : GetOp3 -
537 : : */
538 : :
539 : : static unsigned int GetOp3 (unsigned int quad);
540 : :
541 : : /*
542 : : getBBindex - return the basic block index which starts with quad.
543 : : */
544 : :
545 : : static unsigned int getBBindex (unsigned int quad);
546 : :
547 : : /*
548 : : GenerateCFG -
549 : : */
550 : :
551 : : static void GenerateCFG (void);
552 : :
553 : : /*
554 : : NewEntry -
555 : : */
556 : :
557 : : static M2SymInit_bbEntry NewEntry (void);
558 : :
559 : : /*
560 : : IsAllocate - return TRUE is sym is ALLOCATE.
561 : : */
562 : :
563 : : static bool IsAllocate (unsigned int sym);
564 : :
565 : : /*
566 : : IsDeallocate - return TRUE is sym is DEALLOCATE.
567 : : */
568 : :
569 : : static bool IsDeallocate (unsigned int sym);
570 : :
571 : : /*
572 : : DetectTrash -
573 : : */
574 : :
575 : : static void DetectTrash (M2SymInit_bbEntry bbPtr);
576 : :
577 : : /*
578 : : AppendEntry -
579 : : */
580 : :
581 : : static void AppendEntry (unsigned int Start, unsigned int End);
582 : :
583 : : /*
584 : : DumpAlias -
585 : : */
586 : :
587 : : static void DumpAlias (Indexing_Index array, unsigned int aliasIndex);
588 : :
589 : : /*
590 : : doDumpAliases -
591 : : */
592 : :
593 : : static void doDumpAliases (Indexing_Index array);
594 : :
595 : : /*
596 : : DumpAliases -
597 : : */
598 : :
599 : : static void DumpAliases (void);
600 : :
601 : : /*
602 : : newAlias -
603 : : */
604 : :
605 : : static M2SymInit_symAlias newAlias (void);
606 : :
607 : : /*
608 : : initAlias -
609 : : */
610 : :
611 : : static M2SymInit_symAlias initAlias (unsigned int sym);
612 : :
613 : : /*
614 : : killAlias -
615 : : */
616 : :
617 : : static void killAlias (M2SymInit_symAlias sa);
618 : :
619 : : /*
620 : : initBlock -
621 : : */
622 : :
623 : : static void initBlock (void);
624 : :
625 : : /*
626 : : killBlock -
627 : : */
628 : :
629 : : static void killBlock (void);
630 : :
631 : : /*
632 : : killBlock -
633 : : */
634 : :
635 : : static void doKillBlock (Indexing_Index *array);
636 : :
637 : : /*
638 : : addAlias -
639 : : */
640 : :
641 : : static void addAlias (Indexing_Index array, unsigned int sym, unsigned int aliased);
642 : :
643 : : /*
644 : : lookupAlias -
645 : : */
646 : :
647 : : static M2SymInit_symAlias lookupAlias (Indexing_Index array, unsigned int sym);
648 : :
649 : : /*
650 : : doGetAlias -
651 : : */
652 : :
653 : : static unsigned int doGetAlias (Indexing_Index array, unsigned int sym);
654 : :
655 : : /*
656 : : getLAlias - attempts to looks up an alias which is not a temporary variable.
657 : : */
658 : :
659 : : static unsigned int getLAlias (unsigned int sym);
660 : :
661 : : /*
662 : : SetupLAlias -
663 : : */
664 : :
665 : : static void SetupLAlias (unsigned int des, unsigned int exp);
666 : :
667 : : /*
668 : : SetupIndr -
669 : : */
670 : :
671 : : static void SetupIndr (unsigned int ptr, unsigned int content);
672 : :
673 : : /*
674 : : getContent - attempts to return the content pointed to by ptr.
675 : : sym is the original symbol and ptr will be the equivalent lvalue.
676 : : */
677 : :
678 : : static unsigned int getContent (unsigned int ptr, unsigned int sym, unsigned int tok);
679 : :
680 : : /*
681 : : init -
682 : : */
683 : :
684 : : static void init (void);
685 : :
686 : :
687 : : /*
688 : : KillFieldDesc -
689 : : */
690 : :
691 : 0 : static void KillFieldDesc (Indexing_Index *fielddesc)
692 : : {
693 : 0 : unsigned int i;
694 : 0 : unsigned int h;
695 : 0 : M2SymInit_InitDesc id;
696 : :
697 : 0 : i = 1;
698 : 0 : h = Indexing_HighIndice ((*fielddesc));
699 : 0 : while (i <= h)
700 : : {
701 : 0 : id = static_cast<M2SymInit_InitDesc> (Indexing_GetIndice ((*fielddesc), i));
702 : 0 : M2SymInit_KillSymInit (&id);
703 : 0 : i += 1;
704 : : }
705 : 0 : (*fielddesc) = Indexing_KillIndex ((*fielddesc));
706 : 0 : }
707 : :
708 : :
709 : : /*
710 : : PopulateFields -
711 : : */
712 : :
713 : 70428 : static void PopulateFields (M2SymInit_InitDesc desc, unsigned int recsym)
714 : : {
715 : 70428 : unsigned int field;
716 : 70428 : unsigned int i;
717 : 70428 : M2SymInit_InitDesc fdesc;
718 : :
719 : 70428 : M2Debug_Assert (SymbolTable_IsRecord (recsym));
720 : 70428 : i = 1;
721 : 363684 : do {
722 : 363684 : field = SymbolTable_GetNth (recsym, i);
723 : 363684 : if (field != SymbolTable_NulSym)
724 : : {
725 : 293256 : fdesc = M2SymInit_InitSymInit ();
726 : 293256 : M2SymInit_ConfigSymInit (fdesc, field);
727 : 293256 : Indexing_IncludeIndiceIntoIndex (desc->rec.fieldDesc, reinterpret_cast<void *> (fdesc));
728 : 293256 : i += 1;
729 : : }
730 : 363684 : } while (! (field == SymbolTable_NulSym));
731 : 70428 : }
732 : :
733 : :
734 : : /*
735 : : TrySetInitialized -
736 : : */
737 : :
738 : 936 : static void TrySetInitialized (M2SymInit_InitDesc desc)
739 : : {
740 : 936 : unsigned int i;
741 : 936 : unsigned int h;
742 : 936 : M2SymInit_InitDesc fdesc;
743 : :
744 : 936 : h = Indexing_HighIndice (desc->rec.fieldDesc);
745 : 936 : i = 1;
746 : 2712 : while (i <= h)
747 : : {
748 : 1692 : fdesc = static_cast<M2SymInit_InitDesc> (Indexing_GetIndice (desc->rec.fieldDesc, i));
749 : 1692 : if (! fdesc->initialized)
750 : : {
751 : : return ;
752 : : }
753 : 840 : i += 1;
754 : : }
755 : 84 : desc->initialized = true;
756 : : }
757 : :
758 : :
759 : : /*
760 : : SetFieldInitializedNo -
761 : : */
762 : :
763 : 828 : static bool SetFieldInitializedNo (M2SymInit_InitDesc desc, Lists_List fieldlist, unsigned int level)
764 : : {
765 : 828 : unsigned int nsym;
766 : 828 : M2SymInit_InitDesc fdesc;
767 : :
768 : 828 : if (level > (Lists_NoOfItemsInList (fieldlist)))
769 : : {
770 : : return false;
771 : : }
772 : : else
773 : : {
774 : 828 : nsym = static_cast<unsigned int> (Lists_GetItemFromList (fieldlist, level));
775 : 828 : fdesc = M2SymInit_GetFieldDesc (desc, nsym);
776 : 828 : if (fdesc == NULL)
777 : : {
778 : : return false;
779 : : }
780 : 828 : else if (level == (Lists_NoOfItemsInList (fieldlist)))
781 : : {
782 : : /* avoid dangling else. */
783 : 612 : M2SymInit_SetInitialized (fdesc);
784 : 612 : TrySetInitialized (desc);
785 : 612 : return desc->initialized;
786 : : }
787 : : else
788 : : {
789 : : /* avoid dangling else. */
790 : 216 : if (SetFieldInitializedNo (fdesc, fieldlist, level+1))
791 : : {} /* empty. */
792 : 216 : TrySetInitialized (desc);
793 : 216 : return desc->initialized;
794 : : }
795 : : }
796 : : /* static analysis guarentees a RETURN statement will be used before here. */
797 : : __builtin_unreachable ();
798 : : }
799 : :
800 : :
801 : : /*
802 : : SetFieldInitializedNo -
803 : : */
804 : :
805 : 204 : static bool GetFieldInitializedNo (M2SymInit_InitDesc desc, Lists_List fieldlist, unsigned int level)
806 : : {
807 : 372 : unsigned int nsym;
808 : 372 : M2SymInit_InitDesc fdesc;
809 : :
810 : 372 : if (desc->initialized)
811 : : {
812 : : return true;
813 : : }
814 : 324 : else if (level > (Lists_NoOfItemsInList (fieldlist)))
815 : : {
816 : : /* avoid dangling else. */
817 : : return false;
818 : : }
819 : : else
820 : : {
821 : : /* avoid dangling else. */
822 : 180 : nsym = static_cast<unsigned int> (Lists_GetItemFromList (fieldlist, level));
823 : 180 : fdesc = M2SymInit_GetFieldDesc (desc, nsym);
824 : 180 : if (fdesc == NULL)
825 : : {
826 : : /* The pointer variable maybe uninitialized and hence we cannot
827 : : find the record variable. */
828 : : return false;
829 : : }
830 : 180 : else if (fdesc->initialized)
831 : : {
832 : : /* avoid dangling else. */
833 : : return true;
834 : : }
835 : : else
836 : : {
837 : : /* avoid dangling else. */
838 : 168 : return GetFieldInitializedNo (fdesc, fieldlist, level+1);
839 : : }
840 : : }
841 : : /* static analysis guarentees a RETURN statement will be used before here. */
842 : : __builtin_unreachable ();
843 : : }
844 : :
845 : :
846 : : /*
847 : : IsGlobalVar -
848 : : */
849 : :
850 : 3034 : static bool IsGlobalVar (unsigned int sym)
851 : : {
852 : 3034 : return (SymbolTable_IsVar (sym)) && (! (SymbolTable_IsProcedure (SymbolTable_GetVarScope (sym))));
853 : : /* static analysis guarentees a RETURN statement will be used before here. */
854 : : __builtin_unreachable ();
855 : : }
856 : :
857 : :
858 : : /*
859 : : RecordFieldContainsVarient -
860 : : */
861 : :
862 : 2052 : static bool RecordFieldContainsVarient (unsigned int sym, Lists_List visited)
863 : : {
864 : 2052 : M2Debug_Assert (SymbolTable_IsRecordField (sym));
865 : 2052 : if (doContainsVariant (SymbolTable_GetSType (sym), visited))
866 : : {
867 : : return true;
868 : : }
869 : 2052 : return (SymbolTable_GetVarient (sym)) != SymbolTable_NulSym;
870 : : /* static analysis guarentees a RETURN statement will be used before here. */
871 : : __builtin_unreachable ();
872 : : }
873 : :
874 : :
875 : : /*
876 : : RecordContainsVarient -
877 : : */
878 : :
879 : 972 : static bool RecordContainsVarient (unsigned int sym, Lists_List visited)
880 : : {
881 : 972 : unsigned int i;
882 : 972 : unsigned int fieldsym;
883 : :
884 : 972 : M2Debug_Assert (SymbolTable_IsRecord (sym));
885 : 972 : i = 1;
886 : 3024 : do {
887 : 3024 : fieldsym = SymbolTable_GetNth (sym, i);
888 : 3024 : if (fieldsym != SymbolTable_NulSym)
889 : : {
890 : 2052 : if (SymbolTable_IsRecordField (fieldsym))
891 : : {
892 : : /* avoid dangling else. */
893 : 2052 : if (RecordFieldContainsVarient (fieldsym, visited))
894 : : {
895 : : return true;
896 : : }
897 : : }
898 : 0 : else if (SymbolTable_IsVarient (fieldsym))
899 : : {
900 : : /* avoid dangling else. */
901 : : return true;
902 : : }
903 : 2052 : i += 1;
904 : : }
905 : 3024 : } while (! (fieldsym == SymbolTable_NulSym));
906 : : return false;
907 : : /* static analysis guarentees a RETURN statement will be used before here. */
908 : : __builtin_unreachable ();
909 : : }
910 : :
911 : :
912 : : /*
913 : : VarContainsVarient -
914 : : */
915 : :
916 : 2926 : static bool VarContainsVarient (unsigned int sym, Lists_List visited)
917 : : {
918 : 2926 : M2Debug_Assert (SymbolTable_IsVar (sym));
919 : 2926 : return doContainsVariant (SymbolTable_GetSType (sym), visited);
920 : : /* static analysis guarentees a RETURN statement will be used before here. */
921 : : __builtin_unreachable ();
922 : : }
923 : :
924 : :
925 : : /*
926 : : TypeContainsVarient -
927 : : */
928 : :
929 : 2926 : static bool TypeContainsVarient (unsigned int sym, Lists_List visited)
930 : : {
931 : 2926 : M2Debug_Assert (SymbolTable_IsType (sym));
932 : 2926 : return doContainsVariant (SymbolTable_GetSType (sym), visited);
933 : : /* static analysis guarentees a RETURN statement will be used before here. */
934 : : __builtin_unreachable ();
935 : : }
936 : :
937 : :
938 : : /*
939 : : ArrayContainsVarient -
940 : : */
941 : :
942 : 0 : static bool ArrayContainsVarient (unsigned int sym, Lists_List visited)
943 : : {
944 : 0 : M2Debug_Assert (SymbolTable_IsArray (sym));
945 : 0 : return doContainsVariant (SymbolTable_GetSType (sym), visited);
946 : : /* static analysis guarentees a RETURN statement will be used before here. */
947 : : __builtin_unreachable ();
948 : : }
949 : :
950 : :
951 : : /*
952 : : PointerContainsVarient -
953 : : */
954 : :
955 : 2128 : static bool PointerContainsVarient (unsigned int sym, Lists_List visited)
956 : : {
957 : 2128 : M2Debug_Assert (SymbolTable_IsPointer (sym));
958 : 2128 : return doContainsVariant (SymbolTable_GetSType (sym), visited);
959 : : /* static analysis guarentees a RETURN statement will be used before here. */
960 : : __builtin_unreachable ();
961 : : }
962 : :
963 : :
964 : : /*
965 : : doContainsVariant -
966 : : */
967 : :
968 : 12958 : static bool doContainsVariant (unsigned int sym, Lists_List visited)
969 : : {
970 : 12958 : if ((sym != SymbolTable_NulSym) && (! (Lists_IsItemInList (visited, sym))))
971 : : {
972 : 8952 : Lists_IncludeItemIntoList (visited, sym);
973 : 8952 : if (SymbolTable_IsVar (sym))
974 : : {
975 : 2926 : return VarContainsVarient (sym, visited);
976 : : }
977 : 6026 : else if (SymbolTable_IsRecord (sym))
978 : : {
979 : : /* avoid dangling else. */
980 : 972 : return RecordContainsVarient (sym, visited);
981 : : }
982 : 5054 : else if (SymbolTable_IsPointer (sym))
983 : : {
984 : : /* avoid dangling else. */
985 : 2128 : return PointerContainsVarient (sym, visited);
986 : : }
987 : 2926 : else if (SymbolTable_IsArray (sym))
988 : : {
989 : : /* avoid dangling else. */
990 : 0 : return ArrayContainsVarient (sym, visited);
991 : : }
992 : 2926 : else if (SymbolTable_IsType (sym))
993 : : {
994 : : /* avoid dangling else. */
995 : 2926 : return TypeContainsVarient (sym, visited);
996 : : }
997 : : }
998 : : return false;
999 : : /* static analysis guarentees a RETURN statement will be used before here. */
1000 : : __builtin_unreachable ();
1001 : : }
1002 : :
1003 : :
1004 : : /*
1005 : : ContainsVariant - returns TRUE if type sym contains a variant record.
1006 : : */
1007 : :
1008 : 2926 : static bool ContainsVariant (unsigned int sym)
1009 : : {
1010 : 2926 : Lists_List visited;
1011 : 2926 : bool result;
1012 : :
1013 : 2926 : Lists_InitList (&visited);
1014 : 2926 : result = doContainsVariant (sym, visited);
1015 : 2926 : Lists_KillList (&visited);
1016 : 2926 : return result;
1017 : : /* static analysis guarentees a RETURN statement will be used before here. */
1018 : : __builtin_unreachable ();
1019 : : }
1020 : :
1021 : :
1022 : : /*
1023 : : IssueConditional -
1024 : : */
1025 : :
1026 : 3 : static void IssueConditional (unsigned int quad, bool conditional)
1027 : : {
1028 : 3 : M2Quads_QuadOperator op;
1029 : 3 : unsigned int op1;
1030 : 3 : unsigned int op2;
1031 : 3 : unsigned int op3;
1032 : 3 : unsigned int op1tok;
1033 : 3 : unsigned int op2tok;
1034 : 3 : unsigned int op3tok;
1035 : 3 : unsigned int qtok;
1036 : 3 : bool constExpr;
1037 : 3 : bool overflowChecking;
1038 : 3 : DynamicStrings_String s;
1039 : :
1040 : 3 : M2Quads_GetQuadOtok (quad, &qtok, &op, &op1, &op2, &op3, &overflowChecking, &constExpr, &op1tok, &op2tok, &op3tok);
1041 : 3 : if (IsUniqueWarning (qtok))
1042 : : {
1043 : 2 : op1tok = DefaultTokPos (op1tok, qtok);
1044 : 2 : op2tok = DefaultTokPos (op2tok, qtok);
1045 : 2 : op3tok = DefaultTokPos (op3tok, qtok);
1046 : 1 : if (! conditional)
1047 : : {
1048 : 1 : op = M2Quads_Opposite (op);
1049 : : }
1050 : 1 : s = DynamicStrings_InitString ((const char *) "depending upon the result of {%1Oad} ", 37);
1051 : 1 : s = DynamicStrings_ConCat (s, DynamicStrings_Mark (M2Quads_GetM2OperatorDesc (op)));
1052 : 1 : s = DynamicStrings_ConCat (s, DynamicStrings_InitString ((const char *) " {%2ad}", 7));
1053 : 1 : M2MetaError_MetaErrorStringT2 (qtok, s, op1, op2);
1054 : : }
1055 : 3 : }
1056 : :
1057 : :
1058 : : /*
1059 : : GenerateNoteFlow -
1060 : : */
1061 : :
1062 : 182 : static void GenerateNoteFlow (unsigned int n, bool warning)
1063 : : {
1064 : 182 : unsigned int i;
1065 : 182 : M2SymInit_bbEntry ip1Ptr;
1066 : 182 : M2SymInit_bbEntry iPtr;
1067 : :
1068 : 182 : if (! warning)
1069 : : {
1070 : : /* Only issue flow messages for non warnings. */
1071 : : i = 1;
1072 : 10 : while (i <= n)
1073 : : {
1074 : 8 : iPtr = static_cast<M2SymInit_bbEntry> (Indexing_GetIndice (bbArray, i));
1075 : 8 : if (iPtr->endCond)
1076 : : {
1077 : 5 : if (i < n)
1078 : : {
1079 : 3 : ip1Ptr = static_cast<M2SymInit_bbEntry> (Indexing_GetIndice (bbArray, i+1));
1080 : 3 : IssueConditional (iPtr->end, iPtr->condBB == ip1Ptr->indexBB);
1081 : : }
1082 : : }
1083 : 8 : i += 1;
1084 : : }
1085 : : }
1086 : 182 : }
1087 : :
1088 : :
1089 : : /*
1090 : : IssueWarning - issue a warning or note at tok location.
1091 : : */
1092 : :
1093 : 182 : static void IssueWarning (unsigned int tok, const char *before_, unsigned int _before_high, const char *after_, unsigned int _after_high, unsigned int sym, bool warning)
1094 : : {
1095 : 182 : DynamicStrings_String s;
1096 : 182 : char before[_before_high+1];
1097 : 182 : char after[_after_high+1];
1098 : :
1099 : : /* make a local copy of each unbounded array. */
1100 : 182 : memcpy (before, before_, _before_high+1);
1101 : 182 : memcpy (after, after_, _after_high+1);
1102 : :
1103 : 364 : s = DynamicStrings_InitString ((const char *) before, _before_high);
1104 : 182 : if (warning)
1105 : : {
1106 : 180 : s = DynamicStrings_ConCat (s, DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "{%1Wad}", 7)));
1107 : : }
1108 : : else
1109 : : {
1110 : 2 : s = DynamicStrings_ConCat (s, DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "{%1Oad}", 7)));
1111 : : }
1112 : 182 : s = DynamicStrings_ConCat (s, DynamicStrings_Mark (DynamicStrings_InitString ((const char *) after, _after_high)));
1113 : 182 : M2MetaError_MetaErrorStringT1 (tok, s, sym);
1114 : 182 : }
1115 : :
1116 : :
1117 : : /*
1118 : : IsUniqueWarning - return TRUE if a warning has not been issued at tok.
1119 : : It remembers tok and subsequent calls will always return FALSE.
1120 : : */
1121 : :
1122 : 226 : static bool IsUniqueWarning (unsigned int tok)
1123 : : {
1124 : 226 : if (! (Lists_IsItemInList (errorList, tok)))
1125 : : {
1126 : 159 : Lists_IncludeItemIntoList (errorList, tok);
1127 : 159 : return true;
1128 : : }
1129 : : else
1130 : : {
1131 : : return false;
1132 : : }
1133 : : /* static analysis guarentees a RETURN statement will be used before here. */
1134 : : __builtin_unreachable ();
1135 : : }
1136 : :
1137 : :
1138 : : /*
1139 : : CheckDeferredRecordAccess -
1140 : : */
1141 : :
1142 : 7241 : static void CheckDeferredRecordAccess (unsigned int tok, unsigned int sym, bool canDereference, bool warning, unsigned int i)
1143 : : {
1144 : 7241 : bool unique;
1145 : :
1146 : 7241 : if (SymbolTable_IsVar (sym))
1147 : : {
1148 : 2620 : if (Debugging)
1149 : : {
1150 : : Trace ((const char *) "CheckDeferredRecordAccess %d\\n", 30, sym);
1151 : : M2GCCDeclare_PrintSym (sym);
1152 : : if (canDereference)
1153 : : {
1154 : : M2Printf_printf1 ((const char *) "checkReadInit (%d, true)\\n", 26, (const unsigned char *) &sym, (sizeof (sym)-1));
1155 : : }
1156 : : else
1157 : : {
1158 : : M2Printf_printf1 ((const char *) "checkReadInit (%d, false)\\n", 27, (const unsigned char *) &sym, (sizeof (sym)-1));
1159 : : }
1160 : : }
1161 : 2620 : if (IsExempt (sym))
1162 : : {
1163 : 270 : Trace ((const char *) "checkReadInit sym is a parameter or not a local variable (%d)", 61, sym);
1164 : : /* We assume parameters have been initialized. */
1165 : 270 : SymbolTable_PutVarInitialized (sym, SymbolTable_LeftValue);
1166 : : /* SetVarInitialized (sym, TRUE) */
1167 : 270 : SymbolTable_PutVarInitialized (sym, SymbolTable_RightValue);
1168 : : }
1169 : 2350 : else if (SymbolTable_IsUnbounded (SymbolTable_GetSType (sym)))
1170 : : {
1171 : : /* avoid dangling else. */
1172 : 0 : SetVarInitialized (sym, true, tok);
1173 : : }
1174 : 2350 : else if (SymbolTable_IsComponent (sym))
1175 : : {
1176 : : /* avoid dangling else. */
1177 : 264 : Trace ((const char *) "checkReadInit IsComponent (%d) is true)", 39, sym);
1178 : 264 : if ((! (GetVarComponentInitialized (sym, tok))) && (IsUniqueWarning (tok)))
1179 : : {
1180 : 126 : GenerateNoteFlow (i, warning);
1181 : 126 : IssueWarning (tok, (const char *) "attempting to access ", 21, (const char *) " before it has been initialized", 31, sym, warning);
1182 : : }
1183 : : }
1184 : 2086 : else if (((SymbolTable_GetMode (sym)) == SymbolTable_LeftValue) && canDereference)
1185 : : {
1186 : : /* avoid dangling else. */
1187 : 30 : Trace ((const char *) "checkReadInit GetMode (%d) = LeftValue and canDereference (LeftValue and RightValue VarCheckReadInit)", 101, sym);
1188 : 30 : unique = true;
1189 : 30 : if (! (SymbolTable_VarCheckReadInit (sym, SymbolTable_LeftValue)))
1190 : : {
1191 : 0 : unique = IsUniqueWarning (tok);
1192 : 0 : if (unique)
1193 : : {
1194 : 0 : GenerateNoteFlow (i, warning);
1195 : 0 : IssueWarning (tok, (const char *) "attempting to access the address of ", 36, (const char *) " before it has been initialized", 31, sym, warning);
1196 : : }
1197 : : }
1198 : 30 : if (! (SymbolTable_VarCheckReadInit (sym, SymbolTable_RightValue)))
1199 : : {
1200 : 24 : if (unique)
1201 : : {
1202 : 24 : GenerateNoteFlow (i, warning);
1203 : 24 : IssueWarning (tok, (const char *) "attempting to access ", 21, (const char *) " before it has been initialized", 31, sym, warning);
1204 : : }
1205 : : }
1206 : : }
1207 : : else
1208 : : {
1209 : : /* avoid dangling else. */
1210 : 2056 : Trace ((const char *) "checkReadInit call VarCheckReadInit using GetMode (%d)", 54, sym);
1211 : 2056 : if ((! (SymbolTable_VarCheckReadInit (sym, SymbolTable_GetMode (sym)))) && (IsUniqueWarning (tok)))
1212 : : {
1213 : 32 : GenerateNoteFlow (i, warning);
1214 : 32 : IssueWarning (tok, (const char *) "attempting to access ", 21, (const char *) " before it has been initialized", 31, sym, warning);
1215 : : }
1216 : : }
1217 : : }
1218 : 7241 : }
1219 : :
1220 : :
1221 : : /*
1222 : : SetVarUninitialized - resets variable init state.
1223 : : */
1224 : :
1225 : 45972 : static void SetVarUninitialized (unsigned int sym)
1226 : : {
1227 : 45972 : if (SymbolTable_IsVar (sym))
1228 : : {
1229 : 4076 : if (! (SymbolTable_IsUnbounded (SymbolTable_GetSType (sym))))
1230 : : {
1231 : 4076 : SymbolTable_VarInitState (sym);
1232 : : }
1233 : : }
1234 : 45972 : }
1235 : :
1236 : :
1237 : : /*
1238 : : ComponentFindVar -
1239 : : */
1240 : :
1241 : 900 : static unsigned int ComponentFindVar (unsigned int sym, bool *lvalue, unsigned int tok)
1242 : : {
1243 : 1152 : unsigned int nsym;
1244 : 1152 : unsigned int i;
1245 : :
1246 : 1152 : i = 1;
1247 : 1152 : do {
1248 : 1152 : nsym = SymbolTable_GetNth (sym, i);
1249 : 1152 : (*lvalue) = (SymbolTable_GetMode (nsym)) == SymbolTable_LeftValue;
1250 : 1152 : nsym = getLAlias (nsym);
1251 : 1152 : if (nsym == M2Base_Nil)
1252 : : {
1253 : 36 : M2MetaError_MetaErrorT1 (tok, (const char *) "attempting to dereference {%1Wad} which will be a {%kNIL} pointer", 65, sym);
1254 : 36 : return SymbolTable_NulSym;
1255 : : }
1256 : 1116 : else if ((nsym != SymbolTable_NulSym) && (SymbolTable_IsVar (nsym)))
1257 : : {
1258 : : /* avoid dangling else. */
1259 : 1116 : if ((nsym != sym) && (SymbolTable_IsComponent (nsym)))
1260 : : {
1261 : : return ComponentFindVar (nsym, lvalue, tok);
1262 : : }
1263 : : else
1264 : : {
1265 : 864 : return nsym;
1266 : : }
1267 : : }
1268 : 0 : i += 1;
1269 : 0 : } while (! (nsym == SymbolTable_NulSym));
1270 : : return SymbolTable_NulSym;
1271 : : /* static analysis guarentees a RETURN statement will be used before here. */
1272 : : __builtin_unreachable ();
1273 : : }
1274 : :
1275 : :
1276 : : /*
1277 : : ComponentCreateFieldList - builds a list of fields accessed by the component var.
1278 : : Each item in the list will be a field of incremental levels
1279 : : though a nested record. It is not a list of fields
1280 : : at the same level.
1281 : :
1282 : : foo = RECORD
1283 : : v: RECORD
1284 : : x, y: CARDINAL ;
1285 : : END ;
1286 : : w: CARDINAL ;
1287 : : END ;
1288 : :
1289 : : { v, x } for example and not { v, w }
1290 : : */
1291 : :
1292 : 816 : static Lists_List ComponentCreateFieldList (unsigned int sym)
1293 : : {
1294 : 816 : Lists_List lst;
1295 : :
1296 : 816 : Lists_InitList (&lst);
1297 : 816 : if ((SymbolTable_IsVar (sym)) && (SymbolTable_IsComponent (sym)))
1298 : : {
1299 : 816 : ComponentBuildFieldList (lst, sym);
1300 : : }
1301 : 816 : return lst;
1302 : : /* static analysis guarentees a RETURN statement will be used before here. */
1303 : : __builtin_unreachable ();
1304 : : }
1305 : :
1306 : :
1307 : : /*
1308 : : ComponentCreateFieldList - builds a list of fields accessed by the component var.
1309 : : Each item in the list will be a field of incremental levels
1310 : : though a nested record. It is not a list of fields
1311 : : at the same level.
1312 : :
1313 : : foo = RECORD
1314 : : v: RECORD
1315 : : x, y: CARDINAL ;
1316 : : END ;
1317 : : w: CARDINAL ;
1318 : : END ;
1319 : :
1320 : : { v, x } for example and not { v, w }
1321 : : */
1322 : :
1323 : 1068 : static void ComponentBuildFieldList (Lists_List lst, unsigned int sym)
1324 : : {
1325 : 1068 : unsigned int i;
1326 : 1068 : unsigned int nsym;
1327 : :
1328 : 1068 : i = 1;
1329 : 3204 : do {
1330 : 3204 : nsym = SymbolTable_GetNth (sym, i);
1331 : 3204 : if (nsym != SymbolTable_NulSym)
1332 : : {
1333 : 2136 : if (SymbolTable_IsComponent (nsym))
1334 : : {
1335 : 252 : ComponentBuildFieldList (lst, nsym);
1336 : : }
1337 : 1884 : else if (SymbolTable_IsRecordField (nsym))
1338 : : {
1339 : : /* avoid dangling else. */
1340 : 1068 : Lists_IncludeItemIntoList (lst, nsym);
1341 : : }
1342 : 2136 : i += 1;
1343 : : }
1344 : 3204 : } while (! (nsym == SymbolTable_NulSym));
1345 : 1068 : }
1346 : :
1347 : :
1348 : : /*
1349 : : deRefComponent -
1350 : : */
1351 : :
1352 : 882 : static unsigned int deRefComponent (unsigned int component, bool lvalue, unsigned int sym, unsigned int tok)
1353 : : {
1354 : 0 : if (lvalue)
1355 : : {
1356 : 498 : return getContent (component, sym, tok);
1357 : : }
1358 : : else
1359 : : {
1360 : : return component;
1361 : : }
1362 : : /* static analysis guarentees a RETURN statement will be used before here. */
1363 : : __builtin_unreachable ();
1364 : : }
1365 : :
1366 : :
1367 : : /*
1368 : : SetVarComponentInitialized -
1369 : : */
1370 : :
1371 : 318 : static void SetVarComponentInitialized (unsigned int sym, unsigned int tok)
1372 : : {
1373 : 318 : bool lvalue;
1374 : 318 : unsigned int i;
1375 : 318 : unsigned int n;
1376 : 318 : unsigned int fsym;
1377 : 318 : unsigned int vsym;
1378 : 318 : Lists_List lst;
1379 : :
1380 : 318 : vsym = ComponentFindVar (sym, &lvalue, tok);
1381 : 318 : vsym = deRefComponent (vsym, lvalue, sym, tok);
1382 : 318 : if (vsym != SymbolTable_NulSym)
1383 : : {
1384 : 306 : if (Debugging)
1385 : : {
1386 : : M2Printf_printf0 ((const char *) "*************** vsym is: ", 25);
1387 : : M2GCCDeclare_PrintSym (vsym);
1388 : : }
1389 : : /* Build list accessing the field. */
1390 : 306 : lst = ComponentCreateFieldList (sym);
1391 : 306 : if (Debugging)
1392 : : {
1393 : : M2Printf_printf2 ((const char *) "sym = %d, vsym = %d, fields:", 28, (const unsigned char *) &sym, (sizeof (sym)-1), (const unsigned char *) &vsym, (sizeof (vsym)-1));
1394 : : }
1395 : : /* Now mark this field in the record variable as initialized. */
1396 : 306 : if (SymbolTable_PutVarFieldInitialized (vsym, SymbolTable_RightValue, lst))
1397 : : {
1398 : : /* avoid dangling else. */
1399 : : if (Debugging)
1400 : : {
1401 : : i = 1;
1402 : : n = Lists_NoOfItemsInList (lst);
1403 : : while (i <= n)
1404 : : {
1405 : : fsym = static_cast<unsigned int> (Lists_GetItemFromList (lst, i));
1406 : : M2Printf_printf1 ((const char *) " %d", 3, (const unsigned char *) &fsym, (sizeof (fsym)-1));
1407 : : i += 1;
1408 : : }
1409 : : M2Printf_printf0 ((const char *) " is initialized\\n", 17);
1410 : : }
1411 : : }
1412 : 306 : else if (Debugging)
1413 : : {
1414 : : /* avoid dangling else. */
1415 : : M2Printf_printf0 ((const char *) " vsym is not a var\\n", 20);
1416 : : }
1417 : 306 : Lists_KillList (&lst);
1418 : : }
1419 : 318 : }
1420 : :
1421 : :
1422 : : /*
1423 : : GetVarComponentInitialized -
1424 : : */
1425 : :
1426 : 264 : static bool GetVarComponentInitialized (unsigned int sym, unsigned int tok)
1427 : : {
1428 : 264 : bool lvalue;
1429 : 264 : bool init;
1430 : 264 : unsigned int component;
1431 : 264 : unsigned int vsym;
1432 : 264 : Lists_List lst;
1433 : :
1434 : 264 : component = ComponentFindVar (sym, &lvalue, tok);
1435 : 264 : if ((Lists_IsItemInList (ignoreList, component)) || (IsExempt (component)))
1436 : : {
1437 : 18 : return true;
1438 : : }
1439 : : else
1440 : : {
1441 : 246 : init = false;
1442 : 246 : vsym = deRefComponent (component, lvalue, sym, tok);
1443 : 246 : if (vsym != SymbolTable_NulSym)
1444 : : {
1445 : : /* avoid gcc warning by using compound statement even if not strictly necessary. */
1446 : 204 : if (IsExempt (vsym))
1447 : : {
1448 : : init = true;
1449 : : }
1450 : : else
1451 : : {
1452 : : /* Create list representing how the field is accessed. */
1453 : 204 : lst = ComponentCreateFieldList (sym);
1454 : : /* Now obtain the mark indicating whether this field was initialized. */
1455 : 204 : init = SymbolTable_GetVarFieldInitialized (vsym, SymbolTable_RightValue, lst);
1456 : 204 : Lists_KillList (&lst);
1457 : : }
1458 : : }
1459 : 246 : return init;
1460 : : }
1461 : : /* static analysis guarentees a RETURN statement will be used before here. */
1462 : : __builtin_unreachable ();
1463 : : }
1464 : :
1465 : :
1466 : : /*
1467 : : Trace -
1468 : : */
1469 : :
1470 : 5599 : static void Trace (const char *message_, unsigned int _message_high, unsigned int sym)
1471 : : {
1472 : 5599 : char message[_message_high+1];
1473 : :
1474 : : /* make a local copy of each unbounded array. */
1475 : 5599 : memcpy (message, message_, _message_high+1);
1476 : :
1477 : 5599 : if (Debugging)
1478 : : {
1479 : : M2Printf_printf1 ((const char *) message, _message_high, (const unsigned char *) &sym, (sizeof (sym)-1));
1480 : : M2Printf_printf0 ((const char *) "\\n", 2);
1481 : : }
1482 : 2620 : }
1483 : :
1484 : :
1485 : : /*
1486 : : SetVarInitialized - if the variable has a left mode and can be dereferenced
1487 : : then set the left and right initialization state.
1488 : : */
1489 : :
1490 : 3093 : static void SetVarInitialized (unsigned int sym, bool canDereference, unsigned int tok)
1491 : : {
1492 : 3093 : if (SymbolTable_IsVar (sym))
1493 : : {
1494 : 2979 : Lists_RemoveItemFromList (ignoreList, sym);
1495 : 2979 : if (SymbolTable_IsComponent (sym))
1496 : : {
1497 : 318 : Trace ((const char *) "SetVarInitialized sym %d is a component and calling SetVarComponentInitialized", 78, sym);
1498 : 318 : SetVarComponentInitialized (sym, tok);
1499 : : }
1500 : 2661 : else if (((SymbolTable_GetMode (sym)) == SymbolTable_LeftValue) && canDereference)
1501 : : {
1502 : : /* avoid dangling else. */
1503 : 222 : Trace ((const char *) "SetVarInitialized sym %d is LeftValue and canDeference and calling PutVarInitialized LeftValue and RightValue", 109, sym);
1504 : 222 : SymbolTable_PutVarInitialized (sym, SymbolTable_LeftValue);
1505 : 222 : SymbolTable_PutVarInitialized (sym, SymbolTable_RightValue);
1506 : : }
1507 : : else
1508 : : {
1509 : : /* avoid dangling else. */
1510 : 2439 : Trace ((const char *) "SetVarInitialized sym %d calling PutVarInitialized with its mode", 64, sym);
1511 : 2439 : SymbolTable_PutVarInitialized (sym, SymbolTable_GetMode (sym));
1512 : : }
1513 : : if (Debugging)
1514 : : {
1515 : : M2GCCDeclare_PrintSym (sym);
1516 : : }
1517 : : }
1518 : 3093 : }
1519 : :
1520 : :
1521 : : /*
1522 : : doGetVarInitialized -
1523 : : */
1524 : :
1525 : 1630 : static bool doGetVarInitialized (unsigned int sym, unsigned int tok)
1526 : : {
1527 : 1630 : if (SymbolTable_IsVar (sym))
1528 : : {
1529 : 258 : if (SymbolTable_IsUnbounded (SymbolTable_GetSType (sym)))
1530 : : {
1531 : : return true;
1532 : : }
1533 : 258 : else if (SymbolTable_IsComponent (sym))
1534 : : {
1535 : : /* avoid dangling else. */
1536 : 0 : return GetVarComponentInitialized (sym, tok);
1537 : : }
1538 : 258 : return SymbolTable_VarCheckReadInit (sym, SymbolTable_GetMode (sym));
1539 : : }
1540 : 1372 : return (SymbolTable_IsConst (sym)) && (SymbolTable_IsConstString (sym));
1541 : : /* static analysis guarentees a RETURN statement will be used before here. */
1542 : : __builtin_unreachable ();
1543 : : }
1544 : :
1545 : :
1546 : : /*
1547 : : GetVarInitialized -
1548 : : */
1549 : :
1550 : 1630 : static bool GetVarInitialized (unsigned int sym, unsigned int tok)
1551 : : {
1552 : 1630 : bool init;
1553 : :
1554 : 0 : init = doGetVarInitialized (sym, tok);
1555 : 1630 : if (Debugging)
1556 : : {
1557 : : /* avoid gcc warning by using compound statement even if not strictly necessary. */
1558 : : if (init)
1559 : : {
1560 : : Trace ((const char *) "GetVarInitialized (sym = %d) returning TRUE", 43, sym);
1561 : : }
1562 : : else
1563 : : {
1564 : : Trace ((const char *) "GetVarInitialized (sym = %d) returning FALSE", 44, sym);
1565 : : }
1566 : : }
1567 : 1630 : return init;
1568 : : /* static analysis guarentees a RETURN statement will be used before here. */
1569 : : __builtin_unreachable ();
1570 : : }
1571 : :
1572 : :
1573 : : /*
1574 : : IsExempt - returns TRUE if sym is a global variable or a parameter or
1575 : : a variable with a variant record type.
1576 : : */
1577 : :
1578 : 3070 : static bool IsExempt (unsigned int sym)
1579 : : {
1580 : : /* (IsVarAParam (sym) AND (GetMode (sym) = LeftValue)) OR */
1581 : 3070 : return ((sym != SymbolTable_NulSym) && (SymbolTable_IsVar (sym))) && (((((((IsGlobalVar (sym)) || (ContainsVariant (sym))) || (SymbolTable_IsArray (SymbolTable_GetSType (sym)))) || (SymbolTable_IsSet (SymbolTable_GetSType (sym)))) || (SymbolTable_IsUnbounded (SymbolTable_GetSType (sym)))) || (SymbolTable_IsVarArrayRef (sym))) || (Lists_IsItemInList (ignoreList, sym)));
1582 : : /* static analysis guarentees a RETURN statement will be used before here. */
1583 : : __builtin_unreachable ();
1584 : : }
1585 : :
1586 : :
1587 : : /*
1588 : : CheckBinary -
1589 : : */
1590 : :
1591 : 0 : static void CheckBinary (unsigned int op1tok, unsigned int op1, unsigned int op2tok, unsigned int op2, unsigned int op3tok, unsigned int op3, bool warning, unsigned int i)
1592 : : {
1593 : 0 : CheckDeferredRecordAccess (op2tok, op2, false, warning, i);
1594 : 0 : CheckDeferredRecordAccess (op3tok, op3, false, warning, i);
1595 : 0 : SetVarInitialized (op1, false, op1tok);
1596 : 0 : }
1597 : :
1598 : :
1599 : : /*
1600 : : CheckUnary -
1601 : : */
1602 : :
1603 : 0 : static void CheckUnary (unsigned int lhstok, unsigned int lhs, unsigned int rhstok, unsigned int rhs, bool warning, unsigned int i)
1604 : : {
1605 : 0 : CheckDeferredRecordAccess (rhstok, rhs, false, warning, i);
1606 : 0 : SetVarInitialized (lhs, false, lhstok);
1607 : 0 : }
1608 : :
1609 : :
1610 : : /*
1611 : : CheckXIndr -
1612 : : */
1613 : :
1614 : 18 : static void CheckXIndr (unsigned int lhstok, unsigned int lhs, unsigned int type, unsigned int rhstok, unsigned int rhs, bool warning, unsigned int i)
1615 : : {
1616 : 18 : Lists_List lst;
1617 : 18 : unsigned int content;
1618 : :
1619 : 18 : CheckDeferredRecordAccess (rhstok, rhs, false, warning, i);
1620 : 18 : CheckDeferredRecordAccess (lhstok, lhs, false, warning, i);
1621 : : /* Now see if we know what lhs is pointing to and set fields if necessary. */
1622 : 18 : content = getContent (getLAlias (lhs), lhs, lhstok);
1623 : 18 : if (((content != SymbolTable_NulSym) && (content != lhs)) && ((SymbolTable_GetSType (content)) == type))
1624 : : {
1625 : 18 : if (SymbolTable_IsReallyPointer (rhs))
1626 : : {
1627 : 0 : SetupLAlias (content, rhs);
1628 : : }
1629 : 18 : if (SymbolTable_IsRecord (type))
1630 : : {
1631 : : /* Set all fields of content as initialized. */
1632 : 18 : SetVarInitialized (content, false, lhstok);
1633 : : }
1634 : : else
1635 : : {
1636 : : /* Set only the field assigned in vsym as initialized. */
1637 : 0 : lst = ComponentCreateFieldList (rhs);
1638 : 0 : if (SymbolTable_PutVarFieldInitialized (content, SymbolTable_RightValue, lst))
1639 : : {} /* empty. */
1640 : 0 : Lists_KillList (&lst);
1641 : : }
1642 : : }
1643 : 18 : }
1644 : :
1645 : :
1646 : : /*
1647 : : CheckIndrX -
1648 : : */
1649 : :
1650 : 108 : static void CheckIndrX (unsigned int lhstok, unsigned int lhs, unsigned int rhstok, unsigned int rhs, bool warning, unsigned int i)
1651 : : {
1652 : 108 : unsigned int content;
1653 : :
1654 : 108 : CheckDeferredRecordAccess (rhstok, rhs, false, warning, i);
1655 : 108 : content = getContent (getLAlias (rhs), rhs, rhstok);
1656 : 108 : if (content == SymbolTable_NulSym)
1657 : : {
1658 : 42 : Lists_IncludeItemIntoList (ignoreList, lhs);
1659 : : }
1660 : : else
1661 : : {
1662 : 66 : CheckDeferredRecordAccess (rhstok, content, true, warning, i);
1663 : 66 : SetVarInitialized (lhs, SymbolTable_VarCheckReadInit (content, SymbolTable_RightValue), lhstok);
1664 : 66 : if (SymbolTable_IsReallyPointer (content))
1665 : : {
1666 : 66 : SetupLAlias (lhs, content);
1667 : : }
1668 : : }
1669 : 108 : }
1670 : :
1671 : :
1672 : : /*
1673 : : CheckRecordField -
1674 : : */
1675 : :
1676 : 726 : static void CheckRecordField (unsigned int op1)
1677 : : {
1678 : 0 : SymbolTable_PutVarInitialized (op1, SymbolTable_LeftValue);
1679 : 726 : }
1680 : :
1681 : :
1682 : : /*
1683 : : CheckBecomes -
1684 : : */
1685 : :
1686 : 869 : static void CheckBecomes (unsigned int destok, unsigned int des, unsigned int exprtok, unsigned int expr, bool warning, unsigned int i)
1687 : : {
1688 : 869 : bool lvalue;
1689 : 869 : Lists_List lst;
1690 : 869 : unsigned int vsym;
1691 : :
1692 : 869 : CheckDeferredRecordAccess (exprtok, expr, false, warning, i);
1693 : 869 : SetupLAlias (des, expr);
1694 : 869 : SetVarInitialized (des, false, destok);
1695 : : /* Now see if we know what lhs is pointing to and set fields if necessary. */
1696 : 869 : if (SymbolTable_IsComponent (des))
1697 : : {
1698 : 318 : vsym = ComponentFindVar (des, &lvalue, destok);
1699 : 318 : vsym = deRefComponent (vsym, lvalue, des, destok);
1700 : 318 : if (vsym != SymbolTable_NulSym)
1701 : : {
1702 : : /* Set only the field assigned in vsym as initialized. */
1703 : 306 : lst = ComponentCreateFieldList (des);
1704 : 306 : if (SymbolTable_PutVarFieldInitialized (vsym, SymbolTable_RightValue, lst))
1705 : : {} /* empty. */
1706 : 306 : Lists_KillList (&lst);
1707 : : }
1708 : : }
1709 : 869 : }
1710 : :
1711 : :
1712 : : /*
1713 : : CheckComparison -
1714 : : */
1715 : :
1716 : 318 : static void CheckComparison (unsigned int op1tok, unsigned int op1, unsigned int op2tok, unsigned int op2, bool warning, unsigned int i)
1717 : : {
1718 : 318 : CheckDeferredRecordAccess (op1tok, op1, false, warning, i);
1719 : 318 : CheckDeferredRecordAccess (op2tok, op2, false, warning, i);
1720 : 318 : }
1721 : :
1722 : :
1723 : : /*
1724 : : CheckAddr -
1725 : : */
1726 : :
1727 : 1630 : static void CheckAddr (unsigned int ptrtok, unsigned int ptr, unsigned int contenttok, unsigned int content)
1728 : : {
1729 : 1630 : SetVarInitialized (ptr, GetVarInitialized (content, contenttok), ptrtok);
1730 : 3260 : SetupIndr (ptr, content);
1731 : 1630 : }
1732 : :
1733 : :
1734 : : /*
1735 : : DefaultTokPos -
1736 : : */
1737 : :
1738 : 36747 : static unsigned int DefaultTokPos (unsigned int preferredPos, unsigned int defaultPos)
1739 : : {
1740 : 1 : if (preferredPos == M2LexBuf_UnknownTokenNo)
1741 : : {
1742 : 31999 : return defaultPos;
1743 : : }
1744 : : return preferredPos;
1745 : : /* static analysis guarentees a RETURN statement will be used before here. */
1746 : : __builtin_unreachable ();
1747 : : }
1748 : :
1749 : :
1750 : : /*
1751 : : stop -
1752 : : */
1753 : :
1754 : 0 : static void stop (void)
1755 : : {
1756 : 0 : }
1757 : :
1758 : :
1759 : : /*
1760 : : CheckReadBeforeInitQuad -
1761 : : */
1762 : :
1763 : 12248 : static bool CheckReadBeforeInitQuad (unsigned int procSym, unsigned int quad, bool warning, unsigned int i)
1764 : : {
1765 : 12248 : M2Quads_QuadOperator op;
1766 : 12248 : unsigned int op1;
1767 : 12248 : unsigned int op2;
1768 : 12248 : unsigned int op3;
1769 : 12248 : unsigned int op1tok;
1770 : 12248 : unsigned int op2tok;
1771 : 12248 : unsigned int op3tok;
1772 : 12248 : unsigned int qtok;
1773 : 12248 : bool constExpr;
1774 : 12248 : bool overflowChecking;
1775 : :
1776 : 12248 : if (quad == 3140)
1777 : : {
1778 : 12248 : stop ();
1779 : : }
1780 : 12248 : if (Debugging)
1781 : : {
1782 : : M2Printf_printf1 ((const char *) "CheckReadBeforeInitQuad (quad %d)\\n", 35, (const unsigned char *) &quad, (sizeof (quad)-1));
1783 : : DumpAliases ();
1784 : : SymbolTable_ForeachLocalSymDo (procSym, (SymbolKey_PerformOperation) {(SymbolKey_PerformOperation_t) M2GCCDeclare_PrintSym});
1785 : : M2Printf_printf0 ((const char *) "***********************************\\n", 37);
1786 : : }
1787 : 12248 : M2Quads_GetQuadOtok (quad, &qtok, &op, &op1, &op2, &op3, &overflowChecking, &constExpr, &op1tok, &op2tok, &op3tok);
1788 : 12248 : op1tok = DefaultTokPos (op1tok, qtok);
1789 : 12248 : op2tok = DefaultTokPos (op2tok, qtok);
1790 : 12248 : op3tok = DefaultTokPos (op3tok, qtok);
1791 : 12248 : switch (op)
1792 : : {
1793 : 318 : case M2Quads_IfInOp:
1794 : 318 : case M2Quads_IfNotInOp:
1795 : 318 : case M2Quads_IfEquOp:
1796 : 318 : case M2Quads_IfNotEquOp:
1797 : 318 : case M2Quads_IfLessOp:
1798 : 318 : case M2Quads_IfLessEquOp:
1799 : 318 : case M2Quads_IfGreOp:
1800 : 318 : case M2Quads_IfGreEquOp:
1801 : : /* Jumps, calls and branches. */
1802 : 318 : CheckComparison (op1tok, op1, op2tok, op2, warning, i);
1803 : 318 : break;
1804 : :
1805 : : case M2Quads_TryOp:
1806 : : case M2Quads_ReturnOp:
1807 : : case M2Quads_CallOp:
1808 : : case M2Quads_KillLocalVarOp:
1809 : : case M2Quads_RetryOp:
1810 : : case M2Quads_GotoOp:
1811 : : return true; /* End of basic block. */
1812 : 0 : break;
1813 : :
1814 : 0 : case M2Quads_InclOp:
1815 : 0 : case M2Quads_ExclOp:
1816 : : /* Variable references. */
1817 : 0 : CheckDeferredRecordAccess (op1tok, op1, false, warning, i);
1818 : 0 : CheckDeferredRecordAccess (op1tok, op1, true, warning, i);
1819 : 0 : CheckDeferredRecordAccess (op3tok, op3, false, warning, i);
1820 : 0 : break;
1821 : :
1822 : 0 : case M2Quads_NegateOp:
1823 : 0 : CheckUnary (op1tok, op1, op3tok, op3, warning, i);
1824 : 0 : break;
1825 : :
1826 : 869 : case M2Quads_BecomesOp:
1827 : 869 : CheckBecomes (op1tok, op1, op3tok, op3, warning, i);
1828 : 869 : break;
1829 : :
1830 : 114 : case M2Quads_UnboundedOp:
1831 : 114 : case M2Quads_FunctValueOp:
1832 : 114 : case M2Quads_StandardFunctionOp:
1833 : 114 : case M2Quads_HighOp:
1834 : 114 : case M2Quads_SizeOp:
1835 : 114 : SetVarInitialized (op1, false, op1tok);
1836 : 114 : break;
1837 : :
1838 : 1630 : case M2Quads_AddrOp:
1839 : 1630 : CheckAddr (op1tok, op1, op3tok, op3);
1840 : 1630 : break;
1841 : :
1842 : 0 : case M2Quads_ReturnValueOp:
1843 : 0 : SetVarInitialized (op1, false, op1tok);
1844 : 0 : break;
1845 : :
1846 : : case M2Quads_NewLocalVarOp:
1847 : : break;
1848 : :
1849 : 2763 : case M2Quads_ParamOp:
1850 : 2763 : CheckDeferredRecordAccess (op2tok, op2, false, warning, i);
1851 : 2763 : CheckDeferredRecordAccess (op3tok, op3, false, warning, i);
1852 : 2763 : if (((op1 > 0) && (op1 <= (SymbolTable_NoOfParam (op2)))) && (SymbolTable_IsVarParam (op2, op1)))
1853 : : {
1854 : 156 : SetVarInitialized (op3, true, op3tok);
1855 : : }
1856 : : break;
1857 : :
1858 : 0 : case M2Quads_ArrayOp:
1859 : 0 : CheckDeferredRecordAccess (op3tok, op3, false, warning, i);
1860 : 0 : SetVarInitialized (op1, true, op1tok);
1861 : 0 : break;
1862 : :
1863 : 726 : case M2Quads_RecordFieldOp:
1864 : 726 : CheckRecordField (op1);
1865 : 726 : break;
1866 : :
1867 : 0 : case M2Quads_LogicalShiftOp:
1868 : 0 : case M2Quads_LogicalRotateOp:
1869 : 0 : case M2Quads_LogicalOrOp:
1870 : 0 : case M2Quads_LogicalAndOp:
1871 : 0 : case M2Quads_LogicalXorOp:
1872 : 0 : case M2Quads_LogicalDiffOp:
1873 : 0 : case M2Quads_CoerceOp:
1874 : 0 : case M2Quads_ConvertOp:
1875 : 0 : case M2Quads_CastOp:
1876 : 0 : case M2Quads_AddOp:
1877 : 0 : case M2Quads_ArithAddOp:
1878 : 0 : case M2Quads_SubOp:
1879 : 0 : case M2Quads_MultOp:
1880 : 0 : case M2Quads_DivM2Op:
1881 : 0 : case M2Quads_ModM2Op:
1882 : 0 : case M2Quads_ModFloorOp:
1883 : 0 : case M2Quads_DivCeilOp:
1884 : 0 : case M2Quads_ModCeilOp:
1885 : 0 : case M2Quads_DivFloorOp:
1886 : 0 : case M2Quads_ModTruncOp:
1887 : 0 : case M2Quads_DivTruncOp:
1888 : 0 : CheckBinary (op1tok, op1, op2tok, op2, op3tok, op3, warning, i);
1889 : 0 : break;
1890 : :
1891 : 18 : case M2Quads_XIndrOp:
1892 : 18 : CheckXIndr (op1tok, op1, op2, op3tok, op3, warning, i);
1893 : 18 : break;
1894 : :
1895 : 108 : case M2Quads_IndrXOp:
1896 : 108 : CheckIndrX (op1tok, op1, op3tok, op3, warning, i);
1897 : 108 : break;
1898 : :
1899 : 0 : case M2Quads_SaveExceptionOp:
1900 : 0 : SetVarInitialized (op1, false, op1tok);
1901 : 0 : break;
1902 : :
1903 : 0 : case M2Quads_RestoreExceptionOp:
1904 : 0 : CheckDeferredRecordAccess (op1tok, op1, false, warning, i);
1905 : 0 : break;
1906 : :
1907 : 0 : case M2Quads_SubrangeLowOp:
1908 : 0 : case M2Quads_SubrangeHighOp:
1909 : 0 : M2Error_InternalError ((const char *) "quadruples should have been resolved", 36);
1910 : : break;
1911 : :
1912 : : case M2Quads_ElementSizeOp:
1913 : : case M2Quads_BuiltinConstOp:
1914 : : case M2Quads_BuiltinTypeInfoOp:
1915 : : case M2Quads_StringConvertCnulOp:
1916 : : case M2Quads_StringConvertM2nulOp:
1917 : : case M2Quads_StringLengthOp:
1918 : : case M2Quads_ProcedureScopeOp:
1919 : : case M2Quads_InitEndOp:
1920 : : case M2Quads_InitStartOp:
1921 : : case M2Quads_FinallyStartOp:
1922 : : case M2Quads_FinallyEndOp:
1923 : : case M2Quads_CatchBeginOp:
1924 : : case M2Quads_CatchEndOp:
1925 : : case M2Quads_ThrowOp:
1926 : : case M2Quads_StartDefFileOp:
1927 : : case M2Quads_StartModFileOp:
1928 : : case M2Quads_EndFileOp:
1929 : : case M2Quads_CodeOnOp:
1930 : : case M2Quads_CodeOffOp:
1931 : : case M2Quads_ProfileOnOp:
1932 : : case M2Quads_ProfileOffOp:
1933 : : case M2Quads_OptimizeOnOp:
1934 : : case M2Quads_OptimizeOffOp:
1935 : : case M2Quads_InlineOp:
1936 : : case M2Quads_LineNumberOp:
1937 : : case M2Quads_StatementNoteOp:
1938 : : case M2Quads_SavePriorityOp:
1939 : : case M2Quads_RestorePriorityOp:
1940 : : case M2Quads_RangeCheckOp:
1941 : : case M2Quads_ModuleScopeOp:
1942 : : case M2Quads_ErrorOp:
1943 : : case M2Quads_DummyOp:
1944 : : case M2Quads_OptParamOp:
1945 : : case M2Quads_InitAddressOp:
1946 : : break;
1947 : :
1948 : :
1949 : 0 : default:
1950 : 0 : CaseException ("/home/worker/buildworker/tiber-lcov/build/gcc/m2/gm2-compiler/M2SymInit.def", 20, 1);
1951 : 0 : __builtin_unreachable ();
1952 : : }
1953 : : return false; /* Likewise assigning op1 (const) with a type. */
1954 : : /* static analysis guarentees a RETURN statement will be used before here. */
1955 : : __builtin_unreachable ();
1956 : : }
1957 : :
1958 : :
1959 : : /*
1960 : : FilterCheckReadBeforeInitQuad -
1961 : : */
1962 : :
1963 : 20621 : static bool FilterCheckReadBeforeInitQuad (unsigned int procSym, unsigned int start, bool warning, unsigned int i)
1964 : : {
1965 : 20621 : M2Quads_QuadOperator Op;
1966 : 20621 : unsigned int Op1;
1967 : 20621 : unsigned int Op2;
1968 : 20621 : unsigned int Op3;
1969 : :
1970 : 20621 : M2Quads_GetQuad (start, &Op, &Op1, &Op2, &Op3);
1971 : 20621 : if ((Op != M2Quads_RangeCheckOp) && (Op != M2Quads_StatementNoteOp))
1972 : : {
1973 : 12248 : return CheckReadBeforeInitQuad (procSym, start, warning, i);
1974 : : }
1975 : : return false;
1976 : : /* static analysis guarentees a RETURN statement will be used before here. */
1977 : : __builtin_unreachable ();
1978 : : }
1979 : :
1980 : :
1981 : : /*
1982 : : CheckReadBeforeInitFirstBasicBlock -
1983 : : */
1984 : :
1985 : 4749 : static void CheckReadBeforeInitFirstBasicBlock (unsigned int procSym, unsigned int start, unsigned int end, bool warning, unsigned int i)
1986 : : {
1987 : 36493 : for (;;)
1988 : : {
1989 : 20621 : if (FilterCheckReadBeforeInitQuad (procSym, start, warning, i))
1990 : : {} /* empty. */
1991 : 20621 : if (start == end)
1992 : : {
1993 : 4749 : return ;
1994 : : }
1995 : : else
1996 : : {
1997 : 15872 : start = M2Quads_GetNextQuad (start);
1998 : : }
1999 : : }
2000 : : }
2001 : :
2002 : :
2003 : : /*
2004 : : bbArrayKill -
2005 : : */
2006 : :
2007 : 2258 : static void bbArrayKill (void)
2008 : : {
2009 : 2258 : unsigned int i;
2010 : 2258 : unsigned int h;
2011 : 2258 : M2SymInit_bbEntry bbPtr;
2012 : :
2013 : 2258 : h = Indexing_HighIndice (bbArray);
2014 : 2258 : i = 1;
2015 : 10281 : while (i <= h)
2016 : : {
2017 : 5765 : bbPtr = static_cast<M2SymInit_bbEntry> (Indexing_GetIndice (bbArray, i));
2018 : 5765 : bbPtr->next = bbFreeList;
2019 : 5765 : bbFreeList = bbPtr;
2020 : 5765 : i += 1;
2021 : : }
2022 : 2258 : bbArray = Indexing_KillIndex (bbArray);
2023 : 2258 : }
2024 : :
2025 : :
2026 : : /*
2027 : : DumpBBEntry -
2028 : : */
2029 : :
2030 : 0 : static void DumpBBEntry (M2SymInit_bbEntry bbPtr, unsigned int procSym)
2031 : : {
2032 : 0 : M2Printf_printf4 ((const char *) "bb %d: scope %d: quads: %d .. %d", 33, (const unsigned char *) &bbPtr->indexBB, (sizeof (bbPtr->indexBB)-1), (const unsigned char *) &procSym, (sizeof (procSym)-1), (const unsigned char *) &bbPtr->start, (sizeof (bbPtr->start)-1), (const unsigned char *) &bbPtr->end, (sizeof (bbPtr->end)-1));
2033 : 0 : if (bbPtr->first)
2034 : : {
2035 : 0 : M2Printf_printf0 ((const char *) " first", 6);
2036 : : }
2037 : 0 : if (bbPtr->endCall)
2038 : : {
2039 : 0 : M2Printf_printf0 ((const char *) " endcall", 8);
2040 : : }
2041 : 0 : if (bbPtr->endGoto)
2042 : : {
2043 : 0 : M2Printf_printf0 ((const char *) " endgoto", 8);
2044 : : }
2045 : 0 : if (bbPtr->endCond)
2046 : : {
2047 : 0 : M2Printf_printf0 ((const char *) " endcond", 8);
2048 : : }
2049 : 0 : if (bbPtr->topOfLoop)
2050 : : {
2051 : 0 : M2Printf_printf0 ((const char *) " topofloop", 10);
2052 : : }
2053 : 0 : if (bbPtr->condBB != 0)
2054 : : {
2055 : 0 : M2Printf_printf1 ((const char *) " cond %d", 8, (const unsigned char *) &bbPtr->condBB, (sizeof (bbPtr->condBB)-1));
2056 : : }
2057 : 0 : if (bbPtr->nextBB != 0)
2058 : : {
2059 : 0 : M2Printf_printf1 ((const char *) " next %d", 8, (const unsigned char *) &bbPtr->nextBB, (sizeof (bbPtr->nextBB)-1));
2060 : : }
2061 : 0 : M2Printf_printf0 ((const char *) "\\n", 2);
2062 : 0 : }
2063 : :
2064 : :
2065 : : /*
2066 : : DumpBBArray -
2067 : : */
2068 : :
2069 : 0 : static void DumpBBArray (unsigned int procSym)
2070 : : {
2071 : 0 : M2SymInit_bbEntry bbPtr;
2072 : 0 : unsigned int i;
2073 : 0 : unsigned int n;
2074 : :
2075 : 0 : i = 1;
2076 : 0 : n = Indexing_HighIndice (bbArray);
2077 : 0 : while (i <= n)
2078 : : {
2079 : 0 : bbPtr = static_cast<M2SymInit_bbEntry> (Indexing_GetIndice (bbArray, i));
2080 : 0 : DumpBBEntry (bbPtr, procSym);
2081 : 0 : i += 1;
2082 : : }
2083 : : i = 1;
2084 : 0 : while (i <= n)
2085 : : {
2086 : 0 : bbPtr = static_cast<M2SymInit_bbEntry> (Indexing_GetIndice (bbArray, i));
2087 : 0 : M2Printf_printf4 ((const char *) "bb %d: scope %d: quads: %d .. %d\\n", 35, (const unsigned char *) &bbPtr->indexBB, (sizeof (bbPtr->indexBB)-1), (const unsigned char *) &procSym, (sizeof (procSym)-1), (const unsigned char *) &bbPtr->start, (sizeof (bbPtr->start)-1), (const unsigned char *) &bbPtr->end, (sizeof (bbPtr->end)-1));
2088 : 0 : M2Quads_DisplayQuadRange (procSym, bbPtr->start, bbPtr->end);
2089 : 0 : i += 1;
2090 : : }
2091 : 0 : }
2092 : :
2093 : :
2094 : : /*
2095 : : DumpBBSequence -
2096 : : */
2097 : :
2098 : 0 : static void DumpBBSequence (Lists_List lst)
2099 : : {
2100 : 0 : unsigned int arrayindex;
2101 : 0 : unsigned int listindex;
2102 : 0 : unsigned int n;
2103 : :
2104 : 0 : n = Lists_NoOfItemsInList (lst);
2105 : 0 : listindex = 1;
2106 : 0 : M2Printf_printf0 ((const char *) "=============\\n", 15);
2107 : 0 : M2Printf_printf0 ((const char *) " checking sequence:", 19);
2108 : 0 : while (listindex <= n)
2109 : : {
2110 : 0 : arrayindex = static_cast<unsigned int> (Lists_GetItemFromList (lst, listindex));
2111 : 0 : M2Printf_printf2 ((const char *) " lst[%d] -> %d", 14, (const unsigned char *) &listindex, (sizeof (listindex)-1), (const unsigned char *) &arrayindex, (sizeof (arrayindex)-1));
2112 : 0 : listindex += 1;
2113 : : }
2114 : 0 : M2Printf_printf0 ((const char *) "\\n", 2);
2115 : 0 : }
2116 : :
2117 : :
2118 : : /*
2119 : : trashParam -
2120 : : */
2121 : :
2122 : 120 : static void trashParam (unsigned int trashQuad)
2123 : : {
2124 : 120 : M2Quads_QuadOperator op;
2125 : 120 : unsigned int op1;
2126 : 120 : unsigned int proc;
2127 : 120 : unsigned int param;
2128 : 120 : unsigned int paramValue;
2129 : 120 : unsigned int op1tok;
2130 : 120 : unsigned int op2tok;
2131 : 120 : unsigned int paramtok;
2132 : 120 : unsigned int qtok;
2133 : 120 : bool constExpr;
2134 : 120 : bool overflowChecking;
2135 : 120 : unsigned int heapValue;
2136 : 120 : unsigned int ptrToHeap;
2137 : :
2138 : 120 : if (trashQuad != 0)
2139 : : {
2140 : 120 : M2Quads_GetQuadOtok (trashQuad, &qtok, &op, &op1, &proc, ¶m, &overflowChecking, &constExpr, &op1tok, &op2tok, ¶mtok);
2141 : 120 : heapValue = M2Quads_GetQuadTrash (trashQuad);
2142 : 120 : if (Debugging)
2143 : : {
2144 : : M2Printf_printf1 ((const char *) "heapValue = %d\\n", 16, (const unsigned char *) &heapValue, (sizeof (heapValue)-1));
2145 : : }
2146 : 120 : if (heapValue != SymbolTable_NulSym)
2147 : : {
2148 : 120 : SetVarInitialized (param, false, paramtok);
2149 : 120 : paramValue = getLAlias (param);
2150 : 120 : ptrToHeap = getContent (paramValue, param, paramtok);
2151 : 120 : if (ptrToHeap != SymbolTable_NulSym)
2152 : : {
2153 : : /* avoid gcc warning by using compound statement even if not strictly necessary. */
2154 : 120 : if (IsDeallocate (proc))
2155 : : {
2156 : 48 : SetupLAlias (ptrToHeap, M2Base_Nil);
2157 : 48 : SetVarInitialized (ptrToHeap, false, paramtok);
2158 : : }
2159 : : else
2160 : : {
2161 : 144 : SetupIndr (ptrToHeap, heapValue);
2162 : 72 : SetVarInitialized (ptrToHeap, true, paramtok);
2163 : : }
2164 : : }
2165 : : }
2166 : : }
2167 : 120 : DumpAliases ();
2168 : 120 : }
2169 : :
2170 : :
2171 : : /*
2172 : : SetVarLRInitialized - this sets up an alias between the parameter
2173 : : value and the pointer for the case:
2174 : :
2175 : : procedure foo (var shadow: PtrToType) ;
2176 : :
2177 : : which allows shadow to be statically analyzed
2178 : : once it is re-assigned.
2179 : : */
2180 : :
2181 : 114 : static void SetVarLRInitialized (unsigned int param)
2182 : : {
2183 : 114 : unsigned int heap;
2184 : 114 : unsigned int shadow;
2185 : :
2186 : 114 : M2Debug_Assert (SymbolTable_IsParameter (param));
2187 : 114 : shadow = SymbolTable_GetParameterShadowVar (param);
2188 : 114 : if (shadow != SymbolTable_NulSym)
2189 : : {
2190 : 114 : Lists_IncludeItemIntoList (ignoreList, shadow);
2191 : : }
2192 : 114 : heap = SymbolTable_GetParameterHeapVar (param);
2193 : 114 : if ((shadow != SymbolTable_NulSym) && (heap != SymbolTable_NulSym))
2194 : : {
2195 : 48 : SymbolTable_PutVarInitialized (shadow, SymbolTable_GetMode (shadow));
2196 : 48 : SymbolTable_PutVarInitialized (heap, SymbolTable_GetMode (heap));
2197 : 96 : SetupIndr (shadow, heap);
2198 : 48 : Lists_IncludeItemIntoList (ignoreList, heap);
2199 : : }
2200 : 114 : }
2201 : :
2202 : :
2203 : : /*
2204 : : TestBBSequence -
2205 : : */
2206 : :
2207 : 2334 : static void TestBBSequence (unsigned int procSym, Lists_List lst)
2208 : : {
2209 : 2334 : M2SymInit_bbEntry bbPtr;
2210 : 2334 : unsigned int bbi;
2211 : 2334 : unsigned int i;
2212 : 2334 : unsigned int n;
2213 : 2334 : bool warning;
2214 : :
2215 : 2334 : if (Debugging) /* Should we issue a warning rather than a note? */
2216 : : {
2217 : : DumpBBSequence (lst);
2218 : : }
2219 : 2334 : initBlock ();
2220 : 2334 : SymbolTable_ForeachLocalSymDo (procSym, (SymbolKey_PerformOperation) {(SymbolKey_PerformOperation_t) SetVarUninitialized});
2221 : 2334 : SymbolTable_ForeachParamSymDo (procSym, (SymbolKey_PerformOperation) {(SymbolKey_PerformOperation_t) SetVarLRInitialized});
2222 : 2334 : n = Lists_NoOfItemsInList (lst);
2223 : 2334 : i = 1;
2224 : 2334 : warning = true;
2225 : 9417 : while (i <= n)
2226 : : {
2227 : 4749 : bbi = static_cast<unsigned int> (Lists_GetItemFromList (lst, i));
2228 : 4749 : bbPtr = static_cast<M2SymInit_bbEntry> (Indexing_GetIndice (bbArray, bbi));
2229 : 4749 : CheckReadBeforeInitFirstBasicBlock (procSym, bbPtr->start, bbPtr->end, warning, i);
2230 : 4749 : if (bbPtr->endCond)
2231 : : {
2232 : : /* Check to see if we are moving into an conditional block in which case
2233 : : we will issue a note. */
2234 : : warning = false;
2235 : : }
2236 : 4431 : else if (bbPtr->endCall && (bbPtr->trashQuad != 0))
2237 : : {
2238 : : /* avoid dangling else. */
2239 : 120 : trashParam (bbPtr->trashQuad);
2240 : : }
2241 : 4749 : i += 1;
2242 : : }
2243 : 2334 : killBlock ();
2244 : 2334 : }
2245 : :
2246 : :
2247 : : /*
2248 : : CreateBBPermultations -
2249 : : */
2250 : :
2251 : 5903 : static void CreateBBPermultations (unsigned int procSym, unsigned int i, Lists_List lst)
2252 : : {
2253 : 5903 : Lists_List duplst;
2254 : 5903 : M2SymInit_bbEntry iPtr;
2255 : :
2256 : 5903 : if (i == 0)
2257 : : {
2258 : 1359 : TestBBSequence (procSym, lst);
2259 : : }
2260 : : else
2261 : : {
2262 : 4544 : iPtr = static_cast<M2SymInit_bbEntry> (Indexing_GetIndice (bbArray, i));
2263 : 4544 : if (iPtr->topOfLoop)
2264 : : {
2265 : 0 : TestBBSequence (procSym, lst);
2266 : : }
2267 : : else
2268 : : {
2269 : 4544 : duplst = Lists_DuplicateList (lst);
2270 : 4544 : Lists_IncludeItemIntoList (duplst, i);
2271 : 4544 : if (iPtr->endCall && (iPtr->trashQuad == 0))
2272 : : {
2273 : 813 : TestBBSequence (procSym, duplst);
2274 : : }
2275 : 3731 : else if (iPtr->endGoto)
2276 : : {
2277 : : /* avoid dangling else. */
2278 : 1 : CreateBBPermultations (procSym, iPtr->nextBB, duplst);
2279 : : }
2280 : 3730 : else if (M2Options_UninitVariableConditionalChecking && iPtr->endCond)
2281 : : {
2282 : : /* avoid dangling else. */
2283 : 76 : CreateBBPermultations (procSym, iPtr->nextBB, duplst);
2284 : 76 : CreateBBPermultations (procSym, iPtr->condBB, duplst);
2285 : : }
2286 : 3654 : else if (iPtr->endCond)
2287 : : {
2288 : : /* avoid dangling else. */
2289 : 162 : TestBBSequence (procSym, duplst);
2290 : : }
2291 : : else
2292 : : {
2293 : : /* avoid dangling else. */
2294 : : /* Fall through. */
2295 : 3492 : CreateBBPermultations (procSym, iPtr->nextBB, duplst);
2296 : : }
2297 : 4544 : Lists_KillList (&duplst);
2298 : : }
2299 : : }
2300 : 5903 : }
2301 : :
2302 : :
2303 : : /*
2304 : : GetOp3 -
2305 : : */
2306 : :
2307 : 237 : static unsigned int GetOp3 (unsigned int quad)
2308 : : {
2309 : 237 : M2Quads_QuadOperator op;
2310 : 237 : unsigned int op1;
2311 : 237 : unsigned int op2;
2312 : 237 : unsigned int op3;
2313 : :
2314 : 237 : M2Quads_GetQuad (quad, &op, &op1, &op2, &op3);
2315 : 237 : return op3;
2316 : : /* static analysis guarentees a RETURN statement will be used before here. */
2317 : : __builtin_unreachable ();
2318 : : }
2319 : :
2320 : :
2321 : : /*
2322 : : getBBindex - return the basic block index which starts with quad.
2323 : : */
2324 : :
2325 : 5189 : static unsigned int getBBindex (unsigned int quad)
2326 : : {
2327 : 5189 : M2SymInit_bbEntry iPtr;
2328 : 5189 : unsigned int i;
2329 : 5189 : unsigned int high;
2330 : :
2331 : 5189 : i = 1;
2332 : 5189 : high = Indexing_HighIndice (bbArray);
2333 : 19334 : while (i <= high)
2334 : : {
2335 : 12700 : iPtr = static_cast<M2SymInit_bbEntry> (Indexing_GetIndice (bbArray, i));
2336 : 12700 : if (iPtr->start == quad)
2337 : : {
2338 : 3744 : return iPtr->indexBB;
2339 : : }
2340 : 8956 : i += 1;
2341 : : }
2342 : : return 0;
2343 : : /* static analysis guarentees a RETURN statement will be used before here. */
2344 : : __builtin_unreachable ();
2345 : : }
2346 : :
2347 : :
2348 : : /*
2349 : : GenerateCFG -
2350 : : */
2351 : :
2352 : 2258 : static void GenerateCFG (void)
2353 : : {
2354 : 2258 : M2SymInit_bbEntry iPtr;
2355 : 2258 : unsigned int next;
2356 : 2258 : unsigned int i;
2357 : 2258 : unsigned int high;
2358 : :
2359 : 2258 : i = 1;
2360 : 2258 : high = Indexing_HighIndice (bbArray);
2361 : 10281 : while (i <= high)
2362 : : {
2363 : 5765 : iPtr = static_cast<M2SymInit_bbEntry> (Indexing_GetIndice (bbArray, i));
2364 : 5765 : if ((M2Quads_IsKillLocalVar (iPtr->end)) || (M2Quads_IsReturn (iPtr->end)))
2365 : : {} /* empty. */
2366 : : else
2367 : : {
2368 : : /* Nothing to do as we have reached the end of this scope. */
2369 : 4952 : next = M2Quads_GetNextQuad (iPtr->end);
2370 : 4952 : iPtr->nextQuad = next;
2371 : 4952 : iPtr->nextBB = getBBindex (next);
2372 : 4952 : if (iPtr->endCond)
2373 : : {
2374 : 237 : iPtr->condQuad = GetOp3 (iPtr->end);
2375 : 237 : iPtr->condBB = getBBindex (iPtr->condQuad);
2376 : : }
2377 : : }
2378 : 5765 : i += 1;
2379 : : }
2380 : 2258 : }
2381 : :
2382 : :
2383 : : /*
2384 : : NewEntry -
2385 : : */
2386 : :
2387 : 5765 : static M2SymInit_bbEntry NewEntry (void)
2388 : : {
2389 : 5765 : M2SymInit_bbEntry bbPtr;
2390 : :
2391 : 5765 : if (bbFreeList == NULL)
2392 : : {
2393 : 1135 : Storage_ALLOCATE ((void **) &bbPtr, sizeof (M2SymInit__T3));
2394 : : }
2395 : : else
2396 : : {
2397 : 4630 : bbPtr = bbFreeList;
2398 : 4630 : bbFreeList = bbFreeList->next;
2399 : : }
2400 : 5765 : return bbPtr;
2401 : : /* static analysis guarentees a RETURN statement will be used before here. */
2402 : : __builtin_unreachable ();
2403 : : }
2404 : :
2405 : :
2406 : : /*
2407 : : IsAllocate - return TRUE is sym is ALLOCATE.
2408 : : */
2409 : :
2410 : 860 : static bool IsAllocate (unsigned int sym)
2411 : : {
2412 : 860 : return (SymbolTable_IsProcedure (sym)) && ((SymbolTable_GetSymName (sym)) == (NameKey_MakeKey ((const char *) "ALLOCATE", 8)));
2413 : : /* static analysis guarentees a RETURN statement will be used before here. */
2414 : : __builtin_unreachable ();
2415 : : }
2416 : :
2417 : :
2418 : : /*
2419 : : IsDeallocate - return TRUE is sym is DEALLOCATE.
2420 : : */
2421 : :
2422 : 932 : static bool IsDeallocate (unsigned int sym)
2423 : : {
2424 : 932 : return (SymbolTable_IsProcedure (sym)) && ((SymbolTable_GetSymName (sym)) == (NameKey_MakeKey ((const char *) "DEALLOCATE", 10)));
2425 : : /* static analysis guarentees a RETURN statement will be used before here. */
2426 : : __builtin_unreachable ();
2427 : : }
2428 : :
2429 : :
2430 : : /*
2431 : : DetectTrash -
2432 : : */
2433 : :
2434 : 5765 : static void DetectTrash (M2SymInit_bbEntry bbPtr)
2435 : : {
2436 : 5765 : unsigned int i;
2437 : 5765 : M2Quads_QuadOperator op;
2438 : 5765 : unsigned int op1;
2439 : 5765 : unsigned int op2;
2440 : 5765 : unsigned int op3;
2441 : :
2442 : 5765 : if (bbPtr->endCall)
2443 : : {
2444 : 1047 : i = bbPtr->start;
2445 : 24789 : for (;;)
2446 : : {
2447 : 12918 : M2Quads_GetQuad (i, &op, &op1, &op2, &op3);
2448 : 12918 : if (((op == M2Quads_ParamOp) && (op1 == 1)) && ((IsAllocate (op2)) || (IsDeallocate (op2))))
2449 : : {
2450 : 72 : bbPtr->trashQuad = i;
2451 : : }
2452 : 12918 : if (i == bbPtr->end)
2453 : : {
2454 : 1047 : return ;
2455 : : }
2456 : 11871 : i = M2Quads_GetNextQuad (i);
2457 : : }
2458 : : }
2459 : : }
2460 : :
2461 : :
2462 : : /*
2463 : : AppendEntry -
2464 : : */
2465 : :
2466 : 5765 : static void AppendEntry (unsigned int Start, unsigned int End)
2467 : : {
2468 : 5765 : M2SymInit_bbEntry bbPtr;
2469 : 5765 : unsigned int high;
2470 : :
2471 : 5765 : high = Indexing_HighIndice (bbArray);
2472 : 5765 : bbPtr = NewEntry ();
2473 : 5765 : bbPtr->start = Start;
2474 : 5765 : bbPtr->end = End;
2475 : 5765 : bbPtr->first = high == 0;
2476 : 5765 : bbPtr->endCall = M2Quads_IsCall (End);
2477 : 5765 : bbPtr->endGoto = M2Quads_IsGoto (End);
2478 : 5765 : bbPtr->endCond = M2Quads_IsConditional (End);
2479 : 5765 : bbPtr->topOfLoop = M2Quads_IsBackReference (Start);
2480 : 5765 : bbPtr->trashQuad = 0;
2481 : 5765 : bbPtr->indexBB = high+1;
2482 : 5765 : bbPtr->nextQuad = 0;
2483 : 5765 : bbPtr->condQuad = 0;
2484 : 5765 : bbPtr->nextBB = 0;
2485 : 5765 : bbPtr->condBB = 0;
2486 : 5765 : bbPtr->next = NULL;
2487 : 5765 : DetectTrash (bbPtr);
2488 : 5765 : Indexing_PutIndice (bbArray, high+1, reinterpret_cast<void *> (bbPtr));
2489 : 5765 : }
2490 : :
2491 : :
2492 : : /*
2493 : : DumpAlias -
2494 : : */
2495 : :
2496 : 0 : static void DumpAlias (Indexing_Index array, unsigned int aliasIndex)
2497 : : {
2498 : 0 : M2SymInit_symAlias sa;
2499 : :
2500 : 0 : sa = static_cast<M2SymInit_symAlias> (Indexing_GetIndice (array, aliasIndex));
2501 : 0 : M2Printf_printf2 ((const char *) "keySym = %d: alias = %d\\n", 25, (const unsigned char *) &sa->keySym, (sizeof (sa->keySym)-1), (const unsigned char *) &sa->alias, (sizeof (sa->alias)-1));
2502 : 0 : }
2503 : :
2504 : :
2505 : : /*
2506 : : doDumpAliases -
2507 : : */
2508 : :
2509 : 0 : static void doDumpAliases (Indexing_Index array)
2510 : : {
2511 : 0 : unsigned int i;
2512 : 0 : unsigned int n;
2513 : :
2514 : 0 : i = 1;
2515 : 0 : n = Indexing_HighIndice (array);
2516 : 0 : while (i <= n)
2517 : : {
2518 : 0 : DumpAlias (array, i);
2519 : 0 : i += 1;
2520 : : }
2521 : 0 : }
2522 : :
2523 : :
2524 : : /*
2525 : : DumpAliases -
2526 : : */
2527 : :
2528 : 642 : static void DumpAliases (void)
2529 : : {
2530 : 642 : if (Debugging)
2531 : : {
2532 : : M2Printf_printf0 ((const char *) "LArray\\n", 8);
2533 : : doDumpAliases (LArray);
2534 : : M2Printf_printf0 ((const char *) "IndirectArray\\n", 15);
2535 : : doDumpAliases (IndirectArray);
2536 : : }
2537 : 642 : }
2538 : :
2539 : :
2540 : : /*
2541 : : newAlias -
2542 : : */
2543 : :
2544 : 2392 : static M2SymInit_symAlias newAlias (void)
2545 : : {
2546 : 2392 : M2SymInit_symAlias sa;
2547 : :
2548 : 2392 : if (freeList == NULL)
2549 : : {
2550 : 908 : Storage_ALLOCATE ((void **) &sa, sizeof (M2SymInit__T2));
2551 : : }
2552 : : else
2553 : : {
2554 : 1484 : sa = freeList;
2555 : 1484 : freeList = freeList->next;
2556 : : }
2557 : 2392 : return sa;
2558 : : /* static analysis guarentees a RETURN statement will be used before here. */
2559 : : __builtin_unreachable ();
2560 : : }
2561 : :
2562 : :
2563 : : /*
2564 : : initAlias -
2565 : : */
2566 : :
2567 : 2392 : static M2SymInit_symAlias initAlias (unsigned int sym)
2568 : : {
2569 : 2392 : M2SymInit_symAlias sa;
2570 : :
2571 : 0 : sa = newAlias ();
2572 : 2392 : sa->keySym = sym;
2573 : 2392 : sa->alias = SymbolTable_NulSym;
2574 : 2392 : sa->next = NULL;
2575 : 2392 : return sa;
2576 : : /* static analysis guarentees a RETURN statement will be used before here. */
2577 : : __builtin_unreachable ();
2578 : : }
2579 : :
2580 : :
2581 : : /*
2582 : : killAlias -
2583 : : */
2584 : :
2585 : 2392 : static void killAlias (M2SymInit_symAlias sa)
2586 : : {
2587 : 2392 : sa->next = freeList;
2588 : 2392 : freeList = sa;
2589 : 0 : }
2590 : :
2591 : :
2592 : : /*
2593 : : initBlock -
2594 : : */
2595 : :
2596 : 2334 : static void initBlock (void)
2597 : : {
2598 : 2334 : LArray = Indexing_InitIndex (1);
2599 : 2334 : IndirectArray = Indexing_InitIndex (1);
2600 : 2334 : Lists_InitList (&ignoreList);
2601 : 2334 : }
2602 : :
2603 : :
2604 : : /*
2605 : : killBlock -
2606 : : */
2607 : :
2608 : 2334 : static void killBlock (void)
2609 : : {
2610 : 2334 : doKillBlock (&LArray);
2611 : 2334 : doKillBlock (&IndirectArray);
2612 : 2334 : Lists_KillList (&ignoreList);
2613 : 2334 : }
2614 : :
2615 : :
2616 : : /*
2617 : : killBlock -
2618 : : */
2619 : :
2620 : 4668 : static void doKillBlock (Indexing_Index *array)
2621 : : {
2622 : 4668 : unsigned int i;
2623 : 4668 : unsigned int n;
2624 : :
2625 : 4668 : i = 1;
2626 : 4668 : n = Indexing_HighIndice ((*array));
2627 : 11728 : while (i <= n)
2628 : : {
2629 : 2392 : killAlias (reinterpret_cast<M2SymInit_symAlias> (Indexing_GetIndice ((*array), i)));
2630 : 2392 : i += 1;
2631 : : }
2632 : 4668 : (*array) = Indexing_KillIndex ((*array));
2633 : 4668 : }
2634 : :
2635 : :
2636 : : /*
2637 : : addAlias -
2638 : : */
2639 : :
2640 : 2392 : static void addAlias (Indexing_Index array, unsigned int sym, unsigned int aliased)
2641 : : {
2642 : 2392 : unsigned int i;
2643 : 2392 : unsigned int n;
2644 : 2392 : M2SymInit_symAlias sa;
2645 : :
2646 : 2392 : i = 1;
2647 : 2392 : n = Indexing_HighIndice (array);
2648 : 6784 : while (i <= n)
2649 : : {
2650 : 2000 : sa = static_cast<M2SymInit_symAlias> (Indexing_GetIndice (array, i));
2651 : 2000 : if (sa->keySym == sym)
2652 : : {
2653 : 0 : sa->alias = aliased;
2654 : 0 : return ;
2655 : : }
2656 : 2000 : i += 1;
2657 : : }
2658 : 2392 : sa = initAlias (sym);
2659 : 2392 : Indexing_IncludeIndiceIntoIndex (array, reinterpret_cast<void *> (sa));
2660 : 2392 : sa->alias = aliased;
2661 : : }
2662 : :
2663 : :
2664 : : /*
2665 : : lookupAlias -
2666 : : */
2667 : :
2668 : 2730 : static M2SymInit_symAlias lookupAlias (Indexing_Index array, unsigned int sym)
2669 : : {
2670 : 2730 : unsigned int i;
2671 : 2730 : unsigned int n;
2672 : 2730 : M2SymInit_symAlias sa;
2673 : :
2674 : 2730 : i = 1;
2675 : 2730 : n = Indexing_HighIndice (array);
2676 : 8550 : while (i <= n)
2677 : : {
2678 : 4974 : sa = static_cast<M2SymInit_symAlias> (Indexing_GetIndice (array, i));
2679 : 4974 : if (sa->keySym == sym)
2680 : : {
2681 : 1884 : return sa;
2682 : : }
2683 : 3090 : i += 1;
2684 : : }
2685 : : return NULL;
2686 : : /* static analysis guarentees a RETURN statement will be used before here. */
2687 : : __builtin_unreachable ();
2688 : : }
2689 : :
2690 : :
2691 : : /*
2692 : : doGetAlias -
2693 : : */
2694 : :
2695 : 2730 : static unsigned int doGetAlias (Indexing_Index array, unsigned int sym)
2696 : : {
2697 : 2730 : M2SymInit_symAlias sa;
2698 : :
2699 : 0 : sa = lookupAlias (array, sym);
2700 : 2730 : if ((sa != NULL) && (sa->alias != SymbolTable_NulSym))
2701 : : {
2702 : : return sa->alias;
2703 : : }
2704 : : return SymbolTable_NulSym;
2705 : : /* static analysis guarentees a RETURN statement will be used before here. */
2706 : : __builtin_unreachable ();
2707 : : }
2708 : :
2709 : :
2710 : : /*
2711 : : getLAlias - attempts to looks up an alias which is not a temporary variable.
2712 : : */
2713 : :
2714 : 1398 : static unsigned int getLAlias (unsigned int sym)
2715 : : {
2716 : 1398 : unsigned int type;
2717 : 1398 : unsigned int nsym;
2718 : :
2719 : 1398 : nsym = sym;
2720 : 2646 : do {
2721 : 2646 : sym = nsym;
2722 : 2646 : type = SymbolTable_GetSType (sym);
2723 : 2646 : if (((SymbolTable_IsTemporary (sym)) && ((SymbolTable_GetMode (sym)) == SymbolTable_LeftValue)) || ((type != SymbolTable_NulSym) && (SymbolTable_IsReallyPointer (type))))
2724 : : {
2725 : 2010 : nsym = doGetAlias (LArray, sym);
2726 : : }
2727 : : else
2728 : : {
2729 : 636 : return sym;
2730 : : }
2731 : 2010 : } while (! (nsym == SymbolTable_NulSym));
2732 : : return sym;
2733 : : /* static analysis guarentees a RETURN statement will be used before here. */
2734 : : __builtin_unreachable ();
2735 : : }
2736 : :
2737 : :
2738 : : /*
2739 : : SetupLAlias -
2740 : : */
2741 : :
2742 : 983 : static void SetupLAlias (unsigned int des, unsigned int exp)
2743 : : {
2744 : 983 : if ((exp == M2Base_Nil) || ((SymbolTable_IsVar (exp)) && (((SymbolTable_GetMode (des)) == SymbolTable_LeftValue) || (SymbolTable_IsReallyPointer (SymbolTable_GetSType (des))))))
2745 : : {
2746 : 642 : addAlias (LArray, des, exp);
2747 : 642 : DumpAliases ();
2748 : : }
2749 : 983 : }
2750 : :
2751 : :
2752 : : /*
2753 : : SetupIndr -
2754 : : */
2755 : :
2756 : 1750 : static void SetupIndr (unsigned int ptr, unsigned int content)
2757 : : {
2758 : 1750 : addAlias (IndirectArray, ptr, content);
2759 : 0 : }
2760 : :
2761 : :
2762 : : /*
2763 : : getContent - attempts to return the content pointed to by ptr.
2764 : : sym is the original symbol and ptr will be the equivalent lvalue.
2765 : : */
2766 : :
2767 : 744 : static unsigned int getContent (unsigned int ptr, unsigned int sym, unsigned int tok)
2768 : : {
2769 : 744 : if (ptr == M2Base_Nil)
2770 : : {
2771 : 24 : M2MetaError_MetaErrorT1 (tok, (const char *) "attempting to dereference {%1Wad} which will be a {%kNIL} pointer", 65, sym);
2772 : 24 : return SymbolTable_NulSym;
2773 : : }
2774 : : else
2775 : : {
2776 : 720 : return doGetAlias (IndirectArray, ptr);
2777 : : }
2778 : : /* static analysis guarentees a RETURN statement will be used before here. */
2779 : : __builtin_unreachable ();
2780 : : }
2781 : :
2782 : :
2783 : : /*
2784 : : init -
2785 : : */
2786 : :
2787 : 16645 : static void init (void)
2788 : : {
2789 : 16645 : freeList = NULL;
2790 : 16645 : bbFreeList = NULL;
2791 : 0 : Lists_InitList (&errorList);
2792 : 0 : }
2793 : :
2794 : :
2795 : : /*
2796 : : PrintSymInit -
2797 : : */
2798 : :
2799 : 15647370 : extern "C" M2SymInit_InitDesc M2SymInit_InitSymInit (void)
2800 : : {
2801 : 15647370 : M2SymInit_InitDesc id;
2802 : :
2803 : 15647370 : Storage_ALLOCATE ((void **) &id, sizeof (M2SymInit__T1));
2804 : 15647370 : id->sym = SymbolTable_NulSym;
2805 : 15647370 : id->type = SymbolTable_NulSym;
2806 : 15647370 : id->initialized = true;
2807 : 15647370 : id->kind = M2SymInit_scalar;
2808 : 15647370 : return id;
2809 : : /* static analysis guarentees a RETURN statement will be used before here. */
2810 : : __builtin_unreachable ();
2811 : : }
2812 : :
2813 : :
2814 : : /*
2815 : : PrintSymInit -
2816 : : */
2817 : :
2818 : 0 : extern "C" void M2SymInit_KillSymInit (M2SymInit_InitDesc *desc)
2819 : : {
2820 : 0 : switch ((*desc)->kind)
2821 : : {
2822 : 0 : case M2SymInit_record:
2823 : 0 : KillFieldDesc (&(*desc)->rec.fieldDesc);
2824 : 0 : break;
2825 : :
2826 : :
2827 : : default:
2828 : : break;
2829 : : }
2830 : 0 : Storage_DEALLOCATE ((void **) &(*desc), sizeof (M2SymInit__T1));
2831 : 0 : (*desc) = NULL;
2832 : 0 : }
2833 : :
2834 : :
2835 : : /*
2836 : : PrintSymInit -
2837 : : */
2838 : :
2839 : 15223594 : extern "C" void M2SymInit_ConfigSymInit (M2SymInit_InitDesc desc, unsigned int sym)
2840 : : {
2841 : 15223594 : if ((SymbolTable_IsVar (sym)) || (SymbolTable_IsRecordField (sym)))
2842 : : {
2843 : 15223174 : desc->sym = sym;
2844 : 15223174 : desc->type = SymbolTable_GetSType (sym);
2845 : 15223174 : desc->initialized = false;
2846 : 15223174 : if (SymbolTable_IsRecord (desc->type))
2847 : : {
2848 : 70428 : desc->kind = M2SymInit_record;
2849 : 70428 : desc->rec.fieldDesc = Indexing_InitIndex (1);
2850 : 70428 : PopulateFields (desc, desc->type);
2851 : : }
2852 : : else
2853 : : {
2854 : 15152746 : desc->kind = M2SymInit_scalar;
2855 : 15152746 : if (SymbolTable_IsArray (desc->type))
2856 : : {
2857 : 167644 : desc->initialized = true; /* For now we don't attempt to handle array types. */
2858 : : }
2859 : : }
2860 : : }
2861 : 15223594 : }
2862 : :
2863 : :
2864 : : /*
2865 : : PopulateFields -
2866 : : */
2867 : :
2868 : 4857 : extern "C" void M2SymInit_SetInitialized (M2SymInit_InitDesc desc)
2869 : : {
2870 : 4857 : desc->initialized = true;
2871 : 4857 : }
2872 : :
2873 : :
2874 : : /*
2875 : : PopulateFields -
2876 : : */
2877 : :
2878 : 2440 : extern "C" bool M2SymInit_GetInitialized (M2SymInit_InitDesc desc)
2879 : : {
2880 : 2440 : if (! desc->initialized)
2881 : : {
2882 : 307 : if (SymbolTable_IsRecord (desc->type))
2883 : : {
2884 : 108 : TrySetInitialized (desc);
2885 : : }
2886 : : }
2887 : 2440 : if (Debugging)
2888 : : {
2889 : : M2SymInit_PrintSymInit (desc);
2890 : : }
2891 : 2440 : return desc->initialized;
2892 : : /* static analysis guarentees a RETURN statement will be used before here. */
2893 : : __builtin_unreachable ();
2894 : : }
2895 : :
2896 : :
2897 : : /*
2898 : : PopulateFields -
2899 : : */
2900 : :
2901 : 1008 : extern "C" M2SymInit_InitDesc M2SymInit_GetFieldDesc (M2SymInit_InitDesc desc, unsigned int field)
2902 : : {
2903 : 1008 : unsigned int fsym;
2904 : 1008 : unsigned int i;
2905 : :
2906 : 1008 : if (SymbolTable_IsRecord (desc->type))
2907 : : {
2908 : : i = 1;
2909 : 1506 : do {
2910 : 1506 : fsym = SymbolTable_GetNth (desc->type, i);
2911 : 1506 : if (field == fsym)
2912 : : {
2913 : 1008 : return static_cast<M2SymInit_InitDesc> (Indexing_GetIndice (desc->rec.fieldDesc, i));
2914 : : }
2915 : 498 : i += 1;
2916 : 498 : } while (! (fsym == SymbolTable_NulSym));
2917 : : }
2918 : : return NULL;
2919 : : /* static analysis guarentees a RETURN statement will be used before here. */
2920 : : __builtin_unreachable ();
2921 : : }
2922 : :
2923 : :
2924 : : /*
2925 : : PopulateFields -
2926 : : */
2927 : :
2928 : 612 : extern "C" bool M2SymInit_SetFieldInitialized (M2SymInit_InitDesc desc, Lists_List fieldlist)
2929 : : {
2930 : 612 : return SetFieldInitializedNo (desc, fieldlist, 1);
2931 : : /* static analysis guarentees a RETURN statement will be used before here. */
2932 : : __builtin_unreachable ();
2933 : : }
2934 : :
2935 : :
2936 : : /*
2937 : : SetFieldInitializedNo -
2938 : : */
2939 : :
2940 : 204 : extern "C" bool M2SymInit_GetFieldInitialized (M2SymInit_InitDesc desc, Lists_List fieldlist)
2941 : : {
2942 : 204 : return GetFieldInitializedNo (desc, fieldlist, 1);
2943 : : /* static analysis guarentees a RETURN statement will be used before here. */
2944 : : __builtin_unreachable ();
2945 : : }
2946 : :
2947 : :
2948 : : /*
2949 : : ScopeBlockVariableAnalysis - checks to see whether a variable is
2950 : : read before it has been initialized.
2951 : : */
2952 : :
2953 : 326216 : extern "C" void M2SymInit_ScopeBlockVariableAnalysis (unsigned int Scope, unsigned int Start, unsigned int End)
2954 : : {
2955 : 326216 : M2BasicBlock_BasicBlock bb;
2956 : 326216 : Lists_List lst;
2957 : :
2958 : 326216 : if (M2Options_UninitVariableChecking)
2959 : : {
2960 : 2258 : bbArray = Indexing_InitIndex (1);
2961 : 2258 : bb = M2BasicBlock_InitBasicBlocksFromRange (Scope, Start, End);
2962 : 2258 : M2BasicBlock_ForeachBasicBlockDo (bb, (M2BasicBlock_BasicBlockProc) {(M2BasicBlock_BasicBlockProc_t) AppendEntry});
2963 : 2258 : M2BasicBlock_KillBasicBlocks (&bb);
2964 : 2258 : GenerateCFG ();
2965 : 2258 : if (Scope != SymbolTable_NulSym)
2966 : : {
2967 : 2258 : Lists_InitList (&lst);
2968 : 2258 : if (Debugging)
2969 : : {
2970 : : DumpBBArray (Scope);
2971 : : if (M2Options_UninitVariableConditionalChecking)
2972 : : {
2973 : : M2Printf_printf0 ((const char *) "UninitVariableConditionalChecking is TRUE\\n", 43);
2974 : : }
2975 : : }
2976 : 2258 : CreateBBPermultations (Scope, 1, lst);
2977 : 2258 : Lists_KillList (&lst);
2978 : : }
2979 : 2258 : bbArrayKill ();
2980 : : }
2981 : 326216 : }
2982 : :
2983 : :
2984 : : /*
2985 : : PrintSymInit -
2986 : : */
2987 : :
2988 : 0 : extern "C" void M2SymInit_PrintSymInit (M2SymInit_InitDesc desc)
2989 : : {
2990 : 0 : unsigned int i;
2991 : 0 : unsigned int n;
2992 : :
2993 : 0 : libc_printf ((const char *) "sym %d: type %d ", 16, desc->sym, desc->type);
2994 : 0 : if (desc->kind == M2SymInit_scalar)
2995 : : {
2996 : 0 : libc_printf ((const char *) "scalar", 6);
2997 : : }
2998 : : else
2999 : : {
3000 : 0 : libc_printf ((const char *) "record", 6);
3001 : : }
3002 : 0 : if (! desc->initialized)
3003 : : {
3004 : 0 : libc_printf ((const char *) " not", 4);
3005 : : }
3006 : 0 : libc_printf ((const char *) " initialized\\n", 14);
3007 : 0 : if ((desc->type != SymbolTable_NulSym) && (SymbolTable_IsRecord (desc->type)))
3008 : : {
3009 : 0 : i = 1;
3010 : 0 : n = Indexing_HighIndice (desc->rec.fieldDesc);
3011 : 0 : while (i <= n)
3012 : : {
3013 : 0 : M2SymInit_PrintSymInit (reinterpret_cast<M2SymInit_InitDesc> (Indexing_GetIndice (desc->rec.fieldDesc, i)));
3014 : 0 : i += 1;
3015 : : }
3016 : : }
3017 : 0 : }
3018 : :
3019 : 16645 : extern "C" void _M2_M2SymInit_init (__attribute__((unused)) int argc,__attribute__((unused)) char *argv[],__attribute__((unused)) char *envp[])
3020 : : {
3021 : 16645 : init ();
3022 : 16645 : }
3023 : :
3024 : 0 : extern "C" void _M2_M2SymInit_fini (__attribute__((unused)) int argc,__attribute__((unused)) char *argv[],__attribute__((unused)) char *envp[])
3025 : : {
3026 : 0 : }
|