2 ** LCLint - annotation-assisted static program checker
3 ** Copyright (C) 1994-2000 University of Virginia,
4 ** Massachusetts Institute of Technology
6 ** This program is free software; you can redistribute it and/or modify it
7 ** under the terms of the GNU General Public License as published by the
8 ** Free Software Foundation; either version 2 of the License, or (at your
9 ** option) any later version.
11 ** This program is distributed in the hope that it will be useful, but
12 ** WITHOUT ANY WARRANTY; without even the implied warranty of
13 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 ** General Public License for more details.
16 ** The GNU General Public License is available from http://www.gnu.org/ or
17 ** the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
18 ** MA 02111-1307, USA.
20 ** For information on lclint: lclint-request@cs.virginia.edu
21 ** To report a bug: lclint-bug@cs.virginia.edu
22 ** For more information: http://lclint.cs.virginia.edu
28 # include "lclintMacros.nf"
31 //#include "environmentTable.h"
34 #include "exprDataQuite.i"
39 /*@constant int ATINVALID; @*/
42 #define ENVIRONMENTSEARCHLIMIT ALIASSEARCHLIMIT
43 #define FLG_GLOBENVIRONMENT FLG_GLOBALIAS
44 #define NOENVIRONMENT NOALIAS
47 environmentTable_canEnvironmentAux (environmentTable p_s, sRef p_sr, int p_lim) /*@*/ ;
49 environmentTable_aliasedByLimit (environmentTable p_s, sRef p_sr, int p_lim) /*@*/ ;
51 environmentTable_aliasedByAux (environmentTable p_s, sRef p_sr, int p_lim) /*@*/ ;
53 static /*@only@*/ sRefSet environmentTable_environmentedByLimit (environmentTable p_s, sRef p_sr, int p_lim) ;
56 environmentTable_new ()
58 return (environmentTable_undefined);
62 environmentTable_insertRelativeRange (/*@returned@*/ environmentTable p_s,
63 /*@exposed@*/ sRef p_sr,
64 int p_min, int p_max);
67 static /*@only@*/ /*@notnull@*/ environmentTable
68 environmentTable_newEmpty (void)
70 environmentTable s = (environmentTable) dmalloc (sizeof (*s));
73 s->nspace = environmentTableBASESIZE;
74 s->keys = (sRef *) dmalloc (sizeof (*s->keys) * environmentTableBASESIZE);
75 s->values = (sRefSet *) dmalloc (sizeof (*s->values) * environmentTableBASESIZE);
76 s->rangeValues = (rangeAt*) dmalloc (sizeof (*s->rangeValues) * environmentTableBASESIZE);
81 environmentTable_grow (/*@notnull@*/ environmentTable s)
84 o_sRefSet *oldvalues = s->values;
85 sRef *oldkeys = s->keys;
86 rangeAt *oldranges = s->rangeValues;
88 s->nspace += environmentTableBASESIZE;
90 s->values = (sRefSet *) dmalloc (sizeof (*s->values)
91 * (s->nelements + s->nspace));
92 s->keys = (sRef *) dmalloc (sizeof (*s->keys) * (s->nelements + environmentTableBASESIZE));
94 s->rangeValues = (rangeAt *) dmalloc (sizeof (*s->rangeValues) * (s->nelements + environmentTableBASESIZE));
97 if (s->keys == (sRef *) 0 || s->values == (sRefSet *)0 || s->rangeValues == (rangeAt*) 0 )
99 llfatalerror (cstring_makeLiteral ("environmentTable_grow: out of memory!"));
102 for (i = 0; i < s->nelements; i++)
104 s->values[i] = oldvalues[i];
105 s->keys[i] = oldkeys[i];
106 s->rangeValues[i] = oldranges[i];
108 // s->rangeValues[i] = dmalloc (sizeof (rangeAt));
116 static int environmentTable_lookupRefs (/*@notnull@*/ environmentTable s, sRef sr)
121 for (i = 0; i < environmentTable_size (s); i++)
123 if (sRef_same (sr, s->keys[i]))
133 environmentTable_postOpvar (/*@returned@*/ environmentTable s, sRef sr)
136 // printf("doing postop\n");
137 if (environmentTable_isUndefined (s) )
139 s = environmentTable_newEmpty();
142 ind = environmentTable_lookupRefs (s, sr);
143 if (ind == ATINVALID)
145 s = environmentTable_addRelativeRange (s, sr);
148 // assume it ++ we'll do -- later
150 s->rangeValues[ind].max++;
151 s->rangeValues[ind].min++;
157 environmentTable_mergeEnvironments (environmentTable s1, environmentTable s2)
161 t1 = environmentTable_copy (s1);
162 if (environmentTable_isUndefined (s2) )
165 for (i = 0; i < s2->nelements; i++)
167 int ind = environmentTable_lookupRefs ( t1, s1->keys[i]);
168 if (s2->rangeValues[i].isRelative)
170 if (ind == ATINVALID)
172 t1 = environmentTable_insertRelativeRange(t1, s2->keys[i], s2->rangeValues[i].max, s2->rangeValues[i].min);
176 t1->rangeValues[ind].min += s2->rangeValues[i].min;
177 t1->rangeValues[ind].max += s2->rangeValues[i].max;
182 /* we want to overwrite old value .. */
183 t1 = environmentTable_addExactValue (t1, s2->keys[i], s2->rangeValues[i].max);
184 /*should fix this to do min and max ... */
191 rangeAt_createRelativeRange ()
194 tmp.isRelative = TRUE;
201 rangeAt rangeAt_createExactRange (int min, int max)
204 tmp.isRelative = FALSE;
212 environmentTable_addRelativeRange (/*@returned@*/ environmentTable s,
213 /*@exposed@*/ sRef sr)
219 if (environmentTable_isUndefined (s))
221 s = environmentTable_newEmpty ();
226 ind = environmentTable_lookupRefs (s, sr);
229 if (ind == ATINVALID)
231 if (s->nspace <= 0) {
232 environmentTable_grow (s);
236 s->keys[s->nelements] = sr;
238 // s->values[s->nelements] = sRefSet_single (al);
242 range = rangeAt_createRelativeRange();
244 s->rangeValues[ind] = range;
249 environmentTable_testInRange ( environmentTable s, /*@exposed@*/ sRef sr, int index)
254 if (environmentTable_isUndefined (s))
256 fprintf(stderr,"environmentTable not defined\n");
260 ind = environmentTable_lookupRefs (s, sr);
261 if (ind == ATINVALID)
263 fprintf (stderr,"range not known\n");
266 if ( &s->rangeValues[ind] )
268 if ( (s->rangeValues[ind].min <= index ) && (s->rangeValues[ind].max >= index) )
270 printf("The value %d is in the range for this variable \n", index);
273 printf("The value %d is NOT in the range for this variable \n", index);
280 environmentTable_addExactValue (/*@returned@*/ environmentTable s,
281 /*@exposed@*/ sRef sr,
288 if (environmentTable_isUndefined (s))
290 s = environmentTable_newEmpty ();
295 ind = environmentTable_lookupRefs (s, sr);
298 if (ind == ATINVALID)
300 if (s->nspace <= 0) {
301 environmentTable_grow (s);
305 s->keys[s->nelements] = sr;
307 // s->values[s->nelements] = sRefSet_single (al);
314 /* s->values[ind] = sRefSet_insert (s->values[ind], al); */
317 if ( (s->rangeValues[ind]) == 0 )
319 s->rangeValues[ind] = dmalloc(sizeof(rangeAt) );
325 s->rangeValues[ind] = range;
330 environmentTable_insertRelativeRange (/*@returned@*/ environmentTable s,
331 /*@exposed@*/ sRef sr,
338 if (environmentTable_isUndefined (s))
340 s = environmentTable_newEmpty ();
345 ind = environmentTable_lookupRefs (s, sr);
348 if (ind == ATINVALID)
350 if (s->nspace <= 0) {
351 environmentTable_grow (s);
355 s->keys[s->nelements] = sr;
357 // s->values[s->nelements] = sRefSet_single (al);
362 range = rangeAt_createRelativeRange();
366 s->rangeValues[ind] = range;
371 environmentTable_addMustAlias (/*@returned@*/ environmentTable s,
372 /*@exposed@*/ sRef sr,
378 llassert (NOENVIRONMENT (sr, al));
380 if (environmentTable_isUndefined (s))
382 s = environmentTable_newEmpty ();
387 ind = environmentTable_lookupRefs (s, sr);
390 ss = environmentTable_canEnvironment (s, al);
393 if (ind == ATINVALID)
395 if (s->nspace <= 0) {
396 environmentTable_grow (s);
400 s->keys[s->nelements] = sr;
401 s->values[s->nelements] = sRefSet_single (al);
407 s->values[ind] = sRefSet_insert (s->values[ind], al);
410 s->values[ind] = sRefSet_unionExcept (s->values[ind], ss, s->keys[ind]);
416 static environmentTable
417 environmentTable_addSet (/*@returned@*/ environmentTable s,
418 /*@exposed@*/ sRef key, /*@only@*/ sRefSet value)
420 if (!sRefSet_isEmpty (value))
422 if (environmentTable_isUndefined (s))
424 s = environmentTable_newEmpty ();
430 environmentTable_grow (s);
435 s->keys[s->nelements] = key;
436 s->values[s->nelements] = value;
441 sRefSet_free (value);
448 ** When environmentes are cleared:
450 ** o remove all entries for sr
451 ** o replace all environmentes for things which environment sr with sr's environmentes
453 ** Clear environmentes for sr; if sr is a direct param reference, clear its environmentes too.
456 static void environmentTable_clearEnvironmentesAux (/*@notnull@*/ environmentTable p_s, sRef p_sr)
459 void environmentTable_clearEnvironmentes (environmentTable s, sRef sr)
461 if (environmentTable_isUndefined (s))
467 sRef rb = sRef_getRootBase (sr);
470 if (!sRef_isCvar (sr) && sRef_isLocalVar (rb))
472 int ind = environmentTable_lookupRefs (s, rb);
474 if (ind != ATINVALID)
476 sRefSet al = s->values[ind];
479 sRefSet_realElements (al, el)
482 if (sRef_isParam (el))
484 if (sRef_sameName (el, rb))
486 sRef fb = sRef_fixBase (sr, el);
488 environmentTable_clearEnvironmentesAux (s, fb);
491 } end_sRefSet_realElements ;
495 environmentTable_clearEnvironmentesAux (s, sr);
500 void environmentTable_clearEnvironmentesAux (/*@notnull@*/ environmentTable s, sRef sr)
504 for (i = 0; i < s->nelements; i++)
506 sRef key = s->keys[i];
508 if (sRef_includedBy (key, sr))
510 sRefSet_clear (s->values[i]);
514 (void) sRefSet_deleteBase (s->values[i], sr);
520 ** returns set of all sRefs that must environment sr (but are different from sr)
523 static /*@only@*/ sRefSet environmentTable_environmentedByAux (environmentTable s, sRef sr, int lim)
525 static bool hadWarning = FALSE;
526 sRefSet res = sRefSet_undefined;
529 llassert (!sRef_isConj (sr));
532 if (environmentTable_isUndefined (s) || lim >= ENVIRONMENTSEARCHLIMIT)
534 if (lim >= ENVIRONMENTSEARCHLIMIT && !hadWarning)
537 (message ("Environment search limit exceeded, checking %q. "
538 "This either means there is a variable with at least "
539 "%d indirections, or there is a bug in LCLint.",
541 ENVIRONMENTSEARCHLIMIT));
546 return sRefSet_undefined;
552 if (sRef_isPointer (sr))
554 abl = environmentTable_environmentedByLimit (s, sRef_getBase (sr), lim);
555 res = sRefSet_addIndirection (abl);
557 else if (sRef_isAddress (sr))
559 abl = environmentTable_environmentedByLimit (s, sRef_getBase (sr), lim);
560 res = sRefSet_removeIndirection (abl);
562 else if (sRef_isField (sr))
564 abl = environmentTable_environmentedByLimit (s, sRef_getBase (sr), lim);
565 res = sRefSet_accessField (abl, sRef_getField (sr));
567 else if (sRef_isArrayFetch (sr))
569 abl = environmentTable_environmentedByLimit (s, sRef_getBase (sr), lim);
571 if (sRef_isIndexKnown (sr))
573 int idx = sRef_getIndex (sr);
575 res = sRefSet_fetchKnown (abl, idx);
579 res = sRefSet_fetchUnknown (abl);
584 abl = sRefSet_undefined;
590 for (i = 0; i < s->nelements; i++)
592 sRef elem = s->keys[i];
594 if (!sRef_same (sr, elem)) /* was sameName */
597 sRefSet_realElements (s->values[i], current)
600 if (sRef_similar (sr, current))
602 res = sRefSet_insert (res, sRef_fixOuterRef (elem));
603 /*@innerbreak@*/ break;
605 } end_sRefSet_realElements;
612 static /*@only@*/ sRefSet environmentTable_environmentedByLimit (environmentTable s, sRef sr, int lim)
617 if (sRef_isConj (sr))
619 res = sRefSet_unionFree (environmentTable_environmentedByLimit (s, sRef_getConjA (sr), lim),
620 environmentTable_environmentedByLimit (s, sRef_getConjB (sr), lim));
624 res = environmentTable_environmentedByAux (s, sr, lim + 1);
630 /*@only@*/ sRefSet environmentTable_environmentedBy (environmentTable s, sRef sr)
632 if (sRef_isConj (sr))
634 return (sRefSet_unionFree (environmentTable_environmentedBy (s, sRef_getConjA (sr)),
635 environmentTable_environmentedBy (s, sRef_getConjB (sr))));
638 return (environmentTable_environmentedByAux (s, sr, 0));
641 /*@only@*/ sRefSet environmentTable_canEnvironment (environmentTable s, sRef sr)
646 if (sRef_isConj (sr))
648 res = sRefSet_unionFree (environmentTable_canEnvironment (s, sRef_getConjA (sr)),
649 environmentTable_canEnvironment (s, sRef_getConjB (sr)));
653 res = environmentTable_canEnvironmentAux (s, sr, 0);
660 ** need to limit the depth of environmenting searches
663 static /*@only@*/ sRefSet environmentTable_canEnvironmentLimit (environmentTable s, sRef sr, int lim)
667 if (sRef_isConj (sr))
669 sRefSet a = environmentTable_canEnvironmentLimit (s, sRef_getConjA (sr), lim);
670 sRefSet b = environmentTable_canEnvironmentLimit (s, sRef_getConjB (sr), lim);
672 res = sRefSet_unionFree (a, b);
676 res = environmentTable_canEnvironmentAux (s, sr, lim + 1);
682 static /*@only@*/ sRefSet
683 environmentTable_canEnvironmentAux (environmentTable s, sRef sr, int lim)
685 static bool hadWarning = FALSE;
686 llassert (!sRef_isConj (sr));
689 if (environmentTable_isUndefined (s) || lim >= ALIASSEARCHLIMIT)
691 if (lim >= ALIASSEARCHLIMIT && !hadWarning)
694 (message ("Environment search limit exceeded, checking %q. "
695 "This either means there is a variable with at least "
696 "%d indirections, or there is a bug in LCLint.",
698 ENVIRONMENTSEARCHLIMIT));
703 return sRefSet_undefined;
707 int ind = environmentTable_lookupRefs (s, sr);
709 if (sRef_isPointer (sr) || sRef_isAddress (sr) || sRef_isField (sr)
710 || sRef_isArrayFetch (sr))
712 sRef base = sRef_getBase (sr);
713 sRefSet tmp = environmentTable_canEnvironmentLimit (s, base, lim);
716 if (sRef_isPointer (sr))
718 ret = sRefSet_addIndirection (tmp);
720 else if (sRef_isAddress (sr))
722 ret = sRefSet_removeIndirection (tmp);
724 else if (sRef_isField (sr))
726 ret = sRefSet_accessField (tmp, sRef_getField (sr));
728 else if (sRef_isArrayFetch (sr))
730 if (sRef_isIndexKnown (sr))
732 ret = sRefSet_fetchKnown (tmp, sRef_getIndex (sr));
736 ret = sRefSet_fetchUnknown (tmp);
744 if (ind != ATINVALID)
746 ret = sRefSet_union (ret, s->values[ind]);
753 if (ind == ATINVALID) return sRefSet_undefined;
755 return sRefSet_newCopy (s->values[ind]);
759 environmentTable environmentTable_copy (environmentTable s)
761 if (environmentTable_isEmpty (s))
763 return environmentTable_undefined;
767 environmentTable t = (environmentTable) dmalloc (sizeof (*s));
770 t->nelements = s->nelements;
772 t->keys = (sRef *) dmalloc (sizeof (*s->keys) * s->nelements);
773 t->values = (sRefSet *) dmalloc (sizeof (*s->values) * t->nelements);
774 t->rangeValues = (rangeAt *) dmalloc (sizeof (*s->rangeValues) * t->nelements);
776 for (i = 0; i < s->nelements; i++)
778 t->keys[i] = s->keys[i];
779 t->values[i] = sRefSet_newCopy (s->values[i]);
780 t->rangeValues[i] = s->rangeValues[i];
788 environmentTable_levelPrune (environmentTable s, int lexlevel)
792 if (environmentTable_isEmpty (s))
799 int backcount = s->nelements - 1;
801 for (i = 0; i <= backcount; i++)
803 sRef key = s->keys[i];
805 if (sRef_lexLevel (key) > lexlevel)
808 for (j = backcount; j > i; j--)
814 if (sRef_lexLevel (s->keys[j]) <= lexlevel)
816 s->keys[i] = s->keys[j];
817 s->values[i] = s->values[j];
818 sRefSet_levelPrune (s->values[i], lexlevel);
819 /*@innerbreak@*/ break;
827 sRefSet_levelPrune (s->values[i], lexlevel);
836 ** like level union, but know that t2 was executed after t1. So if
837 ** t1 has x -> { a, b } and t2 has x -> { a }, then result has x -> { a }.
839 ** NOTE: t2 is "only".
842 environmentTable environmentTable_levelUnionSeq (/*@returned@*/ environmentTable t1,
843 /*@only@*/ environmentTable t2, int level)
845 if (environmentTable_isUndefined (t2))
850 if (environmentTable_isUndefined (t1))
852 t1 = environmentTable_newEmpty ();
856 environmentTable_levelPrune (t1, level);
859 environmentTable_elements (t2, key, value)
861 if (sRef_lexLevel (key) <= level)
863 int ind = environmentTable_lookupRefs (t1, key);
865 sRefSet_levelPrune (value, level);
867 if (ind == ATINVALID)
869 /* okay, t2 is killed */
870 /*@-exposetrans@*/ /*@-dependenttrans@*/
871 t1 = environmentTable_addSet (t1, key, value);
872 /*@=exposetrans@*/ /*@=dependenttrans@*/
876 sRefSet_free (t1->values[ind]);
878 /*@-dependenttrans@*/ /* okay, t2 is killed */
879 t1->values[ind] = value;
880 /*@=dependenttrans@*/
885 /*@-exposetrans@*/ /*@-dependenttrans@*/
886 sRefSet_free (value);
887 /*@=exposetrans@*/ /*@=dependenttrans@*/
890 } end_environmentTable_elements;
900 environmentTable_levelUnion (/*@returned@*/ environmentTable t1, environmentTable t2, int level)
902 if (environmentTable_isUndefined (t1))
904 if (environmentTable_isUndefined (t2))
910 t1 = environmentTable_newEmpty ();
915 environmentTable_levelPrune (t1, level);
918 environmentTable_elements (t2, key, cvalue)
920 sRefSet value = sRefSet_newCopy (cvalue);
922 if (sRef_lexLevel (key) <= level)
924 sRefSet_levelPrune (value, level);
926 if (sRefSet_size (value) > 0)
928 int ind = environmentTable_lookupRefs (t1, key);
930 if (ind == ATINVALID)
932 t1 = environmentTable_addSet (t1, key, value);
936 t1->values[ind] = sRefSet_union (t1->values[ind], value);
937 sRefSet_free (value);
942 sRefSet_free (value);
947 sRefSet_free (value);
949 } end_environmentTable_elements;
954 environmentTable environmentTable_levelUnionNew (environmentTable t1, environmentTable t2, int level)
956 environmentTable ret = environmentTable_levelUnion (environmentTable_copy (t1), t2, level);
962 environmentTable_unparse (environmentTable s)
964 cstring st = cstring_undefined;
966 if (environmentTable_isUndefined (s)) return (cstring_makeLiteral ("<NULL>"));
968 environmentTable_elements (s, key, value)
970 st = message ("%q\t%q -> %q\n", st, sRef_unparse (key),
971 sRefSet_unparse (value));
972 } end_environmentTable_elements;
982 environmentTable_fixSrefs (environmentTable s)
986 if (environmentTable_isUndefined (s)) return;
988 for (i = 0; i < s->nelements; i++)
990 sRef old = s->keys[i];
992 if (sRef_isLocalVar (old))
994 s->keys[i] = uentry_getSref (sRef_getUentry (old));
997 sRefSet_fixSrefs (s->values[i]);
1002 environmentTable_free (/*@only@*/ environmentTable s)
1006 if (environmentTable_isUndefined (s)) return;
1008 for (i = 0; i < s->nelements; i++)
1010 sRefSet_free (s->values[i]);
1019 environmentTable_checkGlobs (environmentTable t)
1021 environmentTable_elements (t, key, value)
1023 sRef root = sRef_getRootBase (key);
1025 if (sRef_isAliasCheckedGlobal (root))
1027 sRefSet_realElements (value, sr)
1029 root = sRef_getRootBase (sr);
1031 if (((sRef_isAliasCheckedGlobal (root)
1032 && !(sRef_similar (root, key)))
1033 || sRef_isAnyParam (root))
1034 && !sRef_isExposed (root))
1036 if (sRef_isAliasCheckedGlobal (key))
1038 if (!(sRef_isShared (key)
1039 && sRef_isShared (root)))
1042 (FLG_GLOBENVIRONMENT,
1044 ("Function returns with %q variable %q environmenting %q %q",
1045 cstring_makeLiteral (sRef_isRealGlobal (key)
1046 ? "global" : "file static"),
1048 cstring_makeLiteral (sRef_isAnyParam (root)
1049 ? "parameter" : "global"),
1056 } end_sRefSet_realElements;
1058 else if (sRef_isAnyParam (key) || sRef_isAnyParam (root))
1060 sRefSet_realElements (value, sr)
1062 root = sRef_getRootBase (sr);
1064 if (sRef_isAliasCheckedGlobal (root)
1065 && !sRef_isExposed (root)
1066 && !sRef_isDead (key)
1067 && !sRef_isShared (root))
1070 (FLG_GLOBENVIRONMENT,
1071 message ("Function returns with parameter %q environmenting %q %q",
1073 cstring_makeLiteral (sRef_isRealGlobal (root)
1074 ? "global" : "file static"),
1078 } end_sRefSet_realElements;
1084 } end_environmentTable_elements;
1088 exprNode exprNode_mergeEnvironments (exprNode ret, exprNode e1, exprNode e2)
1090 if (exprNode_isDefined (e1) && exprNode_isDefined (e2) )
1092 ret->environment = environmentTable_mergeEnvironments (e1->environment, e2->environment);
1095 if (exprNode_isUndefined(e1) && exprNode_isUndefined(e2) )
1097 ret->environment = environmentTable_undefined;
1101 ret->environment = exprNode_isUndefined (e1) ? environmentTable_copy(e2->environment)
1102 : environmentTable_copy (e1->environment);
1110 exprNode_updateForPostOp ( /*@notnull@*/ /*@returned@*/ exprNode e1)
1112 e1->environment = environmentTable_postOpvar (e1->environment, e1->sref);
1116 void updateEnvironmentForPostOp (/*@notnull@*/ exprNode e1)
1119 // printf("doing updateEnvironmentForPostOp\n");
1120 e1 = exprNode_updateForPostOp (e1);
1121 /*do in exprNode update exprnode*/
1122 usymtab_postopVar (s1);
1125 void updateEnvironment (/*@notnull@*/ exprNode e1, /*@notnull@*/ exprNode e2)
1127 // printf("doing updateEnvironment\n");
1128 if (!context_inProtectVars ())
1131 ** depends on types of e1 and e2
1136 ctype t1 = exprNode_getType (e1);
1137 // printf(" for %s = %s \n", sRef_unparse(s1), sRef_unparse(s2) );
1138 // printf("type is %d\n", t1);
1139 if (multiVal_isInt( e2->val) )
1141 int val = multiVal_forceInt(e2->val);
1142 // printf("value is %d \n", val);
1143 usymtab_addExactValue( s1, val);
1144 environmentTable_addExactValue (e1->environment, s1, val);
1147 /* handle pointer sRefs, record fields, arrays, etc... */
1151 // printf("context_inProtectVars\n");