Main Page   Alphabetical List   Compound List   File List   Compound Members   File Members  

aliasTable.c

Go to the documentation of this file.
00001 /*
00002 ** LCLint - annotation-assisted static program checker
00003 ** Copyright (C) 1994-2000 University of Virginia,
00004 **         Massachusetts Institute of Technology
00005 **
00006 ** This program is free software; you can redistribute it and/or modify it
00007 ** under the terms of the GNU General Public License as published by the
00008 ** Free Software Foundation; either version 2 of the License, or (at your
00009 ** option) any later version.
00010 ** 
00011 ** This program is distributed in the hope that it will be useful, but
00012 ** WITHOUT ANY WARRANTY; without even the implied warranty of
00013 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014 ** General Public License for more details.
00015 ** 
00016 ** The GNU General Public License is available from http://www.gnu.org/ or
00017 ** the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
00018 ** MA 02111-1307, USA.
00019 **
00020 ** For information on lclint: lclint-request@cs.virginia.edu
00021 ** To report a bug: lclint-bug@cs.virginia.edu
00022 ** For more information: http://lclint.cs.virginia.edu
00023 */
00024 /*
00025 ** aliasTable.c
00026 */
00027 
00028 # include "lclintMacros.nf"
00029 # include "basic.h"
00030 
00031 /*@constant int ATINVALID; @*/
00032 # define ATINVALID -1
00033 
00034 static sRefSet
00035   aliasTable_canAliasAux (aliasTable p_s, sRef p_sr, int p_lim) /*@*/ ;
00036 static sRefSet
00037   aliasTable_aliasedByLimit (aliasTable p_s, sRef p_sr, int p_lim) /*@*/ ;
00038 static sRefSet 
00039   aliasTable_aliasedByAux (aliasTable p_s, sRef p_sr, int p_lim) /*@*/ ;
00040 
00041 aliasTable
00042 aliasTable_new ()
00043 {
00044   return (aliasTable_undefined);
00045 }
00046 
00047 static /*@only@*/ /*@notnull@*/ aliasTable
00048 aliasTable_newEmpty (void)
00049 {
00050   aliasTable s = (aliasTable) dmalloc (sizeof (*s));
00051   
00052   s->nelements = 0;
00053   s->nspace = aliasTableBASESIZE;
00054   s->keys     = (sRef *) dmalloc (sizeof (*s->keys) * aliasTableBASESIZE);
00055   s->values   = (sRefSet *) dmalloc (sizeof (*s->values) * aliasTableBASESIZE);
00056   
00057   return (s);
00058 }
00059 
00060 static void
00061 aliasTable_grow (/*@notnull@*/ aliasTable s)
00062 {
00063   int i;
00064   o_sRefSet *oldvalues = s->values;
00065   sRef    *oldkeys = s->keys;
00066   
00067   s->nspace += aliasTableBASESIZE; 
00068 
00069   s->values = (sRefSet *) dmalloc (sizeof (*s->values)
00070                                    * (s->nelements + s->nspace));
00071   s->keys = (sRef *) dmalloc (sizeof (*s->keys) * (s->nelements + aliasTableBASESIZE));
00072 
00073   if (s->keys == (sRef *) 0 || s->values == (sRefSet *)0)
00074     {
00075       llfatalerror (cstring_makeLiteral ("aliasTable_grow: out of memory!"));
00076     }
00077 
00078   for (i = 0; i < s->nelements; i++)
00079     {
00080       s->values[i] = oldvalues[i];
00081       s->keys[i] = oldkeys[i];
00082     }
00083   
00084   sfree (oldvalues);
00085   sfree (oldkeys);
00086 }
00087 
00088 static int aliasTable_lookupRefs (/*@notnull@*/ aliasTable s, sRef sr)
00089 {
00090   int i;
00091 
00092   
00093   for (i = 0; i < aliasTable_size (s); i++)
00094     {
00095       if (sRef_same (sr, s->keys[i])) 
00096         {
00097           return i;
00098         }
00099     }
00100 
00101   return ATINVALID;
00102 }
00103 
00104 /*
00105 ** sr aliases al (and anything al aliases!)
00106 */
00107 
00108 aliasTable
00109 aliasTable_addMustAlias (/*@returned@*/ aliasTable s,
00110                          /*@exposed@*/ sRef sr,
00111                          sRef al)
00112 {
00113   int ind;
00114   sRefSet ss;
00115   
00116   llassert (NOALIAS (sr, al));
00117 
00118   if (aliasTable_isUndefined (s))
00119     {
00120       s = aliasTable_newEmpty ();
00121       ind = ATINVALID;
00122     }
00123   else
00124     {
00125       ind = aliasTable_lookupRefs (s, sr);
00126     }
00127   
00128   ss = aliasTable_canAlias (s, al); 
00129   
00130   
00131   if (ind == ATINVALID)
00132     {
00133       if (s->nspace <= 0) {
00134         aliasTable_grow (s);
00135       }
00136 
00137       s->nspace--;
00138       s->keys[s->nelements] = sr;
00139       s->values[s->nelements] = sRefSet_single (al); 
00140       ind = s->nelements;
00141       s->nelements++;      
00142     }
00143   else
00144     {
00145       s->values[ind] = sRefSet_insert (s->values[ind], al); 
00146     }
00147   
00148   s->values[ind] = sRefSet_unionExcept (s->values[ind], ss, s->keys[ind]); 
00149 
00150   sRefSet_free (ss);
00151   return s;
00152 }
00153 
00154 static aliasTable 
00155   aliasTable_addSet (/*@returned@*/ aliasTable s,
00156                      /*@exposed@*/ sRef key, /*@only@*/ sRefSet value)
00157 {
00158   if (!sRefSet_isEmpty (value))
00159     {
00160       if (aliasTable_isUndefined (s))
00161         {
00162           s = aliasTable_newEmpty ();
00163         }
00164       else
00165         {
00166           if (s->nspace <= 0)
00167             {
00168               aliasTable_grow (s);
00169             }
00170         }
00171 
00172       s->nspace--;
00173       s->keys[s->nelements] = key;
00174       s->values[s->nelements] = value;
00175       s->nelements++;      
00176     }
00177   else
00178     {
00179       sRefSet_free (value);
00180     }
00181 
00182   return s;
00183 }
00184 
00185 /*
00186 ** When aliases are cleared:
00187 **
00188 **    o remove all entries for sr
00189 **    o replace all aliases for things which alias sr with sr's aliases
00190 **
00191 ** Clear aliases for sr; if sr is a direct param reference, clear its aliases too.
00192 */
00193 
00194 static void aliasTable_clearAliasesAux (/*@notnull@*/ aliasTable p_s, sRef p_sr)
00195    /*@modifies p_s@*/ ;
00196 
00197 void aliasTable_clearAliases (aliasTable s, sRef sr)
00198 {
00199   if (aliasTable_isUndefined (s))
00200     {
00201       return;
00202     }
00203   else
00204     {
00205       sRef rb = sRef_getRootBase (sr);
00206 
00207             
00208       if (!sRef_isCvar (sr) && sRef_isLocalVar (rb))
00209         {
00210           int ind = aliasTable_lookupRefs (s, rb);
00211           
00212           if (ind != ATINVALID)
00213             {
00214               sRefSet al = s->values[ind];
00215               
00216                       
00217               sRefSet_realElements (al, el)
00218                 {
00219                                   
00220                   if (sRef_isParam (el))
00221                     {
00222                       if (sRef_sameName (el, rb))
00223                         {
00224                           sRef fb = sRef_fixBase (sr, el); 
00225 
00226                           aliasTable_clearAliasesAux (s, fb); 
00227                         }
00228                     }
00229                 } end_sRefSet_realElements ;
00230             }
00231         }
00232       
00233       aliasTable_clearAliasesAux (s, sr); 
00234     }  
00235 }
00236 
00237 static
00238 void aliasTable_clearAliasesAux (/*@notnull@*/ aliasTable s, sRef sr)
00239 {
00240   int i;
00241   
00242   for (i = 0; i < s->nelements; i++)
00243     {
00244       sRef key = s->keys[i];
00245       
00246       if (sRef_includedBy (key, sr))
00247         {
00248           sRefSet_clear (s->values[i]);
00249         }
00250       else
00251         {
00252           (void) sRefSet_deleteBase (s->values[i], sr);   
00253         }
00254     }
00255 }
00256 
00257 /*
00258 ** returns set of all sRefs that must alias sr (but are different from sr)
00259 */
00260 
00261 static /*@only@*/ sRefSet aliasTable_aliasedByAux (aliasTable s, sRef sr, int lim)
00262 {
00263   static bool hadWarning = FALSE;
00264   sRefSet res = sRefSet_undefined;
00265   int i;
00266 
00267   llassert (!sRef_isConj (sr));
00268   
00269   
00270   if (aliasTable_isUndefined (s) || lim >= ALIASSEARCHLIMIT)
00271     {
00272       if (lim >= ALIASSEARCHLIMIT && !hadWarning)
00273         {
00274           llquietbug
00275             (message ("Alias search limit exceeded, checking %q. "
00276                       "This either means there is a variable with at least "
00277                       "%d indirections, or there is a bug in LCLint.",
00278                       sRef_unparse (sr),
00279                       ALIASSEARCHLIMIT));
00280           
00281           hadWarning = TRUE;
00282         }
00283 
00284       return sRefSet_undefined;
00285     }
00286   else
00287     {
00288       sRefSet abl;
00289 
00290       if (sRef_isPointer (sr))
00291         {
00292           abl = aliasTable_aliasedByLimit (s, sRef_getBase (sr), lim);
00293           res = sRefSet_addIndirection (abl);
00294         }
00295       else if (sRef_isAddress (sr))
00296         {
00297           abl = aliasTable_aliasedByLimit (s, sRef_getBase (sr), lim);
00298           res = sRefSet_removeIndirection (abl);
00299         }
00300       else if (sRef_isField (sr))
00301         {
00302           abl = aliasTable_aliasedByLimit (s, sRef_getBase (sr), lim);
00303           res = sRefSet_accessField (abl, sRef_getField (sr));
00304         }
00305       else if (sRef_isArrayFetch (sr))
00306         {
00307           abl = aliasTable_aliasedByLimit (s, sRef_getBase (sr), lim);
00308 
00309           if (sRef_isIndexKnown (sr))
00310             {
00311               int idx = sRef_getIndex (sr);
00312               
00313               res = sRefSet_fetchKnown (abl, idx);
00314             }
00315           else
00316             {
00317               res = sRefSet_fetchUnknown (abl);
00318             }
00319         }
00320       else
00321         {
00322           abl = sRefSet_undefined;
00323         }
00324 
00325       sRefSet_free (abl);
00326     }
00327 
00328   for (i = 0; i < s->nelements; i++)
00329     {
00330       sRef elem = s->keys[i];
00331       
00332       if (!sRef_same (sr, elem)) /* was sameName */
00333         {
00334                   
00335           sRefSet_realElements (s->values[i], current)
00336             {
00337                       
00338               if (sRef_similar (sr, current))
00339                 {
00340                                                   res = sRefSet_insert (res, sRef_fixOuterRef (elem));
00341                   /*@innerbreak@*/ break;
00342                 }
00343             } end_sRefSet_realElements;
00344         } 
00345     }
00346   
00347     return res;
00348 }
00349 
00350 static /*@only@*/ sRefSet aliasTable_aliasedByLimit (aliasTable s, sRef sr, int lim)
00351 {
00352   sRefSet res;
00353   
00354   
00355   if (sRef_isConj (sr))
00356     {
00357       res = sRefSet_unionFree (aliasTable_aliasedByLimit (s, sRef_getConjA (sr), lim),
00358                                aliasTable_aliasedByLimit (s, sRef_getConjB (sr), lim));
00359     }
00360   else
00361     {
00362       res = aliasTable_aliasedByAux (s, sr, lim + 1);
00363     }
00364   
00365     return res;
00366 }
00367 
00368 /*@only@*/ sRefSet aliasTable_aliasedBy (aliasTable s, sRef sr)
00369 { 
00370   if (sRef_isConj (sr))
00371     {
00372       return (sRefSet_unionFree (aliasTable_aliasedBy (s, sRef_getConjA (sr)),
00373                                  aliasTable_aliasedBy (s, sRef_getConjB (sr))));
00374     }
00375 
00376   return (aliasTable_aliasedByAux (s, sr, 0));
00377 }
00378 
00379 /*@only@*/ sRefSet aliasTable_canAlias (aliasTable s, sRef sr)
00380 {
00381   sRefSet res;
00382 
00383     
00384   if (sRef_isConj (sr))
00385     {
00386       res = sRefSet_unionFree (aliasTable_canAlias (s, sRef_getConjA (sr)),
00387                                aliasTable_canAlias (s, sRef_getConjB (sr)));
00388     }
00389   else
00390     {
00391       res = aliasTable_canAliasAux (s, sr, 0);
00392           }
00393 
00394     return res;
00395 }
00396 
00397 /*
00398 ** need to limit the depth of aliasing searches 
00399 */
00400 
00401 static /*@only@*/ sRefSet aliasTable_canAliasLimit (aliasTable s, sRef sr, int lim)
00402 {
00403   sRefSet res;
00404   
00405   if (sRef_isConj (sr))
00406     {
00407       sRefSet a = aliasTable_canAliasLimit (s, sRef_getConjA (sr), lim);
00408       sRefSet b = aliasTable_canAliasLimit (s, sRef_getConjB (sr), lim);
00409 
00410       res = sRefSet_unionFree (a, b);
00411     }
00412   else
00413     {
00414       res = aliasTable_canAliasAux (s, sr, lim + 1);
00415     }
00416   
00417   return res;
00418 }
00419 
00420 static /*@only@*/ sRefSet 
00421   aliasTable_canAliasAux (aliasTable s, sRef sr, int lim)
00422 {
00423   static bool hadWarning = FALSE;
00424   llassert (!sRef_isConj (sr));
00425   
00426   
00427   if (aliasTable_isUndefined (s) || lim >= ALIASSEARCHLIMIT)
00428     {
00429       if (lim >= ALIASSEARCHLIMIT && !hadWarning)
00430         {
00431           llquietbug
00432             (message ("Alias search limit exceeded, checking %q. "
00433                       "This either means there is a variable with at least "
00434                       "%d indirections, or there is a bug in LCLint.",
00435                       sRef_unparse (sr),
00436                       ALIASSEARCHLIMIT));
00437           
00438           hadWarning = TRUE;
00439         }
00440 
00441       return sRefSet_undefined;
00442     }
00443   else
00444     {
00445       int ind = aliasTable_lookupRefs (s, sr);
00446 
00447       if (sRef_isPointer (sr) || sRef_isAddress (sr) || sRef_isField (sr)
00448           || sRef_isArrayFetch (sr))
00449         {
00450           sRef base = sRef_getBase (sr);
00451           sRefSet tmp = aliasTable_canAliasLimit (s, base, lim);
00452           sRefSet ret;
00453 
00454           if (sRef_isPointer (sr))
00455             {
00456               ret = sRefSet_addIndirection (tmp); 
00457             }
00458           else if (sRef_isAddress (sr))
00459             {
00460               ret = sRefSet_removeIndirection (tmp);
00461             }
00462           else if (sRef_isField (sr))
00463             {
00464               ret = sRefSet_accessField (tmp, sRef_getField (sr));
00465             }
00466           else if (sRef_isArrayFetch (sr))
00467             {
00468               if (sRef_isIndexKnown (sr))
00469                 {
00470                   ret = sRefSet_fetchKnown (tmp, sRef_getIndex (sr));
00471                 }
00472               else
00473                 {
00474                   ret = sRefSet_fetchUnknown (tmp);
00475                 }
00476             }
00477           else
00478             {
00479               BADBRANCH;
00480             }
00481 
00482           if (ind != ATINVALID)
00483             {
00484               ret = sRefSet_union (ret, s->values[ind]);
00485             }
00486 
00487           sRefSet_free (tmp);
00488                   return ret;
00489         }
00490       
00491       if (ind == ATINVALID) return sRefSet_undefined;      
00492       
00493       return sRefSet_newCopy (s->values[ind]);
00494     }
00495 }
00496 
00497 aliasTable aliasTable_copy (aliasTable s)
00498 {
00499   if (aliasTable_isEmpty (s))
00500     {
00501       return aliasTable_undefined;
00502     }
00503   else
00504     {
00505       aliasTable t = (aliasTable) dmalloc (sizeof (*s));
00506       int i;
00507 
00508       t->nelements = s->nelements;
00509       t->nspace = 0;
00510       t->keys = (sRef *) dmalloc (sizeof (*s->keys) * s->nelements);
00511       t->values = (sRefSet *) dmalloc (sizeof (*s->values) * t->nelements);
00512         
00513       for (i = 0; i < s->nelements; i++)
00514         {
00515           t->keys[i] = s->keys[i];
00516           t->values[i] = sRefSet_newCopy (s->values[i]);
00517         }
00518 
00519       return t;
00520     }
00521 }
00522 
00523 static void
00524 aliasTable_levelPrune (aliasTable s, int lexlevel)
00525 {
00526   
00527   
00528   if (aliasTable_isEmpty (s))
00529     {
00530       return;
00531     }
00532   else
00533     {
00534       int i;
00535       int backcount = s->nelements - 1;
00536       
00537       for (i = 0; i <= backcount; i++)
00538         {
00539           sRef key = s->keys[i];
00540           
00541           if (sRef_lexLevel (key) > lexlevel)
00542             {
00543               int j;
00544               for (j = backcount; j > i; j--)
00545                 {
00546                   backcount--;
00547                   s->nelements--;
00548                   s->nspace++;
00549                   
00550                   if (sRef_lexLevel (s->keys[j]) <= lexlevel)
00551                     {
00552                       s->keys[i] = s->keys[j];
00553                       s->values[i] = s->values[j];
00554                       sRefSet_levelPrune (s->values[i], lexlevel);
00555                       /*@innerbreak@*/ break;
00556                     }
00557                 }
00558               if (backcount == i)
00559                 s->nelements--;
00560             }
00561           else
00562             {
00563               sRefSet_levelPrune (s->values[i], lexlevel);
00564             }
00565         }
00566     }
00567 }
00568 
00569 /*
00570 ** levelUnionSeq
00571 **
00572 **    like level union, but know that t2 was executed after t1.  So if
00573 **    t1 has x -> { a, b } and t2 has x -> { a }, then result has x -> { a }.
00574 **
00575 ** NOTE: t2 is "only".
00576 */
00577 
00578 aliasTable aliasTable_levelUnionSeq (/*@returned@*/ aliasTable t1, 
00579                                      /*@only@*/ aliasTable t2, int level)
00580 {
00581   if (aliasTable_isUndefined (t2))
00582     {
00583       return t1;
00584     }
00585 
00586   if (aliasTable_isUndefined (t1))
00587     {
00588       t1 = aliasTable_newEmpty ();
00589     }
00590   else
00591     {
00592       aliasTable_levelPrune (t1, level);
00593     }
00594 
00595   aliasTable_elements (t2, key, value)
00596     {
00597       if (sRef_lexLevel (key) <= level)
00598         {
00599           int ind = aliasTable_lookupRefs (t1, key);
00600 
00601           sRefSet_levelPrune (value, level);
00602               
00603           if (ind == ATINVALID)
00604             {
00605               /* okay, t2 is killed */
00606               /*@-exposetrans@*/ /*@-dependenttrans@*/ 
00607               t1 = aliasTable_addSet (t1, key, value);
00608               /*@=exposetrans@*/ /*@=dependenttrans@*/ 
00609             }
00610           else
00611             {
00612               sRefSet_free (t1->values[ind]);
00613 
00614               /*@-dependenttrans@*/ /* okay, t2 is killed */
00615               t1->values[ind] = value;
00616               /*@=dependenttrans@*/
00617             } 
00618         }
00619       else
00620         {
00621           /*@-exposetrans@*/ /*@-dependenttrans@*/ 
00622           sRefSet_free (value);
00623           /*@=exposetrans@*/ /*@=dependenttrans@*/ 
00624         }
00625 
00626     } end_aliasTable_elements;
00627   
00628   sfree (t2->keys);
00629   sfree (t2->values);
00630   sfree (t2);
00631 
00632     return t1;
00633 }
00634 
00635 aliasTable 
00636 aliasTable_levelUnion (/*@returned@*/ aliasTable t1, aliasTable t2, int level)
00637 {
00638   if (aliasTable_isUndefined (t1))
00639     {
00640       if (aliasTable_isUndefined (t2)) 
00641         {
00642           return t1;
00643         }
00644       else
00645         {
00646           t1 = aliasTable_newEmpty ();
00647         }
00648     }
00649   else
00650     {
00651       aliasTable_levelPrune (t1, level);
00652     }
00653 
00654   aliasTable_elements (t2, key, cvalue)
00655     {
00656       sRefSet value = sRefSet_newCopy (cvalue);
00657 
00658       if (sRef_lexLevel (key) <= level)
00659         {
00660           sRefSet_levelPrune (value, level);
00661 
00662           if (sRefSet_size (value) > 0)
00663             {
00664               int ind = aliasTable_lookupRefs (t1, key);
00665               
00666               if (ind == ATINVALID)
00667                 {
00668                   t1 = aliasTable_addSet (t1, key, value);
00669                 }
00670               else
00671                 {
00672                   t1->values[ind] = sRefSet_union (t1->values[ind], value);
00673                   sRefSet_free (value);
00674                 }
00675             }
00676           else
00677             {
00678               sRefSet_free (value); 
00679             }
00680         }
00681       else
00682         {
00683           sRefSet_free (value); 
00684         }
00685     } end_aliasTable_elements;
00686 
00687     return t1;
00688 }
00689 
00690 aliasTable aliasTable_levelUnionNew (aliasTable t1, aliasTable t2, int level)
00691 {
00692   aliasTable ret = aliasTable_levelUnion (aliasTable_copy (t1), t2, level);
00693 
00694   return ret;
00695 }
00696 
00697 /*@only@*/ cstring
00698 aliasTable_unparse (aliasTable s)
00699 {
00700    cstring st = cstring_undefined;
00701 
00702    if (aliasTable_isUndefined (s)) return (cstring_makeLiteral ("<NULL>"));
00703 
00704    aliasTable_elements (s, key, value)
00705      {
00706        st = message ("%q\t%q -> %q\n", st, sRef_unparse (key), 
00707                      sRefSet_unparse (value));
00708      } end_aliasTable_elements;
00709 
00710    return st;
00711 }
00712 
00713 /*
00714 ** bogus!
00715 */
00716 
00717 void
00718 aliasTable_fixSrefs (aliasTable s)
00719 {
00720   int i;
00721 
00722   if (aliasTable_isUndefined (s)) return;
00723 
00724   for (i = 0; i < s->nelements; i++)
00725     {
00726       sRef old = s->keys[i];
00727 
00728       if (sRef_isLocalVar (old))
00729         {
00730           s->keys[i] = uentry_getSref (sRef_getUentry (old));
00731         }
00732 
00733       sRefSet_fixSrefs (s->values[i]);
00734     }
00735 }
00736 
00737 void
00738 aliasTable_free (/*@only@*/ aliasTable s)
00739 {
00740   int i;
00741   
00742   if (aliasTable_isUndefined (s)) return;
00743   
00744   for (i = 0; i < s->nelements; i++)
00745     {
00746       sRefSet_free (s->values[i]); 
00747     }
00748   
00749   sfree (s->values);
00750   sfree (s->keys);
00751   sfree (s);
00752 }
00753 
00754 void 
00755 aliasTable_checkGlobs (aliasTable t)
00756 {
00757   aliasTable_elements (t, key, value)
00758     {
00759       sRef root = sRef_getRootBase (key);
00760 
00761       if (sRef_isAliasCheckedGlobal (root))
00762         {
00763           sRefSet_realElements (value, sr)
00764             {
00765               root = sRef_getRootBase (sr);
00766 
00767               if (((sRef_isAliasCheckedGlobal (root) 
00768                     && !(sRef_similar (root, key)))
00769                    || sRef_isAnyParam (root))
00770                   && !sRef_isExposed (root))
00771                 {
00772                   if (sRef_isAliasCheckedGlobal (key))
00773                     {
00774                       if (!(sRef_isShared (key) 
00775                             && sRef_isShared (root)))
00776                         {
00777                           voptgenerror 
00778                             (FLG_GLOBALIAS,
00779                              message 
00780                              ("Function returns with %q variable %q aliasing %q %q",
00781                               cstring_makeLiteral (sRef_isRealGlobal (key) 
00782                                                    ? "global" : "file static"),
00783                               sRef_unparse (key),
00784                               cstring_makeLiteral (sRef_isAnyParam (root) 
00785                                                    ? "parameter" : "global"),
00786                               sRef_unparse (sr)),
00787                              g_currentloc);
00788                         }
00789                     }
00790 
00791                 }
00792             } end_sRefSet_realElements;
00793         }
00794       else if (sRef_isAnyParam (key) || sRef_isAnyParam (root))
00795         {
00796           sRefSet_realElements (value, sr)
00797             {
00798               root = sRef_getRootBase (sr);
00799               
00800               if (sRef_isAliasCheckedGlobal (root) 
00801                   && !sRef_isExposed (root)
00802                   && !sRef_isDead (key)
00803                   && !sRef_isShared (root))
00804                 {
00805                   voptgenerror 
00806                     (FLG_GLOBALIAS,
00807                      message ("Function returns with parameter %q aliasing %q %q",
00808                               sRef_unparse (key),
00809                               cstring_makeLiteral (sRef_isRealGlobal (root) 
00810                                                    ? "global" : "file static"),
00811                               sRef_unparse (sr)),
00812                      g_currentloc);
00813                 }
00814             } end_sRefSet_realElements;
00815         }
00816       else
00817         {
00818           ;
00819         }
00820     } end_aliasTable_elements;
00821 }
00822 
00823 
00824 

Generated at Fri Nov 3 18:57:39 2000 for LCLint by doxygen1.2.3 written by Dimitri van Heesch, © 1997-2000