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