00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 # include "lclintMacros.nf"
00038 # include "basic.h"
00039 # include "exprChecks.h"
00040 # include "aliasChecks.h"
00041 # include "sRefTable.h"
00042 # include "structNames.h"
00043
00044
00045
00046
00047
00048
00049 # define OR(a,b) (a ? (b, TRUE) : b)
00050
00051
00052 # define AND(a,b) (a ? b : (b, FALSE))
00053
00054 static bool sRef_isDerived (sRef p_s) ;
00055
00056 static sRef sRef_fixDirectBase (sRef p_s, sRef p_base)
00057 ;
00058
00059 static bool sRef_isAllocatedStorage (sRef p_s) ;
00060 static void sRef_setNullErrorLoc (sRef p_s, fileloc) ;
00061
00062 static void
00063 sRef_aliasSetComplete (void (p_predf) (sRef, fileloc), sRef p_s, fileloc p_loc)
00064 ;
00065
00066 static int sRef_depth (sRef p_s) ;
00067
00068 static void
00069 sRef_innerAliasSetComplete (void (p_predf) (sRef, fileloc), sRef p_s,
00070 fileloc p_loc)
00071 ;
00072
00073 static void
00074 sRef_innerAliasSetCompleteParam (void (p_predf) (sRef, sRef), sRef p_s, sRef p_t)
00075 ;
00076
00077 static void
00078 sRef_aliasSetCompleteParam (void (p_predf) (sRef, alkind, fileloc), sRef p_s,
00079 alkind p_kind, fileloc p_loc)
00080 ;
00081
00082 static speckind speckind_fromInt (int p_i);
00083 static bool sRef_equivalent (sRef p_s1, sRef p_s2);
00084 static bool sRef_isDeepUnionField (sRef p_s);
00085 static void sRef_addDeriv ( sRef p_s, sRef p_t);
00086 static sRef sRef_makeResultType (ctype p_ct) ;
00087 static bool sRef_checkModify (sRef p_s, sRefSet p_sl) ;
00088
00089 static bool skind_isSimple (skind sk)
00090 {
00091 switch (sk)
00092 {
00093 case SK_PARAM: case SK_CVAR: case SK_CONST:
00094 case SK_OBJECT: case SK_UNKNOWN: case SK_NEW:
00095 return TRUE;
00096 default:
00097 return FALSE;
00098 }
00099 }
00100
00101 static void sinfo_free ( sRef p_s)
00102
00103 ;
00104
00105 static sinfo sinfo_copy ( sRef p_s) ;
00106 static void sRef_setPartsFromUentry (sRef p_s, uentry p_ue)
00107 ;
00108 static bool checkDeadState ( sRef p_el, bool p_tbranch, fileloc p_loc);
00109 static sRef sRef_constructPointerAux ( sRef p_t) ;
00110
00111 static void
00112 sRef_combineExKinds ( sRef p_res, sRef p_other)
00113 ;
00114
00115 static void
00116 sRef_combineAliasKinds ( sRef p_res, sRef p_other,
00117 clause p_cl, fileloc p_loc)
00118 ;
00119
00120 static void
00121 sRef_combineNullState ( sRef p_res, sRef p_other)
00122 ;
00123
00124 static void
00125 sRef_combineDefState ( sRef p_res, sRef p_other)
00126 ;
00127
00128 static void sRef_setStateFromAbstractUentry (sRef p_s, uentry p_ue)
00129 ;
00130
00131 static void
00132 sinfo_update ( sRef p_res,
00133 sRef p_other);
00134 static alinfo alinfo_makeRefLoc ( sRef p_ref, fileloc p_loc);
00135 static void sRef_setDefinedAux (sRef p_s, fileloc p_loc, bool p_clear)
00136 ;
00137 static void sRef_setDefinedNoClear (sRef p_s, fileloc p_loc)
00138 ;
00139 static void sRef_setStateAux (sRef p_s, sstate p_ss, fileloc p_loc)
00140 ;
00141
00142 static sRef
00143 sRef_buildNCField ( sRef p_rec, cstring p_f);
00144
00145 static void
00146 sRef_mergeStateAux ( sRef p_res, sRef p_other,
00147 clause p_cl, bool p_opt, fileloc p_loc,
00148 bool p_doDerivs)
00149 ;
00150
00151 static sinfo sinfo_fullCopy ( sRef p_s);
00152 static bool sRef_doModify (sRef p_s, sRefSet p_sl) ;
00153 static bool sRef_doModifyVal (sRef p_s, sRefSet p_sl) ;
00154 static bool sRef_checkModifyVal (sRef p_s, sRefSet p_sl) ;
00155
00156 static sRefSet
00157 sRef_mergeDerivs ( sRefSet p_res, sRefSet p_other,
00158 bool p_opt, clause p_cl, fileloc p_loc);
00159
00160 static sRefSet
00161 sRef_mergeUnionDerivs ( sRefSet p_res,
00162 sRefSet p_other,
00163 bool p_opt, clause p_cl, fileloc p_loc);
00164
00165 static sRefSet
00166 sRef_mergePdefinedDerivs ( sRefSet p_res, sRefSet p_other, bool p_opt,
00167 clause p_cl, fileloc p_loc);
00168
00169 static cstring sRef_unparseWithArgs (sRef p_s, uentryList p_args);
00170 static cstring sRef_unparseNoArgs (sRef p_s);
00171
00172 static sRef sRef_findDerivedPointer (sRef p_s);
00173 static sRef sRef_findDerivedField ( sRef p_rec, cstring p_f);
00174 static sRef
00175 sRef_getDeriv ( sRef p_set, sRef p_guide);
00176
00177 static bool inFunction = FALSE;
00178 static sRefTable allRefs;
00179
00180
00181
00182 # ifdef DEBUGREFS
00183 static nsrefs = 0;
00184 static totnsrefs = 0;
00185 static maxnsrefs = 0;
00186 static ntotrefers = 0;
00187 static nrefers = 0;
00188 # endif
00189
00190
00191 # define alinfo_undefined ((alinfo) NULL)
00192
00193 static alinfo alinfo_makeLoc (fileloc p_loc);
00194 static alinfo alinfo_copy (alinfo p_a);
00195
00196 static bool protectDerivs = FALSE;
00197
00198 void sRef_protectDerivs (void)
00199 {
00200 llassert (!protectDerivs);
00201 protectDerivs = TRUE;
00202 }
00203
00204 void sRef_clearProtectDerivs (void)
00205 {
00206 llassert (protectDerivs);
00207 protectDerivs = FALSE;
00208 }
00209
00210
00211
00212
00213
00214
00215 bool
00216 sRef_isRecursiveField (sRef s)
00217 {
00218 if (sRef_isField (s))
00219 {
00220 if (sRef_depth (s) > 13)
00221 {
00222 sRef base;
00223 cstring fieldname;
00224
00225 fieldname = sRef_getField (s);
00226 base = sRef_getBase (s);
00227
00228 while (sRef_isValid (base))
00229 {
00230 if (sRef_isField (base))
00231 {
00232 if (cstring_equal (fieldname, sRef_getField (base)))
00233 {
00234 return TRUE;
00235 }
00236 }
00237
00238 base = sRef_getBaseSafe (base);
00239 }
00240 }
00241 }
00242
00243 return FALSE;
00244 }
00245
00246 static void
00247 sRef_addDeriv ( sRef s, sRef t)
00248 {
00249 if (!context_inProtectVars ()
00250 && !protectDerivs
00251 && sRef_isValid (s)
00252 && sRef_isValid (t)
00253 && !sRef_isConst (s))
00254 {
00255 int sd = sRef_depth (s);
00256 int td = sRef_depth (t);
00257
00258 if (sd >= td)
00259 {
00260 return;
00261 }
00262
00263 if (sRef_isGlobal (s))
00264 {
00265 if (context_inFunctionLike ()
00266 && ctype_isKnown (sRef_getType (s))
00267 && !ctype_isFunction (sRef_getType (s)))
00268 {
00269 globSet g = context_getUsedGlobs ();
00270
00271 if (!globSet_member (g, s))
00272 {
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284 }
00285 else
00286 {
00287 s->deriv = sRefSet_insert (s->deriv, t);
00288 }
00289 }
00290 }
00291 else
00292 {
00293 s->deriv = sRefSet_insert (s->deriv, t);
00294 }
00295 }
00296 }
00297
00298 bool
00299 sRef_deepPred (bool (predf) (sRef), sRef s)
00300 {
00301 if (sRef_isValid (s))
00302 {
00303 if ((*predf)(s)) return TRUE;
00304
00305 switch (s->kind)
00306 {
00307 case SK_PTR:
00308 return (sRef_deepPred (predf, s->info->ref));
00309 case SK_ARRAYFETCH:
00310 return (sRef_deepPred (predf, s->info->arrayfetch->arr));
00311 case SK_FIELD:
00312 return (sRef_deepPred (predf, s->info->field->rec));
00313 case SK_CONJ:
00314 return (sRef_deepPred (predf, s->info->conj->a)
00315 || sRef_deepPred (predf, s->info->conj->b));
00316 default:
00317 return FALSE;
00318 }
00319 }
00320
00321 return FALSE;
00322 }
00323
00324 bool sRef_modInFunction (void)
00325 {
00326 return inFunction;
00327 }
00328
00329 void sRef_setStateFromType (sRef s, ctype ct)
00330 {
00331 if (sRef_isValid (s))
00332 {
00333 if (ctype_isUser (ct))
00334 {
00335 sRef_setStateFromUentry
00336 (s, usymtab_getTypeEntry (ctype_typeId (ct)));
00337 }
00338 else if (ctype_isAbstract (ct))
00339 {
00340 sRef_setStateFromAbstractUentry
00341 (s, usymtab_getTypeEntry (ctype_typeId (ct)));
00342 }
00343 else
00344 {
00345 ;
00346 }
00347 }
00348 }
00349
00350 static void sRef_setTypeState (sRef s)
00351 {
00352 if (sRef_isValid (s))
00353 {
00354 sRef_setStateFromType (s, s->type);
00355 }
00356 }
00357
00358 static void alinfo_free ( alinfo a)
00359 {
00360 if (a != NULL)
00361 {
00362 fileloc_free (a->loc);
00363 sfree (a);
00364 }
00365 }
00366
00367 static alinfo alinfo_update ( alinfo old, alinfo newinfo)
00368
00369
00370
00371
00372
00373 {
00374 if (old == NULL)
00375 {
00376 old = alinfo_copy (newinfo);
00377 }
00378 else if (newinfo == NULL)
00379 {
00380 alinfo_free (old);
00381 return NULL;
00382 }
00383 else
00384 {
00385 old->loc = fileloc_update (old->loc, newinfo->loc);
00386 old->ref = newinfo->ref;
00387 old->ue = newinfo->ue;
00388 }
00389
00390 return old;
00391 }
00392
00393 static alinfo alinfo_updateLoc ( alinfo old, fileloc loc)
00394 {
00395 if (old == NULL)
00396 {
00397 old = alinfo_makeLoc (loc);
00398 }
00399 else
00400 {
00401 old->loc = fileloc_update (old->loc, loc);
00402 old->ue = uentry_undefined;
00403 old->ref = sRef_undefined;
00404 }
00405
00406 return old;
00407 }
00408
00409 static alinfo
00410 alinfo_updateRefLoc ( alinfo old, sRef ref, fileloc loc)
00411 {
00412 if (old == NULL)
00413 {
00414 old = alinfo_makeRefLoc (ref, loc);
00415 }
00416 else
00417 {
00418 old->loc = fileloc_update (old->loc, loc);
00419 old->ue = uentry_undefined;
00420 old->ref = ref;
00421 }
00422
00423 return old;
00424 }
00425
00426 static alinfo
00427 alinfo_copy (alinfo a)
00428 {
00429 if (a == NULL)
00430 {
00431 return NULL;
00432 }
00433 else
00434 {
00435 alinfo ret = (alinfo) dmalloc (sizeof (*ret));
00436
00437 ret->loc = fileloc_copy (a->loc);
00438 ret->ue = a->ue;
00439 ret->ref = a->ref;
00440
00441 return ret;
00442 }
00443 }
00444
00445 static bool
00446 sRef_hasAliasInfoLoc (sRef s)
00447 {
00448 return (sRef_isValid (s) && (s->aliasinfo != NULL)
00449 && (fileloc_isDefined (s->aliasinfo->loc)));
00450 }
00451
00452 static bool
00453 sRef_hasStateInfoLoc (sRef s)
00454 {
00455 return (sRef_isValid (s) && (s->definfo != NULL)
00456 && (fileloc_isDefined (s->definfo->loc)));
00457 }
00458
00459 static bool
00460 sRef_hasExpInfoLoc (sRef s)
00461 {
00462 return (sRef_isValid (s)
00463 && (s->expinfo != NULL) && (fileloc_isDefined (s->expinfo->loc)));
00464 }
00465
00466 static bool
00467 sRef_hasNullInfoLoc (sRef s)
00468 {
00469 return (sRef_isValid (s) && (s->nullinfo != NULL)
00470 && (fileloc_isDefined (s->nullinfo->loc)));
00471 }
00472
00473 bool
00474 sRef_hasAliasInfoRef (sRef s)
00475 {
00476 return (sRef_isValid (s) && (s->aliasinfo != NULL)
00477 && (sRef_isValid (s->aliasinfo->ref)));
00478 }
00479
00480 static fileloc
00481 sRef_getAliasInfoLoc ( sRef s)
00482 {
00483 llassert (sRef_isValid (s) && s->aliasinfo != NULL
00484 && (fileloc_isDefined (s->aliasinfo->loc)));
00485 return (s->aliasinfo->loc);
00486 }
00487
00488 static fileloc
00489 sRef_getStateInfoLoc ( sRef s)
00490 {
00491 llassert (sRef_isValid (s) && s->definfo != NULL
00492 && (fileloc_isDefined (s->definfo->loc)));
00493 return (s->definfo->loc);
00494 }
00495
00496 static fileloc
00497 sRef_getExpInfoLoc ( sRef s)
00498 {
00499 llassert (sRef_isValid (s) && s->expinfo != NULL
00500 && (fileloc_isDefined (s->expinfo->loc)));
00501 return (s->expinfo->loc);
00502 }
00503
00504 static fileloc
00505 sRef_getNullInfoLoc ( sRef s)
00506 {
00507 llassert (sRef_isValid (s) && s->nullinfo != NULL
00508 && (fileloc_isDefined (s->nullinfo->loc)));
00509 return (s->nullinfo->loc);
00510 }
00511
00512 sRef
00513 sRef_getAliasInfoRef ( sRef s)
00514 {
00515 llassert (sRef_isValid (s) && s->aliasinfo != NULL);
00516 return (s->aliasinfo->ref);
00517 }
00518
00519 static alinfo
00520 alinfo_makeLoc (fileloc loc)
00521 {
00522 alinfo ret = (alinfo) dmalloc (sizeof (*ret));
00523
00524 ret->loc = fileloc_copy (loc);
00525 ret->ue = uentry_undefined;
00526 ret->ref = sRef_undefined;
00527
00528 return ret;
00529 }
00530
00531 static alinfo
00532 alinfo_makeRefLoc ( sRef ref, fileloc loc)
00533 {
00534 alinfo ret = (alinfo) dmalloc (sizeof (*ret));
00535
00536 ret->loc = fileloc_copy (loc);
00537 ret->ref = ref;
00538 ret->ue = uentry_undefined;
00539
00540 return ret;
00541 }
00542
00543
00544
00545
00546
00547
00548
00549 void sRef_setGlobalScope ()
00550 {
00551 llassert (inFunction);
00552 inFunction = FALSE;
00553 }
00554
00555 void sRef_clearGlobalScope ()
00556 {
00557 llassert (!inFunction);
00558 inFunction = TRUE;
00559 }
00560
00561 static bool oldInFunction = FALSE;
00562
00563 void sRef_setGlobalScopeSafe ()
00564 {
00565 oldInFunction = inFunction;
00566 inFunction = FALSE;
00567 }
00568
00569 void sRef_clearGlobalScopeSafe ()
00570 {
00571 inFunction = oldInFunction;
00572 }
00573
00574 void sRef_enterFunctionScope ()
00575 {
00576 llassert (!inFunction);
00577 llassert (sRefTable_isEmpty (allRefs));
00578 inFunction = TRUE;
00579 }
00580
00581 void sRef_exitFunctionScope ()
00582 {
00583
00584 if (inFunction)
00585 {
00586 sRefTable_clear (allRefs);
00587 inFunction = FALSE;
00588 }
00589 else
00590 {
00591 llbuglit ("sRef_exitFunctionScope: not in function");
00592 }
00593 }
00594
00595 void sRef_destroyMod ()
00596 {
00597 # ifdef DEBUGREFS
00598 llmsg (message ("Live: %d / %d ", nsrefs, totnsrefs));
00599 # endif
00600
00601 sRefTable_free (allRefs);
00602 }
00603
00604
00605
00606
00607
00608
00609 static sRef
00610 sRef_alloc (void)
00611 {
00612 sRef s = (sRef) dmalloc (sizeof (*s));
00613
00614 if (inFunction)
00615 {
00616 allRefs = sRefTable_add (allRefs, s);
00617
00618 }
00619
00620
00621 # ifdef DEBUGREFS
00622 if (nsrefs >= maxnsrefs)
00623 {
00624 maxnsrefs = nsrefs;
00625 }
00626
00627 totnsrefs++;
00628 nsrefs++;
00629 # endif
00630
00631
00632 return s;
00633
00634 }
00635
00636 static sRef
00637 sRef_new (void)
00638
00639
00640
00641 {
00642 sRef s = sRef_alloc ();
00643
00644 s->kind = SK_UNKNOWN;
00645 s->safe = TRUE;
00646 s->modified = FALSE;
00647 s->type = ctype_unknown;
00648 s->defstate = SS_UNKNOWN;
00649
00650 s->aliaskind = AK_UNKNOWN;
00651 s->oaliaskind = AK_UNKNOWN;
00652
00653 s->nullstate = NS_UNKNOWN;
00654
00655 s->expkind = XO_UNKNOWN;
00656 s->oexpkind = XO_UNKNOWN;
00657
00658 s->aliasinfo = alinfo_undefined;
00659 s->definfo = alinfo_undefined;
00660 s->nullinfo = alinfo_undefined;
00661 s->expinfo = alinfo_undefined;
00662
00663 s->info = NULL;
00664 s->deriv = sRefSet_undefined;
00665
00666 return s;
00667 }
00668
00669 static sRef
00670 sRef_fixConj ( sRef s)
00671 {
00672 if (sRef_isConj (s))
00673 {
00674 do {
00675 s = sRef_getConjA (s);
00676 } while (sRef_isConj (s));
00677
00678 llassert (sRef_isValid (s));
00679 return s;
00680 }
00681 else
00682 {
00683 return s;
00684 }
00685 }
00686
00687 static bool
00688 sRef_isExternallyVisibleAux (sRef s)
00689 {
00690 bool res = FALSE;
00691 sRef base = sRef_getRootBase (s);
00692
00693 if (sRef_isValid (base))
00694 {
00695 res = sRef_isParam (base) || sRef_isGlobal (base) || sRef_isExternal (base);
00696 }
00697
00698 return res;
00699 }
00700
00701 bool
00702 sRef_isExternallyVisible (sRef s)
00703 {
00704 return (sRef_aliasCheckSimplePred (sRef_isExternallyVisibleAux, s));
00705 }
00706
00707 uentry
00708 sRef_getBaseUentry (sRef s)
00709 {
00710 sRef base = sRef_getRootBase (s);
00711 uentry res = uentry_undefined;
00712
00713 if (sRef_isValid (base))
00714 {
00715 switch (base->kind)
00716 {
00717 case SK_PARAM:
00718 res = usymtab_getRefQuiet (paramsScope, base->info->paramno);
00719 break;
00720
00721 case SK_CVAR:
00722 res = usymtab_getRefQuiet (base->info->cvar->lexlevel,
00723 base->info->cvar->index);
00724 break;
00725
00726 default:
00727 break;
00728 }
00729 }
00730
00731 return res;
00732 }
00733
00734
00735
00736
00737
00738
00739 sRef
00740 sRef_updateSref (sRef s)
00741 {
00742 sRef inner;
00743 sRef ret;
00744 sRef res;
00745
00746 if (!sRef_isValid (s)) return sRef_undefined;
00747
00748
00749 switch (s->kind)
00750 {
00751 case SK_UNKNOWN:
00752 case SK_OBJECT:
00753 case SK_NEW:
00754 case SK_TYPE:
00755 case SK_EXTERNAL:
00756 case SK_DERIVED:
00757 case SK_UNCONSTRAINED:
00758 case SK_CONST:
00759 case SK_SPECIAL:
00760 case SK_RESULT:
00761 return s;
00762 case SK_PARAM:
00763 case SK_CVAR:
00764 {
00765 uentry ue = sRef_getUentry (s);
00766
00767
00768 ue = usymtab_lookupSafe (uentry_rawName (ue));
00769
00770 if (uentry_isUndefined (ue))
00771 {
00772 return s;
00773 }
00774 else
00775 {
00776 return (uentry_getSref (ue));
00777 }
00778 }
00779 case SK_ARRAYFETCH:
00780
00781 inner = s->info->arrayfetch->arr;
00782 ret = sRef_updateSref (inner);
00783
00784 if (ret == inner)
00785 {
00786 res = s;
00787 }
00788 else
00789 {
00790 res = sRef_makeArrayFetch (ret);
00791 }
00792
00793 return res;
00794
00795 case SK_FIELD:
00796 inner = s->info->field->rec;
00797 ret = sRef_updateSref (inner);
00798
00799 if (ret == inner)
00800 {
00801 res = s;
00802 }
00803 else
00804 {
00805 res = (sRef_makeField (ret, s->info->field->field));
00806 }
00807
00808 return (res);
00809 case SK_PTR:
00810 inner = s->info->ref;
00811 ret = sRef_updateSref (inner);
00812 if (ret == inner)
00813 {
00814 res = s;
00815 }
00816 else
00817 {
00818 res = sRef_makePointer (ret);
00819 }
00820
00821 return (res);
00822
00823 case SK_ADR:
00824 inner = s->info->ref;
00825 ret = sRef_updateSref (inner);
00826
00827 if (ret == inner)
00828 {
00829 res = s;
00830 }
00831 else
00832 {
00833 res = sRef_makeAddress (ret);
00834 }
00835
00836 return (res);
00837
00838 case SK_CONJ:
00839 {
00840 sRef innera = s->info->conj->a;
00841 sRef innerb = s->info->conj->b;
00842 sRef reta = sRef_updateSref (innera);
00843 sRef retb = sRef_updateSref (innerb);
00844
00845 if (innera == reta && innerb == retb)
00846 {
00847 res = s;
00848 }
00849 else
00850 {
00851 res = sRef_makeConj (reta, retb);
00852 }
00853
00854 return (res);
00855 }
00856 }
00857
00858 BADEXIT;
00859 }
00860
00861 uentry
00862 sRef_getUentry (sRef s)
00863 {
00864 llassert (sRef_isValid (s));
00865
00866 switch (s->kind)
00867 {
00868 case SK_PARAM:
00869 return (usymtab_getRefQuiet (paramsScope, s->info->paramno));
00870 case SK_CVAR:
00871 return (usymtab_getRefQuiet (s->info->cvar->lexlevel, s->info->cvar->index));
00872 case SK_CONJ:
00873 {
00874 if (sRef_isCvar (s->info->conj->a) || sRef_isParam (s->info->conj->a)
00875 || sRef_isConj (s->info->conj->a))
00876 {
00877 return sRef_getUentry (s->info->conj->a);
00878 }
00879 else
00880 {
00881 return sRef_getUentry (s->info->conj->b);
00882 }
00883 }
00884 case SK_UNKNOWN:
00885 case SK_SPECIAL:
00886 return uentry_undefined;
00887 BADDEFAULT;
00888 }
00889 }
00890
00891 int
00892 sRef_getParam (sRef s)
00893 {
00894 llassert (sRef_isValid (s));
00895 llassert (s->kind == SK_PARAM);
00896
00897 return s->info->paramno;
00898 }
00899
00900 bool
00901 sRef_isModified (sRef s)
00902 {
00903 return (!sRef_isValid (s) || s->modified);
00904 }
00905
00906 void sRef_setModified (sRef s)
00907 {
00908 if (sRef_isValid (s))
00909 {
00910 s->modified = TRUE;
00911
00912
00913 if (sRef_isRefsField (s))
00914 {
00915 sRef base = sRef_getBase (s);
00916
00917
00918 llassert (s->kind == SK_FIELD);
00919
00920
00921 if (sRef_isPointer (base))
00922 {
00923 base = sRef_getBase (base);
00924 }
00925
00926 if (sRef_isRefCounted (base))
00927 {
00928 base->aliaskind = AK_NEWREF;
00929 }
00930 }
00931
00932 }
00933 }
00934
00935
00936
00937
00938
00939
00940 bool
00941 sRef_canModifyVal (sRef s, sRefSet sl)
00942 {
00943 if (context_getFlag (FLG_MUSTMOD))
00944 {
00945 return (sRef_doModifyVal (s, sl));
00946 }
00947 else
00948 {
00949 return (sRef_checkModifyVal (s, sl));
00950 }
00951 }
00952
00953 bool
00954 sRef_canModify (sRef s, sRefSet sl)
00955 {
00956
00957 if (context_getFlag (FLG_MUSTMOD))
00958 {
00959 return (sRef_doModify (s, sl));
00960 }
00961 else
00962 {
00963 return (sRef_checkModify (s, sl));
00964 }
00965 }
00966
00967
00968
00969
00970
00971 static
00972 bool sRef_checkModifyVal (sRef s, sRefSet sl)
00973 {
00974 if (sRef_isInvalid (s))
00975 {
00976 return TRUE;
00977 }
00978
00979 switch (s->kind)
00980 {
00981 case SK_UNCONSTRAINED:
00982 case SK_CONST:
00983 return TRUE;
00984 case SK_CVAR:
00985 if (sRef_isGlobal (s))
00986 {
00987 if (context_checkGlobMod (s))
00988 {
00989 return (sRefSet_member (sl, s));
00990 }
00991
00992 return TRUE;
00993 }
00994 else
00995 {
00996 return TRUE;
00997 }
00998 case SK_PARAM:
00999 return (sRefSet_member (sl, s)
01000 || alkind_isOnly (sRef_getOrigAliasKind (s)));
01001 case SK_ARRAYFETCH:
01002
01003 return (sRefSet_member (sl, s) ||
01004 sRef_checkModifyVal (s->info->arrayfetch->arr, sl));
01005 case SK_FIELD:
01006 return (sRefSet_member (sl, s) || sRef_checkModifyVal (s->info->field->rec, sl));
01007 case SK_PTR:
01008 return (sRefSet_member (sl, s) || sRef_checkModifyVal (s->info->ref, sl));
01009 case SK_ADR:
01010 return (sRefSet_member (sl, s) || sRef_checkModifyVal (s->info->ref, sl));
01011 case SK_CONJ:
01012 return ((sRef_checkModifyVal (s->info->conj->a, sl)) &&
01013 (sRef_checkModifyVal (s->info->conj->b, sl)));
01014 case SK_UNKNOWN:
01015 case SK_OBJECT:
01016 case SK_NEW:
01017 case SK_TYPE:
01018 case SK_DERIVED:
01019 return TRUE;
01020 case SK_EXTERNAL:
01021 return TRUE;
01022 case SK_SPECIAL:
01023 {
01024 switch (s->info->spec)
01025 {
01026 case SR_NOTHING: return TRUE;
01027 case SR_INTERNAL:
01028 if (context_getFlag (FLG_INTERNALGLOBS))
01029 {
01030 return (sRefSet_member (sl, s));
01031 }
01032 else
01033 {
01034 return TRUE;
01035 }
01036 case SR_SPECSTATE: return TRUE;
01037 case SR_SYSTEM: return (sRefSet_member (sl, s));
01038 }
01039 }
01040 case SK_RESULT: BADBRANCH;
01041 }
01042 BADEXIT;
01043 }
01044
01045
01046
01047
01048
01049
01050
01051 static bool sRef_checkModify (sRef s, sRefSet sl)
01052 {
01053 llassert (sRef_isValid (s));
01054
01055 switch (s->kind)
01056 {
01057 case SK_UNCONSTRAINED:
01058 case SK_CONST:
01059 return TRUE;
01060 case SK_CVAR:
01061 if (sRef_isGlobal (s))
01062 {
01063 if (context_checkGlobMod (s))
01064 {
01065 return (sRefSet_member (sl, s));
01066 }
01067
01068 return TRUE;
01069 }
01070 else
01071 {
01072 return TRUE;
01073 }
01074 case SK_PARAM:
01075 return TRUE;
01076 case SK_ARRAYFETCH:
01077 return (sRefSet_member (sl, s) ||
01078 sRef_checkModifyVal (s->info->arrayfetch->arr, sl));
01079 case SK_FIELD:
01080 {
01081 sRef sr = s->info->field->rec;
01082
01083 if (sr->kind == SK_PARAM)
01084 return TRUE;
01085
01086 return (sRefSet_member (sl, s) || sRef_checkModifyVal (s->info->field->rec, sl));
01087 }
01088 case SK_PTR:
01089 {
01090 bool sm;
01091
01092 sm = sRefSet_member (sl, s);
01093
01094 if (sm)
01095 return TRUE;
01096 else
01097 return (sRef_checkModifyVal (s->info->ref, sl));
01098 }
01099 case SK_ADR:
01100 return (sRefSet_member (sl, s) || sRef_checkModifyVal (s->info->ref, sl));
01101 case SK_CONJ:
01102 return ((sRef_checkModify (s->info->conj->a, sl)) &&
01103 (sRef_checkModify (s->info->conj->b, sl)));
01104 case SK_NEW:
01105 case SK_OBJECT:
01106 case SK_UNKNOWN:
01107 case SK_TYPE:
01108 case SK_DERIVED:
01109 case SK_EXTERNAL:
01110 return TRUE;
01111 case SK_SPECIAL:
01112 {
01113 switch (s->info->spec)
01114 {
01115 case SR_NOTHING: return TRUE;
01116 case SR_INTERNAL:
01117 if (context_getFlag (FLG_INTERNALGLOBS))
01118 {
01119 return (sRefSet_member (sl, s));
01120 }
01121 else
01122 {
01123 return TRUE;
01124 }
01125 case SR_SPECSTATE: return TRUE;
01126 case SR_SYSTEM: return (sRefSet_member (sl, s));
01127 }
01128 }
01129 case SK_RESULT: BADBRANCH;
01130 }
01131 BADEXIT;
01132 }
01133
01134 cstring sRef_stateVerb (sRef s)
01135 {
01136 if (sRef_isDead (s))
01137 {
01138 return cstring_makeLiteralTemp ("released");
01139 }
01140 else if (sRef_isKept (s))
01141 {
01142 return cstring_makeLiteralTemp ("kept");
01143 }
01144 else if (sRef_isDependent (s))
01145 {
01146 return cstring_makeLiteralTemp ("dependent");
01147 }
01148 else
01149 {
01150 BADEXIT;
01151 }
01152 }
01153
01154 cstring sRef_stateAltVerb (sRef s)
01155 {
01156 if (sRef_isDead (s))
01157 {
01158 return cstring_makeLiteralTemp ("live");
01159 }
01160 else if (sRef_isKept (s))
01161 {
01162 return cstring_makeLiteralTemp ("not kept");
01163 }
01164 else if (sRef_isDependent (s))
01165 {
01166 return cstring_makeLiteralTemp ("independent");
01167 }
01168 else
01169 {
01170 BADEXIT;
01171 }
01172 }
01173
01174 static
01175 bool sRef_doModifyVal (sRef s, sRefSet sl)
01176 {
01177 llassert (sRef_isValid (s));
01178
01179
01180 switch (s->kind)
01181 {
01182 case SK_UNCONSTRAINED:
01183 case SK_CONST:
01184 return TRUE;
01185 case SK_CVAR:
01186 if (sRef_isGlobal (s))
01187 {
01188
01189 if (context_checkGlobMod (s))
01190 {
01191 return (sRefSet_modifyMember (sl, s));
01192 }
01193 else
01194 {
01195 (void) sRefSet_modifyMember (sl, s);
01196 }
01197
01198 return TRUE;
01199 }
01200 else
01201 {
01202 return TRUE;
01203 }
01204 case SK_PARAM:
01205 return (sRefSet_modifyMember (sl, s)
01206 || alkind_isOnly (sRef_getOrigAliasKind (s)));
01207 case SK_ARRAYFETCH:
01208
01209
01210 return (OR (sRefSet_modifyMember (sl, s),
01211 sRef_doModifyVal (s->info->arrayfetch->arr, sl)));
01212 case SK_FIELD:
01213 return (OR (sRefSet_modifyMember (sl, s),
01214 sRef_doModifyVal (s->info->field->rec, sl)));
01215 case SK_PTR:
01216 return (OR (sRefSet_modifyMember (sl, s),
01217 sRef_doModifyVal (s->info->ref, sl)));
01218 case SK_ADR:
01219 return (OR (sRefSet_modifyMember (sl, s),
01220 sRef_doModifyVal (s->info->ref, sl)));
01221 case SK_CONJ:
01222 return (AND (sRef_doModifyVal (s->info->conj->a, sl) ,
01223 sRef_doModifyVal (s->info->conj->b, sl)));
01224 case SK_OBJECT:
01225 case SK_DERIVED:
01226 case SK_EXTERNAL:
01227 case SK_UNKNOWN:
01228 case SK_NEW:
01229 case SK_TYPE:
01230 return TRUE;
01231 case SK_SPECIAL:
01232 {
01233 switch (s->info->spec)
01234 {
01235 case SR_NOTHING: return TRUE;
01236 case SR_INTERNAL:
01237 if (context_getFlag (FLG_INTERNALGLOBS))
01238 {
01239 return (sRefSet_modifyMember (sl, s));
01240 }
01241 else
01242 {
01243 (void) sRefSet_modifyMember (sl, s);
01244 return TRUE;
01245 }
01246 case SR_SPECSTATE:
01247 {
01248 return TRUE;
01249 }
01250 case SR_SYSTEM:
01251 {
01252 return (sRefSet_modifyMember (sl, s));
01253 }
01254 }
01255 }
01256 case SK_RESULT: BADBRANCH;
01257 }
01258 BADEXIT;
01259 }
01260
01261
01262
01263
01264
01265
01266
01267 static
01268 bool sRef_doModify (sRef s, sRefSet sl)
01269 {
01270 llassert (sRef_isValid (s));
01271
01272 switch (s->kind)
01273 {
01274 case SK_UNCONSTRAINED:
01275 case SK_CONST:
01276 return TRUE;
01277 case SK_CVAR:
01278 if (sRef_isGlobal (s))
01279 {
01280 if (context_checkGlobMod (s))
01281 {
01282 return (sRefSet_modifyMember (sl, s));
01283 }
01284 else
01285 {
01286 (void) sRefSet_modifyMember (sl, s);
01287 }
01288
01289 return TRUE;
01290 }
01291 else
01292 {
01293 return TRUE;
01294 }
01295 case SK_PARAM:
01296 return TRUE;
01297 case SK_ARRAYFETCH:
01298 return (OR (sRefSet_modifyMember (sl, s),
01299 sRef_doModifyVal (s->info->arrayfetch->arr, sl)));
01300 case SK_FIELD:
01301 {
01302 sRef sr = s->info->field->rec;
01303
01304 if (sr->kind == SK_PARAM)
01305 {
01306 return TRUE;
01307 }
01308
01309 return (OR (sRefSet_modifyMember (sl, s),
01310 sRef_doModifyVal (s->info->field->rec, sl)));
01311 }
01312 case SK_PTR:
01313 {
01314 return (OR (sRefSet_modifyMember (sl, s),
01315 sRef_doModifyVal (s->info->ref, sl)));
01316 }
01317 case SK_ADR:
01318 return (OR (sRefSet_modifyMember (sl, s),
01319 sRef_doModifyVal (s->info->ref, sl)));
01320 case SK_CONJ:
01321 return (AND (sRef_doModify (s->info->conj->a, sl),
01322 (sRef_doModify (s->info->conj->b, sl))));
01323 case SK_UNKNOWN:
01324 case SK_NEW:
01325 case SK_TYPE:
01326 return TRUE;
01327 case SK_OBJECT:
01328 case SK_DERIVED:
01329 case SK_EXTERNAL:
01330 return TRUE;
01331 case SK_SPECIAL:
01332 {
01333 switch (s->info->spec)
01334 {
01335 case SR_NOTHING: return TRUE;
01336 case SR_INTERNAL: return TRUE;
01337 case SR_SPECSTATE: return TRUE;
01338 case SR_SYSTEM: return (sRefSet_modifyMember (sl, s));
01339 }
01340 }
01341 case SK_RESULT: BADBRANCH;
01342 }
01343 BADEXIT;
01344 }
01345
01346 static sRef
01347 sRef_leastCommon ( sRef s1, sRef s2)
01348 {
01349 llassert (sRef_similar (s1, s2));
01350
01351 if (!sRef_isValid (s1)) return s1;
01352 if (!sRef_isValid (s2)) return s1;
01353
01354 sRef_combineDefState (s1, s2);
01355 sRef_combineNullState (s1, s2);
01356 sRef_combineExKinds (s1, s2);
01357
01358 if (s1->aliaskind != s2->aliaskind)
01359 {
01360 if (s1->aliaskind == AK_UNKNOWN)
01361 {
01362 s1->aliaskind = s2->aliaskind;
01363 }
01364 else if (s2->aliaskind == AK_UNKNOWN)
01365 {
01366 ;
01367 }
01368 else
01369 {
01370 s1->aliaskind = AK_ERROR;
01371 }
01372 }
01373
01374 return s1;
01375 }
01376
01377 int sRef_compare (sRef s1, sRef s2)
01378 {
01379 if (s1 == s2) return 0;
01380
01381 if (sRef_isInvalid (s1)) return -1;
01382 if (sRef_isInvalid (s2)) return 1;
01383
01384 INTCOMPARERETURN (s1->kind, s2->kind);
01385 INTCOMPARERETURN (s1->defstate, s2->defstate);
01386 INTCOMPARERETURN (s1->aliaskind, s2->aliaskind);
01387
01388 COMPARERETURN (nstate_compare (s1->nullstate, s2->nullstate));
01389
01390 switch (s1->kind)
01391 {
01392 case SK_PARAM:
01393 return (int_compare (s1->info->paramno, s2->info->paramno));
01394 case SK_ARRAYFETCH:
01395 {
01396 COMPARERETURN (sRef_compare (s1->info->arrayfetch->arr,
01397 s2->info->arrayfetch->arr));
01398
01399 if (s1->info->arrayfetch->indknown && s2->info->arrayfetch->indknown)
01400 {
01401 return (int_compare (s1->info->arrayfetch->ind,
01402 s2->info->arrayfetch->ind));
01403 }
01404 if (!s1->info->arrayfetch->indknown && !s2->info->arrayfetch->indknown)
01405 return 0;
01406
01407 return 1;
01408 }
01409 case SK_FIELD:
01410 {
01411 COMPARERETURN (sRef_compare (s1->info->field->rec, s2->info->field->rec));
01412
01413 if (cstring_equal (s1->info->field->field, s2->info->field->field))
01414 return 0;
01415
01416 return 1;
01417 }
01418 case SK_PTR:
01419 case SK_ADR:
01420 return (sRef_compare (s1->info->ref, s2->info->ref));
01421 case SK_CONJ:
01422 COMPARERETURN (sRef_compare (s1->info->conj->a, s2->info->conj->a));
01423 return (sRef_compare (s1->info->conj->b, s2->info->conj->b));
01424 case SK_UNCONSTRAINED:
01425 return (cstring_compare (s1->info->fname, s2->info->fname));
01426 case SK_NEW:
01427 case SK_CVAR:
01428 case SK_UNKNOWN:
01429 case SK_OBJECT:
01430 case SK_TYPE:
01431 case SK_DERIVED:
01432 case SK_EXTERNAL:
01433 case SK_CONST:
01434 case SK_RESULT:
01435 return 0;
01436 case SK_SPECIAL:
01437 return (generic_compare (s1->info->spec, s2->info->spec));
01438 }
01439 BADEXIT;
01440 }
01441
01442 static bool cref_equal (cref c1, cref c2)
01443 {
01444 return ((c1->lexlevel == c2->lexlevel) &&
01445 (usymId_equal (c1->index, c2->index)));
01446 }
01447
01448
01449
01450
01451
01452
01453
01454
01455
01456
01457
01458 static bool
01459 sRef_uniqueReference (sRef s)
01460 {
01461 return (sRef_isFresh (s) || sRef_isUnique (s)
01462 || sRef_isOnly (s) || sRef_isStack (s)
01463 || sRef_isAddress (s));
01464 }
01465
01466 static bool
01467 sRef_similarRelaxedAux (sRef s1, sRef s2)
01468 {
01469 if (s1 == s2)
01470 {
01471 if (sRef_isUnknownArrayFetch (s1))
01472 {
01473 return FALSE;
01474 }
01475 else
01476 {
01477 return TRUE;
01478 }
01479 }
01480
01481 if (sRef_isInvalid (s1) || sRef_isInvalid (s2)) return FALSE;
01482
01483 if (sRef_isConj (s2))
01484 return (sRef_similarRelaxedAux (s1, sRef_getConjA (s2)) ||
01485 sRef_similarRelaxedAux (s1, sRef_getConjB (s2)));
01486
01487 switch (s1->kind)
01488 {
01489 case SK_CVAR:
01490 return ((s2->kind == SK_CVAR)
01491 && (cref_equal (s1->info->cvar, s2->info->cvar)));
01492 case SK_PARAM:
01493 return ((s2->kind == SK_PARAM)
01494 && (s1->info->paramno == s2->info->paramno));
01495 case SK_ARRAYFETCH:
01496 if (s2->kind == SK_ARRAYFETCH)
01497 {
01498 if (sRef_similarRelaxedAux (s1->info->arrayfetch->arr,
01499 s2->info->arrayfetch->arr))
01500 {
01501 if (s1->info->arrayfetch->indknown)
01502 {
01503 if (s2->info->arrayfetch->indknown)
01504 {
01505 return (s1->info->arrayfetch->ind == s2->info->arrayfetch->ind);
01506 }
01507 else
01508 {
01509 return FALSE;
01510 }
01511 }
01512 else
01513 {
01514 return FALSE;
01515 }
01516 }
01517 }
01518 return FALSE;
01519 case SK_FIELD:
01520 return ((s2->kind == SK_FIELD
01521 && (sRef_similarRelaxedAux (s1->info->field->rec,
01522 s2->info->field->rec)
01523 && cstring_equal (s1->info->field->field,
01524 s2->info->field->field))));
01525 case SK_PTR:
01526 return ((s2->kind == SK_PTR)
01527 && sRef_similarRelaxedAux (s1->info->ref, s2->info->ref));
01528 case SK_ADR:
01529 return ((s2->kind == SK_ADR)
01530 && sRef_similarRelaxedAux (s1->info->ref, s2->info->ref));
01531 case SK_CONJ:
01532 return ((sRef_similarRelaxedAux (s1->info->conj->a, s2) ||
01533 (sRef_similarRelaxedAux (s1->info->conj->b, s2))));
01534 case SK_SPECIAL:
01535 return (s1->info->spec == s2->info->spec);
01536 case SK_UNCONSTRAINED:
01537 return (cstring_equal (s1->info->fname, s2->info->fname));
01538 case SK_DERIVED:
01539 case SK_CONST:
01540 case SK_TYPE:
01541 case SK_NEW:
01542 case SK_UNKNOWN:
01543 case SK_OBJECT:
01544 case SK_EXTERNAL:
01545 case SK_RESULT:
01546 return FALSE;
01547 }
01548 BADEXIT;
01549 }
01550
01551 bool
01552 sRef_similarRelaxed (sRef s1, sRef s2)
01553 {
01554 bool us1, us2;
01555
01556 if (s1 == s2)
01557 {
01558 if (sRef_isThroughArrayFetch (s1))
01559 {
01560 return FALSE;
01561 }
01562 else
01563 {
01564 return TRUE;
01565 }
01566 }
01567
01568 if (sRef_isInvalid (s1) || sRef_isInvalid (s2)) return FALSE;
01569
01570 us1 = sRef_uniqueReference (s1);
01571 us2 = sRef_uniqueReference (s2);
01572
01573 if ((s1->kind == SK_EXTERNAL && (s2->kind != SK_EXTERNAL && !us2))
01574 || (s2->kind == SK_EXTERNAL && (s1->kind != SK_EXTERNAL && !us1)))
01575 {
01576
01577
01578
01579
01580
01581
01582
01583
01584 if (sRef_isExposed (s1) && sRef_isCvar (s1))
01585 {
01586 uentry ue1 = sRef_getUentry (s1);
01587
01588 if (uentry_isRefParam (ue1))
01589 {
01590 return sRef_similarRelaxedAux (s1, s2);
01591 }
01592 }
01593
01594 if (sRef_isExposed (s2) && sRef_isCvar (s2))
01595 {
01596 uentry ue2 = sRef_getUentry (s2);
01597
01598 if (uentry_isRefParam (ue2))
01599 {
01600 return sRef_similarRelaxedAux (s1, s2);
01601 }
01602 }
01603
01604 return (ctype_match (s1->type, s2->type));
01605 }
01606 else
01607 {
01608 return sRef_similarRelaxedAux (s1, s2);
01609 }
01610 }
01611
01612 bool
01613 sRef_similar (sRef s1, sRef s2)
01614 {
01615 if (s1 == s2) return TRUE;
01616 if (sRef_isInvalid (s1) || sRef_isInvalid (s2)) return FALSE;
01617
01618 if (sRef_isConj (s2))
01619 {
01620 return (sRef_similar (s1, sRef_getConjA (s2)) ||
01621 sRef_similar (s1, sRef_getConjB (s2)));
01622 }
01623
01624 if (sRef_isDerived (s2))
01625 {
01626 return (sRef_includedBy (s1, s2->info->ref));
01627 }
01628
01629 switch (s1->kind)
01630 {
01631 case SK_CVAR:
01632 return ((s2->kind == SK_CVAR)
01633 && (cref_equal (s1->info->cvar, s2->info->cvar)));
01634 case SK_PARAM:
01635 return ((s2->kind == SK_PARAM)
01636 && (s1->info->paramno == s2->info->paramno));
01637 case SK_ARRAYFETCH:
01638 if (s2->kind == SK_ARRAYFETCH)
01639 {
01640 if (sRef_similar (s1->info->arrayfetch->arr,
01641 s2->info->arrayfetch->arr))
01642 {
01643 if (s1->info->arrayfetch->indknown)
01644 {
01645 if (s2->info->arrayfetch->indknown)
01646 {
01647 return (s1->info->arrayfetch->ind == s2->info->arrayfetch->ind);
01648 }
01649 else
01650 {
01651 return TRUE;
01652 }
01653 }
01654 else
01655 {
01656 return TRUE;
01657 }
01658 }
01659 }
01660 else
01661 {
01662 if (s2->kind == SK_PTR)
01663 {
01664 if (sRef_similar (s1->info->arrayfetch->arr,
01665 s2->info->ref))
01666 {
01667 return TRUE;
01668 }
01669 }
01670 }
01671
01672 return FALSE;
01673 case SK_FIELD:
01674 return ((s2->kind == SK_FIELD
01675 && (sRef_similar (s1->info->field->rec,
01676 s2->info->field->rec)
01677 && cstring_equal (s1->info->field->field,
01678 s2->info->field->field))));
01679 case SK_PTR:
01680 if (s2->kind == SK_PTR)
01681 {
01682 return sRef_similar (s1->info->ref, s2->info->ref);
01683 }
01684 else
01685 {
01686 if (s2->kind == SK_ARRAYFETCH)
01687 {
01688 if (sRef_similar (s2->info->arrayfetch->arr,
01689 s1->info->ref))
01690 {
01691 return TRUE;
01692 }
01693 }
01694 }
01695
01696 return FALSE;
01697 case SK_ADR:
01698 return ((s2->kind == SK_ADR)
01699 && sRef_similar (s1->info->ref, s2->info->ref));
01700 case SK_CONJ:
01701 return ((sRef_similar (s1->info->conj->a, s2) ||
01702 (sRef_similar (s1->info->conj->b, s2))));
01703 case SK_DERIVED:
01704 return (sRef_includedBy (s2, s1->info->ref));
01705 case SK_UNCONSTRAINED:
01706 return (s2->kind == SK_UNCONSTRAINED
01707 && cstring_equal (s1->info->fname, s2->info->fname));
01708 case SK_CONST:
01709 case SK_TYPE:
01710 case SK_NEW:
01711 case SK_UNKNOWN:
01712 case SK_OBJECT:
01713 case SK_EXTERNAL:
01714 case SK_RESULT:
01715 return FALSE;
01716 case SK_SPECIAL:
01717 return (s2->kind == SK_SPECIAL
01718 && (s1->info->spec == s2->info->spec));
01719 }
01720
01721 DPRINTF (("Fell through for: %s / %s", sRef_unparse (s1), sRef_unparse (s2)));
01722 BADEXIT;
01723 }
01724
01725
01726
01727
01728
01729
01730
01731
01732 bool
01733 sRef_includedBy (sRef small, sRef big)
01734 {
01735 if (small == big) return TRUE;
01736 if (sRef_isInvalid (small) || sRef_isInvalid (big)) return FALSE;
01737
01738 if (sRef_isConj (big))
01739 return (sRef_similar (small, sRef_getConjA (big)) ||
01740 sRef_similar (small, sRef_getConjB (big)));
01741
01742 switch (small->kind)
01743 {
01744 case SK_CVAR:
01745 case SK_PARAM:
01746 return (sRef_same (small, big));
01747 case SK_ARRAYFETCH:
01748 if (big->kind == SK_ARRAYFETCH)
01749 {
01750 if (sRef_same (small->info->arrayfetch->arr, big->info->arrayfetch->arr))
01751 {
01752 if (small->info->arrayfetch->indknown)
01753 {
01754 if (big->info->arrayfetch->indknown)
01755 {
01756 return (small->info->arrayfetch->ind == big->info->arrayfetch->ind);
01757 }
01758 else
01759 {
01760 return TRUE;
01761 }
01762 }
01763 else
01764 {
01765 return TRUE;
01766 }
01767 }
01768 }
01769 return (sRef_includedBy (small->info->arrayfetch->arr, big));
01770 case SK_FIELD:
01771 if (big->kind == SK_FIELD)
01772 {
01773 return
01774 (sRef_same (small->info->field->rec, big->info->field->rec) &&
01775 cstring_equal (small->info->field->field, big->info->field->field));
01776 }
01777 else
01778 {
01779 return (sRef_includedBy (small->info->field->rec, big));
01780 }
01781
01782 case SK_PTR:
01783 if (big->kind == SK_PTR)
01784 {
01785 return sRef_same (small->info->ref, big->info->ref);
01786 }
01787 else
01788 {
01789 return (sRef_includedBy (small->info->ref, big));
01790 }
01791
01792 case SK_ADR:
01793 return ((big->kind == SK_ADR) && sRef_similar (small->info->ref, big->info->ref));
01794 case SK_CONJ:
01795 return ((sRef_includedBy (small->info->conj->a, big) ||
01796 (sRef_includedBy (small->info->conj->b, big))));
01797 case SK_DERIVED:
01798 return (sRef_includedBy (small->info->ref, big));
01799 case SK_UNCONSTRAINED:
01800 case SK_CONST:
01801 case SK_TYPE:
01802 case SK_NEW:
01803 case SK_UNKNOWN:
01804 case SK_OBJECT:
01805 case SK_EXTERNAL:
01806 case SK_RESULT:
01807 return FALSE;
01808 case SK_SPECIAL:
01809 switch (small->info->spec)
01810 {
01811 case SR_NOTHING: return TRUE;
01812 case SR_SPECSTATE:
01813 case SR_INTERNAL: return (sRef_isSpecInternalState (big) ||
01814 sRef_isFileStatic (big));
01815 case SR_SYSTEM: return (sRef_isSystemState (big));
01816 }
01817 }
01818 BADEXIT;
01819 }
01820
01821
01822
01823
01824
01825
01826
01827
01828
01829
01830
01831
01832
01833
01834
01835
01836
01837
01838 bool
01839 sRef_realSame (sRef s1, sRef s2)
01840 {
01841 if (s1 == s2) return TRUE;
01842 if (sRef_isInvalid (s1) || sRef_isInvalid (s2)) return FALSE;
01843
01844 switch (s1->kind)
01845 {
01846 case SK_CVAR:
01847 return ((s2->kind == SK_CVAR) && (cref_equal (s1->info->cvar, s2->info->cvar)));
01848 case SK_PARAM:
01849 return ((s2->kind == SK_PARAM) && (s1->info->paramno == s2->info->paramno));
01850 case SK_ARRAYFETCH:
01851 if (s2->kind == SK_ARRAYFETCH)
01852 {
01853 if (sRef_realSame (s1->info->arrayfetch->arr, s2->info->arrayfetch->arr))
01854 {
01855 if (s1->info->arrayfetch->indknown && s2->info->arrayfetch->indknown)
01856 {
01857 return (s1->info->arrayfetch->ind == s2->info->arrayfetch->ind);
01858 }
01859 if (!s1->info->arrayfetch->indknown && !s2->info->arrayfetch->indknown)
01860 {
01861 return TRUE;
01862 }
01863 return FALSE;
01864 }
01865 }
01866 return FALSE;
01867 case SK_FIELD:
01868 return ((s2->kind == SK_FIELD &&
01869 (sRef_realSame (s1->info->field->rec, s2->info->field->rec) &&
01870 cstring_equal (s1->info->field->field, s2->info->field->field))));
01871 case SK_PTR:
01872 return ((s2->kind == SK_PTR) && sRef_realSame (s1->info->ref, s2->info->ref));
01873 case SK_ADR:
01874 return ((s2->kind == SK_ADR) && sRef_realSame (s1->info->ref, s2->info->ref));
01875 case SK_CONJ:
01876 return ((sRef_realSame (s1->info->conj->a, s2) ||
01877 (sRef_realSame (s1->info->conj->b, s2))));
01878 case SK_OBJECT:
01879 return ((s2->kind == SK_OBJECT)
01880 && ctype_match (s1->info->object, s2->info->object));
01881 case SK_EXTERNAL:
01882 return ((s2->kind == SK_EXTERNAL)
01883 && sRef_realSame (s1->info->ref, s2->info->ref));
01884 case SK_SPECIAL:
01885 return ((s2->kind == SK_SPECIAL) && s1->info->spec == s2->info->spec);
01886 case SK_DERIVED:
01887 return ((s2->kind == SK_DERIVED) && sRef_realSame (s1->info->ref, s2->info->ref));
01888 case SK_UNCONSTRAINED:
01889 return ((s2->kind == SK_UNCONSTRAINED)
01890 && (cstring_equal (s1->info->fname, s2->info->fname)));
01891 case SK_TYPE:
01892 case SK_CONST:
01893 case SK_NEW:
01894 case SK_UNKNOWN:
01895 case SK_RESULT:
01896 return TRUE;
01897 }
01898 BADEXIT;
01899 }
01900
01901
01902
01903
01904
01905
01906
01907
01908
01909 bool
01910 sRef_same (sRef s1, sRef s2)
01911 {
01912 if (s1 == s2) return TRUE;
01913 if (sRef_isInvalid (s1) || sRef_isInvalid (s2)) return FALSE;
01914
01915 switch (s1->kind)
01916 {
01917 case SK_CVAR:
01918 return ((s2->kind == SK_CVAR) && (cref_equal (s1->info->cvar, s2->info->cvar)));
01919 case SK_PARAM:
01920 return ((s2->kind == SK_PARAM) && (s1->info->paramno == s2->info->paramno));
01921 case SK_ARRAYFETCH:
01922 if (s2->kind == SK_ARRAYFETCH)
01923 {
01924 llassert (s1->info->field->rec != s1);
01925 if (sRef_same (s1->info->arrayfetch->arr, s2->info->arrayfetch->arr))
01926 {
01927 if (s1->info->arrayfetch->indknown && s2->info->arrayfetch->indknown)
01928 {
01929 return (s1->info->arrayfetch->ind == s2->info->arrayfetch->ind);
01930 }
01931 return TRUE;
01932 }
01933 }
01934 return FALSE;
01935 case SK_FIELD:
01936 {
01937 llassert (s1->info->field->rec != s1);
01938 return ((s2->kind == SK_FIELD &&
01939 (sRef_same (s1->info->field->rec, s2->info->field->rec) &&
01940 cstring_equal (s1->info->field->field, s2->info->field->field))));
01941 }
01942 case SK_PTR:
01943 {
01944 llassert (s1->info->ref != s1);
01945 return ((s2->kind == SK_PTR) && sRef_same (s1->info->ref, s2->info->ref));
01946 }
01947 case SK_ADR:
01948 {
01949 llassert (s1->info->ref != s1);
01950 return ((s2->kind == SK_ADR) && sRef_same (s1->info->ref, s2->info->ref));
01951 }
01952 case SK_CONJ:
01953 llassert (s1->info->conj->a != s1);
01954 llassert (s1->info->conj->b != s1);
01955 return ((sRef_same (s1->info->conj->a, s2)) &&
01956 (sRef_same (s1->info->conj->b, s2)));
01957 case SK_SPECIAL:
01958 return ((s2->kind == SK_SPECIAL) && s1->info->spec == s2->info->spec);
01959 case SK_DERIVED:
01960 llassert (s1->info->ref != s1);
01961 return ((s2->kind == SK_DERIVED) && sRef_same (s1->info->ref, s2->info->ref));
01962 case SK_CONST:
01963 case SK_UNCONSTRAINED:
01964 case SK_TYPE:
01965 case SK_UNKNOWN:
01966 case SK_NEW:
01967 case SK_OBJECT:
01968 case SK_EXTERNAL:
01969 case SK_RESULT:
01970 return FALSE;
01971 }
01972 BADEXIT;
01973 }
01974
01975
01976
01977
01978
01979 static bool
01980 sRef_closeEnough (sRef s1, sRef s2)
01981 {
01982 if (s1 == s2) return TRUE;
01983 if (sRef_isInvalid (s1) || sRef_isInvalid (s2)) return FALSE;
01984
01985 switch (s1->kind)
01986 {
01987 case SK_CVAR:
01988 return (((s2->kind == SK_CVAR) &&
01989 (cref_equal (s1->info->cvar, s2->info->cvar))) ||
01990 (s2->kind == SK_UNCONSTRAINED && s1->info->cvar->lexlevel == 0));
01991 case SK_UNCONSTRAINED:
01992 return (s2->kind == SK_UNCONSTRAINED
01993 || ((s2->kind == SK_CVAR) && (s2->info->cvar->lexlevel == 0)));
01994 case SK_PARAM:
01995 return ((s2->kind == SK_PARAM)
01996 && (s1->info->paramno == s2->info->paramno));
01997 case SK_ARRAYFETCH:
01998 if (s2->kind == SK_ARRAYFETCH)
01999 {
02000 if (sRef_closeEnough (s1->info->arrayfetch->arr, s2->info->arrayfetch->arr))
02001 {
02002 if (s1->info->arrayfetch->indknown && s2->info->arrayfetch->indknown)
02003 {
02004 return (s1->info->arrayfetch->ind == s2->info->arrayfetch->ind);
02005 }
02006 return TRUE;
02007 }
02008 }
02009 return FALSE;
02010 case SK_FIELD:
02011 return ((s2->kind == SK_FIELD &&
02012 (sRef_closeEnough (s1->info->field->rec, s2->info->field->rec) &&
02013 cstring_equal (s1->info->field->field, s2->info->field->field))));
02014 case SK_PTR:
02015 return ((s2->kind == SK_PTR) && sRef_closeEnough (s1->info->ref, s2->info->ref));
02016 case SK_ADR:
02017 return ((s2->kind == SK_ADR) && sRef_closeEnough (s1->info->ref, s2->info->ref));
02018 case SK_DERIVED:
02019 return ((s2->kind == SK_DERIVED) && sRef_closeEnough (s1->info->ref, s2->info->ref));
02020 case SK_CONJ:
02021 return ((sRef_closeEnough (s1->info->conj->a, s2)) ||
02022 (sRef_closeEnough (s1->info->conj->b, s2)));
02023 case SK_SPECIAL:
02024 return ((s2->kind == SK_SPECIAL) && s1->info->spec == s2->info->spec);
02025 case SK_TYPE:
02026 case SK_CONST:
02027 case SK_UNKNOWN:
02028 case SK_NEW:
02029 case SK_OBJECT:
02030 case SK_EXTERNAL:
02031 case SK_RESULT:
02032
02033 return FALSE;
02034 }
02035 BADEXIT;
02036 }
02037
02038 sRef
02039 sRef_fixBaseParam ( sRef s, exprNodeList args)
02040 {
02041 if (sRef_isInvalid (s)) return (sRef_undefined);
02042
02043 switch (s->kind)
02044 {
02045 case SK_UNCONSTRAINED:
02046 case SK_CVAR:
02047 return s;
02048 case SK_PARAM:
02049 {
02050 if (exprNodeList_size (args) > s->info->paramno)
02051 {
02052 exprNode e = exprNodeList_nth (args, s->info->paramno);
02053
02054 if (exprNode_isError (e))
02055 {
02056 return sRef_makeUnknown ();
02057 }
02058
02059 return (exprNode_getSref (e));
02060 }
02061 else
02062 {
02063 return sRef_makeUnknown ();
02064 }
02065 }
02066 case SK_ARRAYFETCH:
02067
02068 if (s->info->arrayfetch->indknown)
02069 {
02070 return (sRef_makeArrayFetchKnown
02071 (sRef_fixBaseParam (s->info->arrayfetch->arr, args),
02072 s->info->arrayfetch->ind));
02073 }
02074 else
02075 {
02076 return (sRef_makeArrayFetch
02077 (sRef_fixBaseParam (s->info->arrayfetch->arr, args)));
02078 }
02079 case SK_FIELD:
02080 return (sRef_makeField (sRef_fixBaseParam (s->info->field->rec, args),
02081 s->info->field->field));
02082
02083 case SK_PTR:
02084 return (sRef_makePointer (sRef_fixBaseParam (s->info->ref, args)));
02085
02086 case SK_ADR:
02087 return (sRef_makeAddress (sRef_fixBaseParam (s->info->ref, args)));
02088
02089 case SK_CONJ:
02090 return (sRef_makeConj (sRef_fixBaseParam (s->info->conj->a, args),
02091 sRef_fixBaseParam (s->info->conj->b, args)));
02092 case SK_DERIVED:
02093 case SK_SPECIAL:
02094 case SK_TYPE:
02095 case SK_CONST:
02096 case SK_NEW:
02097 case SK_UNKNOWN:
02098 case SK_OBJECT:
02099 case SK_EXTERNAL:
02100 case SK_RESULT:
02101 return s;
02102 }
02103 BADEXIT;
02104 }
02105
02106 sRef
02107 sRef_undumpGlobal (char **c)
02108 {
02109 char p = **c;
02110
02111 (*c)++;
02112
02113 switch (p)
02114 {
02115 case 'g':
02116 {
02117 usymId uid = usymId_fromInt (getInt (c));
02118 sstate defstate;
02119 nstate nullstate;
02120 sRef ret;
02121
02122 checkChar (c, '@');
02123 defstate = sstate_fromInt (getInt (c));
02124
02125 checkChar (c, '@');
02126 nullstate = nstate_fromInt (getInt (c));
02127
02128 ret = sRef_makeGlobal (uid, ctype_unknown);
02129 ret->nullstate = nullstate;
02130 ret->defstate = defstate;
02131 return ret;
02132 }
02133 case 's':
02134 {
02135 int i = getInt (c);
02136 speckind sk = speckind_fromInt (i);
02137
02138 switch (sk)
02139 {
02140 case SR_NOTHING: return (sRef_makeNothing ());
02141 case SR_INTERNAL: return (sRef_makeInternalState ());
02142 case SR_SPECSTATE: return (sRef_makeSpecState ());
02143 case SR_SYSTEM: return (sRef_makeSystemState ());
02144 }
02145 BADEXIT;
02146 }
02147 case '-':
02148 return sRef_undefined;
02149 case 'u':
02150 return sRef_makeUnknown ();
02151 case 'x':
02152 return sRef_makeUnknown ();
02153 default:
02154 llfatalerror (message ("sRef_undumpGlobal: bad line: %s",
02155 cstring_fromChars (*c)));
02156 }
02157 BADEXIT;
02158 }
02159
02160 sRef
02161 sRef_undump (char **c)
02162 {
02163 char p = **c;
02164
02165 (*c)++;
02166
02167 switch (p)
02168 {
02169 case 'g':
02170 return (sRef_makeGlobal (usymId_fromInt (getInt (c)), ctype_unknown));
02171 case 'p':
02172 return (sRef_makeParam (getInt (c), ctype_unknown));
02173 case 'r':
02174 return (sRef_makeResultType (ctype_undump (c)));
02175 case 'a':
02176 {
02177 if ((**c >= '0' && **c <= '9') || **c == '-')
02178 {
02179 int i = getInt (c);
02180 sRef arr = sRef_undump (c);
02181 sRef ret = sRef_buildArrayFetchKnown (arr, i);
02182
02183 return ret;
02184 }
02185 else
02186 {
02187 sRef arr = sRef_undump (c);
02188 sRef ret = sRef_buildArrayFetch (arr);
02189
02190 return ret;
02191 }
02192 }
02193 case 'f':
02194 {
02195 cstring fname = cstring_undefined;
02196 sRef ret;
02197
02198 while (**c != '.')
02199 {
02200 fname = cstring_appendChar (fname, **c);
02201 (*c)++;
02202 }
02203 (*c)++;
02204
02205 ret = sRef_buildField (sRef_undump (c), fname);
02206 cstring_markOwned (fname);
02207 return (ret);
02208 }
02209 case 's':
02210 {
02211 int i = getInt (c);
02212 speckind sk = speckind_fromInt (i);
02213
02214 switch (sk)
02215 {
02216 case SR_NOTHING: return (sRef_makeNothing ());
02217 case SR_INTERNAL: return (sRef_makeInternalState ());
02218 case SR_SPECSTATE: return (sRef_makeSpecState ());
02219 case SR_SYSTEM: return (sRef_makeSystemState ());
02220 }
02221 BADEXIT;
02222 }
02223 case 't':
02224 {
02225 sRef ptr = sRef_undump (c);
02226 sRef ret = sRef_makePointer (ptr);
02227
02228 return (ret);
02229 }
02230 case 'd':
02231 {
02232 sRef adr = sRef_undump (c);
02233 sRef ret = sRef_makeAddress (adr);
02234
02235 return (ret);
02236 }
02237 case 'o':
02238 {
02239 return (sRef_makeObject (ctype_undump (c)));
02240 }
02241 case 'c':
02242 {
02243 sRef s1 = sRef_undump (c);
02244 sRef s2 = ((*c)++, sRef_undump (c));
02245 sRef ret = sRef_makeConj (s1, s2);
02246
02247 return (ret);
02248 }
02249 case '-':
02250 return sRef_undefined;
02251 case 'u':
02252 return sRef_makeUnknown ();
02253 case 'x':
02254 return sRef_makeUnknown ();
02255 default:
02256 llfatalerror (message ("sRef_undump: bad line: %s", cstring_fromChars (*c)));
02257 }
02258 BADEXIT;
02259 }
02260
02261 cstring
02262 sRef_dump (sRef s)
02263 {
02264 if (sRef_isInvalid (s))
02265 {
02266 return (cstring_makeLiteral ("-"));
02267 }
02268 else
02269 {
02270 switch (s->kind)
02271 {
02272 case SK_PARAM:
02273 return (message ("p%d", s->info->paramno));
02274 case SK_ARRAYFETCH:
02275 if (s->info->arrayfetch->indknown)
02276 {
02277 return (message ("a%d%q", s->info->arrayfetch->ind,
02278 sRef_dump (s->info->arrayfetch->arr)));
02279 }
02280 else
02281 {
02282 return (message ("a%q", sRef_dump (s->info->arrayfetch->arr)));
02283 }
02284 case SK_FIELD:
02285 return (message ("f%s.%q", s->info->field->field,
02286 sRef_dump (s->info->field->rec)));
02287 case SK_PTR:
02288 return (message ("t%q", sRef_dump (s->info->ref)));
02289 case SK_ADR:
02290 return (message ("d%q", sRef_dump (s->info->ref)));
02291 case SK_OBJECT:
02292 return (message ("o%q", ctype_dump (s->info->object)));
02293 case SK_SPECIAL:
02294 return (message ("s%d", (int) s->info->spec));
02295 case SK_CONJ:
02296 return (message ("c%q.%q",
02297 sRef_dump (s->info->conj->a),
02298 sRef_dump (s->info->conj->b)));
02299 case SK_CVAR:
02300 if (sRef_isGlobal (s))
02301 {
02302 return (message ("g%d",
02303 usymtab_convertId (s->info->cvar->index)));
02304 }
02305 else
02306 {
02307 llcontbug (message ("Dumping local variable: %q",
02308 sRef_unparseDebug (s)));
02309 return (cstring_makeLiteral ("u"));
02310 }
02311 case SK_UNKNOWN:
02312 return (cstring_makeLiteral ("u"));
02313 case SK_RESULT:
02314 return (message ("r%q", ctype_dump (s->type)));
02315 case SK_TYPE:
02316 case SK_CONST:
02317 case SK_EXTERNAL:
02318 case SK_DERIVED:
02319 case SK_NEW:
02320 case SK_UNCONSTRAINED:
02321 llcontbug (message ("sRef_dump: bad kind: %q",
02322 sRef_unparseFull (s)));
02323 return (cstring_makeLiteral ("x"));
02324 }
02325 }
02326
02327 BADEXIT;
02328 }
02329
02330 cstring sRef_dumpGlobal (sRef s)
02331 {
02332 if (sRef_isInvalid (s))
02333 {
02334 return (cstring_makeLiteral ("-"));
02335 }
02336 else
02337 {
02338 switch (s->kind)
02339 {
02340 case SK_CVAR:
02341 if (sRef_isGlobal (s))
02342 {
02343 return (message ("g%d@%d@%d",
02344 usymtab_convertId (s->info->cvar->index),
02345 (int) s->defstate,
02346 (int) s->nullstate));
02347 }
02348 else
02349 {
02350 llcontbug (message ("Dumping local variable: %q",
02351 sRef_unparseDebug (s)));
02352 return (cstring_makeLiteral ("u"));
02353 }
02354 case SK_UNKNOWN:
02355 return (cstring_makeLiteral ("u"));
02356 case SK_SPECIAL:
02357 return (message ("s%d", (int) s->info->spec));
02358 default:
02359 llcontbug (message ("sRef_dumpGlobal: bad kind: %q",
02360 sRef_unparseFull (s)));
02361 return (cstring_makeLiteral ("x"));
02362 }
02363 }
02364
02365 BADEXIT;
02366 }
02367
02368 ctype
02369 sRef_deriveType (sRef s, uentryList cl)
02370 {
02371 if (sRef_isInvalid (s)) return ctype_unknown;
02372
02373 switch (s->kind)
02374 {
02375 case SK_CVAR:
02376 return (uentry_getType (usymtab_getRefQuiet (s->info->cvar->lexlevel,
02377 s->info->cvar->index)));
02378 case SK_UNCONSTRAINED:
02379 return (ctype_unknown);
02380 case SK_PARAM:
02381 return uentry_getType (uentryList_getN (cl, s->info->paramno));
02382 case SK_ARRAYFETCH:
02383 {
02384 ctype ca = sRef_deriveType (s->info->arrayfetch->arr, cl);
02385
02386 if (ctype_isArray (ca))
02387 {
02388 return (ctype_baseArrayPtr (ca));
02389 }
02390 else if (ctype_isUnknown (ca))
02391 {
02392 return (ca);
02393 }
02394 else
02395 {
02396 llcontbuglit ("sRef_deriveType: inconsistent array type");
02397 return ca;
02398 }
02399 }
02400 case SK_FIELD:
02401 {
02402 ctype ct = sRef_deriveType (s->info->field->rec, cl);
02403
02404 if (ctype_isStructorUnion (ct))
02405 {
02406 uentry ue = uentryList_lookupField (ctype_getFields (ct),
02407 s->info->field->field);
02408
02409 if (uentry_isValid (ue))
02410 {
02411 return (uentry_getType (ue));
02412 }
02413 else
02414 {
02415 llcontbuglit ("sRef_deriveType: bad field");
02416 return ctype_unknown;
02417 }
02418 }
02419 else if (ctype_isUnknown (ct))
02420 {
02421 return (ct);
02422 }
02423 else
02424 {
02425 llcontbuglit ("sRef_deriveType: inconsistent field type");
02426 return (ct);
02427 }
02428 }
02429 case SK_PTR:
02430 {
02431 ctype ct = sRef_deriveType (s->info->ref, cl);
02432
02433 if (ctype_isUnknown (ct)) return ct;
02434 if (ctype_isPointer (ct)) return (ctype_baseArrayPtr (ct));
02435 else
02436 {
02437 llcontbuglit ("sRef_deriveType: inconsistent pointer type");
02438 return (ct);
02439 }
02440 }
02441 case SK_ADR:
02442 {
02443 ctype ct = sRef_deriveType (s->info->ref, cl);
02444
02445 if (ctype_isUnknown (ct)) return ct;
02446 return ctype_makePointer (ct);
02447 }
02448 case SK_DERIVED:
02449 {
02450 return sRef_deriveType (s->info->ref, cl);
02451 }
02452 case SK_OBJECT:
02453 {
02454 return (s->info->object);
02455 }
02456 case SK_CONJ:
02457 {
02458 return (ctype_makeConj (sRef_deriveType (s->info->conj->a, cl),
02459 sRef_deriveType (s->info->conj->b, cl)));
02460 }
02461 case SK_RESULT:
02462 case SK_CONST:
02463 case SK_TYPE:
02464 {
02465 return (s->type);
02466 }
02467 case SK_SPECIAL:
02468 case SK_UNKNOWN:
02469 case SK_EXTERNAL:
02470 case SK_NEW:
02471 return ctype_unknown;
02472 }
02473 BADEXIT;
02474 }
02475
02476 ctype
02477 sRef_getType (sRef s)
02478 {
02479 if (sRef_isInvalid (s)) return ctype_unknown;
02480 return s->type;
02481 }
02482
02483
02484 cstring
02485 sRef_unparseOpt (sRef s)
02486 {
02487 sRef rb = sRef_getRootBase (s);
02488
02489 if (sRef_isMeaningful (rb) && !sRef_isConst (rb))
02490 {
02491 cstring ret = sRef_unparse (s);
02492
02493 llassertprint (!cstring_equalLit (ret, "?"), ("print: %s", sRef_unparseDebug (s)));
02494
02495 if (!cstring_isEmpty (ret))
02496 {
02497 return (cstring_appendChar (ret, ' '));
02498 }
02499 else
02500 {
02501 return ret;
02502 }
02503 }
02504
02505 return cstring_undefined;
02506 }
02507
02508 cstring
02509 sRef_unparsePreOpt (sRef s)
02510 {
02511 sRef rb = sRef_getRootBase (s);
02512
02513 if (sRef_isMeaningful (rb) && !sRef_isConst (rb))
02514 {
02515 cstring ret = sRef_unparse (s);
02516
02517 llassertprint (!cstring_equalLit (ret, "?"), ("print: %s", sRef_unparseDebug (s)));
02518 return (cstring_prependCharO (' ', ret));
02519 }
02520
02521 return cstring_undefined;
02522 }
02523
02524 cstring
02525 sRef_unparse (sRef s)
02526 {
02527 if (sRef_isInvalid (s)) return (cstring_makeLiteral ("?"));
02528
02529 if (context_inFunctionLike ())
02530 {
02531 return (sRef_unparseWithArgs (s, context_getParams ()));
02532 }
02533 else
02534 {
02535 return (sRef_unparseNoArgs (s));
02536 }
02537 }
02538
02539 static cstring
02540 sRef_unparseWithArgs (sRef s, uentryList args)
02541 {
02542 if (sRef_isInvalid (s))
02543 {
02544 return (cstring_makeLiteral ("?"));
02545 }
02546
02547 switch (s->kind)
02548 {
02549 case SK_CVAR:
02550 return (uentry_getName (usymtab_getRefQuiet (s->info->cvar->lexlevel,
02551 s->info->cvar->index)));
02552 case SK_UNCONSTRAINED:
02553 return (cstring_copy (s->info->fname));
02554 case SK_PARAM:
02555 {
02556 if (s->info->paramno < uentryList_size (args))
02557 {
02558 uentry ue = uentryList_getN (args, s->info->paramno);
02559
02560 if (uentry_isValid (ue))
02561 return uentry_getName (ue);
02562 }
02563
02564 return (message ("<bad param: %q / args %q",
02565 sRef_unparseDebug (s),
02566 uentryList_unparse (args)));
02567 }
02568 case SK_ARRAYFETCH:
02569 if (s->info->arrayfetch->indknown)
02570 {
02571 return (message ("%q[%d]", sRef_unparseWithArgs (s->info->arrayfetch->arr, args),
02572 s->info->arrayfetch->ind));
02573 }
02574 else
02575 {
02576 return (message ("%q[]", sRef_unparseWithArgs (s->info->arrayfetch->arr, args)));
02577 }
02578 case SK_FIELD:
02579 if (s->info->field->rec->kind == SK_PTR)
02580 {
02581 sRef ptr = s->info->field->rec;
02582
02583 return (message ("%q->%s", sRef_unparseWithArgs (ptr->info->ref, args),
02584 s->info->field->field));
02585 }
02586 return (message ("%q.%s", sRef_unparseWithArgs (s->info->field->rec, args),
02587 s->info->field->field));
02588
02589 case SK_PTR:
02590 {
02591 sRef ref = sRef_fixConj (s->info->ref);
02592 skind sk = ref->kind;
02593 cstring ret;
02594
02595 if (sk == SK_NEW)
02596 {
02597 ret = message ("storage pointed to by %q",
02598 sRef_unparseWithArgs (ref, args));
02599 }
02600 else if (skind_isSimple (sk) || sk == SK_PTR)
02601 {
02602 ret = message ("*%q", sRef_unparseWithArgs (ref, args));
02603 }
02604 else
02605 {
02606 ret = message ("*(%q)", sRef_unparseWithArgs (ref, args));
02607 }
02608
02609 return ret;
02610 }
02611 case SK_ADR:
02612 return (message ("&%q", sRef_unparseWithArgs (s->info->ref, args)));
02613 case SK_OBJECT:
02614 return (cstring_copy (ctype_unparse (s->info->object)));
02615 case SK_CONJ:
02616 return (sRef_unparseWithArgs (sRef_getConjA (s), args));
02617 case SK_NEW:
02618 if (cstring_isDefined (s->info->fname))
02619 {
02620 return (message ("[result of %s]", s->info->fname));
02621 }
02622 else
02623 {
02624 return (cstring_makeLiteral ("<new>"));
02625 }
02626 case SK_UNKNOWN:
02627 return (cstring_makeLiteral ("?"));
02628 case SK_DERIVED:
02629 return (message ("<derived %q>", sRef_unparse (s->info->ref)));
02630 case SK_EXTERNAL:
02631 return (message ("<external %q>", sRef_unparse (s->info->ref)));
02632 case SK_TYPE:
02633 return (message ("<type %s>", ctype_unparse (s->type)));
02634 case SK_CONST:
02635 return (message ("<const %s>", ctype_unparse (s->type)));
02636 case SK_SPECIAL:
02637 return (cstring_makeLiteral
02638 (s->info->spec == SR_NOTHING ? "nothing"
02639 : s->info->spec == SR_INTERNAL ? "internal state"
02640 : s->info->spec == SR_SPECSTATE ? "spec state"
02641 : s->info->spec == SR_SYSTEM ? "file system state"
02642 : "<spec error>"));
02643 case SK_RESULT:
02644 return cstring_makeLiteral ("result");
02645 default:
02646 {
02647 llbug (message ("Bad sref, kind = %d", (int) s->kind));
02648 }
02649 }
02650
02651 BADEXIT;
02652 }
02653
02654 cstring
02655 sRef_unparseDebug (sRef s)
02656 {
02657 if (sRef_isInvalid (s)) return (cstring_makeLiteral ("<undef>"));
02658
02659 switch (s->kind)
02660 {
02661 case SK_UNCONSTRAINED:
02662 return (message ("<unconstrained %s>", s->info->fname));
02663 case SK_CVAR:
02664 {
02665 uentry ce;
02666
02667 ce = usymtab_getRefQuiet (s->info->cvar->lexlevel, s->info->cvar->index);
02668
02669 if (uentry_isInvalid (ce))
02670 {
02671 return (message ("<scope: %d.%d *invalid*>",
02672 s->info->cvar->lexlevel,
02673 s->info->cvar->index));
02674 }
02675 else
02676 {
02677 return (message ("<scope: %d.%d *%q*>",
02678 s->info->cvar->lexlevel,
02679 s->info->cvar->index,
02680 uentry_getName (ce)));
02681 }
02682
02683 }
02684 case SK_PARAM:
02685 {
02686 return (message ("<parameter %d>", s->info->paramno + 1));
02687 }
02688 case SK_ARRAYFETCH:
02689 if (s->info->arrayfetch->indknown)
02690 {
02691 return (message ("%q[%d]", sRef_unparseDebug (s->info->arrayfetch->arr),
02692 s->info->arrayfetch->ind));
02693 }
02694 else
02695 {
02696 return (message ("%q[]", sRef_unparseDebug (s->info->arrayfetch->arr)));
02697 }
02698 case SK_FIELD:
02699 return (message ("%q.%s", sRef_unparseDebug (s->info->field->rec),
02700 s->info->field->field));
02701 case SK_PTR:
02702 return (message ("*(%q)", sRef_unparseDebug (s->info->ref)));
02703 case SK_ADR:
02704 return (message ("&%q", sRef_unparseDebug (s->info->ref)));
02705 case SK_OBJECT:
02706 return (message ("<object type %s>", ctype_unparse (s->info->object)));
02707 case SK_CONJ:
02708 return (message ("%q | %q", sRef_unparseDebug (s->info->conj->a),
02709 sRef_unparseDebug (s->info->conj->b)));
02710 case SK_NEW:
02711 return message ("<new: %s>", s->info->fname);
02712 case SK_DERIVED:
02713 return (message ("<derived %q>", sRef_unparseDebug (s->info->ref)));
02714 case SK_EXTERNAL:
02715 return (message ("<external %q>", sRef_unparseDebug (s->info->ref)));
02716 case SK_TYPE:
02717 return (message ("<type %s>", ctype_unparse (s->type)));
02718 case SK_CONST:
02719 return (message ("<const %s>", ctype_unparse (s->type)));
02720 case SK_RESULT:
02721 return (message ("<result %s>", ctype_unparse (s->type)));
02722 case SK_SPECIAL:
02723 return (message ("<spec %s>",
02724 cstring_makeLiteralTemp
02725 (s->info->spec == SR_NOTHING ? "nothing"
02726 : s->info->spec == SR_INTERNAL ? "internalState"
02727 : s->info->spec == SR_SPECSTATE ? "spec state"
02728 : s->info->spec == SR_SYSTEM ? "fileSystem"
02729 : "error")));
02730 case SK_UNKNOWN:
02731 return cstring_makeLiteral ("<unknown>");
02732 }
02733
02734 BADEXIT;
02735 }
02736
02737 static cstring
02738 sRef_unparseNoArgs (sRef s)
02739 {
02740 if (sRef_isInvalid (s)) return (cstring_makeLiteral ("?"));
02741
02742 switch (s->kind)
02743 {
02744 case SK_UNCONSTRAINED:
02745 return (cstring_copy (s->info->fname));
02746 case SK_CVAR:
02747 {
02748 uentry ce = usymtab_getRefQuiet (s->info->cvar->lexlevel,
02749 s->info->cvar->index);
02750
02751 if (uentry_isInvalid (ce))
02752 {
02753 llcontbug (message ("sRef_unparseNoArgs: bad cvar: %q", sRef_unparseDebug (s)));
02754 return (sRef_unparseDebug (s));
02755 }
02756 else
02757 {
02758 return (uentry_getName (ce));
02759 }
02760 }
02761 case SK_ARRAYFETCH:
02762 if (s->info->arrayfetch->indknown)
02763 {
02764 return (message ("%q[%d]", sRef_unparseNoArgs (s->info->arrayfetch->arr),
02765 s->info->arrayfetch->ind));
02766 }
02767 else
02768 {
02769 return (message ("%q[]", sRef_unparseNoArgs (s->info->arrayfetch->arr)));
02770 }
02771 case SK_FIELD:
02772 return (message ("%q.%s", sRef_unparseNoArgs (s->info->field->rec),
02773 s->info->field->field));
02774 case SK_PTR:
02775 {
02776 sRef ref = sRef_fixConj (s->info->ref);
02777 skind sk = ref->kind;
02778 cstring ret;
02779
02780 if (skind_isSimple (sk) || sk == SK_PTR)
02781 {
02782 ret = message ("*%q", sRef_unparseNoArgs (ref));
02783 }
02784 else
02785 {
02786 ret = message ("*(%q)", sRef_unparseNoArgs (ref));
02787 }
02788
02789 return (ret);
02790 }
02791 case SK_ADR:
02792 return (message ("&%q", sRef_unparseNoArgs (s->info->ref)));
02793 case SK_OBJECT:
02794 return (cstring_copy (ctype_unparse (s->info->object)));
02795 case SK_CONJ:
02796 return (sRef_unparseNoArgs (s->info->conj->a));
02797 case SK_NEW:
02798 return (message ("result of %s", s->info->fname));
02799 case SK_DERIVED:
02800 return (message ("<der %q>", sRef_unparseNoArgs (s->info->ref)));
02801 case SK_EXTERNAL:
02802 return message ("<ext %q>", sRef_unparseNoArgs (s->info->ref));
02803 case SK_SPECIAL:
02804 return (cstring_makeLiteral
02805 (s->info->spec == SR_NOTHING ? "nothing"
02806 : s->info->spec == SR_INTERNAL ? "internal state"
02807 : s->info->spec == SR_SPECSTATE ? "spec state"
02808 : s->info->spec == SR_SYSTEM ? "file system state"
02809 : "<spec error>"));
02810 case SK_RESULT:
02811 return cstring_makeLiteral ("result");
02812 case SK_CONST:
02813 case SK_TYPE:
02814 case SK_UNKNOWN:
02815 return cstring_makeLiteral ("?");
02816 case SK_PARAM:
02817
02818 return (sRef_unparseDebug (s));
02819 }
02820 BADEXIT;
02821 }
02822
02823 sRef sRef_makeUnconstrained (cstring fname)
02824 {
02825 sRef s = sRef_new ();
02826
02827 s->kind = SK_UNCONSTRAINED;
02828 s->info = (sinfo) dmalloc (sizeof (*s->info));
02829 s->info->fname = fname;
02830
02831 return (s);
02832 }
02833
02834 cstring sRef_unconstrainedName (sRef s)
02835 {
02836 llassert (sRef_isUnconstrained (s));
02837
02838 return s->info->fname;
02839 }
02840
02841 bool sRef_isUnconstrained (sRef s)
02842 {
02843 return (sRef_isValid(s) && s->kind == SK_UNCONSTRAINED);
02844 }
02845
02846 static sRef
02847 sRef_makeCvarAux (int level, usymId index, ctype ct)
02848 {
02849 sRef s = sRef_new ();
02850
02851 s->kind = SK_CVAR;
02852 s->info = (sinfo) dmalloc (sizeof (*s->info));
02853
02854 s->info->cvar = (cref) dmalloc (sizeof (*s->info->cvar));
02855 s->info->cvar->lexlevel = level;
02856 s->info->cvar->index = index;
02857
02858
02859
02860 if (level <= fileScope)
02861 {
02862 s->defstate = SS_UNKNOWN;
02863 }
02864 else
02865 {
02866 ctype rct = ctype_realType (ct);
02867
02868 if (level != paramsScope
02869 && (ctype_isStructorUnion (rct) || ctype_isRealArray (rct)))
02870 {
02871 s->defstate = SS_ALLOCATED;
02872 s->oaliaskind = s->aliaskind = AK_STACK;
02873 }
02874 else
02875 {
02876 s->defstate = SS_UNDEFINED;
02877 s->oaliaskind = s->aliaskind = AK_LOCAL;
02878 }
02879 }
02880
02881 s->type = ct;
02882
02883 llassert (level >= globScope);
02884 llassert (usymId_isValid (index));
02885
02886 return s;
02887 }
02888
02889 sRef sRef_makeCvar (int level, usymId index, ctype ct)
02890 {
02891 return (sRef_makeCvarAux (level, index, ct));
02892 }
02893
02894 int sRef_lexLevel (sRef s)
02895 {
02896 if (sRef_isValid (s))
02897 {
02898 sRef conj;
02899
02900 conj = sRef_fixConj (s);
02901 s = sRef_getRootBase (conj);
02902
02903 if (sRef_isValid (s) && s->kind == SK_CVAR)
02904 {
02905 return (s->info->cvar->lexlevel);
02906 }
02907 }
02908
02909 return globScope;
02910 }
02911
02912 sRef
02913 sRef_makeGlobal (usymId l, ctype ct)
02914 {
02915 return (sRef_makeCvar (globScope, l, ct));
02916 }
02917
02918 void
02919 sRef_setParamNo (sRef s, int l)
02920 {
02921 llassert (sRef_isValid (s) && s->kind == SK_PARAM);
02922 s->info->paramno = l;
02923 }
02924
02925 sRef
02926 sRef_makeParam (int l, ctype ct)
02927 {
02928 sRef s = sRef_new ();
02929
02930 s->kind = SK_PARAM;
02931 s->type = ct;
02932
02933 s->info = (sinfo) dmalloc (sizeof (*s->info));
02934 s->info->paramno = l;
02935 s->defstate = SS_UNKNOWN;
02936
02937 return s;
02938 }
02939
02940 bool
02941 sRef_isIndexKnown (sRef arr)
02942 {
02943 bool res;
02944
02945 llassert (sRef_isValid (arr));
02946 arr = sRef_fixConj (arr);
02947
02948 llassert (arr->kind == SK_ARRAYFETCH);
02949 res = arr->info->arrayfetch->indknown;
02950 return (res);
02951 }
02952
02953 int
02954 sRef_getIndex (sRef arr)
02955 {
02956 int result;
02957
02958 llassert (sRef_isValid (arr));
02959 arr = sRef_fixConj (arr);
02960
02961 llassert (arr->kind == SK_ARRAYFETCH);
02962
02963 if (!arr->info->arrayfetch->indknown)
02964 {
02965 llcontbug (message ("sRef_getIndex: unknown: %q", sRef_unparse (arr)));
02966 result = 0;
02967 }
02968 else
02969 {
02970 result = arr->info->arrayfetch->ind;
02971 }
02972
02973 return result;
02974 }
02975
02976 static bool sRef_isZerothArrayFetch ( sRef s)
02977 {
02978 return (s->kind == SK_ARRAYFETCH
02979 && s->info->arrayfetch->indknown
02980 && (s->info->arrayfetch->ind == 0));
02981 }
02982
02983 sRef sRef_makeAddress ( sRef t)
02984 {
02985
02986 if (sRef_isInvalid (t)) return sRef_undefined;
02987
02988 if (sRef_isPointer (t))
02989 {
02990 return (t->info->ref);
02991 }
02992 else if (sRef_isZerothArrayFetch (t))
02993 {
02994 return (t->info->arrayfetch->arr);
02995 }
02996 else
02997 {
02998 sRef s = sRef_new ();
02999
03000 s->kind = SK_ADR;
03001 s->type = ctype_makePointer (t->type);
03002 s->info = (sinfo) dmalloc (sizeof (*s->info));
03003 s->info->ref = t;
03004
03005 if (t->defstate == SS_UNDEFINED)
03006
03007 {
03008 s->defstate = SS_ALLOCATED;
03009 }
03010 else
03011 {
03012 s->defstate = t->defstate;
03013 }
03014
03015 if (t->aliaskind == AK_LOCAL)
03016 {
03017 if (sRef_isLocalVar (t))
03018 {
03019 s->aliaskind = AK_STACK;
03020 }
03021 }
03022
03023 return s;
03024 }
03025 }
03026
03027 cstring sRef_getField (sRef s)
03028 {
03029 cstring res;
03030
03031 llassert (sRef_isValid (s));
03032 s = sRef_fixConj (s);
03033
03034 llassertprint (sRef_isValid (s) && (s->kind == SK_FIELD),
03035 ("s = %s", sRef_unparseDebug (s)));
03036
03037 res = s->info->field->field;
03038 return (res);
03039 }
03040
03041 sRef sRef_getBase (sRef s)
03042 {
03043 sRef res;
03044
03045 if (sRef_isInvalid (s)) return (sRef_undefined);
03046
03047 s = sRef_fixConj (s);
03048
03049 switch (s->kind)
03050 {
03051 case SK_ADR:
03052 case SK_PTR:
03053 case SK_DERIVED:
03054 case SK_EXTERNAL:
03055 res = s->info->ref;
03056 break;
03057 case SK_FIELD:
03058 res = s->info->field->rec;
03059 break;
03060
03061 case SK_ARRAYFETCH:
03062 res = s->info->arrayfetch->arr;
03063 break;
03064
03065 default:
03066 res = sRef_undefined;
03067 }
03068
03069 return (res);
03070 }
03071
03072
03073
03074
03075
03076
03077 sRef
03078 sRef_getBaseSafe (sRef s)
03079 {
03080 sRef res;
03081
03082 if (sRef_isInvalid (s)) { return sRef_undefined; }
03083
03084 s = sRef_fixConj (s);
03085
03086 switch (s->kind)
03087 {
03088 case SK_PTR:
03089 res = s->info->ref;
03090 break;
03091 case SK_FIELD:
03092 res = s->info->field->rec; break;
03093 case SK_ARRAYFETCH:
03094 res = s->info->arrayfetch->arr;
03095 break;
03096 default:
03097 res = sRef_undefined; break;
03098 }
03099
03100 return res;
03101 }
03102
03103
03104 # define MAXBASEDEPTH 25
03105
03106 static sRef
03107 sRef_getRootBaseAux (sRef s, int depth)
03108 {
03109 if (sRef_isInvalid (s)) return sRef_undefined;
03110
03111 if (depth > MAXBASEDEPTH)
03112 {
03113 llgenmsg (message
03114 ("Warning: reference base limit exceeded for %q. "
03115 "This either means there is a variable with at least "
03116 "%d indirections from this reference, or "
03117 "there is a bug in LCLint.",
03118 sRef_unparse (s),
03119 MAXBASEDEPTH),
03120 g_currentloc);
03121
03122 return sRef_undefined;
03123 }
03124
03125 switch (s->kind)
03126 {
03127 case SK_ADR:
03128 case SK_PTR:
03129 return (sRef_getRootBaseAux (s->info->ref, depth + 1));
03130 case SK_FIELD:
03131 return (sRef_getRootBaseAux (s->info->field->rec, depth + 1));
03132 case SK_ARRAYFETCH:
03133 return (sRef_getRootBaseAux (s->info->arrayfetch->arr, depth + 1));
03134 case SK_CONJ:
03135 return (sRef_getRootBaseAux (sRef_fixConj (s), depth + 1));
03136 default:
03137 return s;
03138 }
03139 }
03140
03141 sRef sRef_getRootBase (sRef s)
03142 {
03143 return (sRef_getRootBaseAux (s, 0));
03144 }
03145
03146 static bool sRef_isDeep (sRef s)
03147 {
03148 if (sRef_isInvalid (s)) return FALSE;
03149
03150 switch (s->kind)
03151 {
03152 case SK_ADR:
03153 case SK_PTR:
03154 case SK_FIELD:
03155 case SK_ARRAYFETCH:
03156 return TRUE;
03157 case SK_CONJ:
03158 return (sRef_isDeep (sRef_fixConj (s)));
03159 default:
03160 return FALSE;
03161 }
03162 }
03163
03164 static int sRef_depth (sRef s)
03165 {
03166 if (sRef_isInvalid (s)) return 0;
03167
03168 switch (s->kind)
03169 {
03170 case SK_ADR:
03171 case SK_PTR:
03172 case SK_DERIVED:
03173 case SK_EXTERNAL:
03174 return 1 + sRef_depth (s->info->ref);
03175 case SK_FIELD:
03176 return 1 + sRef_depth (s->info->field->rec);
03177 case SK_ARRAYFETCH:
03178 return 1 + sRef_depth (s->info->arrayfetch->arr);
03179 case SK_CONJ:
03180 return (sRef_depth (sRef_fixConj (s)));
03181 default:
03182 return 1;
03183 }
03184 }
03185
03186 sRef
03187 sRef_makeObject (ctype o)
03188 {
03189 sRef s = sRef_new ();
03190
03191 s->kind = SK_OBJECT;
03192 s->info = (sinfo) dmalloc (sizeof (*s->info));
03193 s->info->object = o;
03194 return s;
03195 }
03196
03197 sRef sRef_makeExternal ( sRef t)
03198 {
03199 sRef s = sRef_new ();
03200
03201 llassert (sRef_isValid (t));
03202
03203 s->kind = SK_EXTERNAL;
03204 s->info = (sinfo) dmalloc (sizeof (*s->info));
03205 s->type = t->type;
03206 s->info->ref = t;
03207 return s;
03208 }
03209
03210 sRef sRef_makeDerived ( sRef t)
03211 {
03212 if (sRef_isValid (t))
03213 {
03214 sRef s = sRef_new ();
03215
03216 s->kind = SK_DERIVED;
03217 s->info = (sinfo) dmalloc (sizeof (*s->info));
03218 s->info->ref = t;
03219
03220 s->type = t->type;
03221 return s;
03222 }
03223 else
03224 {
03225 return sRef_undefined;
03226 }
03227 }
03228
03229
03230
03231
03232
03233
03234
03235 void
03236 sRef_mergeStateQuiet (sRef res, sRef other)
03237 {
03238 llassert (sRef_isValid (res));
03239 llassert (sRef_isValid (other));
03240
03241 res->modified = res->modified || other->modified;
03242 res->safe = res->safe && other->safe;
03243
03244 if (res->defstate == SS_UNKNOWN)
03245 {
03246 res->defstate = other->defstate;
03247 res->definfo = alinfo_update (res->definfo, other->definfo);
03248 }
03249
03250 if (res->aliaskind == AK_UNKNOWN ||
03251 (res->aliaskind == AK_LOCAL && alkind_isKnown (other->aliaskind)))
03252 {
03253 res->aliaskind = other->aliaskind;
03254 res->oaliaskind = other->oaliaskind;
03255 res->aliasinfo = alinfo_update (res->aliasinfo, other->aliasinfo);
03256 }
03257
03258 if (res->expkind == XO_UNKNOWN)
03259 {
03260 res->expkind = other->expkind;
03261 res->oexpkind = other->oexpkind;
03262 res->expinfo = alinfo_update (res->expinfo, other->expinfo);
03263 }
03264
03265
03266 if (res->defstate == SS_DEFINED && other->defstate != SS_UNKNOWN)
03267 {
03268 res->defstate = other->defstate;
03269 res->definfo = alinfo_update (res->definfo, other->definfo);
03270 }
03271
03272 if (other->nullstate == NS_ERROR || res->nullstate == NS_ERROR)
03273 {
03274 res->nullstate = NS_ERROR;
03275 }
03276 else
03277 {
03278 if (other->nullstate != NS_UNKNOWN
03279 && (res->nullstate == NS_UNKNOWN || res->nullstate == NS_NOTNULL
03280 || res->nullstate == NS_MNOTNULL))
03281 {
03282 res->nullstate = other->nullstate;
03283 res->nullinfo = alinfo_update (res->nullinfo, other->nullinfo);
03284 }
03285 }
03286 }
03287
03288
03289
03290
03291
03292
03293
03294 void
03295 sRef_mergeStateQuietReverse (sRef res, sRef other)
03296 {
03297 bool changed = FALSE;
03298
03299 llassert (sRef_isValid (res));
03300 llassert (sRef_isValid (other));
03301
03302 if (res->kind != other->kind)
03303 {
03304 changed = TRUE;
03305
03306 sinfo_free (res);
03307
03308 res->kind = other->kind;
03309 res->type = other->type;
03310 res->info = sinfo_fullCopy (other);
03311 }
03312 else
03313 {
03314 if (!ctype_equal (res->type, other->type))
03315 {
03316 changed = TRUE;
03317 res->type = other->type;
03318 }
03319
03320 sinfo_update (res, other);
03321 }
03322
03323 res->modified = res->modified || other->modified;
03324 res->safe = res->safe && other->safe;
03325
03326 if (res->aliaskind != other->aliaskind
03327 && (res->aliaskind == AK_UNKNOWN
03328 || ((res->aliaskind == AK_LOCAL
03329 || (res->aliaskind == AK_REFCOUNTED
03330 && other->aliaskind != AK_LOCAL))
03331 && other->aliaskind != AK_UNKNOWN)))
03332 {
03333 changed = TRUE;
03334 res->aliaskind = other->aliaskind;
03335 res->oaliaskind = other->oaliaskind;
03336 res->aliasinfo = alinfo_update (res->aliasinfo, other->aliasinfo);
03337 }
03338
03339 if (other->expkind != XO_UNKNOWN && other->expkind != res->expkind)
03340 {
03341 changed = TRUE;
03342 res->expkind = other->expkind;
03343 res->expinfo = alinfo_update (res->expinfo, other->expinfo);
03344 }
03345
03346 if (other->oexpkind != XO_UNKNOWN)
03347 {
03348 res->oexpkind = other->oexpkind;
03349 }
03350
03351
03352
03353 if (res->defstate != other->defstate)
03354 {
03355 if (other->defstate != SS_UNKNOWN)
03356 {
03357 res->defstate = other->defstate;
03358 }
03359 }
03360
03361 if (other->nullstate == NS_ERROR || res->nullstate == NS_ERROR)
03362 {
03363 if (res->nullstate != NS_ERROR)
03364 {
03365 res->nullstate = NS_ERROR;
03366 changed = TRUE;
03367 }
03368 }
03369 else
03370 {
03371 if (other->nullstate != NS_UNKNOWN && other->nullstate != res->nullstate)
03372 {
03373 changed = TRUE;
03374 res->nullstate = other->nullstate;
03375 res->nullinfo = alinfo_update (res->nullinfo, other->nullinfo);
03376 }
03377 }
03378
03379 if (changed)
03380 {
03381 sRef_clearDerived (res);
03382 }
03383 }
03384
03385 void
03386 sRef_mergeState (sRef res, sRef other, clause cl, fileloc loc)
03387 {
03388 if (sRef_isValid (res) && sRef_isValid (other))
03389 {
03390 sRef_mergeStateAux (res, other, cl, FALSE, loc, TRUE);
03391 }
03392 else
03393 {
03394 if (sRef_isInvalid (res))
03395 {
03396 llbug (message ("sRef_mergeState: invalid res sRef: %q",
03397 sRef_unparseDebug (other)));
03398 }
03399 else
03400 {
03401 llbug (message ("sRef_mergeState: invalid other sRef: %q",
03402 sRef_unparseDebug (res)));
03403 }
03404 }
03405 }
03406
03407 void
03408 sRef_mergeOptState (sRef res, sRef other, clause cl, fileloc loc)
03409 {
03410 if (sRef_isValid (res) && sRef_isValid (other))
03411 {
03412 sRef_mergeStateAux (res, other, cl, TRUE, loc, TRUE);
03413 }
03414 else
03415 {
03416 if (sRef_isInvalid (res))
03417 {
03418 llbug (message ("sRef_mergeOptState: invalid res sRef: %q",
03419 sRef_unparseDebug (other)));
03420 }
03421 else
03422 {
03423 llbug (message ("sRef_mergeOptState: invalid other sRef: %q",
03424 sRef_unparseDebug (res)));
03425 }
03426 }
03427 }
03428
03429 static void
03430 sRef_mergeStateAux ( sRef res, sRef other,
03431 clause cl, bool opt, fileloc loc,
03432 bool doDerivs)
03433
03434 {
03435 llassertfatal (sRef_isValid (res));
03436 llassertfatal (sRef_isValid (other));
03437
03438 res->modified = res->modified || other->modified;
03439
03440 if (res->kind == other->kind
03441 || (other->kind == SK_UNKNOWN || res->kind == SK_UNKNOWN))
03442 {
03443 sstate odef = other->defstate;
03444 sstate rdef = res->defstate;
03445 nstate onull = other->nullstate;
03446
03447
03448
03449
03450
03451
03452
03453 if (other->defstate == SS_DEAD
03454 && ((sRef_isOnly (res) && sRef_definitelyNull (res))
03455 || (res->defstate == SS_UNDEFINED
03456 || res->defstate == SS_UNUSEABLE)))
03457 {
03458 if (res->defstate == SS_UNDEFINED
03459 || res->defstate == SS_UNUSEABLE)
03460 {
03461 res->defstate = SS_UNUSEABLE;
03462 }
03463 else
03464 {
03465 res->defstate = SS_DEAD;
03466 }
03467
03468 res->definfo = alinfo_update (res->definfo, other->definfo);
03469 sRef_clearDerived (other);
03470 sRef_clearDerived (res);
03471 }
03472 else if (res->defstate == SS_DEAD
03473 && ((sRef_isOnly (other) && sRef_definitelyNull (other))
03474 || (other->defstate == SS_UNDEFINED
03475 || other->defstate == SS_UNUSEABLE)))
03476 {
03477 if (other->defstate == SS_UNDEFINED
03478 || other->defstate == SS_UNUSEABLE)
03479 {
03480 res->defstate = SS_UNUSEABLE;
03481 }
03482 else
03483 {
03484 res->defstate = SS_DEAD;
03485 }
03486
03487 sRef_clearDerived (other);
03488 sRef_clearDerived (res);
03489 }
03490 else if (res->defstate == SS_DEFINED
03491 && (other->defstate == SS_ALLOCATED
03492 && sRef_definitelyNull (other)))
03493 {
03494 other->defstate = SS_DEFINED;
03495 }
03496 else if (other->defstate == SS_DEFINED
03497 && (res->defstate == SS_ALLOCATED && sRef_definitelyNull (res)))
03498 {
03499 res->defstate = SS_DEFINED;
03500 res->definfo = alinfo_update (res->definfo, other->definfo);
03501 }
03502 else
03503 {
03504 ;
03505 }
03506
03507 if (res->defstate == SS_DEAD && other->defstate == SS_DEAD)
03508 {
03509 sRef_clearDerived (other);
03510 sRef_clearDerived (res);
03511 }
03512
03513
03514
03515
03516
03517 if (alkind_isOnly (other->aliaskind) && other->defstate == SS_DEAD)
03518 {
03519 other->aliaskind = AK_UNKNOWN;
03520 }
03521
03522 if (alkind_isOnly (res->aliaskind) && res->defstate == SS_DEAD)
03523 {
03524 res->aliaskind = AK_UNKNOWN;
03525 }
03526
03527
03528
03529
03530
03531 if (alkind_isDependent (other->aliaskind) && res->defstate == SS_DEAD)
03532 {
03533 other->aliaskind = AK_UNKNOWN;
03534 other->defstate = SS_DEAD;
03535 sRef_clearDerived (res);
03536 sRef_clearDerived (other);
03537 }
03538
03539 if (alkind_isDependent (res->aliaskind) && other->defstate == SS_DEAD)
03540 {
03541 res->aliaskind = AK_UNKNOWN;
03542 res->defstate = SS_DEAD;
03543 sRef_clearDerived (res);
03544 sRef_clearDerived (other);
03545 }
03546
03547
03548
03549
03550
03551
03552 sRef_combineAliasKinds (res, other, cl, loc);
03553 sRef_combineDefState (res, other);
03554 sRef_combineNullState (res, other);
03555
03556 if (rdef == SS_ALLOCATED || rdef == SS_SPECIAL)
03557 {
03558 if (odef == SS_DEFINED)
03559 {
03560 if (onull == NS_DEFNULL || onull == NS_CONSTNULL)
03561 {
03562 res->deriv = sRefSet_copy (res->deriv, other->deriv);
03563 }
03564
03565 ;
03566 }
03567 else if (odef == SS_ALLOCATED
03568 || odef == SS_SPECIAL)
03569 {
03570
03571 if (doDerivs)
03572 {
03573 if (ctype_isUnion (ctype_realType (sRef_getType (res))))
03574 {
03575 res->deriv = sRef_mergeUnionDerivs (res->deriv,
03576 other->deriv,
03577 opt, cl, loc);
03578 }
03579 else
03580 {
03581 res->deriv = sRef_mergeDerivs (res->deriv, other->deriv,
03582 opt, cl, loc);
03583 }
03584 }
03585 }
03586 else
03587 {
03588 if (doDerivs)
03589 {
03590 res->deriv = sRef_mergeDerivs (res->deriv, other->deriv,
03591 opt, cl, loc);
03592 }
03593 else
03594 {
03595 }
03596 }
03597 }
03598 else
03599 {
03600 if (rdef == SS_PDEFINED
03601 || (rdef == SS_DEFINED && odef == SS_PDEFINED))
03602 {
03603 if (doDerivs)
03604 {
03605 res->deriv = sRef_mergePdefinedDerivs (res->deriv, other->deriv,
03606 opt, cl, loc);
03607 }
03608 }
03609 else
03610 {
03611 if ((rdef == SS_DEFINED || rdef == SS_UNKNOWN)
03612 && res->defstate == SS_ALLOCATED)
03613 {
03614 res->deriv = sRefSet_copy (res->deriv, other->deriv);
03615 }
03616 else
03617 {
03618 if (doDerivs)
03619 {
03620 res->deriv = sRef_mergeDerivs (res->deriv, other->deriv,
03621 opt, cl, loc);
03622 }
03623 }
03624 }
03625 }
03626
03627
03628 sRef_combineExKinds (res, other);
03629 }
03630 else
03631 {
03632 if (res->kind == SK_ARRAYFETCH && other->kind == SK_PTR)
03633 {
03634 sRef nother = sRef_buildArrayFetchKnown (sRef_getBase (other), 0);
03635
03636 sRef_copyState (nother, other);
03637 sRef_mergeStateAux (res, nother, cl, opt, loc, doDerivs);
03638 }
03639 else if (res->kind == SK_PTR && other->kind == SK_ARRAYFETCH)
03640 {
03641 sRef nother = sRef_buildPointer (sRef_getBase (other));
03642
03643 if (sRef_isValid (nother))
03644 {
03645 sRef_copyState (nother, other);
03646 sRef_mergeStateAux (res, nother, cl, opt, loc, doDerivs);
03647 }
03648 }
03649 else
03650 {
03651 llcontbug (message ("merge conj: %q / %q", sRef_unparseFull (res),
03652 sRef_unparseFull (other)));
03653
03654 }
03655 }
03656
03657 }
03658
03659 static sRefSet
03660 sRef_mergeUnionDerivs ( sRefSet res,
03661 sRefSet other, bool opt,
03662 clause cl, fileloc loc)
03663 {
03664 if (sRefSet_isEmpty (res))
03665 {
03666 return sRefSet_copy (res, other);
03667 }
03668 else
03669 {
03670 sRefSet_allElements (other, el)
03671 {
03672 if (sRef_isValid (el))
03673 {
03674 sRef e2 = sRefSet_lookupMember (other, el);
03675
03676 if (sRef_isValid (e2))
03677 {
03678 sRef_mergeStateAux (el, e2, cl, opt, loc, FALSE);
03679 }
03680 else
03681 {
03682 res = sRefSet_insert (res, el);
03683 }
03684 }
03685 } end_sRefSet_allElements ;
03686
03687 return res;
03688 }
03689 }
03690
03691 static sRefSet
03692 sRef_mergeDerivs ( sRefSet res, sRefSet other,
03693 bool opt, clause cl, fileloc loc)
03694 {
03695 sRefSet ret = sRefSet_new ();
03696
03697
03698 sRefSet_allElements (res, el)
03699 {
03700 if (sRef_isValid (el))
03701 {
03702 sRef e2 = sRefSet_lookupMember (other, el);
03703
03704 if (sRef_isValid (e2))
03705 {
03706 if (el->defstate == SS_ALLOCATED &&
03707 e2->defstate == SS_PDEFINED)
03708 {
03709 e2->defstate = SS_ALLOCATED;
03710 }
03711 else if (e2->defstate == SS_ALLOCATED &&
03712 el->defstate == SS_PDEFINED)
03713 {
03714 el->defstate = SS_ALLOCATED;
03715 sRef_clearDerived (el);
03716 }
03717 else if ((el->defstate == SS_DEAD || sRef_isKept (el)) &&
03718 (e2->defstate == SS_DEFINED && !sRef_isKept (e2)))
03719 {
03720
03721 if (checkDeadState (el, TRUE, loc))
03722 {
03723 if (sRef_isThroughArrayFetch (el))
03724 {
03725 sRef_maybeKill (el, loc);
03726 sRef_maybeKill (e2, loc);
03727 }
03728 }
03729 }
03730 else if ((e2->defstate == SS_DEAD || sRef_isKept (e2)) &&
03731 (el->defstate == SS_DEFINED && !sRef_isKept (el)))
03732 {
03733
03734 if (checkDeadState (e2, FALSE, loc))
03735 {
03736 if (sRef_isThroughArrayFetch (el))
03737 {
03738 sRef_maybeKill (el, loc);
03739 sRef_maybeKill (e2, loc);
03740 }
03741 }
03742 }
03743 else if (el->defstate == SS_DEFINED &&
03744 e2->defstate == SS_PDEFINED)
03745 {
03746 el->defstate = SS_PDEFINED;
03747 }
03748 else if (e2->defstate == SS_DEFINED &&
03749 el->defstate == SS_PDEFINED)
03750 {
03751 e2->defstate = SS_PDEFINED;
03752 }
03753 else
03754 {
03755 ;
03756 }
03757
03758 if (ctype_isUnion (ctype_realType (sRef_getType (el))))
03759 {
03760 el->deriv = sRef_mergeUnionDerivs (el->deriv, e2->deriv,
03761 opt, cl, loc);
03762 }
03763 else
03764 {
03765 el->deriv = sRef_mergeDerivs (el->deriv, e2->deriv, opt, cl, loc);
03766 }
03767
03768 if (sRef_equivalent (el, e2))
03769 {
03770 ret = sRefSet_insert (ret, el);
03771 }
03772 else
03773 {
03774 sRef sr = sRef_leastCommon (el, e2);
03775
03776 if (sRef_isValid (sr))
03777 {
03778 ret = sRefSet_insert (ret, sr);
03779 }
03780 else
03781 {
03782 ;
03783 }
03784 }
03785
03786 (void) sRefSet_delete (other, e2);
03787 }
03788 else
03789 {
03790 (void) checkDeadState (el, TRUE, loc);
03791 }
03792 }
03793 } end_sRefSet_allElements;
03794
03795 sRefSet_allElements (other, el)
03796 {
03797 if (sRef_isValid (el))
03798 {
03799 (void) checkDeadState (el, FALSE, loc);
03800 }
03801 } end_sRefSet_allElements;
03802
03803 sRefSet_free (res);
03804 return (ret);
03805 }
03806
03807
03808
03809
03810
03811 static bool checkDeadState ( sRef el, bool tbranch, fileloc loc)
03812 {
03813
03814
03815
03816
03817
03818
03819
03820
03821
03822
03823
03824
03825
03826
03827 if ((sRef_isDead (el) || sRef_isKept (el))
03828 && !sRef_isDeepUnionField (el) && !sRef_isThroughArrayFetch (el))
03829 {
03830
03831 if (!tbranch)
03832 {
03833 if (usymtab_isProbableDeepNull (el))
03834 {
03835 return TRUE;
03836 }
03837 }
03838 else
03839 {
03840 if (usymtab_isAltProbablyDeepNull (el))
03841 {
03842 return TRUE;
03843 }
03844 }
03845
03846 if (optgenerror
03847 (FLG_BRANCHSTATE,
03848 message ("Storage %q is %q in one path, but live in another.",
03849 sRef_unparse (el),
03850 cstring_makeLiteral (sRef_isKept (el)
03851 ? "kept" : "released")),
03852 loc))
03853 {
03854
03855 if (sRef_isKept (el))
03856 {
03857 sRef_showAliasInfo (el);
03858 }
03859 else
03860 {
03861 sRef_showStateInfo (el);
03862 }
03863
03864
03865 el->defstate = SS_UNKNOWN;
03866 sRef_setAliasKind (el, AK_ERROR, fileloc_undefined);
03867
03868 return FALSE;
03869 }
03870 }
03871
03872 return TRUE;
03873 }
03874
03875 static void
03876 checkDerivDeadState ( sRef el, bool tbranch, fileloc loc)
03877 {
03878
03879 if (checkDeadState (el, tbranch, loc))
03880 {
03881 sRefSet_allElements (el->deriv, t)
03882 {
03883 if (sRef_isValid (t))
03884 {
03885 checkDerivDeadState (t, tbranch, loc);
03886 }
03887 } end_sRefSet_allElements;
03888 }
03889 }
03890
03891 static sRefSet
03892 sRef_mergePdefinedDerivs (sRefSet res, sRefSet other, bool opt,
03893 clause cl, fileloc loc)
03894 {
03895 sRefSet ret = sRefSet_new ();
03896
03897 sRefSet_allElements (res, el)
03898 {
03899 if (sRef_isValid (el))
03900 {
03901 sRef e2 = sRefSet_lookupMember (other, el);
03902
03903 if (sRef_isValid (e2))
03904 {
03905 if (sRef_isAllocated (el) && !sRef_isAllocated (e2))
03906 {
03907 ;
03908 }
03909 else if (sRef_isAllocated (e2) && !sRef_isAllocated (el))
03910 {
03911 el->deriv = sRefSet_copy (el->deriv, e2->deriv);
03912 }
03913 else
03914 {
03915 el->deriv = sRef_mergePdefinedDerivs (el->deriv, e2->deriv,
03916 opt, cl, loc);
03917 }
03918
03919 sRef_mergeStateAux (el, e2, cl, opt, loc, FALSE);
03920
03921 ret = sRefSet_insert (ret, el);
03922 (void) sRefSet_delete (other, e2);
03923 }
03924 else
03925 {
03926 if (!opt)
03927 {
03928 checkDerivDeadState (el, (cl == FALSECLAUSE), loc);
03929 }
03930
03931 ret = sRefSet_insert (ret, el);
03932 }
03933 }
03934 } end_sRefSet_allElements;
03935
03936 sRefSet_allElements (other, el)
03937 {
03938 if (sRef_isValid (el))
03939 {
03940 if (!sRefSet_member (ret, el))
03941 {
03942
03943 checkDerivDeadState (el, FALSE, loc);
03944 ret = sRefSet_insert (ret, el);
03945 }
03946 else
03947 {
03948
03949
03950
03951 }
03952 }
03953 } end_sRefSet_allElements;
03954
03955 sRefSet_free (res);
03956 return (ret);
03957 }
03958
03959 sRef sRef_makeConj ( sRef a, sRef b)
03960 {
03961 llassert (sRef_isValid (a));
03962 llassert (sRef_isValid (b));
03963
03964 if (!sRef_equivalent (a, b))
03965 {
03966 sRef s = sRef_new ();
03967
03968 s->kind = SK_CONJ;
03969 s->info = (sinfo) dmalloc (sizeof (*s->info));
03970 s->info->conj = (cjinfo) dmalloc (sizeof (*s->info->conj));
03971 s->info->conj->a = a;
03972 s->info->conj->b = b;
03973
03974 if (ctype_equal (a->type, b->type)) s->type = a->type;
03975 else s->type = ctype_makeConj (a->type, b->type);
03976
03977 if (a->defstate == b->defstate)
03978 {
03979 s->defstate = a->defstate;
03980 }
03981 else
03982 {
03983 s->defstate = SS_UNKNOWN;
03984 }
03985
03986 s->nullstate = NS_UNKNOWN;
03987
03988 s->safe = a->safe && b->safe;
03989 s->aliaskind = alkind_resolve (a->aliaskind, b->aliaskind);
03990
03991 return s;
03992 }
03993 else
03994 {
03995 return a;
03996 }
03997 }
03998
03999 sRef
04000 sRef_makeUnknown ()
04001 {
04002 sRef s = sRef_new ();
04003
04004 s->kind = SK_UNKNOWN;
04005 return s;
04006 }
04007
04008 static sRef
04009 sRef_makeSpecial (speckind sk)
04010 {
04011 sRef s = sRef_new ();
04012
04013 s->kind = SK_SPECIAL;
04014 s->info = (sinfo) dmalloc (sizeof (*s->info));
04015 s->info->spec = sk;
04016 return s;
04017 }
04018
04019 static sRef srnothing = sRef_undefined;
04020 static sRef srinternal = sRef_undefined;
04021 static sRef srsystem = sRef_undefined;
04022 static sRef srspec = sRef_undefined;
04023
04024 sRef
04025 sRef_makeNothing (void)
04026 {
04027 if (sRef_isInvalid (srnothing))
04028 {
04029 srnothing = sRef_makeSpecial (SR_NOTHING);
04030 }
04031
04032
04033 return srnothing;
04034
04035 }
04036
04037 sRef
04038 sRef_makeInternalState (void)
04039 {
04040 if (sRef_isInvalid (srinternal))
04041 {
04042 srinternal = sRef_makeSpecial (SR_INTERNAL);
04043 }
04044
04045
04046 return srinternal;
04047
04048 }
04049
04050 sRef
04051 sRef_makeSpecState (void)
04052 {
04053 if (sRef_isInvalid (srspec))
04054 {
04055 srspec = sRef_makeSpecial (SR_SPECSTATE);
04056 }
04057
04058
04059 return srspec;
04060
04061 }
04062
04063 sRef
04064 sRef_makeSystemState (void)
04065 {
04066 if (sRef_isInvalid (srsystem))
04067 {
04068 srsystem = sRef_makeSpecial (SR_SYSTEM);
04069 }
04070
04071
04072 return (srsystem);
04073
04074 }
04075
04076 static sRef
04077 sRef_makeResultType (ctype ct)
04078 {
04079 sRef res = sRef_makeResult ();
04080
04081 res->type = ct;
04082 return res;
04083 }
04084
04085 sRef
04086 sRef_makeResult ()
04087 {
04088 sRef s = sRef_new ();
04089
04090 s->kind = SK_RESULT;
04091 s->type = ctype_unknown;
04092 s->defstate = SS_UNKNOWN;
04093 s->aliaskind = AK_UNKNOWN;
04094 s->nullstate = NS_UNKNOWN;
04095
04096 return s;
04097 }
04098
04099
04100 bool
04101 sRef_isNothing (sRef s)
04102 {
04103 return (sRef_isKindSpecial (s) && s->info->spec == SR_NOTHING);
04104 }
04105
04106 bool
04107 sRef_isInternalState (sRef s)
04108 {
04109 return (sRef_isKindSpecial (s) && s->info->spec == SR_INTERNAL);
04110 }
04111
04112 bool
04113 sRef_isSpecInternalState (sRef s)
04114 {
04115 return (sRef_isKindSpecial (s)
04116 && (s->info->spec == SR_INTERNAL || s->info->spec == SR_SPECSTATE));
04117 }
04118
04119 bool
04120 sRef_isSpecState (sRef s)
04121 {
04122 return (sRef_isKindSpecial (s) && s->info->spec == SR_SPECSTATE);
04123 }
04124
04125 bool
04126 sRef_isResult (sRef s)
04127 {
04128 return (sRef_isValid (s) && s->kind == SK_RESULT);
04129 }
04130
04131 bool
04132 sRef_isSystemState (sRef s)
04133 {
04134 return (sRef_isKindSpecial (s) && s->info->spec == SR_SYSTEM);
04135 }
04136
04137 usymId
04138 sRef_getScopeIndex (sRef s)
04139 {
04140 llassert (sRef_isValid (s));
04141 llassert (sRef_isCvar (s));
04142
04143 return (s->info->cvar->index);
04144 }
04145
04146 void
04147 sRef_makeSafe (sRef s)
04148 {
04149 if (sRef_isValid (s))
04150 {
04151 s->safe = TRUE;
04152 }
04153 }
04154
04155 void
04156 sRef_makeUnsafe (sRef s)
04157 {
04158 if (sRef_isValid (s))
04159 {
04160 s->safe = FALSE;
04161 }
04162 }
04163
04164
04165
04166
04167
04168 cstring sRef_unparseFull (sRef s)
04169 {
04170 if (sRef_isInvalid (s)) return (cstring_undefined);
04171
04172 return (message ("[%d] %q - %q [%s] { %q }",
04173 (int) s,
04174 sRef_unparseDebug (s),
04175 sRef_unparseState (s),
04176 exkind_unparse (s->oexpkind),
04177 sRefSet_unparseDebug (s->deriv)));
04178 }
04179
04180 cstring sRef_unparseDeep (sRef s)
04181 {
04182 cstring st = cstring_undefined;
04183
04184 st = message ("%q:", sRef_unparseFull (s));
04185
04186 if (sRef_isValid (s))
04187 {
04188 sRefSet_allElements (s->deriv, el)
04189 {
04190 st = message("%q\n%q", st, sRef_unparseDeep (el));
04191 } end_sRefSet_allElements ;
04192 }
04193
04194 return st;
04195 }
04196
04197 cstring sRef_unparseState (sRef s)
04198 {
04199 if (sRef_isConj (s))
04200 {
04201 return (message ("%q | %q",
04202 sRef_unparseState (s->info->conj->a),
04203 sRef_unparseState (s->info->conj->b)));
04204 }
04205
04206 if (sRef_isInvalid (s))
04207 {
04208 return (cstring_makeLiteral ("<invalid>"));
04209 }
04210
04211 return (message ("%s.%s.%s.%s",
04212 alkind_unparse (s->aliaskind),
04213 nstate_unparse (s->nullstate),
04214 exkind_unparse (s->expkind),
04215 sstate_unparse (s->defstate)));
04216 }
04217
04218 bool sRef_isNotUndefined (sRef s)
04219 {
04220 return (sRef_isInvalid (s)
04221 || (s->defstate != SS_UNDEFINED
04222 && s->defstate != SS_UNUSEABLE
04223 && s->defstate != SS_DEAD));
04224 }
04225
04226 ynm sRef_isWriteable (sRef s)
04227 {
04228 if (sRef_isInvalid (s)) return MAYBE;
04229
04230 if (sRef_isConj (s) && s->defstate == SS_UNKNOWN)
04231 {
04232 if (ynm_toBoolStrict (sRef_isWriteable (sRef_getConjA (s))))
04233 {
04234 if (ynm_toBoolStrict (sRef_isWriteable (sRef_getConjB (s))))
04235 {
04236 return YES;
04237 }
04238 return MAYBE;
04239 }
04240 else
04241 {
04242 if (ynm_toBoolStrict (sRef_isWriteable (sRef_getConjB (s))))
04243 {
04244 return MAYBE;
04245 }
04246 return NO;
04247 }
04248 }
04249
04250 return (ynm_fromBool (s->defstate != SS_UNUSEABLE));
04251 }
04252
04253 bool sRef_hasNoStorage (sRef s)
04254 {
04255 return (!sRef_isAllocatedStorage (s) || sRef_isDefinitelyNull (s));
04256 }
04257
04258 bool sRef_isStrictReadable (sRef s)
04259 {
04260 return (ynm_toBoolStrict (sRef_isReadable (s)));
04261 }
04262
04263 ynm sRef_isReadable (sRef s)
04264 {
04265 sstate ss;
04266
04267 if (sRef_isInvalid (s)) return YES;
04268
04269 ss = s->defstate;
04270
04271 if (sRef_isConj (s) && s->defstate == SS_UNKNOWN)
04272 {
04273 if (ynm_toBoolStrict (sRef_isReadable (sRef_getConjA (s))))
04274 {
04275 if (ynm_toBoolStrict (sRef_isReadable (sRef_getConjB (s))))
04276 {
04277 return YES;
04278 }
04279 return MAYBE;
04280 }
04281 else
04282 {
04283 if (ynm_toBoolStrict (sRef_isReadable (sRef_getConjB (s))))
04284 {
04285 return MAYBE;
04286 }
04287 return NO;
04288 }
04289 }
04290 else if (ss == SS_HOFFA)
04291 {
04292 if (context_getFlag (FLG_STRICTUSERELEASED))
04293 {
04294 return MAYBE;
04295 }
04296 else
04297 {
04298 return YES;
04299 }
04300 }
04301 else
04302 {
04303 return (ynm_fromBool (ss == SS_DEFINED
04304 || ss == SS_FIXED
04305 || ss == SS_RELDEF
04306 || ss == SS_PDEFINED
04307 || ss == SS_PARTIAL
04308 || ss == SS_SPECIAL
04309 || ss == SS_ALLOCATED
04310 || ss == SS_UNKNOWN));
04311 }
04312 }
04313
04314 static sRef whatUndefined ( sRef fref, int depth)
04315 {
04316 ctype ct;
04317
04318
04319 if (depth > MAXDEPTH)
04320 {
04321 llgenmsg (message
04322 ("Warning: check definition limit exceeded, checking %q. "
04323 "This either means there is a variable with at least "
04324 "%d indirections apparent in the program text, or "
04325 "there is a bug in LCLint.",
04326 sRef_unparse (fref),
04327 MAXDEPTH),
04328 g_currentloc);
04329
04330 return sRef_undefined;
04331 }
04332
04333 if (!sRef_isKnown (fref) || sRef_isAnyDefined (fref))
04334 {
04335 return sRef_undefined;
04336 }
04337
04338 if (sRef_isUnuseable (fref) || sRef_isStateUndefined (fref))
04339 {
04340 return fref;
04341 }
04342
04343 ct = ctype_realType (sRef_getType (fref));
04344
04345 if (ctype_isUnknown (ct))
04346 {
04347 return sRef_undefined;
04348 }
04349 else if (ctype_isPointer (ct) || ctype_isArray (ct))
04350 {
04351 if (sRef_isStateUnknown (fref))
04352 {
04353 return sRef_undefined;
04354 }
04355 else
04356 {
04357 sRef fptr = sRef_constructDeref (fref);
04358
04359 return (whatUndefined (fptr, depth + 1));
04360 }
04361 }
04362 else if (ctype_isStruct (ct))
04363 {
04364 bool hasOneDefined = FALSE;
04365
04366 if (sRef_isStateUnknown (fref))
04367 {
04368 return fref;
04369 }
04370
04371 if (sRef_isPdefined (fref) || sRef_isAnyDefined (fref))
04372 {
04373 sRefSet_realElements (sRef_derivedFields (fref), sr)
04374 {
04375 hasOneDefined = TRUE;
04376
04377 if (sRef_isField (sr))
04378 {
04379 cstring fieldname = sRef_getField (sr);
04380 sRef fldref = sRef_makeField (fref, fieldname);
04381 bool shouldCheck = !sRef_isRecursiveField (fldref);
04382
04383 if (shouldCheck)
04384 {
04385 sRef wdef = whatUndefined (fldref, depth + 1);
04386
04387 if (sRef_isValid (wdef))
04388 {
04389 return wdef;
04390 }
04391 }
04392 }
04393 } end_sRefSet_realElements;
04394 }
04395 else if (sRef_isAllocated (fref))
04396 {
04397
04398
04399
04400
04401 uentryList fields = ctype_getFields (ct);
04402
04403 uentryList_elements (fields, ue)
04404 {
04405 cstring name = uentry_getRealName (ue);
04406 sRef ffield = sRef_makeField (fref, name);
04407 bool shouldCheck = !sRef_isRecursiveField (ffield);
04408
04409 if (sRef_isRelDef (uentry_getSref (ue)))
04410 {
04411 ;
04412 }
04413 else
04414 {
04415 if (shouldCheck)
04416 {
04417 sRef wdef = whatUndefined (ffield, depth + 1);
04418
04419 if (sRef_isInvalid (wdef))
04420 {
04421 return wdef;
04422 }
04423 }
04424 }
04425 } end_uentryList_elements;
04426 }
04427 else
04428 {
04429 ;
04430 }
04431 }
04432 else if (ctype_isUnion (ct))
04433 {
04434 ;
04435 }
04436 else
04437 {
04438 ;
04439 }
04440
04441 return sRef_undefined;
04442 }
04443
04444 static bool checkDefined (sRef sr)
04445 {
04446 return (sRef_isInvalid (whatUndefined (sr, 0)));
04447 }
04448
04449 bool sRef_isReallyDefined (sRef s)
04450 {
04451 if (sRef_isValid (s))
04452 {
04453 if (sRef_isAnyDefined (s))
04454 {
04455 return TRUE;
04456 }
04457 else
04458 {
04459 if (sRef_isAllocated (s) || sRef_isPdefined (s))
04460 {
04461 return checkDefined (s);
04462 }
04463 else
04464 {
04465 return FALSE;
04466 }
04467 }
04468 }
04469 else
04470 {
04471 return TRUE;
04472 }
04473 }
04474
04475 void sRef_showNotReallyDefined (sRef s)
04476 {
04477 if (sRef_isValid (s))
04478 {
04479 if (sRef_isAnyDefined (s))
04480 {
04481 BADBRANCH;
04482 }
04483 else
04484 {
04485 if (sRef_isAllocated (s) || sRef_isPdefined (s))
04486 {
04487 sRef ref = whatUndefined (s, 0);
04488
04489 llassert (sRef_isValid (ref));
04490
04491 if (ref != s)
04492 {
04493 llgenindentmsgnoloc
04494 (message ("This sub-reference is %s: %q",
04495 sstate_unparse (sRef_getDefState (ref)),
04496 sRef_unparse (ref)));
04497 }
04498 }
04499 else
04500 {
04501 ;
04502 }
04503 }
04504 }
04505 else
04506 {
04507 BADBRANCH;
04508 }
04509 }
04510
04511 sstate sRef_getDefState (sRef s)
04512 {
04513 if (sRef_isInvalid (s)) return (SS_UNKNOWN);
04514 return (s->defstate);
04515 }
04516
04517 void sRef_setDefState (sRef s, sstate defstate, fileloc loc)
04518 {
04519 sRef_setStateAux (s, defstate, loc);
04520 }
04521
04522 static void sRef_clearAliasStateAux (sRef s, fileloc loc)
04523 {
04524 sRef_setAliasKind (s, AK_ERROR, loc);
04525 }
04526
04527 void sRef_clearAliasState (sRef s, fileloc loc)
04528 {
04529 sRef_aliasSetComplete (sRef_clearAliasStateAux, s, loc);
04530 }
04531
04532 void sRef_setAliasKindComplete (sRef s, alkind kind, fileloc loc)
04533 {
04534 sRef_aliasSetCompleteParam (sRef_setAliasKind, s, kind, loc);
04535 }
04536
04537 void sRef_setAliasKind (sRef s, alkind kind, fileloc loc)
04538 {
04539 if (sRef_isValid (s))
04540 {
04541 sRef_clearDerived (s);
04542
04543 if ((kind != s->aliaskind && kind != s->oaliaskind)
04544 && fileloc_isDefined (loc))
04545 {
04546 s->aliasinfo = alinfo_updateLoc (s->aliasinfo, loc);
04547 }
04548
04549 s->aliaskind = kind;
04550 }
04551 }
04552
04553 void sRef_setOrigAliasKind (sRef s, alkind kind)
04554 {
04555 if (sRef_isValid (s))
04556 {
04557 s->oaliaskind = kind;
04558 }
04559 }
04560
04561 exkind sRef_getExKind (sRef s)
04562 {
04563 if (sRef_isValid (s))
04564 {
04565 return (s->expkind);
04566 }
04567 else
04568 {
04569 return XO_UNKNOWN;
04570 }
04571 }
04572
04573 exkind sRef_getOrigExKind (sRef s)
04574 {
04575 if (sRef_isValid (s))
04576 {
04577 return (s->oexpkind);
04578 }
04579 else
04580 {
04581 return XO_UNKNOWN;
04582 }
04583 }
04584
04585 static void sRef_clearExKindAux (sRef s, fileloc loc)
04586 {
04587 sRef_setExKind (s, XO_UNKNOWN, loc);
04588 }
04589
04590 void sRef_setObserver (sRef s, fileloc loc)
04591 {
04592 sRef_setExKind (s, XO_OBSERVER, loc);
04593 }
04594
04595 void sRef_setExposed (sRef s, fileloc loc)
04596 {
04597 sRef_setExKind (s, XO_EXPOSED, loc);
04598 }
04599
04600 void sRef_clearExKindComplete (sRef s, fileloc loc)
04601 {
04602 (void) sRef_aliasSetComplete (sRef_clearExKindAux, s, loc);
04603 }
04604
04605 void sRef_setExKind (sRef s, exkind exp, fileloc loc)
04606 {
04607 if (sRef_isValid (s))
04608 {
04609 if (s->expkind != exp)
04610 {
04611 s->expinfo = alinfo_updateLoc (s->expinfo, loc);
04612 }
04613
04614 s->expkind = exp;
04615 }
04616 }
04617
04618
04619
04620
04621
04622 static void sRef_copyRealDerived (sRef s1, sRef s2)
04623 {
04624 if (sRef_isValid (s1) && sRef_isValid (s2))
04625 {
04626 sRef sb = sRef_getRootBase (s1);
04627
04628 sRefSet_clear (s1->deriv);
04629
04630 sRefSet_allElements (s2->deriv, el)
04631 {
04632 if (sRef_isValid (el))
04633 {
04634 sRef rb = sRef_getRootBase (el);
04635
04636 if (!sRef_same (rb, sb))
04637 {
04638 sRef fb = sRef_fixDirectBase (el, s1);
04639
04640 if (sRef_isValid (fb))
04641 {
04642 sRef_copyRealDerived (fb, el);
04643 sRef_addDeriv (s1, fb);
04644 }
04645 }
04646 else
04647 {
04648 sRef_addDeriv (s1, el);
04649 }
04650 }
04651 } end_sRefSet_allElements ;
04652 }
04653
04654 }
04655
04656 void sRef_copyRealDerivedComplete (sRef s1, sRef s2)
04657 {
04658 sRef_innerAliasSetCompleteParam (sRef_copyRealDerived, s1, s2);
04659 }
04660
04661 void sRef_setUndefined (sRef s, fileloc loc)
04662 {
04663 if (sRef_isValid (s))
04664 {
04665 s->defstate = SS_UNDEFINED;
04666
04667 if (fileloc_isDefined (loc))
04668 {
04669 s->definfo = alinfo_updateLoc (s->definfo, loc);
04670 }
04671
04672 sRef_clearDerived (s);
04673 }
04674 }
04675
04676 static void sRef_setDefinedAux (sRef s, fileloc loc, bool clear)
04677 {
04678 if (sRef_isInvalid (s)) return;
04679
04680 if (s->defstate != SS_DEFINED && fileloc_isDefined (loc))
04681 {
04682 s->definfo = alinfo_updateLoc (s->definfo, loc);
04683 }
04684
04685 s->defstate = SS_DEFINED;
04686
04687
04688
04689 if (s->kind == SK_PTR)
04690 {
04691 sRef p = s->info->ref;
04692
04693 if (p->defstate == SS_ALLOCATED)
04694 {
04695 sRef_setDefinedAux (p, loc, clear);
04696 }
04697 }
04698 else if (s->kind == SK_ARRAYFETCH)
04699 {
04700 if (!s->info->arrayfetch->indknown
04701 || (s->info->arrayfetch->ind == 0))
04702 {
04703 sRef p = s->info->arrayfetch->arr;
04704 sRef ptr = sRef_constructPointer (p);
04705
04706 if (sRef_isValid (ptr))
04707 {
04708 if (ptr->defstate == SS_ALLOCATED
04709 || ptr->defstate == SS_UNDEFINED)
04710 {
04711 sRef_setDefinedAux (ptr, loc, clear);
04712 }
04713 }
04714
04715 if (p->defstate == SS_RELDEF)
04716 {
04717 ;
04718 }
04719 else if (p->defstate == SS_ALLOCATED || p->defstate == SS_PDEFINED)
04720 {
04721 p->defstate = SS_DEFINED;
04722 }
04723 else
04724 {
04725 }
04726 }
04727 }
04728 else if (s->kind == SK_FIELD)
04729 {
04730 sRef parent = s->info->field->rec;
04731
04732 if (sRef_isValid (parent))
04733 {
04734 if (ctype_isUnion (ctype_realType (parent->type)))
04735 {
04736
04737
04738
04739
04740 sRef_setDefinedNoClear (parent, loc);
04741 }
04742 else
04743 {
04744 ;
04745 }
04746 }
04747
04748 }
04749 else
04750 {
04751 ;
04752 }
04753
04754 if (clear)
04755 {
04756 sRef_clearDerived (s);
04757 }
04758 }
04759
04760 static void sRef_setPartialDefined (sRef s, fileloc loc)
04761 {
04762 if (!sRef_isPartial (s))
04763 {
04764 sRef_setDefined (s, loc);
04765 }
04766 }
04767
04768 void sRef_setPartialDefinedComplete (sRef s, fileloc loc)
04769 {
04770 sRef_innerAliasSetComplete (sRef_setPartialDefined, s, loc);
04771 }
04772
04773 void sRef_setDefinedComplete (sRef s, fileloc loc)
04774 {
04775 sRef_innerAliasSetComplete (sRef_setDefined, s, loc);
04776 }
04777
04778 void sRef_setDefined (sRef s, fileloc loc)
04779 {
04780 sRef_setDefinedAux (s, loc, TRUE);
04781 }
04782
04783 static void sRef_setDefinedNoClear (sRef s, fileloc loc)
04784 {
04785 DPRINTF (("Defining: %s", sRef_unparseFull (s)));
04786 sRef_setDefinedAux (s, loc, FALSE);
04787 DPRINTF (("==> %s", sRef_unparseFull (s)));
04788 }
04789
04790 void sRef_setDefinedNCComplete (sRef s, fileloc loc)
04791 {
04792 DPRINTF (("Set Defined Complete: %s", sRef_unparseFull (s)));
04793 sRef_innerAliasSetComplete (sRef_setDefinedNoClear, s, loc);
04794 DPRINTF (("==> %s", sRef_unparseFull (s)));
04795 }
04796
04797 static bool sRef_isDeepUnionField (sRef s)
04798 {
04799 return (sRef_deepPred (sRef_isUnionField, s));
04800 }
04801
04802 bool sRef_isUnionField (sRef s)
04803 {
04804 if (sRef_isValid (s) && s->kind == SK_FIELD)
04805 {
04806
04807
04808
04809
04810 sRef base = s->info->field->rec;
04811
04812 if (sRef_isValid (base))
04813 {
04814 return (ctype_isUnion (ctype_realType (base->type)));
04815 }
04816 }
04817
04818 return FALSE;
04819 }
04820
04821 void sRef_setPdefined (sRef s, fileloc loc)
04822 {
04823 if (sRef_isValid (s) && !sRef_isPartial (s))
04824 {
04825 sRef base = sRef_getBaseSafe (s);
04826
04827 if (s->defstate == SS_ALLOCATED)
04828 {
04829 return;
04830 }
04831
04832 if (s->defstate != SS_PDEFINED && fileloc_isDefined (loc))
04833 {
04834 s->definfo = alinfo_updateLoc (s->definfo, loc);
04835 }
04836
04837 s->defstate = SS_PDEFINED;
04838
04839
04840
04841 while (sRef_isValid (base) && sRef_isKnown (base))
04842 {
04843 if (base->defstate == SS_DEFINED)
04844 {
04845 sRef nb;
04846
04847 base->defstate = SS_PDEFINED;
04848 nb = sRef_getBaseSafe (base);
04849 base = nb;
04850 }
04851 else
04852 {
04853 break;
04854 }
04855 }
04856 }
04857 }
04858
04859 static void sRef_setStateAux (sRef s, sstate ss, fileloc loc)
04860 {
04861 if (sRef_isValid (s))
04862 {
04863
04864
04865 if (s->defstate != ss && fileloc_isDefined (loc))
04866 {
04867 s->definfo = alinfo_updateLoc (s->definfo, loc);
04868 }
04869
04870 s->defstate = ss;
04871 sRef_clearDerived (s);
04872
04873 if (ss == SS_ALLOCATED)
04874 {
04875 sRef base = sRef_getBaseSafe (s);
04876
04877 while (sRef_isValid (base) && sRef_isKnown (base))
04878 {
04879 if (base->defstate == SS_DEFINED)
04880 {
04881 sRef nb;
04882
04883 base->defstate = SS_PDEFINED;
04884
04885 nb = sRef_getBaseSafe (base);
04886 base = nb;
04887 }
04888 else
04889 {
04890 break;
04891 }
04892 }
04893 }
04894
04895 }
04896 }
04897
04898 void sRef_setAllocatedComplete (sRef s, fileloc loc)
04899 {
04900 sRef_innerAliasSetComplete (sRef_setAllocated, s, loc);
04901 }
04902
04903 static void sRef_setAllocatedShallow (sRef s, fileloc loc)
04904 {
04905 if (sRef_isValid (s))
04906 {
04907 if (s->defstate == SS_DEAD || s->defstate == SS_UNDEFINED)
04908 {
04909 s->defstate = SS_ALLOCATED;
04910
04911 if (fileloc_isDefined (loc))
04912 {
04913 s->definfo = alinfo_updateLoc (s->definfo, loc);
04914 }
04915 }
04916 }
04917 }
04918
04919 void sRef_setAllocatedShallowComplete (sRef s, fileloc loc)
04920 {
04921 sRef_innerAliasSetComplete (sRef_setAllocatedShallow, s, loc);
04922 }
04923
04924 void sRef_setAllocated (sRef s, fileloc loc)
04925 {
04926 sRef_setStateAux (s, SS_ALLOCATED, loc);
04927 }
04928
04929 void sRef_setPartial (sRef s, fileloc loc)
04930 {
04931 sRef_setStateAux (s, SS_PARTIAL, loc);
04932 }
04933
04934 void sRef_setShared (sRef s, fileloc loc)
04935 {
04936 if (sRef_isValid (s))
04937 {
04938 if (s->aliaskind != AK_SHARED && fileloc_isDefined (loc))
04939 {
04940 s->aliasinfo = alinfo_updateLoc (s->aliasinfo, loc);
04941 }
04942
04943 s->aliaskind = AK_SHARED;
04944
04945 }
04946 }
04947
04948 void sRef_setLastReference (sRef s, sRef ref, fileloc loc)
04949 {
04950 if (sRef_isValid (s))
04951 {
04952 s->aliaskind = sRef_getAliasKind (ref);
04953 s->aliasinfo = alinfo_updateRefLoc (s->aliasinfo, ref, loc);
04954 }
04955 }
04956
04957 static
04958 void sRef_setNullStateAux ( sRef s, nstate ns, fileloc loc)
04959 {
04960 s->nullstate = ns;
04961
04962 if (fileloc_isDefined (loc))
04963 {
04964 s->nullinfo = alinfo_updateLoc (s->nullinfo, loc);
04965 }
04966 }
04967
04968 void sRef_setNotNull (sRef s, fileloc loc)
04969 {
04970 if (sRef_isValid (s))
04971 {
04972 sRef_setNullStateAux (s, NS_NOTNULL, loc);
04973 }
04974 }
04975
04976 void sRef_setNullState (sRef s, nstate n, fileloc loc)
04977 {
04978 if (sRef_isValid (s))
04979 {
04980 sRef_setNullStateAux (s, n, loc);
04981 }
04982 }
04983
04984 void sRef_setNullStateInnerComplete (sRef s, nstate n, fileloc loc)
04985 {
04986 sRef_setNullState (s, n, loc);
04987
04988 switch (n)
04989 {
04990 case NS_POSNULL:
04991 sRef_innerAliasSetComplete (sRef_setPosNull, s, loc);
04992 break;
04993 case NS_DEFNULL:
04994 sRef_innerAliasSetComplete (sRef_setDefNull, s, loc);
04995 break;
04996 case NS_UNKNOWN:
04997 sRef_innerAliasSetComplete (sRef_setNullUnknown, s, loc);
04998 break;
04999 case NS_NOTNULL:
05000 sRef_innerAliasSetComplete (sRef_setNotNull, s, loc);
05001 break;
05002 case NS_MNOTNULL:
05003 sRef_innerAliasSetComplete (sRef_setNotNull, s, loc);
05004 break;
05005 case NS_RELNULL:
05006 sRef_innerAliasSetComplete (sRef_setNullUnknown, s, loc);
05007 break;
05008 case NS_CONSTNULL:
05009 sRef_innerAliasSetComplete (sRef_setDefNull, s, loc);
05010 break;
05011 case NS_ABSNULL:
05012 sRef_innerAliasSetComplete (sRef_setNullUnknown, s, loc);
05013 break;
05014 case NS_ERROR:
05015 sRef_innerAliasSetComplete (sRef_setNullErrorLoc, s, loc);
05016 break;
05017 }
05018 }
05019
05020 void sRef_setPosNull (sRef s, fileloc loc)
05021 {
05022 if (sRef_isValid (s))
05023 {
05024 sRef_setNullStateAux (s, NS_POSNULL, loc);
05025 }
05026 }
05027
05028 void sRef_setDefNull (sRef s, fileloc loc)
05029 {
05030 if (sRef_isValid (s))
05031 {
05032 sRef_setNullStateAux (s, NS_DEFNULL, loc);
05033 }
05034 }
05035
05036 void sRef_setNullUnknown (sRef s, fileloc loc)
05037 {
05038 if (sRef_isValid (s))
05039 {
05040 sRef_setNullStateAux (s, NS_UNKNOWN, loc);
05041 }
05042 }
05043
05044 void sRef_setNullError (sRef s)
05045 {
05046 if (sRef_isValid (s))
05047 {
05048 sRef_setNullStateAux (s, NS_UNKNOWN, fileloc_undefined);
05049 }
05050 }
05051
05052 void sRef_setNullErrorLoc (sRef s, fileloc loc)
05053 {
05054 sRef_setNullError (s);
05055 }
05056
05057 void sRef_setOnly (sRef s, fileloc loc)
05058 {
05059 if (sRef_isValid (s) && s->aliaskind != AK_ONLY)
05060 {
05061 s->aliaskind = AK_ONLY;
05062 s->aliasinfo = alinfo_updateLoc (s->aliasinfo, loc);
05063 }
05064 }
05065
05066 void sRef_setDependent (sRef s, fileloc loc)
05067 {
05068 if (sRef_isValid (s) && !sRef_isConst (s) && (s->aliaskind != AK_DEPENDENT))
05069 {
05070 s->aliaskind = AK_DEPENDENT;
05071 s->aliasinfo = alinfo_updateLoc (s->aliasinfo, loc);
05072 }
05073 }
05074
05075 void sRef_setOwned (sRef s, fileloc loc)
05076 {
05077 if (sRef_isValid (s) && !sRef_isConst (s) && (s->aliaskind != AK_OWNED))
05078 {
05079 s->aliaskind = AK_OWNED;
05080 s->aliasinfo = alinfo_updateLoc (s->aliasinfo, loc);
05081 }
05082 }
05083
05084 void sRef_setKept (sRef s, fileloc loc)
05085 {
05086 if (sRef_isValid (s) && !sRef_isConst (s) && (s->aliaskind != AK_KEPT))
05087 {
05088 sRef base = sRef_getBaseSafe (s);
05089
05090 while (sRef_isValid (base) && sRef_isKnown (base))
05091 {
05092 if (base->defstate == SS_DEFINED)
05093 {
05094 base->defstate = SS_PDEFINED;
05095 base = sRef_getBaseSafe (base);
05096 }
05097 else
05098 {
05099 break;
05100 }
05101
05102 }
05103
05104 s->aliaskind = AK_KEPT;
05105 s->aliasinfo = alinfo_updateLoc (s->aliasinfo, loc);
05106 }
05107 }
05108
05109 static void sRef_setKeptAux (sRef s, fileloc loc)
05110 {
05111 if (!sRef_isShared (s))
05112 {
05113 sRef_setKept (s, loc);
05114 }
05115 }
05116
05117 static void sRef_setDependentAux (sRef s, fileloc loc)
05118 {
05119 if (!sRef_isShared (s))
05120 {
05121 sRef_setDependent (s, loc);
05122 }
05123 }
05124
05125 void sRef_setKeptComplete (sRef s, fileloc loc)
05126 {
05127 sRef_aliasSetComplete (sRef_setKeptAux, s, loc);
05128 }
05129
05130 void sRef_setDependentComplete (sRef s, fileloc loc)
05131 {
05132 sRef_aliasSetComplete (sRef_setDependentAux, s, loc);
05133 }
05134
05135 void sRef_setFresh (sRef s, fileloc loc)
05136 {
05137 if (sRef_isValid (s))
05138 {
05139 s->aliaskind = AK_FRESH;
05140 s->aliasinfo = alinfo_updateLoc (s->aliasinfo, loc);
05141 }
05142 }
05143
05144 void sRef_kill (sRef s, fileloc loc)
05145 {
05146 DPRINTF (("Kill: %s", sRef_unparseFull (s)));
05147
05148 if (sRef_isValid (s) && !sRef_isShared (s) && !sRef_isConst (s))
05149 {
05150 sRef base = sRef_getBaseSafe (s);
05151
05152 while (sRef_isValid (base) && sRef_isKnown (base))
05153 {
05154 if (base->defstate == SS_DEFINED)
05155 {
05156 base->defstate = SS_PDEFINED;
05157 base = sRef_getBaseSafe (base);
05158 }
05159 else
05160 {
05161 break;
05162 }
05163
05164 }
05165
05166 s->aliaskind = s->oaliaskind;
05167 s->defstate = SS_DEAD;
05168 s->definfo = alinfo_updateLoc (s->definfo, loc);
05169
05170 sRef_clearDerived (s);
05171 }
05172 }
05173
05174 void sRef_maybeKill (sRef s, fileloc loc)
05175 {
05176
05177 if (sRef_isValid (s))
05178 {
05179 sRef base = sRef_getBaseSafe (s);
05180
05181
05182 while (sRef_isValid (base) && sRef_isKnown (base))
05183 {
05184 if (base->defstate == SS_DEFINED || base->defstate == SS_RELDEF)
05185 {
05186 base->defstate = SS_PDEFINED;
05187 base = sRef_getBaseSafe (base);
05188 }
05189 else
05190 {
05191 break;
05192 }
05193
05194 }
05195
05196 s->aliaskind = s->oaliaskind;
05197 s->defstate = SS_HOFFA;
05198 s->definfo = alinfo_updateLoc (s->definfo, loc);
05199 sRef_clearDerived (s);
05200 }
05201
05202 }
05203
05204
05205
05206
05207
05208 static void sRef_killAux (sRef s, fileloc loc)
05209 {
05210 if (sRef_isValid (s) && !sRef_isShared (s))
05211 {
05212 if (sRef_isUnknownArrayFetch (s))
05213 {
05214 sRef_maybeKill (s, loc);
05215 }
05216 else
05217 {
05218 sRef_kill (s, loc);
05219 }
05220 }
05221 }
05222
05223
05224
05225
05226
05227 void sRef_killComplete (sRef s, fileloc loc)
05228 {
05229 DPRINTF (("Kill complete: %s", sRef_unparseFull (s)));
05230 sRef_aliasSetComplete (sRef_killAux, s, loc);
05231 }
05232
05233 static bool sRef_equivalent (sRef s1, sRef s2)
05234 {
05235 return (sRef_compare (s1, s2) == 0);
05236 }
05237
05238
05239
05240
05241
05242 sRef sRef_saveCopy (sRef s)
05243 {
05244 sRef ret;
05245
05246 if (sRef_isValid (s))
05247 {
05248 bool old = inFunction;
05249
05250
05251
05252
05253
05254
05255 inFunction = FALSE;
05256 DPRINTF (("Copying sref: %s", sRef_unparseFull(s)));
05257 ret = sRef_copy (s);
05258 DPRINTF (("Copying ===>: %s", sRef_unparseFull(ret)));
05259 inFunction = old;
05260 }
05261 else
05262 {
05263 ret = sRef_undefined;
05264 }
05265
05266
05267 return ret;
05268
05269 }
05270
05271 sRef sRef_copy (sRef s)
05272 {
05273 if (sRef_isKindSpecial (s))
05274 {
05275
05276 return s;
05277
05278 }
05279
05280 if (sRef_isValid (s))
05281 {
05282 sRef t = sRef_alloc ();
05283
05284 t->kind = s->kind;
05285 t->safe = s->safe;
05286 t->modified = s->modified;
05287 t->type = s->type;
05288
05289 t->info = sinfo_copy (s);
05290
05291 t->defstate = s->defstate;
05292
05293 t->nullstate = s->nullstate;
05294
05295 t->aliaskind = s->aliaskind;
05296 t->oaliaskind = s->oaliaskind;
05297
05298 t->expkind = s->expkind;
05299 t->oexpkind = s->oexpkind;
05300
05301 t->aliasinfo = alinfo_copy (s->aliasinfo);
05302 t->definfo = alinfo_copy (s->definfo);
05303 t->nullinfo = alinfo_copy (s->nullinfo);
05304 t->expinfo = alinfo_copy (s->expinfo);
05305
05306 t->deriv = sRefSet_newDeepCopy (s->deriv);
05307
05308 return t;
05309 }
05310 else
05311 {
05312 return sRef_undefined;
05313 }
05314 }
05315
05316
05317 # define PREDTEST(func,s) \
05318 do { if (sRef_isInvalid (s)) { return FALSE; } \
05319 else { if (sRef_isConj (s)) \
05320 { return (func (sRef_getConjA (s)) \
05321 || func (sRef_getConjB (s))); }}} while (FALSE);
05322
05323 bool sRef_isAddress (sRef s)
05324 {
05325 PREDTEST (sRef_isAddress, s);
05326 return (s->kind == SK_ADR);
05327 }
05328
05329
05330
05331
05332
05333 bool sRef_isThroughArrayFetch (sRef s)
05334 {
05335 if (sRef_isValid (s))
05336 {
05337 sRef tref = s;
05338
05339 do
05340 {
05341 sRef lt;
05342
05343 if (sRef_isArrayFetch (tref))
05344 {
05345 return TRUE;
05346 }
05347
05348 lt = sRef_getBase (tref);
05349 tref = lt;
05350 } while (sRef_isValid (tref));
05351 }
05352
05353 return FALSE;
05354 }
05355
05356 bool sRef_isArrayFetch (sRef s)
05357 {
05358 PREDTEST (sRef_isArrayFetch, s);
05359 return (s->kind == SK_ARRAYFETCH);
05360 }
05361
05362 bool sRef_isMacroParamRef (sRef s)
05363 {
05364 if (context_inMacro () && sRef_isCvar (s))
05365 {
05366 uentry ue = sRef_getUentry (s);
05367 cstring pname = makeParam (uentry_rawName (ue));
05368 uentry mac = usymtab_lookupSafe (pname);
05369
05370 cstring_free (pname);
05371 return (uentry_isValid (mac));
05372 }
05373
05374 return FALSE;
05375 }
05376
05377 bool sRef_isCvar (sRef s)
05378 {
05379 PREDTEST (sRef_isCvar, s);
05380 return (s->kind == SK_CVAR);
05381 }
05382
05383 bool sRef_isConst (sRef s)
05384 {
05385 PREDTEST (sRef_isConst, s);
05386 return (s->kind == SK_CONST);
05387 }
05388
05389 bool sRef_isObject (sRef s)
05390 {
05391 PREDTEST (sRef_isObject, s);
05392 return (s->kind == SK_OBJECT);
05393 }
05394
05395 bool sRef_isExternal (sRef s)
05396 {
05397 PREDTEST (sRef_isExternal, s);
05398 return (s->kind == SK_EXTERNAL);
05399 }
05400
05401 static bool sRef_isDerived (sRef s)
05402 {
05403 PREDTEST (sRef_isDerived, s);
05404 return (s->kind == SK_DERIVED);
05405 }
05406
05407 bool sRef_isField (sRef s)
05408 {
05409 PREDTEST (sRef_isField, s);
05410 return (s->kind == SK_FIELD);
05411 }
05412
05413 static bool sRef_isIndex (sRef s)
05414 {
05415 PREDTEST (sRef_isIndex, s);
05416 return (s->kind == SK_ARRAYFETCH);
05417 }
05418
05419 bool sRef_isAnyParam (sRef s)
05420 {
05421 PREDTEST (sRef_isAnyParam, s);
05422 return (s->kind == SK_PARAM);
05423 }
05424
05425 bool sRef_isParam (sRef s)
05426 {
05427 PREDTEST (sRef_isParam, s);
05428 return (s->kind == SK_PARAM);
05429 }
05430
05431 bool sRef_isDirectParam (sRef s)
05432 {
05433 PREDTEST (sRef_isDirectParam, s);
05434
05435 return ((s->kind == SK_CVAR) &&
05436 (s->info->cvar->lexlevel == functionScope) &&
05437 (context_inFunction () &&
05438 (s->info->cvar->index <= uentryList_size (context_getParams ()))));
05439 }
05440
05441 bool sRef_isPointer (sRef s)
05442 {
05443 PREDTEST (sRef_isPointer, s);
05444 return (s->kind == SK_PTR);
05445 }
05446
05447
05448
05449
05450
05451 bool sRef_isReference (sRef s)
05452 {
05453 PREDTEST (sRef_isReference, s);
05454
05455 return (sRef_isPointer (s) || sRef_isIndex (s) || sRef_isGlobal (s)
05456 || (sRef_isField (s) && (sRef_isReference (s->info->field->rec))));
05457 }
05458
05459 bool sRef_isIReference (sRef s)
05460 {
05461 return (sRef_isPointer (s) || sRef_isAddress (s) || sRef_isIndex (s)
05462 || sRef_isField (s) || sRef_isArrayFetch (s));
05463 }
05464
05465 bool sRef_isGlobal (sRef s)
05466 {
05467 return (sRef_isCvar (s) && (s->info->cvar->lexlevel <= fileScope));
05468 }
05469
05470 bool sRef_isRealGlobal (sRef s)
05471 {
05472 return (sRef_isCvar (s) && (s->info->cvar->lexlevel == globScope));
05473 }
05474
05475 bool sRef_isFileStatic (sRef s)
05476 {
05477 return (sRef_isCvar (s) && (s->info->cvar->lexlevel == fileScope));
05478 }
05479
05480 bool sRef_isAliasCheckedGlobal (sRef s)
05481 {
05482 if (sRef_isGlobal (s))
05483 {
05484 uentry ue = sRef_getUentry (s);
05485
05486 return context_checkAliasGlob (ue);
05487 }
05488 else
05489 {
05490 return FALSE;
05491 }
05492 }
05493
05494 void sRef_free ( sRef s)
05495 {
05496 if (s != sRef_undefined && s->kind != SK_SPECIAL)
05497 {
05498 alinfo_free (s->expinfo);
05499 alinfo_free (s->aliasinfo);
05500 alinfo_free (s->definfo);
05501 alinfo_free (s->nullinfo);
05502
05503 sRefSet_free (s->deriv);
05504 s->deriv = sRefSet_undefined;
05505 sinfo_free (s);
05506
05507 sfree (s);
05508 }
05509 }
05510
05511 void sRef_setType (sRef s, ctype t)
05512 {
05513 if (sRef_isValid (s))
05514 {
05515 s->type = t;
05516 }
05517 }
05518
05519 void sRef_setTypeFull (sRef s, ctype t)
05520 {
05521 if (sRef_isValid (s))
05522 {
05523 s->type = t;
05524
05525 sRefSet_allElements (s->deriv, current)
05526 {
05527 sRef_setTypeFull (current, ctype_unknown);
05528 } end_sRefSet_allElements ;
05529 }
05530 }
05531
05532 sRef
05533 sRef_buildField (sRef rec, cstring f)
05534 {
05535 return (sRef_buildNCField (rec, f));
05536 }
05537
05538 static sRef
05539 sRef_findDerivedField ( sRef rec, cstring f)
05540 {
05541 sRefSet_allElements (rec->deriv, sr)
05542 {
05543 if (sRef_isValid (sr))
05544 {
05545 if (sr->kind == SK_FIELD && cstring_equal (sr->info->field->field, f))
05546 {
05547 return sr;
05548 }
05549 }
05550 } end_sRefSet_allElements;
05551
05552 return sRef_undefined;
05553 }
05554
05555 sRefSet
05556 sRef_derivedFields (sRef rec)
05557 {
05558 if (sRef_isValid (rec))
05559 {
05560 sRefSet ret;
05561 ret = rec->deriv;
05562 return (ret);
05563 }
05564 else
05565 {
05566 return (sRefSet_undefined);
05567 }
05568 }
05569
05570 static sRef
05571 sRef_findDerivedPointer (sRef s)
05572 {
05573 if (sRef_isValid (s))
05574 {
05575 sRefSet_realElements (s->deriv, sr)
05576 {
05577 if (sRef_isValid (sr) && sr->kind == SK_PTR)
05578 {
05579 return sr;
05580 }
05581 } end_sRefSet_realElements;
05582 }
05583
05584 return sRef_undefined;
05585 }
05586
05587 bool
05588 sRef_isUnknownArrayFetch (sRef s)
05589 {
05590 return (sRef_isValid (s)
05591 && s->kind == SK_ARRAYFETCH
05592 && !s->info->arrayfetch->indknown);
05593 }
05594
05595 static sRef
05596 sRef_findDerivedArrayFetch ( sRef s, bool isknown, int idx, bool dead)
05597 {
05598
05599 if (isknown)
05600 {
05601 sRefSet_realElements (s->deriv, sr)
05602 {
05603 if (sRef_isValid (sr)
05604 && sr->kind == SK_ARRAYFETCH
05605 && sr->info->arrayfetch->indknown
05606 && (sr->info->arrayfetch->ind == idx))
05607 {
05608 return sr;
05609 }
05610 } end_sRefSet_realElements;
05611 }
05612 else
05613 {
05614 sRefSet_realElements (s->deriv, sr)
05615 {
05616 if (sRef_isValid (sr)
05617 && sr->kind == SK_ARRAYFETCH
05618 && (!sr->info->arrayfetch->indknown
05619 || (sr->info->arrayfetch->indknown &&
05620 sr->info->arrayfetch->ind == 0)))
05621 {
05622 if (sRef_isDead (sr) || sRef_isKept (sr))
05623 {
05624 if (dead || context_getFlag (FLG_STRICTUSERELEASED))
05625 {
05626 return sr;
05627 }
05628 }
05629 else
05630 {
05631 return sr;
05632 }
05633 }
05634 } end_sRefSet_realElements;
05635 }
05636
05637 return sRef_undefined;
05638 }
05639
05640 static sRef
05641 sRef_buildNCField ( sRef rec, cstring f)
05642 {
05643 sRef s;
05644
05645 if (sRef_isInvalid (rec))
05646 {
05647 return sRef_undefined;
05648 }
05649
05650
05651
05652
05653
05654 s = sRef_findDerivedField (rec, f);
05655
05656 if (sRef_isValid (s))
05657 {
05658 return s;
05659 }
05660 else
05661 {
05662 ctype ct = ctype_realType (rec->type);
05663
05664 s = sRef_new ();
05665 s->kind = SK_FIELD;
05666 s->info = (sinfo) dmalloc (sizeof (*s->info));
05667 s->info->field = (fldinfo) dmalloc (sizeof (*s->info->field));
05668 s->info->field->rec = rec;
05669 s->info->field->field = f;
05670
05671
05672 if (ctype_isKnown (ct) && ctype_isSU (ct))
05673 {
05674 uentry ue = uentryList_lookupField (ctype_getFields (ct), f);
05675
05676 if (!uentry_isUndefined (ue))
05677 {
05678 s->type = uentry_getType (ue);
05679
05680 if (ctype_isMutable (s->type)
05681 && rec->aliaskind != AK_STACK
05682 && !alkind_isStatic (rec->aliaskind))
05683 {
05684 s->aliaskind = rec->aliaskind;
05685 }
05686 else
05687 {
05688 s->aliaskind = AK_UNKNOWN;
05689 }
05690
05691 if (sRef_isStateDefined (rec) || sRef_isStateUnknown (rec)
05692 || sRef_isPdefined (rec))
05693 {
05694 sRef_setStateFromUentry (s, ue);
05695 }
05696 else
05697 {
05698 sRef_setPartsFromUentry (s, ue);
05699 }
05700
05701 s->oaliaskind = s->aliaskind;
05702 s->oexpkind = s->expkind;
05703 }
05704 else
05705 {
05706
05707
05708
05709
05710
05711
05712
05713
05714
05715
05716
05717 return sRef_undefined;
05718 }
05719 }
05720
05721 if (rec->defstate == SS_DEFINED
05722 && (s->defstate == SS_UNDEFINED || s->defstate == SS_UNKNOWN))
05723 {
05724 s->defstate = SS_DEFINED;
05725 }
05726 else if (rec->defstate == SS_PARTIAL)
05727 {
05728 s->defstate = SS_PARTIAL;
05729 }
05730 else if (rec->defstate == SS_ALLOCATED)
05731 {
05732 if (ctype_isStackAllocated (ct) && ctype_isStackAllocated (s->type))
05733 {
05734 s->defstate = SS_ALLOCATED;
05735 }
05736 else
05737 {
05738 s->defstate = SS_UNDEFINED;
05739 }
05740 }
05741 else if (s->defstate == SS_UNKNOWN)
05742 {
05743 s->defstate = rec->defstate;
05744 }
05745 else
05746 {
05747 ;
05748 }
05749
05750 if (s->defstate == SS_UNDEFINED)
05751 {
05752 ctype rt = ctype_realType (s->type);
05753
05754 if (ctype_isArray (rt) || ctype_isSU (rt))
05755 {
05756 s->defstate = SS_ALLOCATED;
05757 }
05758 }
05759
05760 sRef_addDeriv (rec, s);
05761
05762 if (ctype_isInt (s->type) && cstring_equal (f, REFSNAME))
05763 {
05764 s->aliaskind = AK_REFS;
05765 s->oaliaskind = AK_REFS;
05766 }
05767
05768 return s;
05769 }
05770 }
05771
05772 bool
05773 sRef_isStackAllocated (sRef s)
05774 {
05775 return (sRef_isValid(s)
05776 && s->defstate == SS_ALLOCATED && ctype_isStackAllocated (s->type));
05777 }
05778
05779 static
05780 void sRef_setArrayFetchState ( sRef s,
05781 sRef arr)
05782 {
05783 if (ctype_isRealAP (arr->type))
05784 {
05785 s->type = ctype_baseArrayPtr (arr->type);
05786 }
05787
05788
05789 if (sRef_isAddress (arr))
05790 {
05791 sRef t = arr->info->ref;
05792
05793 if (sRef_isArrayFetch (t))
05794 {
05795 s->info->arrayfetch->arr = t->info->arrayfetch->arr;
05796 }
05797 }
05798 else if (ctype_isRealPointer (arr->type))
05799 {
05800 sRef sp = sRef_findDerivedPointer (arr);
05801
05802
05803 if (sRef_isValid (sp))
05804 {
05805
05806 if (ctype_isMutable (s->type))
05807 {
05808 sRef_setExKind (s, sRef_getExKind (sp), fileloc_undefined);
05809
05810
05811 s->aliaskind = sp->aliaskind;
05812 }
05813
05814 s->defstate = sp->defstate;
05815
05816 if (s->defstate == SS_DEFINED)
05817 {
05818 if (!context_getFlag (FLG_STRICTDESTROY))
05819 {
05820 s->defstate = SS_PARTIAL;
05821 }
05822 }
05823
05824 s->nullstate = sp->nullstate;
05825 }
05826 else
05827 {
05828 if (arr->defstate == SS_UNDEFINED)
05829 {
05830 s->defstate = SS_UNUSEABLE;
05831 }
05832 else if ((arr->defstate == SS_ALLOCATED) && !ctype_isSU (s->type))
05833 {
05834 s->defstate = SS_UNDEFINED;
05835 }
05836 else
05837 {
05838 if (!context_getFlag (FLG_STRICTDESTROY))
05839 {
05840 s->defstate = SS_PARTIAL;
05841 }
05842 else
05843 {
05844 s->defstate = SS_DEFINED;
05845 }
05846
05847
05848
05849
05850
05851
05852 }
05853
05854 sRef_setExKind (s, sRef_getExKind (arr), g_currentloc);
05855
05856 if (arr->aliaskind == AK_LOCAL || arr->aliaskind == AK_FRESH)
05857 {
05858 s->aliaskind = AK_LOCAL;
05859 }
05860 else
05861 {
05862 s->aliaskind = AK_UNKNOWN;
05863 }
05864
05865 sRef_setTypeState (s);
05866 }
05867 }
05868 else
05869 {
05870 if (arr->defstate == SS_DEFINED)
05871 {
05872
05873
05874
05875
05876
05877
05878 if (context_getFlag (FLG_STRICTDESTROY))
05879 {
05880 s->defstate = SS_DEFINED;
05881 }
05882 else
05883 {
05884 s->defstate = SS_PARTIAL;
05885 }
05886 }
05887 else if (arr->defstate == SS_ALLOCATED)
05888 {
05889 if (ctype_isRealArray (s->type))
05890 {
05891 s->defstate = SS_ALLOCATED;
05892 }
05893 else
05894 {
05895 if (!s->info->arrayfetch->indknown)
05896 {
05897
05898
05899
05900
05901
05902 s->defstate = SS_UNDEFINED;
05903
05904 sRefSet_allElements (arr->deriv, sr)
05905 {
05906 if (sRef_isValid (sr))
05907 {
05908 if (sr->defstate == SS_ALLOCATED)
05909 {
05910 s->defstate = SS_ALLOCATED;
05911 }
05912 else
05913 {
05914 if (sr->defstate == SS_DEFINED)
05915 {
05916 if (context_getFlag (FLG_STRICTDESTROY))
05917 {
05918 s->defstate = SS_DEFINED;
05919 }
05920 else
05921 {
05922 s->defstate = SS_PARTIAL;
05923 }
05924
05925 break;
05926 }
05927 }
05928 }
05929 } end_sRefSet_allElements;
05930
05931 }
05932 else
05933 {
05934 s->defstate = SS_UNDEFINED;
05935 }
05936 }
05937 }
05938 else
05939 {
05940 s->defstate = arr->defstate;
05941 }
05942
05943
05944
05945
05946
05947
05948 if (ctype_isMutable (s->type)
05949 && !ctype_isPointer (arr->type)
05950 && !alkind_isStatic (arr->aliaskind)
05951 && !alkind_isStack (arr->aliaskind))
05952 {
05953 s->aliaskind = arr->aliaskind;
05954 }
05955 else
05956 {
05957 s->aliaskind = AK_UNKNOWN;
05958 }
05959
05960 sRef_setTypeState (s);
05961 }
05962
05963 if (sRef_isObserver (arr))
05964 {
05965 s->expkind = XO_OBSERVER;
05966 }
05967 }
05968
05969 sRef sRef_buildArrayFetch ( sRef arr)
05970 {
05971 sRef s;
05972
05973 if (!sRef_isValid (arr)) {
05974 return arr ;
05975 }
05976
05977 if (ctype_isRealPointer (arr->type))
05978 {
05979 (void) sRef_buildPointer (arr);
05980 }
05981
05982 s = sRef_findDerivedArrayFetch (arr, FALSE, 0, FALSE);
05983
05984 if (sRef_isValid (s))
05985 {
05986 sRef_setExKind (s, sRef_getExKind (arr), g_currentloc);
05987 return s;
05988 }
05989 else
05990 {
05991 s = sRef_new ();
05992
05993 s->kind = SK_ARRAYFETCH;
05994 s->info = (sinfo) dmalloc (sizeof (*s->info));
05995 s->info->arrayfetch = (ainfo) dmalloc (sizeof (*s->info->arrayfetch));
05996 s->info->arrayfetch->indknown = FALSE;
05997 s->info->arrayfetch->ind = 0;
05998 s->info->arrayfetch->arr = arr;
05999 sRef_setArrayFetchState (s, arr);
06000 s->oaliaskind = s->aliaskind;
06001 s->oexpkind = s->expkind;
06002
06003 if (!context_inProtectVars ())
06004 {
06005 sRef_addDeriv (arr, s);
06006 }
06007
06008 return (s);
06009 }
06010 }
06011
06012 sRef
06013 sRef_buildArrayFetchKnown ( sRef arr, int i)
06014 {
06015 sRef s;
06016
06017 if (!sRef_isValid (arr)) {
06018 return arr ;
06019 }
06020
06021 if (ctype_isRealPointer (arr->type))
06022 {
06023 (void) sRef_buildPointer (arr);
06024 }
06025
06026 s = sRef_findDerivedArrayFetch (arr, TRUE, i, FALSE);
06027
06028 if (sRef_isValid (s))
06029 {
06030 sRef_setExKind (s, sRef_getExKind (arr), g_currentloc);
06031 return s;
06032 }
06033 else
06034 {
06035 s = sRef_new ();
06036
06037 s->kind = SK_ARRAYFETCH;
06038 s->info = (sinfo) dmalloc (sizeof (*s->info));
06039 s->info->arrayfetch = (ainfo) dmalloc (sizeof (*s->info->arrayfetch));
06040 s->info->arrayfetch->arr = arr;
06041 s->info->arrayfetch->indknown = TRUE;
06042 s->info->arrayfetch->ind = i;
06043
06044 sRef_setArrayFetchState (s, arr);
06045
06046 s->oaliaskind = s->aliaskind;
06047 s->oexpkind = s->expkind;
06048 sRef_addDeriv (arr, s);
06049
06050 return (s);
06051 }
06052 }
06053
06054
06055
06056
06057
06058 static void
06059 sRef_setPartsFromUentry (sRef s, uentry ue)
06060 {
06061
06062 llassert (sRef_isValid (s));
06063
06064 s->aliaskind = alkind_derive (s->aliaskind, uentry_getAliasKind (ue));
06065 s->oaliaskind = s->aliaskind;
06066
06067 if (s->expkind == XO_UNKNOWN)
06068 {
06069 s->expkind = uentry_getExpKind (ue);
06070 }
06071
06072 s->oexpkind = s->expkind;
06073
06074 if (s->nullstate == NS_UNKNOWN)
06075 {
06076 s->nullstate = sRef_getNullState (uentry_getSref (ue));
06077 }
06078
06079 if (s->aliaskind == AK_IMPONLY
06080 && (sRef_isExposed (s) || sRef_isObserver (s)))
06081 {
06082 s->oaliaskind = s->aliaskind = AK_IMPDEPENDENT;
06083 }
06084
06085 }
06086
06087 static void
06088 sRef_setStateFromAbstractUentry (sRef s, uentry ue)
06089 {
06090 llassert (sRef_isValid (s));
06091
06092 sRef_setPartsFromUentry (s, ue);
06093
06094 s->aliaskind = alkind_derive (s->aliaskind, uentry_getAliasKind (ue));
06095 s->oaliaskind = s->aliaskind;
06096
06097 if (s->expkind == XO_UNKNOWN)
06098 {
06099 s->expkind = uentry_getExpKind (ue);
06100 }
06101
06102 s->oexpkind = s->expkind;
06103 }
06104
06105 void
06106 sRef_setStateFromUentry (sRef s, uentry ue)
06107 {
06108 sstate defstate;
06109
06110 llassert (sRef_isValid (s));
06111
06112 sRef_setPartsFromUentry (s, ue);
06113
06114 defstate = uentry_getDefState (ue);
06115
06116 if (sstate_isKnown (defstate))
06117 {
06118 s->defstate = defstate;
06119 }
06120 else
06121 {
06122 ;
06123 }
06124 }
06125
06126 sRef
06127 sRef_buildPointer ( sRef t)
06128 {
06129 DPRINTF (("build pointer: %s", sRef_unparse (t)));
06130
06131 if (sRef_isInvalid (t)) return sRef_undefined;
06132
06133 if (sRef_isAddress (t))
06134 {
06135 DPRINTF (("Return ref: %s", sRef_unparse (t->info->ref)));
06136 return (t->info->ref);
06137 }
06138 else
06139 {
06140 sRef s = sRef_findDerivedPointer (t);
06141
06142 DPRINTF (("find derived: %s", sRef_unparse (s)));
06143
06144 if (sRef_isValid (s))
06145 {
06146
06147 sRef_setExKind (s, sRef_getExKind (t), g_currentloc);
06148 s->oaliaskind = s->aliaskind;
06149 s->oexpkind = s->expkind;
06150
06151 return s;
06152 }
06153 else
06154 {
06155 s = sRef_constructPointerAux (t);
06156
06157 DPRINTF (("construct: %s", sRef_unparse (s)));
06158
06159 if (sRef_isValid (s))
06160 {
06161 sRef_addDeriv (t, s);
06162
06163 s->oaliaskind = s->aliaskind;
06164 s->oexpkind = s->expkind;
06165 }
06166
06167 return s;
06168 }
06169 }
06170 }
06171
06172 sRef
06173 sRef_constructPointer (sRef t)
06174
06175 {
06176 return sRef_buildPointer (t);
06177 }
06178
06179 static sRef sRef_constructDerefAux (sRef t, bool isdead)
06180 {
06181 if (sRef_isValid (t))
06182 {
06183 sRef s;
06184
06185
06186
06187
06188
06189
06190 s = sRef_findDerivedArrayFetch (t, FALSE, 0, isdead);
06191
06192 if (sRef_isValid (s))
06193 {
06194 return s;
06195 }
06196 else
06197 {
06198 sRef ret = sRef_constructPointer (t);
06199
06200
06201
06202
06203
06204
06205
06206 if (isdead)
06207 {
06208
06209 return ret;
06210 }
06211 else
06212 {
06213 return ret;
06214 }
06215 }
06216 }
06217 else
06218 {
06219 return sRef_undefined;
06220 }
06221 }
06222
06223 sRef sRef_constructDeref (sRef t)
06224 {
06225 return sRef_constructDerefAux (t, FALSE);
06226 }
06227
06228 sRef sRef_constructDeadDeref (sRef t)
06229 {
06230 return sRef_constructDerefAux (t, TRUE);
06231 }
06232
06233 static sRef
06234 sRef_constructPointerAux ( sRef t)
06235 {
06236 sRef s = sRef_new ();
06237 ctype rt = t->type;
06238 ctype st;
06239
06240 s->kind = SK_PTR;
06241 s->info = (sinfo) dmalloc (sizeof (*s->info));
06242 s->info->ref = t;
06243
06244 if (ctype_isRealAP (rt))
06245 {
06246 s->type = ctype_baseArrayPtr (rt);
06247 }
06248
06249 st = ctype_realType (s->type);
06250
06251
06252 if (t->defstate == SS_UNDEFINED)
06253 {
06254 s->defstate = SS_UNUSEABLE;
06255 }
06256 else if ((t->defstate == SS_ALLOCATED) && !ctype_isSU (st))
06257 {
06258 s->defstate = SS_UNDEFINED;
06259 }
06260 else
06261 {
06262 s->defstate = t->defstate;
06263 }
06264
06265 if (t->aliaskind == AK_LOCAL || t->aliaskind == AK_FRESH)
06266 {
06267 s->aliaskind = AK_LOCAL;
06268 }
06269 else
06270 {
06271 s->aliaskind = AK_UNKNOWN;
06272 }
06273
06274 sRef_setExKind (s, sRef_getExKind (t), fileloc_undefined);
06275 sRef_setTypeState (s);
06276
06277 s->oaliaskind = s->aliaskind;
06278 s->oexpkind = s->expkind;
06279
06280 return s;
06281 }
06282
06283 bool sRef_hasDerived (sRef s)
06284 {
06285 return (sRef_isValid (s) && !sRefSet_isEmpty (s->deriv));
06286 }
06287
06288 void
06289 sRef_clearDerived (sRef s)
06290 {
06291 if (sRef_isValid (s))
06292 {
06293 sRefSet_clear (s->deriv);
06294 }
06295 }
06296
06297 void
06298 sRef_clearDerivedComplete (sRef s)
06299 {
06300
06301 if (sRef_isValid (s))
06302 {
06303 sRef base = sRef_getBaseSafe (s);
06304
06305 while (sRef_isValid (base))
06306 {
06307 sRefSet_clear (base->deriv);
06308 base = sRef_getBaseSafe (base);
06309 }
06310
06311 sRefSet_clear (s->deriv);
06312 }
06313 }
06314
06315 sRef
06316 sRef_makePointer (sRef s)
06317
06318 {
06319 sRef res = sRef_buildPointer (s);
06320
06321 DPRINTF (("Res: %s", sRef_unparse (res)));
06322 return res;
06323 }
06324
06325
06326
06327
06328
06329 sRef
06330 sRef_makeAnyArrayFetch ( sRef arr)
06331 {
06332
06333 if (sRef_isAddress (arr))
06334 {
06335 return (arr->info->ref);
06336 }
06337 else
06338 {
06339 return (sRef_buildArrayFetch (arr));
06340 }
06341 }
06342
06343 sRef
06344 sRef_makeArrayFetch (sRef arr)
06345 {
06346 return (sRef_buildArrayFetch (arr));
06347 }
06348
06349 sRef
06350 sRef_makeArrayFetchKnown (sRef arr, int i)
06351 {
06352 return (sRef_buildArrayFetchKnown (arr, i));
06353 }
06354
06355 sRef
06356 sRef_makeField (sRef rec, cstring f)
06357 {
06358 sRef ret;
06359 ret = sRef_buildField (rec, f);
06360 return ret;
06361 }
06362
06363 sRef
06364 sRef_makeNCField (sRef rec, cstring f)
06365 {
06366 return (sRef_buildNCField (rec, f));
06367 }
06368
06369 cstring
06370 sRef_unparseKindName (sRef s)
06371 {
06372 cstring result;
06373
06374 if (s == sRef_undefined) return cstring_makeLiteral ("<invalid>");
06375
06376 s = sRef_fixConj (s);
06377
06378 switch (s->kind)
06379 {
06380 case SK_CVAR:
06381 if (sRef_isLocalVar (s))
06382 {
06383 result = cstring_makeLiteral ("Variable");
06384 }
06385 else
06386 {
06387 result = cstring_makeLiteral ("Undef global");
06388 }
06389 break;
06390 case SK_PARAM:
06391 result = cstring_makeLiteral ("Out parameter");
06392 break;
06393 case SK_ARRAYFETCH:
06394 if (sRef_isAnyParam (s->info->arrayfetch->arr))
06395 {
06396 result = cstring_makeLiteral ("Out parameter");
06397 }
06398 else if (sRef_isIndexKnown (s))
06399 {
06400 result = cstring_makeLiteral ("Array element");
06401 }
06402 else
06403 {
06404 result = cstring_makeLiteral ("Value");
06405 }
06406 break;
06407 case SK_PTR:
06408 if (sRef_isAnyParam (s->info->ref))
06409 {
06410 result = cstring_makeLiteral ("Out parameter");
06411 }
06412 else
06413 {
06414 result = cstring_makeLiteral ("Value");
06415 }
06416 break;
06417 case SK_ADR:
06418 result = cstring_makeLiteral ("Value");
06419 break;
06420 case SK_FIELD:
06421 result = cstring_makeLiteral ("Field");
06422 break;
06423 case SK_OBJECT:
06424 result = cstring_makeLiteral ("Object");
06425 break;
06426 case SK_UNCONSTRAINED:
06427 result = cstring_makeLiteral ("<anything>");
06428 break;
06429 case SK_RESULT:
06430 case SK_SPECIAL:
06431 case SK_UNKNOWN:
06432 case SK_EXTERNAL:
06433 case SK_DERIVED:
06434 case SK_CONST:
06435 case SK_TYPE:
06436 result = cstring_makeLiteral ("<unknown>");
06437 break;
06438 case SK_CONJ:
06439 result = cstring_makeLiteral ("<conj>");
06440 break;
06441 case SK_NEW:
06442 result = cstring_makeLiteral ("Storage");
06443 break;
06444 }
06445
06446 return result;
06447 }
06448
06449 cstring
06450 sRef_unparseKindNamePlain (sRef s)
06451 {
06452 cstring result;
06453
06454 if (s == sRef_undefined) return cstring_makeLiteral ("<invalid>");
06455
06456 s = sRef_fixConj (s);
06457
06458 switch (s->kind)
06459 {
06460 case SK_CVAR:
06461 if (sRef_isLocalVar (s))
06462 {
06463 result = cstring_makeLiteral ("Variable");
06464 }
06465 else
06466 {
06467 result = cstring_makeLiteral ("Global");
06468 }
06469 break;
06470 case SK_PARAM:
06471 result = cstring_makeLiteral ("Parameter");
06472 break;
06473 case SK_ARRAYFETCH:
06474 if (sRef_isAnyParam (s->info->arrayfetch->arr))
06475 {
06476 result = cstring_makeLiteral ("Parameter");
06477 }
06478 else if (sRef_isIndexKnown (s))
06479 {
06480 result = cstring_makeLiteral ("Array element");
06481 }
06482 else
06483 {
06484 result = cstring_makeLiteral ("Value");
06485 }
06486 break;
06487 case SK_PTR:
06488 if (sRef_isAnyParam (s->info->ref))
06489 {
06490 result = cstring_makeLiteral ("Parameter");
06491 }
06492 else
06493 {
06494 result = cstring_makeLiteral ("Value");
06495 }
06496 break;
06497 case SK_ADR:
06498 result = cstring_makeLiteral ("Value");
06499 break;
06500 case SK_FIELD:
06501 result = cstring_makeLiteral ("Field");
06502 break;
06503 case SK_OBJECT:
06504 result = cstring_makeLiteral ("Object");
06505 break;
06506 case SK_NEW:
06507 result = cstring_makeLiteral ("Storage");
06508 break;
06509 case SK_UNCONSTRAINED:
06510 result = cstring_makeLiteral ("<anything>");
06511 break;
06512 case SK_RESULT:
06513 case SK_TYPE:
06514 case SK_CONST:
06515 case SK_EXTERNAL:
06516 case SK_DERIVED:
06517 case SK_UNKNOWN:
06518 case SK_SPECIAL:
06519 result = cstring_makeLiteral ("<unknown>");
06520 break;
06521 case SK_CONJ:
06522 result = cstring_makeLiteral ("<conj>");
06523 break;
06524 }
06525
06526 return result;
06527 }
06528
06529
06530
06531
06532
06533 void
06534 sRef_copyState (sRef s1, sRef s2)
06535 {
06536 if (sRef_isValid (s1) && sRef_isValid (s2))
06537 {
06538 s1->defstate = s2->defstate;
06539
06540 s1->nullstate = s2->nullstate;
06541 s1->nullinfo = alinfo_update (s1->nullinfo, s2->nullinfo);
06542
06543 s1->aliaskind = s2->aliaskind;
06544 s1->aliasinfo = alinfo_update (s1->aliasinfo, s2->aliasinfo);
06545
06546 s1->expkind = s2->expkind;
06547 s1->expinfo = alinfo_update (s1->expinfo, s2->expinfo);
06548
06549 s1->safe = s2->safe;
06550 }
06551 }
06552
06553 sRef
06554 sRef_makeNew (ctype ct, sRef t, cstring name)
06555 {
06556 sRef s = sRef_new ();
06557
06558 s->kind = SK_NEW;
06559 s->type = ct;
06560
06561 llassert (sRef_isValid (t));
06562 s->defstate = t->defstate;
06563
06564 s->aliaskind = t->aliaskind;
06565 s->oaliaskind = s->aliaskind;
06566
06567 s->nullstate = t->nullstate;
06568
06569 s->expkind = t->expkind;
06570 s->oexpkind = s->expkind;
06571
06572 s->info = (sinfo) dmalloc (sizeof (*s->info));
06573 s->info->fname = name;
06574
06575 return s;
06576 }
06577
06578 sRef
06579 sRef_makeType (ctype ct)
06580 {
06581 sRef s = sRef_new ();
06582
06583 s->kind = SK_TYPE;
06584 s->type = ct;
06585
06586 s->defstate = SS_UNKNOWN;
06587 s->aliaskind = AK_UNKNOWN;
06588 s->nullstate = NS_UNKNOWN;
06589
06590
06591 if (ctype_isUA (ct))
06592 {
06593 typeId uid = ctype_typeId (ct);
06594 uentry ue = usymtab_getTypeEntrySafe (uid);
06595
06596 if (uentry_isValid (ue))
06597 {
06598 sRef_mergeStateQuiet (s, uentry_getSref (ue));
06599 }
06600 }
06601
06602 s->oaliaskind = s->aliaskind;
06603 s->oexpkind = s->expkind;
06604
06605 return s;
06606 }
06607
06608 sRef
06609 sRef_makeConst (ctype ct)
06610 {
06611 sRef s = sRef_new ();
06612
06613 s->kind = SK_CONST;
06614 s->type = ct;
06615
06616 s->defstate = SS_UNKNOWN;
06617 s->aliaskind = AK_UNKNOWN;
06618 s->nullstate = NS_UNKNOWN;
06619
06620
06621 if (ctype_isUA (ct))
06622 {
06623 typeId uid = ctype_typeId (ct);
06624 uentry te = usymtab_getTypeEntrySafe (uid);
06625
06626 if (uentry_isValid (te))
06627 {
06628 sRef_mergeStateQuiet (s, uentry_getSref (te));
06629 }
06630 }
06631
06632
06633 s->oaliaskind = s->aliaskind;
06634 s->oexpkind = s->expkind;
06635
06636 return s;
06637 }
06638
06639 bool sRef_hasName (sRef s)
06640 {
06641 if (sRef_isInvalid (s))
06642 {
06643 return (FALSE);
06644 }
06645
06646 switch (s->kind)
06647 {
06648 case SK_CVAR:
06649 {
06650 uentry u = usymtab_getRefQuiet (s->info->cvar->lexlevel,
06651 s->info->cvar->index);
06652 return (uentry_hasName (u));
06653 }
06654 case SK_PARAM:
06655 {
06656 uentry u = uentryList_getN (context_getParams (),
06657 s->info->paramno);
06658
06659 return (uentry_hasName (u));
06660 }
06661 default:
06662 return TRUE;
06663 }
06664 }
06665
06666 bool
06667 sRef_sameName (sRef s1, sRef s2)
06668 {
06669 if (sRef_isInvalid (s1))
06670 {
06671 return sRef_isInvalid (s2);
06672 }
06673
06674 if (sRef_isInvalid (s2))
06675 {
06676 return (FALSE);
06677 }
06678
06679 switch (s1->kind)
06680 {
06681 case SK_CVAR:
06682 if (s2->kind == SK_CVAR)
06683 {
06684 return (s1->info->cvar->lexlevel == s2->info->cvar->lexlevel
06685 && s1->info->cvar->index == s2->info->cvar->index);
06686 }
06687 else if (s2->kind == SK_PARAM)
06688 {
06689 if (context_inFunctionLike ())
06690 {
06691 uentry u1 = usymtab_getRefQuiet (s1->info->cvar->lexlevel,
06692 s1->info->cvar->index);
06693 uentry u2 = uentryList_getN (context_getParams (),
06694 s2->info->paramno);
06695
06696 return (cstring_equalFree (uentry_getName (u1),
06697 uentry_getName (u2)));
06698 }
06699 else
06700 {
06701 return FALSE;
06702 }
06703 }
06704 else
06705 {
06706 return FALSE;
06707 }
06708 case SK_PARAM:
06709 {
06710 if (s2->kind == SK_PARAM)
06711 {
06712 return (s1->info->paramno == s2->info->paramno);
06713 }
06714 else if (s2->kind == SK_CVAR)
06715 {
06716 if (context_inFunctionLike ())
06717 {
06718 uentry u1 = uentryList_getN (context_getParams (),
06719 s1->info->paramno);
06720 uentry u2 = usymtab_getRefQuiet (s2->info->cvar->lexlevel,
06721 s2->info->cvar->index);
06722
06723
06724 return (cstring_equalFree (uentry_getName (u1),
06725 uentry_getName (u2)));
06726 }
06727 else
06728 {
06729 return FALSE;
06730 }
06731 }
06732 else
06733 {
06734 return FALSE;
06735 }
06736 }
06737
06738 case SK_UNCONSTRAINED:
06739 return FALSE;
06740
06741 case SK_ARRAYFETCH:
06742 if (s2->kind == SK_ARRAYFETCH)
06743 {
06744 if (bool_equal (s1->info->arrayfetch->indknown,
06745 s2->info->arrayfetch->indknown))
06746 {
06747 if (!s1->info->arrayfetch->indknown
06748 || (s1->info->arrayfetch->ind == s2->info->arrayfetch->ind))
06749 {
06750 return sRef_sameName (s1->info->arrayfetch->arr,
06751 s2->info->arrayfetch->arr);
06752 }
06753 }
06754 }
06755
06756 return FALSE;
06757 case SK_FIELD:
06758 if (s2->kind == SK_FIELD)
06759 {
06760 if (cstring_equal (s1->info->field->field,
06761 s2->info->field->field))
06762 {
06763 return sRef_sameName (s1->info->field->rec,
06764 s2->info->field->rec);
06765 }
06766
06767 }
06768 return FALSE;
06769 case SK_PTR:
06770 case SK_ADR:
06771 case SK_DERIVED:
06772 case SK_EXTERNAL:
06773 if (s2->kind == s1->kind)
06774 {
06775 return sRef_sameName (s1->info->ref,
06776 s2->info->ref);
06777 }
06778
06779 return FALSE;
06780 case SK_OBJECT:
06781 return FALSE;
06782 case SK_CONJ:
06783 return sRef_sameName (sRef_getConjA (s1), s2);
06784 case SK_NEW:
06785 return FALSE;
06786 case SK_UNKNOWN:
06787 return (s2->kind == SK_UNKNOWN);
06788 case SK_TYPE:
06789 case SK_CONST:
06790 if (s2->kind == s1->kind)
06791 {
06792 return (ctype_equal (s1->type, s2->type));
06793 }
06794
06795 return FALSE;
06796 case SK_SPECIAL:
06797 if (s2->kind == SK_SPECIAL)
06798 {
06799 return (s1->info->spec == s2->info->spec);
06800 }
06801 return FALSE;
06802 case SK_RESULT:
06803 return (s2->kind == SK_RESULT);
06804 default:
06805 return FALSE;
06806 }
06807 BADEXIT;
06808 }
06809
06810 sRef
06811 sRef_fixOuterRef ( sRef s)
06812 {
06813 sRef root = sRef_getRootBase (s);
06814
06815 if (sRef_isCvar (root))
06816 {
06817 uentry ue = usymtab_getRefQuiet (root->info->cvar->lexlevel,
06818 root->info->cvar->index);
06819
06820 if (uentry_isValid (ue))
06821 {
06822 sRef uref = uentry_getSref (ue);
06823 sRef sr = sRef_fixBase (s, uref);
06824
06825 return (sr);
06826 }
06827 else
06828 {
06829 llcontbug (message ("sRef_fixOuterRef: undefined: %q", sRef_unparseDebug (s)));
06830 return (s);
06831 }
06832 }
06833
06834 return (s);
06835 }
06836
06837 void
06838 sRef_storeState (sRef s)
06839 {
06840 if (sRef_isInvalid (s)) return;
06841
06842 s->oaliaskind = s->aliaskind;
06843 s->oexpkind = s->expkind;
06844 }
06845
06846 static void sRef_resetStateAux (sRef s, fileloc loc)
06847 {
06848 sRef_resetState (s);
06849 }
06850
06851 void
06852 sRef_resetState (sRef s)
06853 {
06854 bool changed = FALSE;
06855 if (sRef_isInvalid (s)) return;
06856
06857
06858 if (s->oaliaskind == AK_KILLREF && !sRef_isParam (s))
06859 {
06860
06861
06862
06863
06864
06865 if (s->expkind != s->oexpkind)
06866 {
06867 changed = TRUE;
06868 s->expkind = s->oexpkind;
06869 }
06870 }
06871 else
06872 {
06873 if (s->expkind != s->oexpkind)
06874 {
06875 changed = TRUE;
06876 s->expkind = s->oexpkind;
06877 }
06878
06879 if (s->aliaskind != s->oaliaskind
06880 && s->aliaskind != AK_REFCOUNTED
06881 && s->aliaskind != AK_REFS)
06882 {
06883 changed = TRUE;
06884 s->aliaskind = s->oaliaskind;
06885 }
06886 }
06887
06888 if (changed)
06889 {
06890 sRef_clearDerived (s);
06891 }
06892
06893 }
06894
06895 void
06896 sRef_resetStateComplete (sRef s)
06897 {
06898 sRef_innerAliasSetComplete (sRef_resetStateAux, s, fileloc_undefined);
06899 }
06900
06901 sRef
06902 sRef_fixBase ( sRef s, sRef base)
06903 {
06904 sRef tmp = sRef_undefined;
06905 sRef ret;
06906
06907 if (sRef_isInvalid (s)) return s;
06908 if (sRef_isInvalid (base)) return base;
06909
06910 switch (s->kind)
06911 {
06912 case SK_RESULT:
06913 case SK_PARAM:
06914 case SK_CVAR:
06915 ret = base;
06916 break;
06917 case SK_ARRAYFETCH:
06918 tmp = sRef_fixBase (s->info->arrayfetch->arr, base);
06919
06920 if (s->info->arrayfetch->indknown)
06921 {
06922 ret = sRef_makeArrayFetchKnown (tmp, s->info->arrayfetch->ind);
06923 }
06924 else
06925 {
06926 ret = sRef_makeArrayFetch (tmp);
06927 }
06928 break;
06929 case SK_FIELD:
06930 tmp = sRef_fixBase (s->info->field->rec, base);
06931 ret = sRef_buildNCField (tmp, s->info->field->field);
06932 break;
06933 case SK_PTR:
06934 tmp = sRef_fixBase (s->info->ref, base);
06935 ret = sRef_makePointer (tmp);
06936 break;
06937 case SK_ADR:
06938 tmp = sRef_fixBase (s->info->ref, base);
06939 ret = sRef_makeAddress (tmp);
06940 break;
06941 case SK_CONJ:
06942 {
06943 sRef tmpb;
06944
06945 tmp = sRef_fixBase (s->info->conj->a, base);
06946 tmpb = sRef_fixBase (s->info->conj->b, base);
06947
06948 ret = sRef_makeConj (tmp, tmpb);
06949 break;
06950 }
06951 BADDEFAULT;
06952 }
06953
06954 return ret;
06955 }
06956
06957 static sRef
06958 sRef_fixDirectBase (sRef s, sRef base)
06959 {
06960 sRef ret;
06961
06962
06963 if (sRef_isInvalid (s))
06964 {
06965 return sRef_undefined;
06966 }
06967
06968 switch (s->kind)
06969 {
06970 case SK_ARRAYFETCH:
06971 if (s->info->arrayfetch->indknown)
06972 {
06973 ret = sRef_makeArrayFetchKnown (base, s->info->arrayfetch->ind);
06974 }
06975 else
06976 {
06977 ret = sRef_makeArrayFetch (base);
06978 }
06979 break;
06980 case SK_FIELD:
06981 ret = sRef_buildNCField (base, s->info->field->field);
06982 break;
06983 case SK_PTR:
06984 ret = sRef_makePointer (base);
06985 break;
06986 case SK_ADR:
06987 ret = sRef_makeAddress (base);
06988 break;
06989 case SK_CONJ:
06990 {
06991 sRef tmpa, tmpb;
06992
06993 tmpa = sRef_fixDirectBase (s->info->conj->a, base);
06994 tmpb = sRef_fixDirectBase (s->info->conj->b, base);
06995
06996 ret = sRef_makeConj (tmpa, tmpb);
06997 break;
06998 }
06999 BADDEFAULT;
07000 }
07001
07002 sRef_copyState (ret, s);
07003 return ret;
07004 }
07005
07006 bool
07007 sRef_isAllocIndexRef (sRef s)
07008 {
07009 return (sRef_isArrayFetch (s) && !(s->info->arrayfetch->indknown)
07010 && sRef_isAllocated (s->info->arrayfetch->arr));
07011 }
07012
07013 void
07014 sRef_showRefLost (sRef s)
07015 {
07016 if (sRef_hasAliasInfoLoc (s))
07017 {
07018 llgenindentmsg (cstring_makeLiteral ("Original reference lost"),
07019 sRef_getAliasInfoLoc (s));
07020 }
07021 }
07022
07023 void
07024 sRef_showRefKilled (sRef s)
07025 {
07026 if (sRef_hasStateInfoLoc (s))
07027 {
07028 llgenindentmsg (message ("Storage %q released",
07029 sRef_unparse (s)), sRef_getStateInfoLoc (s));
07030 }
07031 }
07032
07033 void
07034 sRef_showStateInconsistent (sRef s)
07035 {
07036 if (sRef_hasStateInfoLoc (s))
07037 {
07038 llgenindentmsg
07039 (message ("Storage %qbecomes inconsistent (released on one branch)",
07040 sRef_unparseOpt (s)),
07041 sRef_getStateInfoLoc (s));
07042 }
07043 }
07044
07045 void
07046 sRef_showStateInfo (sRef s)
07047 {
07048 if (sRef_hasStateInfoLoc (s))
07049 {
07050 if (s->defstate == SS_DEAD)
07051 {
07052 llgenindentmsg
07053 (message ("Storage %qis released", sRef_unparseOpt (s)),
07054 sRef_getStateInfoLoc (s));
07055 }
07056 else if (s->defstate == SS_ALLOCATED || s->defstate == SS_DEFINED)
07057 {
07058 llgenindentmsg
07059 (message ("Storage %qis %s", sRef_unparseOpt (s),
07060 sstate_unparse (s->defstate)),
07061 sRef_getStateInfoLoc (s));
07062 }
07063 else if (s->defstate == SS_UNUSEABLE)
07064 {
07065 llgenindentmsg
07066 (message ("Storage %qbecomes inconsistent (clauses merge with"
07067 "%qreleased on one branch)",
07068 sRef_unparseOpt (s),
07069 sRef_unparseOpt (s)),
07070 sRef_getStateInfoLoc (s));
07071 }
07072 else
07073 {
07074 llgenindentmsg (message ("Storage %qbecomes %s",
07075 sRef_unparseOpt (s),
07076 sstate_unparse (s->defstate)),
07077 sRef_getStateInfoLoc (s));
07078 }
07079 }
07080 }
07081
07082 void
07083 sRef_showExpInfo (sRef s)
07084 {
07085 if (sRef_hasExpInfoLoc (s))
07086 {
07087 llgenindentmsg (message ("Storage %qbecomes %s", sRef_unparseOpt (s),
07088 exkind_unparse (s->expkind)),
07089 sRef_getExpInfoLoc (s));
07090 }
07091 }
07092
07093 void
07094 sRef_showNullInfo (sRef s)
07095 {
07096 if (sRef_hasNullInfoLoc (s) && sRef_isKnown (s))
07097 {
07098 switch (s->nullstate)
07099 {
07100 case NS_CONSTNULL:
07101 {
07102 fileloc loc = sRef_getNullInfoLoc (s);
07103
07104 if (fileloc_isDefined (loc) && !fileloc_isLib (loc))
07105 {
07106 llgenindentmsg
07107 (message ("Storage %qbecomes null", sRef_unparseOpt (s)),
07108 loc);
07109 }
07110 break;
07111 }
07112 case NS_DEFNULL:
07113 {
07114 fileloc loc = sRef_getNullInfoLoc (s);
07115
07116 if (fileloc_isDefined (loc) && !fileloc_isLib (loc))
07117 {
07118 llgenindentmsg (message ("Storage %qbecomes null", sRef_unparseOpt (s)),
07119 loc);
07120 }
07121 break;
07122 }
07123 case NS_ABSNULL:
07124 case NS_POSNULL:
07125 llgenindentmsg
07126 (message ("Storage %qmay become null", sRef_unparseOpt (s)),
07127 sRef_getNullInfoLoc (s));
07128 break;
07129 case NS_NOTNULL:
07130 case NS_MNOTNULL:
07131 llgenindentmsg
07132 (message ("Storage %qbecomes not null", sRef_unparseOpt (s)),
07133 sRef_getNullInfoLoc (s));
07134 break;
07135 case NS_UNKNOWN:
07136 llgenindentmsg
07137 (message ("Storage %qnull state becomes unknown",
07138 sRef_unparseOpt (s)),
07139 sRef_getNullInfoLoc (s));
07140 break;
07141
07142 case NS_ERROR:
07143 BADBRANCHCONT;
07144 break;
07145
07146 default:
07147 llgenindentmsg
07148 (message ("<error case> Storage %q becomes %s",
07149 sRef_unparse (s),
07150 nstate_unparse (s->nullstate)),
07151 sRef_getNullInfoLoc (s));
07152
07153 break;
07154 }
07155 }
07156 }
07157
07158 void
07159 sRef_showAliasInfo (sRef s)
07160 {
07161 if (sRef_hasAliasInfoLoc (s))
07162 {
07163 if (sRef_isFresh (s))
07164 {
07165 llgenindentmsg
07166 (message ("Fresh storage %qallocated", sRef_unparseOpt (s)),
07167 sRef_getAliasInfoLoc (s));
07168 }
07169 else
07170 {
07171 if (!sRef_isRefCounted (s))
07172 {
07173 llgenindentmsg
07174 (message ("Storage %qbecomes %s",
07175 sRef_unparseOpt (s),
07176 alkind_unparse (sRef_getAliasKind (s))),
07177 sRef_getAliasInfoLoc (s));
07178 }
07179 }
07180 }
07181 }
07182
07183 void
07184 sRef_mergeNullState (sRef s, nstate n)
07185 {
07186 if (sRef_isValid (s))
07187 {
07188 nstate old;
07189
07190 old = s->nullstate;
07191
07192 if (n != old && n != NS_UNKNOWN)
07193 {
07194
07195 s->nullstate = n;
07196 s->nullinfo = alinfo_updateLoc (s->nullinfo, g_currentloc);
07197 }
07198 }
07199 else
07200 {
07201 llbuglit ("sRef_mergeNullState: invalid");
07202 }
07203 }
07204
07205 bool
07206 sRef_possiblyNull (sRef s)
07207 {
07208 if (sRef_isValid (s))
07209 {
07210 if (s->nullstate == NS_ABSNULL)
07211 {
07212 ctype rct = ctype_realType (s->type);
07213
07214 if (ctype_isAbstract (rct))
07215 {
07216 return FALSE;
07217 }
07218 else
07219 {
07220 if (ctype_isUser (rct))
07221 {
07222 uentry ue = usymtab_getTypeEntry (ctype_typeId (rct));
07223
07224 return (nstate_possiblyNull
07225 (sRef_getNullState (uentry_getSref (ue))));
07226 }
07227 else
07228 {
07229 return FALSE;
07230 }
07231 }
07232 }
07233 else
07234 {
07235 return nstate_possiblyNull (s->nullstate);
07236 }
07237 }
07238
07239 return FALSE;
07240 }
07241
07242 cstring
07243 sRef_getScopeName (sRef s)
07244 {
07245 sRef base = sRef_getRootBase (s);
07246
07247 if (sRef_isRealGlobal (base))
07248 {
07249 return (cstring_makeLiteralTemp ("Global"));
07250 }
07251 else if (sRef_isFileStatic (base))
07252 {
07253 return (cstring_makeLiteralTemp ("Static"));
07254 }
07255 else
07256 {
07257 return (cstring_makeLiteralTemp ("Local"));
07258 }
07259 }
07260
07261 cstring
07262 sRef_unparseScope (sRef s)
07263 {
07264 sRef base = sRef_getRootBase (s);
07265
07266 if (sRef_isRealGlobal (base))
07267 {
07268 return (cstring_makeLiteralTemp ("global"));
07269 }
07270 else if (sRef_isFileStatic (base))
07271 {
07272 return (cstring_makeLiteralTemp ("file static"));
07273 }
07274 else
07275 {
07276 BADEXIT;
07277 }
07278 }
07279
07280 int
07281 sRef_getScope (sRef s)
07282 {
07283 llassert (sRef_isValid (s));
07284
07285 if (sRef_isCvar (s))
07286 {
07287 return s->info->cvar->lexlevel;
07288 }
07289 else if (sRef_isParam (s))
07290 {
07291 return paramsScope;
07292 }
07293 else
07294 {
07295 return fileScope;
07296 }
07297 }
07298
07299 bool
07300 sRef_isDead (sRef s)
07301 {
07302 return (sRef_isValid (s) && (s)->defstate == SS_DEAD);
07303 }
07304
07305 bool
07306 sRef_isDeadStorage (sRef s)
07307 {
07308 if (sRef_isValid (s))
07309 {
07310 if (s->defstate == SS_DEAD
07311 || s->defstate == SS_UNUSEABLE
07312 || s->defstate == SS_UNDEFINED
07313 || s->defstate == SS_UNKNOWN)
07314 {
07315 return TRUE;
07316 }
07317 else
07318 {
07319 return (sRef_isDefinitelyNull (s));
07320 }
07321 }
07322 else
07323 {
07324 return FALSE;
07325 }
07326 }
07327
07328 bool
07329 sRef_isPossiblyDead (sRef s)
07330 {
07331 return (sRef_isValid (s) && s->defstate == SS_HOFFA);
07332 }
07333
07334 bool sRef_isStateLive (sRef s)
07335 {
07336 if (sRef_isValid (s))
07337 {
07338 sstate ds = s->defstate;
07339
07340 return (!(ds == SS_UNDEFINED
07341 || ds == SS_DEAD
07342 || ds == SS_UNUSEABLE
07343 || ds == SS_HOFFA));
07344 }
07345 else
07346 {
07347 return FALSE;
07348 }
07349 }
07350
07351
07352 bool sRef_isStateUndefined (sRef s)
07353 {
07354 return ((sRef_isValid(s)) && ((s)->defstate == SS_UNDEFINED));
07355 }
07356
07357 bool sRef_isJustAllocated (sRef s)
07358 {
07359 if (sRef_isAllocated (s))
07360 {
07361 sRefSet_allElements (s->deriv, el)
07362 {
07363 if (!(sRef_isStateUndefined (el) || sRef_isUnuseable (el)))
07364 {
07365 return FALSE;
07366 }
07367 } end_sRefSet_allElements ;
07368
07369 return TRUE;
07370 }
07371
07372 return FALSE;
07373 }
07374
07375 static bool
07376 sRef_isAllocatedStorage (sRef s)
07377 {
07378 if (sRef_isValid (s) && ynm_toBoolStrict (sRef_isReadable (s)))
07379 {
07380 return (ctype_isVisiblySharable (sRef_getType (s)));
07381 }
07382 else
07383 {
07384 return FALSE;
07385 }
07386 }
07387
07388 bool
07389 sRef_isUnuseable (sRef s)
07390 {
07391 return ((sRef_isValid(s)) && ((s)->defstate == SS_UNUSEABLE));
07392 }
07393
07394 bool
07395 sRef_perhapsNull (sRef s)
07396 {
07397 if (sRef_isValid (s))
07398 {
07399 if (s->nullstate == NS_ABSNULL)
07400 {
07401 ctype rct = ctype_realType (s->type);
07402
07403 if (ctype_isAbstract (rct))
07404 {
07405 return FALSE;
07406 }
07407 else
07408 {
07409 if (ctype_isUser (rct))
07410 {
07411 uentry ue = usymtab_getTypeEntry (ctype_typeId (rct));
07412
07413 return (nstate_perhapsNull
07414 (sRef_getNullState (uentry_getSref (ue))));
07415 }
07416 else
07417 {
07418 return FALSE;
07419 }
07420 }
07421 }
07422 else
07423 {
07424 return nstate_perhapsNull (s->nullstate);
07425 }
07426 }
07427
07428 return FALSE;
07429 }
07430
07431
07432
07433
07434
07435 bool
07436 sRef_definitelyNull (sRef s)
07437 {
07438 return (sRef_isValid (s)
07439 && (s->nullstate == NS_DEFNULL || s->nullstate == NS_CONSTNULL));
07440 }
07441
07442
07443
07444
07445
07446 void
07447 sRef_setDerivNullState (sRef set, sRef guide, nstate ns)
07448 {
07449 if (sRef_isValid (set))
07450 {
07451 sRef deriv = sRef_getDeriv (set, guide);
07452
07453 if (sRef_isValid (deriv))
07454 {
07455 deriv->nullstate = ns;
07456 }
07457 }
07458 }
07459
07460 static sRef
07461 sRef_getDeriv ( sRef set, sRef guide)
07462 {
07463 llassert (sRef_isValid (set));
07464 llassert (sRef_isValid (guide));
07465
07466 switch (guide->kind)
07467 {
07468 case SK_CVAR:
07469 llassert (set->kind == SK_CVAR);
07470
07471 return set;
07472
07473 case SK_PARAM:
07474 llassert (set->kind == guide->kind);
07475 llassert (set->info->paramno == guide->info->paramno);
07476
07477 return set;
07478
07479 case SK_ARRAYFETCH:
07480
07481 if (set->kind == SK_ARRAYFETCH
07482 && (sRef_similar (set->info->arrayfetch->arr,
07483 guide->info->arrayfetch->arr)))
07484 {
07485 return set;
07486 }
07487 else
07488 {
07489 return (sRef_makeAnyArrayFetch
07490 (sRef_getDeriv (set, guide->info->arrayfetch->arr)));
07491 }
07492
07493 case SK_PTR:
07494
07495 if (set->kind == SK_PTR && sRef_similar (set->info->ref, guide->info->ref))
07496 {
07497 return set;
07498 }
07499 else
07500 {
07501 return (sRef_makePointer (sRef_getDeriv (set, guide->info->ref)));
07502 }
07503
07504 case SK_FIELD:
07505
07506 if ((set->kind == SK_FIELD &&
07507 (sRef_similar (set->info->field->rec, guide->info->field->rec) &&
07508 cstring_equal (set->info->field->field, guide->info->field->field))))
07509 {
07510 return set;
07511 }
07512 else
07513 {
07514 return (sRef_makeField (sRef_getDeriv (set, guide->info->field->rec),
07515 guide->info->field->field));
07516 }
07517 case SK_ADR:
07518
07519 if ((set->kind == SK_ADR) && sRef_similar (set->info->ref, guide->info->ref))
07520 {
07521 return set;
07522 }
07523 else
07524 {
07525 return (sRef_makeAddress (sRef_getDeriv (set, guide->info->ref)));
07526 }
07527
07528 case SK_CONJ:
07529
07530 return sRef_undefined;
07531
07532 case SK_RESULT:
07533 case SK_SPECIAL:
07534 case SK_UNCONSTRAINED:
07535 case SK_TYPE:
07536 case SK_CONST:
07537 case SK_NEW:
07538 case SK_UNKNOWN:
07539 case SK_OBJECT:
07540 case SK_DERIVED:
07541 case SK_EXTERNAL:
07542 return sRef_undefined;
07543 }
07544
07545 BADEXIT;
07546 }
07547
07548
07549
07550
07551
07552
07553
07554
07555
07556
07557
07558
07559
07560 void
07561 sRef_aliasCheckPred (bool (predf) (sRef, exprNode, sRef, exprNode),
07562 bool (checkAliases) (sRef),
07563 sRef s, exprNode e, exprNode err)
07564 {
07565 bool error = (*predf)(s, e, sRef_undefined, err);
07566
07567
07568 if (checkAliases != NULL && !(checkAliases (s)))
07569 {
07570
07571 }
07572 else
07573 {
07574 sRefSet aliases = usymtab_allAliases (s);
07575
07576
07577 sRefSet_realElements (aliases, current)
07578 {
07579 if (sRef_isValid (current))
07580 {
07581 if (!sRef_similar (current, s)
07582 || (error && sRef_sameName (current, s)))
07583 {
07584 (void) (*predf)(current, e, s, err);
07585 }
07586 }
07587 } end_sRefSet_realElements;
07588
07589 sRefSet_free (aliases);
07590 }
07591 }
07592
07593
07594
07595
07596
07597 bool
07598 sRef_aliasCheckSimplePred (sRefTest predf, sRef s)
07599 {
07600
07601 if ((*predf)(s))
07602 {
07603 return TRUE;
07604 }
07605 else
07606 {
07607 sRefSet aliases;
07608
07609 aliases = usymtab_allAliases (s);
07610
07611 sRefSet_realElements (aliases, current)
07612 {
07613 if (sRef_isValid (current))
07614 {
07615 sRef cref = sRef_updateSref (current);
07616
07617
07618
07619
07620
07621
07622
07623
07624 if ((*predf)(cref))
07625 {
07626 sRefSet_free (aliases);
07627 return TRUE;
07628 }
07629 }
07630 } end_sRefSet_realElements;
07631
07632 sRefSet_free (aliases);
07633 }
07634 return FALSE;
07635 }
07636
07637 bool
07638 sRef_aliasCompleteSimplePred (bool (predf) (sRef), sRef s)
07639 {
07640 sRefSet aliases;
07641 bool result = FALSE;
07642
07643
07644 aliases = usymtab_allAliases (s);
07645
07646 if ((*predf)(s)) result = TRUE;
07647
07648
07649 sRefSet_realElements (aliases, current)
07650 {
07651 if (sRef_isValid (current))
07652 {
07653 current = sRef_updateSref (current);
07654 if ((*predf)(current)) result = TRUE;
07655 }
07656 } end_sRefSet_realElements;
07657
07658 sRefSet_free (aliases);
07659 return result;
07660 }
07661
07662 static void
07663 sRef_aliasSetComplete (void (predf) (sRef, fileloc), sRef s, fileloc loc)
07664 {
07665 sRefSet aliases;
07666
07667 aliases = usymtab_allAliases (s);
07668
07669 (*predf)(s, loc);
07670
07671 sRefSet_realElements (aliases, current)
07672 {
07673 if (sRef_isValid (current))
07674 {
07675 current = sRef_updateSref (current);
07676 ((*predf)(current, loc));
07677 }
07678 } end_sRefSet_realElements;
07679
07680 sRefSet_free (aliases);
07681 }
07682
07683 static void
07684 sRef_aliasSetCompleteParam (void (predf) (sRef, alkind, fileloc), sRef s,
07685 alkind kind, fileloc loc)
07686 {
07687 sRefSet aliases;
07688
07689
07690 if (sRef_isDeep (s))
07691 {
07692 aliases = usymtab_allAliases (s);
07693 }
07694 else
07695 {
07696 aliases = usymtab_aliasedBy (s);
07697 }
07698
07699 (*predf)(s, kind, loc);
07700
07701 sRefSet_realElements (aliases, current)
07702 {
07703 if (sRef_isValid (current))
07704 {
07705 current = sRef_updateSref (current);
07706 ((*predf)(current, kind, loc));
07707 }
07708 } end_sRefSet_realElements;
07709
07710 sRefSet_free (aliases);
07711 }
07712
07713 static void
07714 sRef_innerAliasSetComplete (void (predf) (sRef, fileloc), sRef s, fileloc loc)
07715 {
07716 sRef inner;
07717 sRefSet aliases;
07718 ctype ct;
07719
07720 if (!sRef_isValid (s)) return;
07721
07722
07723
07724
07725
07726
07727 (*predf)(s, loc);
07728
07729 switch (s->kind)
07730 {
07731 case SK_UNCONSTRAINED:
07732 case SK_CVAR:
07733 case SK_PARAM:
07734 break;
07735 case SK_PTR:
07736 inner = s->info->ref;
07737 aliases = usymtab_allAliases (inner);
07738 ct = sRef_getType (inner);
07739
07740
07741 sRefSet_realElements (aliases, current)
07742 {
07743 if (sRef_isValid (current))
07744 {
07745 current = sRef_updateSref (current);
07746
07747 if (ctype_equal (ct, sRef_getType (current)))
07748 {
07749 sRef ptr = sRef_makePointer (current);
07750
07751 ((*predf)(ptr, loc));
07752 }
07753 }
07754 } end_sRefSet_realElements;
07755
07756 sRefSet_free (aliases);
07757 break;
07758 case SK_ARRAYFETCH:
07759 inner = s->info->arrayfetch->arr;
07760 aliases = usymtab_allAliases (inner);
07761 ct = sRef_getType (inner);
07762
07763 sRefSet_realElements (aliases, current)
07764 {
07765 if (sRef_isValid (current))
07766 {
07767 current = sRef_updateSref (current);
07768
07769 if (ctype_equal (ct, sRef_getType (current)))
07770 {
07771
07772 if (s->info->arrayfetch->indknown)
07773 {
07774 sRef af = sRef_makeArrayFetchKnown (current, s->info->arrayfetch->ind);
07775
07776 ((*predf)(af, loc));
07777 }
07778 else
07779 {
07780 sRef af = sRef_makeArrayFetch (current);
07781
07782 ((*predf)(af, loc));
07783 }
07784 }
07785 }
07786 } end_sRefSet_realElements;
07787
07788 sRefSet_free (aliases);
07789 break;
07790 case SK_FIELD:
07791 inner = s->info->field->rec;
07792 aliases = usymtab_allAliases (inner);
07793 ct = sRef_getType (inner);
07794
07795
07796 sRefSet_realElements (aliases, current)
07797 {
07798 if (sRef_isValid (current))
07799 {
07800 current = sRef_updateSref (current);
07801
07802 if (ctype_equal (ct, sRef_getType (current)))
07803 {
07804 sRef f = sRef_makeField (current, s->info->field->field);
07805
07806 ((*predf)(f, loc));
07807 }
07808 }
07809 } end_sRefSet_realElements;
07810
07811 sRefSet_free (aliases);
07812 break;
07813 case SK_CONJ:
07814 sRef_innerAliasSetComplete (predf, s->info->conj->a, loc);
07815 sRef_innerAliasSetComplete (predf, s->info->conj->b, loc);
07816 break;
07817 case SK_SPECIAL:
07818 case SK_ADR:
07819 case SK_TYPE:
07820 case SK_CONST:
07821 case SK_NEW:
07822 case SK_UNKNOWN:
07823 case SK_OBJECT:
07824 case SK_DERIVED:
07825 case SK_EXTERNAL:
07826 case SK_RESULT:
07827 break;
07828 }
07829 }
07830
07831 static void
07832 sRef_innerAliasSetCompleteParam (void (predf) (sRef, sRef), sRef s, sRef t)
07833 {
07834 sRef inner;
07835 sRefSet aliases;
07836 ctype ct;
07837
07838 if (!sRef_isValid (s)) return;
07839
07840
07841
07842
07843
07844
07845 (*predf)(s, t);
07846
07847 switch (s->kind)
07848 {
07849 case SK_UNCONSTRAINED:
07850 case SK_CVAR:
07851 case SK_PARAM:
07852 break;
07853 case SK_PTR:
07854 inner = s->info->ref;
07855 aliases = usymtab_allAliases (inner);
07856 ct = sRef_getType (inner);
07857
07858
07859 sRefSet_realElements (aliases, current)
07860 {
07861 if (sRef_isValid (current))
07862 {
07863 current = sRef_updateSref (current);
07864
07865 if (ctype_equal (ct, sRef_getType (current)))
07866 {
07867 sRef ptr = sRef_makePointer (current);
07868
07869 ((*predf)(ptr, t));
07870 }
07871 }
07872 } end_sRefSet_realElements;
07873
07874 sRefSet_free (aliases);
07875 break;
07876 case SK_ARRAYFETCH:
07877 inner = s->info->arrayfetch->arr;
07878 aliases = usymtab_allAliases (inner);
07879 ct = sRef_getType (inner);
07880
07881 sRefSet_realElements (aliases, current)
07882 {
07883 if (sRef_isValid (current))
07884 {
07885 current = sRef_updateSref (current);
07886
07887 if (ctype_equal (ct, sRef_getType (current)))
07888 {
07889
07890 if (s->info->arrayfetch->indknown)
07891 {
07892 sRef af = sRef_makeArrayFetchKnown (current, s->info->arrayfetch->ind);
07893
07894 ((*predf)(af, t));
07895 }
07896 else
07897 {
07898 sRef af = sRef_makeArrayFetch (current);
07899
07900 ((*predf)(af, t));
07901 }
07902 }
07903 }
07904 } end_sRefSet_realElements;
07905
07906 sRefSet_free (aliases);
07907 break;
07908 case SK_FIELD:
07909 inner = s->info->field->rec;
07910 aliases = usymtab_allAliases (inner);
07911 ct = sRef_getType (inner);
07912
07913
07914 sRefSet_realElements (aliases, current)
07915 {
07916 if (sRef_isValid (current))
07917 {
07918 current = sRef_updateSref (current);
07919
07920 if (ctype_equal (ct, sRef_getType (current)))
07921 {
07922 sRef f = sRef_makeField (current, s->info->field->field);
07923
07924 ((*predf)(f, t));
07925 }
07926 }
07927 } end_sRefSet_realElements;
07928
07929 sRefSet_free (aliases);
07930 break;
07931 case SK_CONJ:
07932 sRef_innerAliasSetCompleteParam (predf, s->info->conj->a, t);
07933 sRef_innerAliasSetCompleteParam (predf, s->info->conj->b, t);
07934 break;
07935 case SK_SPECIAL:
07936 case SK_ADR:
07937 case SK_TYPE:
07938 case SK_CONST:
07939 case SK_NEW:
07940 case SK_UNKNOWN:
07941 case SK_OBJECT:
07942 case SK_DERIVED:
07943 case SK_EXTERNAL:
07944 case SK_RESULT:
07945 break;
07946 }
07947 }
07948
07949 static void sRef_combineExKinds ( sRef res, sRef other)
07950 {
07951 exkind a1 = sRef_getExKind (res);
07952 exkind a2 = sRef_getExKind (other);
07953
07954 if (a1 == a2 || a2 == XO_UNKNOWN)
07955 {
07956 ;
07957 }
07958 else if (a1 == XO_UNKNOWN)
07959 {
07960 res->expinfo = alinfo_update (res->expinfo, other->expinfo);
07961 res->expkind = a2;
07962 }
07963 else
07964 {
07965 res->expkind = XO_OBSERVER;
07966 }
07967 }
07968
07969
07970
07971
07972
07973
07974
07975 static void
07976 sRef_combineAliasKindsError ( sRef res,
07977 sRef other,
07978 clause cl, fileloc loc)
07979 {
07980 bool hasError = FALSE;
07981 alkind ares = sRef_getAliasKind (res);
07982 alkind aother = sRef_getAliasKind (other);
07983
07984 if (alkind_isDependent (ares))
07985 {
07986 if (aother == AK_KEPT)
07987 {
07988 res->aliasinfo = alinfo_update (res->aliasinfo, other->aliasinfo);
07989 res->aliaskind = AK_KEPT;
07990 }
07991 else
07992 {
07993 if (aother == AK_LOCAL || aother == AK_STATIC
07994 || alkind_isTemp (aother))
07995 {
07996 res->aliaskind = AK_DEPENDENT;
07997 }
07998 }
07999 }
08000 else if (alkind_isDependent (aother))
08001 {
08002 if (ares == AK_KEPT)
08003 {
08004 res->aliaskind = AK_KEPT;
08005 }
08006 else
08007 {
08008 if (ares == AK_LOCAL || ares == AK_STATIC || alkind_isTemp (ares))
08009 {
08010 res->aliasinfo = alinfo_update (res->aliasinfo, other->aliasinfo);
08011 res->aliaskind = AK_DEPENDENT;
08012 }
08013 }
08014 }
08015 else if ((ares == AK_LOCAL || ares == AK_UNIQUE
08016 || ares == AK_STATIC || alkind_isTemp (ares))
08017 && sRef_isFresh (other))
08018 {
08019
08020
08021
08022
08023
08024 if (usymtab_isAltProbablyDeepNull (res))
08025 {
08026 res->aliaskind = ares;
08027 }
08028 else
08029 {
08030 hasError = TRUE;
08031 }
08032 }
08033 else if ((aother == AK_LOCAL || aother == AK_UNIQUE
08034 || aother == AK_STATIC || alkind_isTemp (aother))
08035 && sRef_isFresh (res))
08036 {
08037
08038
08039
08040
08041
08042 if (usymtab_isProbableDeepNull (other))
08043 {
08044 res->aliasinfo = alinfo_update (res->aliasinfo, other->aliasinfo);
08045 res->aliaskind = aother;
08046 }
08047 else
08048 {
08049 hasError = TRUE;
08050 }
08051 }
08052 else if (ares == AK_NEWREF && aother == AK_REFCOUNTED
08053 && sRef_isConst (other))
08054 {
08055 res->aliaskind = AK_NEWREF;
08056 }
08057 else if (aother == AK_NEWREF && ares == AK_REFCOUNTED
08058 && sRef_isConst (res))
08059 {
08060 res->aliasinfo = alinfo_update (res->aliasinfo, other->aliasinfo);
08061 res->aliaskind = AK_NEWREF;
08062 }
08063 else if (sRef_isLocalVar (res)
08064 && ((ares == AK_KEPT && aother == AK_LOCAL)
08065 || (aother == AK_KEPT && ares == AK_LOCAL)))
08066 {
08067 res->aliaskind = AK_KEPT;
08068 }
08069 else
08070 {
08071 hasError = TRUE;
08072 }
08073
08074 if (hasError)
08075 {
08076 if (sRef_isThroughArrayFetch (res))
08077 {
08078 if (optgenerror2
08079 (FLG_BRANCHSTATE, FLG_STRICTBRANCHSTATE,
08080 message
08081 ("Clauses exit with %q possibly referencing %s storage %s, "
08082 "%s storage %s",
08083 sRef_unparse (res),
08084 alkind_unparse (aother),
08085 clause_nameTaken (cl),
08086 alkind_unparse (ares),
08087 clause_nameAlternate (cl)),
08088 loc))
08089 {
08090 sRef_showAliasInfo (res);
08091 sRef_showAliasInfo (other);
08092 res->aliaskind = AK_ERROR;
08093 }
08094 else
08095 {
08096 if (ares == AK_KEPT || aother == AK_KEPT)
08097 {
08098 sRef_maybeKill (res, loc);
08099 }
08100 }
08101 }
08102 else
08103 {
08104 if (optgenerror
08105 (FLG_BRANCHSTATE,
08106 message ("Clauses exit with %q referencing %s storage %s, "
08107 "%s storage %s",
08108 sRef_unparse (res),
08109 alkind_unparse (aother),
08110 clause_nameTaken (cl),
08111 alkind_unparse (ares),
08112 clause_nameAlternate (cl)),
08113 loc))
08114 {
08115 sRef_showAliasInfo (res);
08116 sRef_showAliasInfo (other);
08117
08118 res->aliaskind = AK_ERROR;
08119 }
08120 }
08121
08122 res->aliaskind = (sRef_isLocalVar (res) ? AK_LOCAL : AK_UNKNOWN);
08123 }
08124 }
08125
08126 static void
08127 sRef_combineAliasKinds ( sRef res, sRef other,
08128 clause cl, fileloc loc)
08129 {
08130 alkind ares = sRef_getAliasKind (res);
08131 alkind aother = sRef_getAliasKind (other);
08132
08133 if (alkind_equal (ares, aother)
08134 || aother == AK_UNKNOWN
08135 || aother == AK_ERROR)
08136 {
08137 ;
08138 }
08139 else if (sRef_isDead (res) || sRef_isDead (other))
08140 {
08141
08142 res ->aliaskind = AK_ERROR;
08143 }
08144 else if (ares == AK_UNKNOWN || ares == AK_ERROR
08145 || sRef_isStateUndefined (res))
08146 {
08147 res->aliasinfo = alinfo_update (res->aliasinfo, other->aliasinfo);
08148 res->aliaskind = aother;
08149 }
08150 else if (sRef_isStateUndefined (other))
08151 {
08152 ;
08153 }
08154 else if (((ares == AK_UNIQUE || alkind_isTemp (ares))
08155 && aother == AK_LOCAL)
08156 || ((aother == AK_UNIQUE || alkind_isTemp (aother))
08157 && ares == AK_LOCAL))
08158 {
08159 if (ares != AK_LOCAL)
08160 {
08161 res->aliasinfo = alinfo_update (res->aliasinfo, other->aliasinfo);
08162 }
08163
08164 res->aliaskind = AK_LOCAL;
08165 }
08166 else if ((ares == AK_OWNED && aother == AK_FRESH)
08167 || (aother == AK_OWNED && ares == AK_FRESH))
08168 {
08169 if (ares != AK_FRESH)
08170 {
08171 res->aliasinfo = alinfo_update (res->aliasinfo, other->aliasinfo);
08172 }
08173
08174 res->aliaskind = AK_FRESH;
08175 }
08176 else if ((ares == AK_KEEP && aother == AK_FRESH) ||
08177 (aother == AK_KEEP && ares == AK_FRESH))
08178 {
08179 if (ares != AK_KEEP)
08180 {
08181 res->aliasinfo = alinfo_update (res->aliasinfo, other->aliasinfo);
08182 }
08183
08184 res->aliaskind = AK_KEEP;
08185 }
08186 else if ((ares == AK_LOCAL && aother == AK_STACK) ||
08187 (aother == AK_LOCAL && ares == AK_STACK))
08188 {
08189 if (ares != AK_STACK)
08190 {
08191 res->aliasinfo = alinfo_update (res->aliasinfo, other->aliasinfo);
08192 }
08193
08194 res->aliaskind = AK_STACK;
08195 }
08196 else if ((ares == AK_LOCAL
08197 && (aother == AK_OWNED && sRef_isLocalVar (other)))
08198 || (aother == AK_LOCAL
08199 && (ares == AK_OWNED && sRef_isLocalVar (res))))
08200 {
08201 if (ares != AK_LOCAL)
08202 {
08203 res->aliasinfo = alinfo_update (res->aliasinfo, other->aliasinfo);
08204 }
08205
08206 res->aliaskind = AK_LOCAL;
08207 }
08208 else if ((ares == AK_FRESH && alkind_isOnly (aother))
08209 || (aother == AK_FRESH && alkind_isOnly (ares)))
08210 {
08211 res->aliaskind = AK_FRESH;
08212 }
08213 else if ((aother == AK_FRESH && sRef_definitelyNull (res))
08214 || (ares == AK_FRESH && sRef_definitelyNull (other)))
08215 {
08216 if (ares != AK_FRESH)
08217 {
08218 res->aliasinfo = alinfo_update (res->aliasinfo, other->aliasinfo);
08219 res->aliaskind = AK_FRESH;
08220 }
08221 }
08222 else if ((sRef_isFresh (res) && sRef_isConst (other))
08223 || (sRef_isFresh (other) && sRef_isConst (res)))
08224 {
08225
08226
08227
08228
08229
08230 if (!sRef_isFresh (res))
08231 {
08232 res->aliasinfo = alinfo_update (res->aliasinfo, other->aliasinfo);
08233 }
08234
08235 res->aliaskind = AK_FRESH;
08236 }
08237 else if ((alkind_isStatic (aother) && sRef_isConst (res))
08238 || (alkind_isStatic (ares) && sRef_isConst (other)))
08239 {
08240 if (!alkind_isStatic (ares))
08241 {
08242 res->aliasinfo = alinfo_update (res->aliasinfo, other->aliasinfo);
08243 res->aliaskind = AK_STATIC;
08244 }
08245 }
08246 else
08247 {
08248 sRef_combineAliasKindsError (res, other, cl, loc);
08249 }
08250 }
08251
08252 static void sRef_combineDefState ( sRef res,
08253 sRef other)
08254 {
08255 sstate s1 = res->defstate;
08256 sstate s2 = other->defstate;
08257 bool flip = FALSE;
08258
08259 if (s1 == s2 || s2 == SS_UNKNOWN)
08260 {
08261 ;
08262 }
08263 else if (s1 == SS_UNKNOWN)
08264 {
08265 flip = TRUE;
08266 }
08267 else
08268 {
08269 switch (s1)
08270 {
08271 case SS_FIXED:
08272 if (s2 == SS_DEFINED)
08273 {
08274 break;
08275 }
08276 else
08277 {
08278 llcontbuglit ("ssfixed: not implemented");
08279 flip = TRUE;
08280 }
08281 break;
08282 case SS_DEFINED:
08283 flip = TRUE;
08284 break;
08285 case SS_PDEFINED:
08286 case SS_ALLOCATED:
08287 flip = (s2 != SS_DEFINED);
08288 break;
08289 case SS_HOFFA:
08290 case SS_RELDEF:
08291 case SS_UNUSEABLE:
08292 case SS_UNDEFINED:
08293 case SS_PARTIAL:
08294 case SS_UNDEFGLOB:
08295 case SS_KILLED:
08296 case SS_DEAD:
08297 case SS_SPECIAL:
08298 break;
08299 BADDEFAULT;
08300 }
08301 }
08302
08303 if (flip)
08304 {
08305 res->definfo = alinfo_update (res->definfo, other->definfo);
08306 res->defstate = s2;
08307 }
08308 }
08309
08310 extern sRef sRef_getConjA (sRef s)
08311 {
08312 sRef ret;
08313 llassert (sRef_isConj (s));
08314
08315 ret = s->info->conj->a;
08316 llassert (ret != NULL);
08317 return ret;
08318 }
08319
08320 extern sRef sRef_getConjB (sRef s)
08321 {
08322 sRef ret;
08323 llassert (sRef_isConj (s));
08324
08325 ret = s->info->conj->b;
08326 llassert (ret != NULL);
08327 return ret;
08328 }
08329
08330 extern sRef sRef_makeArrow (sRef s, cstring f)
08331 {
08332 sRef p;
08333 sRef ret;
08334
08335 p = sRef_makePointer (s);
08336 ret = sRef_makeField (p, f);
08337 return ret;
08338 }
08339
08340 extern sRef sRef_buildArrow (sRef s, cstring f)
08341 {
08342 sRef p;
08343 sRef ret;
08344
08345 p = sRef_buildPointer (s);
08346 ret = sRef_buildField (p, f);
08347
08348 return ret;
08349 }
08350
08351 static sinfo sinfo_copy ( sRef s)
08352 {
08353 sinfo ret;
08354
08355 switch (s->kind)
08356 {
08357 case SK_CVAR:
08358 ret = (sinfo) dmalloc (sizeof (*ret));
08359 ret->cvar = (cref) dmalloc (sizeof (*ret->cvar));
08360 ret->cvar->lexlevel = s->info->cvar->lexlevel;
08361 ret->cvar->index = s->info->cvar->index;
08362 break;
08363
08364 case SK_PARAM:
08365 ret = (sinfo) dmalloc (sizeof (*ret));
08366 ret->paramno = s->info->paramno;
08367 break;
08368
08369 case SK_ARRAYFETCH:
08370 ret = (sinfo) dmalloc (sizeof (*ret));
08371 ret->arrayfetch = (ainfo) dmalloc (sizeof (*ret->arrayfetch));
08372 ret->arrayfetch->indknown = s->info->arrayfetch->indknown;
08373 ret->arrayfetch->ind = s->info->arrayfetch->ind;
08374 ret->arrayfetch->arr = s->info->arrayfetch->arr;
08375 break;
08376
08377 case SK_FIELD:
08378 ret = (sinfo) dmalloc (sizeof (*ret));
08379 ret->field = (fldinfo) dmalloc (sizeof (*ret->field));
08380 ret->field->rec = s->info->field->rec;
08381 ret->field->field = s->info->field->field;
08382 break;
08383
08384 case SK_OBJECT:
08385 ret = (sinfo) dmalloc (sizeof (*ret));
08386 ret->object = s->info->object;
08387 break;
08388
08389 case SK_PTR:
08390 case SK_ADR:
08391 case SK_DERIVED:
08392 case SK_EXTERNAL:
08393 ret = (sinfo) dmalloc (sizeof (*ret));
08394 ret->ref = s->info->ref;
08395 break;
08396
08397 case SK_CONJ:
08398 ret = (sinfo) dmalloc (sizeof (*ret));
08399 ret->conj = (cjinfo) dmalloc (sizeof (*ret->conj));
08400 ret->conj->a = s->info->conj->a;
08401 ret->conj->b = s->info->conj->b;
08402 break;
08403 case SK_SPECIAL:
08404 ret = (sinfo) dmalloc (sizeof (*ret));
08405 ret->spec = s->info->spec;
08406 break;
08407 case SK_UNCONSTRAINED:
08408 case SK_NEW:
08409 ret = (sinfo) dmalloc (sizeof (*ret));
08410 ret->fname = s->info->fname;
08411 break;
08412 case SK_RESULT:
08413 case SK_CONST:
08414 case SK_TYPE:
08415 case SK_UNKNOWN:
08416 llassertprint (s->info == NULL, ("s = %s", sRef_unparse (s)));
08417 ret = NULL;
08418 break;
08419 }
08420
08421 return ret;
08422 }
08423
08424 static sinfo sinfo_fullCopy ( sRef s)
08425 {
08426 sinfo ret;
08427
08428
08429
08430
08431
08432
08433
08434 switch (s->kind)
08435 {
08436 case SK_CVAR:
08437 ret = (sinfo) dmalloc (sizeof (*ret));
08438 ret->cvar = (cref) dmalloc (sizeof (*ret->cvar));
08439 ret->cvar->lexlevel = s->info->cvar->lexlevel;
08440 ret->cvar->index = s->info->cvar->index;
08441 break;
08442
08443 case SK_PARAM:
08444 ret = (sinfo) dmalloc (sizeof (*ret));
08445 ret->paramno = s->info->paramno;
08446 break;
08447
08448 case SK_ARRAYFETCH:
08449 ret = (sinfo) dmalloc (sizeof (*ret));
08450 ret->arrayfetch = (ainfo) dmalloc (sizeof (*ret->arrayfetch));
08451 ret->arrayfetch->indknown = s->info->arrayfetch->indknown;
08452 ret->arrayfetch->ind = s->info->arrayfetch->ind;
08453 ret->arrayfetch->arr = sRef_saveCopy (s->info->arrayfetch->arr);
08454 break;
08455
08456 case SK_FIELD:
08457 ret = (sinfo) dmalloc (sizeof (*ret));
08458 ret->field = (fldinfo) dmalloc (sizeof (*ret->field));
08459 ret->field->rec = sRef_saveCopy (s->info->field->rec);
08460 ret->field->field = s->info->field->field;
08461 break;
08462
08463 case SK_OBJECT:
08464 ret = (sinfo) dmalloc (sizeof (*ret));
08465 ret->object = s->info->object;
08466 break;
08467
08468 case SK_PTR:
08469 case SK_ADR:
08470 case SK_DERIVED:
08471 case SK_EXTERNAL:
08472 ret = (sinfo) dmalloc (sizeof (*ret));
08473 ret->ref = sRef_saveCopy (s->info->ref);
08474 break;
08475
08476 case SK_CONJ:
08477 ret = (sinfo) dmalloc (sizeof (*ret));
08478 ret->conj = (cjinfo) dmalloc (sizeof (*ret->conj));
08479 ret->conj->a = sRef_saveCopy (s->info->conj->a);
08480 ret->conj->b = sRef_saveCopy (s->info->conj->b);
08481 break;
08482 case SK_SPECIAL:
08483 ret = (sinfo) dmalloc (sizeof (*ret));
08484 ret->spec = s->info->spec;
08485 break;
08486 case SK_NEW:
08487 case SK_UNCONSTRAINED:
08488 ret = (sinfo) dmalloc (sizeof (*ret));
08489 ret->fname = s->info->fname;
08490 break;
08491 case SK_CONST:
08492 case SK_TYPE:
08493 case SK_RESULT:
08494 case SK_UNKNOWN:
08495 llassert (s->info == NULL);
08496 ret = NULL;
08497 break;
08498 }
08499
08500 return ret;
08501 }
08502
08503
08504 static void
08505 sinfo_update ( sRef res,
08506 sRef other)
08507 {
08508 llassert (res->kind == other->kind);
08509
08510 switch (res->kind)
08511 {
08512 case SK_CVAR:
08513 res->info->cvar->lexlevel = other->info->cvar->lexlevel;
08514 res->info->cvar->index = other->info->cvar->index;
08515 break;
08516
08517 case SK_PARAM:
08518 res->info->paramno = other->info->paramno;
08519 break;
08520
08521 case SK_ARRAYFETCH:
08522 res->info->arrayfetch->indknown = other->info->arrayfetch->indknown;
08523 res->info->arrayfetch->ind = other->info->arrayfetch->ind;
08524 res->info->arrayfetch->arr = other->info->arrayfetch->arr;
08525 break;
08526
08527 case SK_FIELD:
08528 res->info->field->rec = other->info->field->rec;
08529 res->info->field->field = other->info->field->field;
08530 break;
08531
08532 case SK_OBJECT:
08533 res->info->object = other->info->object;
08534 break;
08535
08536 case SK_PTR:
08537 case SK_ADR:
08538 case SK_DERIVED:
08539 case SK_EXTERNAL:
08540 res->info->ref = other->info->ref;
08541 break;
08542
08543 case SK_CONJ:
08544 res->info->conj->a = other->info->conj->a;
08545 res->info->conj->b = other->info->conj->b;
08546 break;
08547
08548 case SK_SPECIAL:
08549 res->info->spec = other->info->spec;
08550 break;
08551
08552 case SK_NEW:
08553 case SK_UNCONSTRAINED:
08554 res->info->fname = other->info->fname;
08555 break;
08556
08557 case SK_CONST:
08558 case SK_TYPE:
08559 case SK_UNKNOWN:
08560 case SK_RESULT:
08561 llassert (res->info == NULL);
08562 break;
08563 }
08564 }
08565
08566 static void sinfo_free ( sRef s)
08567
08568
08569 {
08570 switch (s->kind)
08571 {
08572 case SK_CVAR:
08573 sfree (s->info->cvar);
08574 break;
08575
08576 case SK_PARAM:
08577 break;
08578
08579 case SK_ARRAYFETCH:
08580 sfree (s->info->arrayfetch);
08581 break;
08582
08583 case SK_FIELD:
08584 sfree (s->info->field);
08585 break;
08586
08587 case SK_OBJECT:
08588 break;
08589
08590 case SK_PTR:
08591 case SK_ADR:
08592 case SK_DERIVED:
08593 case SK_EXTERNAL:
08594 break;
08595
08596 case SK_CONJ:
08597 sfree (s->info->conj);
08598 break;
08599
08600 case SK_UNCONSTRAINED:
08601 case SK_SPECIAL:
08602 case SK_CONST:
08603 case SK_NEW:
08604 case SK_TYPE:
08605 case SK_UNKNOWN:
08606 case SK_RESULT:
08607 break;
08608 }
08609
08610 sfree (s->info);
08611 }
08612
08613 bool sRef_isNSLocalVar (sRef s)
08614 {
08615 if (sRef_isLocalVar (s))
08616 {
08617 uentry ue = sRef_getUentry (s);
08618
08619 return (!uentry_isStatic (ue));
08620 }
08621 else
08622 {
08623 return FALSE;
08624 }
08625 }
08626
08627 bool sRef_isLocalVar (sRef s)
08628 {
08629 if (sRef_isValid(s))
08630 {
08631 return (s->kind == SK_CVAR
08632 && (s->info->cvar->lexlevel > fileScope));
08633 }
08634
08635 return FALSE;
08636 }
08637
08638 bool sRef_isRealLocalVar (sRef s)
08639 {
08640 if (sRef_isValid(s))
08641 {
08642 if (s->kind == SK_CVAR)
08643 {
08644 if (s->info->cvar->lexlevel == functionScope)
08645 {
08646 uentry ue = sRef_getUentry (s);
08647
08648 if (uentry_isAnyParam (ue)
08649 || uentry_isRefParam (ue))
08650 {
08651 return FALSE;
08652 }
08653 else
08654 {
08655 return TRUE;
08656 }
08657 }
08658 else
08659 {
08660 return (s->info->cvar->lexlevel > functionScope);
08661 }
08662 }
08663 }
08664
08665 return FALSE;
08666 }
08667
08668 bool sRef_isLocalParamVar (sRef s)
08669 {
08670 if (sRef_isValid(s))
08671 {
08672 return (s->kind == SK_PARAM
08673 || (s->kind == SK_CVAR
08674 && (s->info->cvar->lexlevel > fileScope)));
08675 }
08676
08677 return FALSE;
08678 }
08679
08680 static speckind speckind_fromInt (int i)
08681 {
08682
08683 llassert (i >= SR_NOTHING && i <= SR_SYSTEM);
08684
08685
08686 return ((speckind) i);
08687 }
08688
08689 void sRef_combineNullState ( sRef res, sRef other)
08690 {
08691 nstate n1 = res->nullstate;
08692 nstate n2 = other->nullstate;
08693 bool flip = FALSE;
08694 nstate nn = n1;
08695
08696 if (n1 == n2 || n2 == NS_UNKNOWN)
08697 {
08698 ;
08699 }
08700 else
08701 {
08702
08703
08704 switch (n1)
08705 {
08706 case NS_ERROR: nn = NS_ERROR; break;
08707 case NS_UNKNOWN: flip = TRUE; nn = n2; break;
08708 case NS_POSNULL: break;
08709 case NS_DEFNULL: nn = NS_POSNULL; break;
08710 case NS_RELNULL: break;
08711 case NS_NOTNULL:
08712 if (n2 == NS_MNOTNULL)
08713 {
08714 ;
08715 }
08716 else
08717 {
08718 flip = TRUE;
08719 nn = NS_POSNULL;
08720 }
08721 break;
08722 case NS_MNOTNULL:
08723 if (n2 == NS_NOTNULL)
08724 {
08725 nn = NS_NOTNULL;
08726 }
08727 else
08728 {
08729 flip = TRUE;
08730 nn = NS_POSNULL;
08731 }
08732 break;
08733 case NS_CONSTNULL:
08734 case NS_ABSNULL:
08735 flip = TRUE;
08736 nn = n2;
08737 }
08738 }
08739
08740 if (flip)
08741 {
08742 res->nullinfo = alinfo_update (res->nullinfo, other->nullinfo);
08743 }
08744
08745 res->nullstate = nn;
08746 }
08747
08748 cstring sRef_nullMessage (sRef s)
08749 {
08750 llassert (sRef_isValid (s));
08751
08752 switch (s->nullstate)
08753 {
08754 case NS_DEFNULL:
08755 case NS_CONSTNULL:
08756 return (cstring_makeLiteralTemp ("null"));
08757 default:
08758 return (cstring_makeLiteralTemp ("possibly null"));
08759 }
08760 BADEXIT;
08761 }
08762
08763 sRef sRef_fixResultType ( sRef s, ctype typ, uentry ue)
08764 {
08765 sRef tmp = sRef_undefined;
08766 sRef ret;
08767
08768 llassert (sRef_isValid (s));
08769
08770 switch (s->kind)
08771 {
08772 case SK_RESULT:
08773 s->type = typ;
08774 ret = s;
08775 break;
08776 case SK_ARRAYFETCH:
08777 {
08778 ctype ct;
08779 tmp = sRef_fixResultType (s->info->arrayfetch->arr, typ, ue);
08780
08781 ct = ctype_realType (sRef_getType (tmp));
08782
08783
08784 if (ctype_isKnown (ct))
08785 {
08786 if (ctype_isAP (ct))
08787 {
08788 ;
08789 }
08790 else
08791 {
08792 voptgenerror
08793 (FLG_TYPE,
08794 message
08795 ("Special clause indexes non-array (%t): *%q",
08796 ct, sRef_unparse (s->info->arrayfetch->arr)),
08797 uentry_whereLast (ue));
08798 }
08799 }
08800
08801 tmp = sRef_fixResultType (s->info->arrayfetch->arr, typ, ue);
08802
08803 if (s->info->arrayfetch->indknown)
08804 {
08805 ret = sRef_makeArrayFetchKnown (tmp, s->info->arrayfetch->ind);
08806 }
08807 else
08808 {
08809 ret = sRef_makeArrayFetch (tmp);
08810 }
08811 }
08812 break;
08813 case SK_FIELD:
08814 {
08815 sRef rec = sRef_fixResultType (s->info->field->rec, typ, ue);
08816 ctype ct = ctype_realType (sRef_getType (rec));
08817
08818 if (ctype_isKnown (ct))
08819 {
08820 if (ctype_isSU (ct))
08821 {
08822 if (uentry_isValid (uentryList_lookupField (ctype_getFields (ct),
08823 s->info->field->field)))
08824 {
08825 ;
08826 }
08827 else
08828 {
08829 voptgenerror
08830 (FLG_TYPE,
08831 message
08832 ("Special clause accesses non-existent field of result: %q.%s",
08833 sRef_unparse (rec), s->info->field->field),
08834 uentry_whereLast (ue));
08835 }
08836 }
08837 else
08838 {
08839 voptgenerror
08840 (FLG_TYPE,
08841 message
08842 ("Special clause accesses field of non-struct or union result (%t): %q.%s",
08843 ct, sRef_unparse (rec), s->info->field->field),
08844 uentry_whereLast (ue));
08845 }
08846 }
08847
08848 ret = sRef_makeField (tmp, s->info->field->field);
08849 break;
08850 }
08851 case SK_PTR:
08852 {
08853 ctype ct;
08854 tmp = sRef_fixResultType (s->info->ref, typ, ue);
08855
08856 ct = ctype_realType (sRef_getType (tmp));
08857
08858 if (ctype_isKnown (ct))
08859 {
08860 if (ctype_isAP (ct))
08861 {
08862 ;
08863 }
08864 else
08865 {
08866 voptgenerror
08867 (FLG_TYPE,
08868 message
08869 ("Special clause dereferences non-pointer (%t): *%q",
08870 ct, sRef_unparse (s->info->ref)),
08871 uentry_whereLast (ue));
08872 }
08873 }
08874
08875 ret = sRef_makePointer (tmp);
08876 break;
08877 }
08878 case SK_ADR:
08879 voptgenerror
08880 (FLG_TYPE,
08881 message
08882 ("Special clause uses & operator (not allowed): &%q", sRef_unparse (s->info->ref)),
08883 uentry_whereLast (ue));
08884 ret = s;
08885 break;
08886 BADDEFAULT;
08887 }
08888
08889 return ret;
08890 }
08891
08892 bool sRef_isOnly (sRef s)
08893 {
08894 return (sRef_isValid(s) && alkind_isOnly (s->aliaskind));
08895 }
08896
08897 bool sRef_isDependent (sRef s)
08898 {
08899 return (sRef_isValid(s) && alkind_isDependent (s->aliaskind));
08900 }
08901
08902 bool sRef_isOwned (sRef s)
08903 {
08904 return (sRef_isValid (s) && (s->aliaskind == AK_OWNED));
08905 }
08906
08907 bool sRef_isKeep (sRef s)
08908 {
08909 return (sRef_isValid (s) && (s->aliaskind == AK_KEEP));
08910 }
08911
08912 bool sRef_isTemp (sRef s)
08913 {
08914 return (sRef_isValid (s) && alkind_isTemp (s->aliaskind));
08915 }
08916
08917 bool sRef_isLocalState (sRef s)
08918 {
08919 return (sRef_isValid (s) && (s->aliaskind == AK_LOCAL));
08920 }
08921
08922 bool sRef_isUnique (sRef s)
08923 {
08924 return (sRef_isValid (s) && (s->aliaskind == AK_UNIQUE));
08925 }
08926
08927 bool sRef_isShared (sRef s)
08928 {
08929 return (sRef_isValid (s) && (s->aliaskind == AK_SHARED));
08930 }
08931
08932 bool sRef_isExposed (sRef s)
08933 {
08934 return (sRef_isValid (s) && (s->expkind == XO_EXPOSED));
08935 }
08936
08937 bool sRef_isObserver (sRef s)
08938 {
08939 return (sRef_isValid (s) && (s->expkind == XO_OBSERVER));
08940 }
08941
08942 bool sRef_isFresh (sRef s)
08943 {
08944 return (sRef_isValid (s) && (s->aliaskind == AK_FRESH));
08945 }
08946
08947 bool sRef_isDefinitelyNull (sRef s)
08948 {
08949 return (sRef_isValid (s) && (s->nullstate == NS_DEFNULL
08950 || s->nullstate == NS_CONSTNULL));
08951 }
08952
08953 bool sRef_isAllocated (sRef s)
08954 {
08955 return (sRef_isValid (s) && (s->defstate == SS_ALLOCATED));
08956 }
08957
08958 bool sRef_isStack (sRef s)
08959 {
08960 return (sRef_isValid (s) && (s->aliaskind == AK_STACK));
08961 }
08962
08963 extern bool sRef_isNotNull (sRef s)
08964 {
08965 return (sRef_isValid(s) && (s->nullstate == NS_MNOTNULL
08966 || s->nullstate == NS_NOTNULL));
08967 }
08968
08969
08970
08971
08972
08973