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

aliasChecks.c File Reference

#include "lclintMacros.nf"
#include "basic.h"
#include "aliasChecks.h"

Go to the source code of this file.

Enumerations

enum  dscCode { DSC_GLOB, DSC_LOCAL, DSC_PARAM, DSC_STRUCT }

Functions

alkind alkind_resolve (alkind a1, alkind a2)
bool checkGlobalDestroyed (sRef fref, fileloc loc)
void checkLocalDestroyed (sRef fref, fileloc loc)
void checkStructDestroyed (sRef fref, fileloc loc)
void checkReturnTransfer (exprNode fexp, uentry rval)
void checkPassTransfer (exprNode fexp, uentry arg, bool isSpec, exprNode fcn, int argno, int totargs)
void checkGlobReturn (uentry glob)
void checkParamReturn (uentry actual)
void checkLoseRef (uentry actual)
void checkInitTransfer (exprNode lhs, exprNode rhs)
void checkAssignTransfer (exprNode lhs, exprNode rhs)
bool canLoseReference (sRef sr, fileloc loc)


Enumeration Type Documentation

enum dscCode
 

Enumeration values:
DSC_GLOB  
DSC_LOCAL  
DSC_PARAM  
DSC_STRUCT  

Definition at line 1167 of file aliasChecks.c.

01167              {
01168   DSC_GLOB, DSC_LOCAL, DSC_PARAM, DSC_STRUCT
01169   }


Function Documentation

alkind alkind_resolve ( alkind a1,
alkind a2 )
 

Definition at line 54 of file aliasChecks.c.

Referenced by sRef_makeConj().

00055 {
00056   if (a1 == AK_UNKNOWN || a1 == AK_ERROR) return a2;
00057   if (a2 == AK_UNKNOWN || a2 == AK_ERROR || a2 == AK_LOCAL) return a1;
00058   if (a1 == AK_LOCAL) return a2;
00059   return a1;
00060 }

bool canLoseReference ( sRef sr,
fileloc loc )
 

Definition at line 3663 of file aliasChecks.c.

Referenced by usymtab_checkFinalScope().

03664 {
03665   bool gotone = FALSE;
03666   sRefSet ab = usymtab_aliasedBy (sr); /* yes, really mean aliasedBy */
03667   
03668     
03669   /*
03670    ** if there is a local variable that aliases sr, then there is no
03671    ** error.  Make the local an only.
03672    */
03673   
03674   if (!sRefSet_isEmpty (ab))
03675     {
03676       /*
03677       ** make one an only, others alias it
03678       */
03679       
03680             
03681       sRefSet_realElements (ab, current)
03682         {
03683           sRef_setLastReference (current, sr, loc);
03684           gotone = TRUE;
03685           break;
03686         } end_sRefSet_realElements;
03687 
03688       sRefSet_free (ab);
03689     }
03690 
03691   return gotone;
03692 }

void checkAssignTransfer ( exprNode lhs,
exprNode rhs )
 

Definition at line 2006 of file aliasChecks.c.

Referenced by checkInitTransfer().

02007 {
02008   sRef slhs = exprNode_getSref (lhs);
02009   sRef srhs = exprNode_getSref (rhs);
02010   sRef base = sRef_getBaseSafe (slhs);
02011   nstate ns;
02012 
02013   DPRINTF (("Check assign: %s = %s", exprNode_unparse (lhs),
02014             exprNode_unparse (rhs)));
02015   DPRINTF (("lhs: %s", sRef_unparseFull (slhs)));
02016   DPRINTF (("rhs: %s", sRef_unparseFull (srhs)));
02017 
02018   if (ctype_isRealSU (sRef_getType (srhs)))
02019     {
02020       checkStructTransfer (lhs, slhs, rhs, srhs, exprNode_loc (lhs), TT_FIELDASSIGN);
02021     }
02022   else
02023     {
02024       (void) checkTransfer (rhs, srhs, lhs, slhs, 
02025                             exprNode_loc (lhs), TT_DOASSIGN);
02026     }
02027 
02028   if (sRef_isConst (srhs) && sRef_isLocalState (srhs))
02029     {
02030       /* constants can match anything (e.g., NULL) */
02031       sRef_setAliasKind (slhs, AK_ERROR, fileloc_undefined);
02032     }
02033 
02034   if (sRef_isValid (base) && sRef_isStateDefined (base))
02035     {
02036       sRef_setPdefined (base, g_currentloc); 
02037     }
02038 
02039   if (sRef_isPartial (srhs))
02040     {
02041       sRef_setPartial (slhs, exprNode_loc (rhs));
02042     }
02043 
02044 
02045   ns = sRef_getNullState (srhs);
02046 
02047   if (nstate_possiblyNull (ns))
02048     {
02049       if (usymtab_isGuarded (srhs))
02050         {
02051           ns = NS_NOTNULL;
02052         }
02053     }
02054 
02055   sRef_setNullStateInnerComplete (slhs, ns, exprNode_loc (rhs));
02056 
02057   if (sRef_isExposed (srhs) || sRef_isObserver (srhs))
02058     {
02059       sRef_setExKind (slhs, sRef_getExKind (srhs), exprNode_loc (rhs));
02060     }
02061 
02062   DPRINTF (("Done transfer: %s", sRef_unparseFull (slhs)));
02063 }

void checkGlobReturn ( uentry glob )
 

Definition at line 1854 of file aliasChecks.c.

01855 {
01856   sRef_protectDerivs ();
01857   checkGlobTrans (glob, TT_GLOBRETURN);
01858   sRef_clearProtectDerivs ();
01859 }

bool checkGlobalDestroyed ( sRef fref,
fileloc loc )
 

Definition at line 1192 of file aliasChecks.c.

01193 {
01194   return (checkCompletelyDestroyed (exprNode_undefined, fref, TRUE,
01195                                     loc, 0, DSC_GLOB));
01196 }

void checkInitTransfer ( exprNode lhs,
exprNode rhs )
 

Definition at line 1990 of file aliasChecks.c.

01991 {
01992   sRef slhs = exprNode_getSref (lhs);
01993   
01994   if (sRef_isGlobal (slhs) || (!sRef_isCvar (slhs)))
01995     {
01996       (void) checkTransfer (rhs, exprNode_getSref (rhs), 
01997                             lhs, slhs, exprNode_loc (rhs), TT_GLOBINIT);
01998     }
01999   else
02000     {
02001       checkAssignTransfer (lhs, rhs);
02002     }
02003 }

void checkLocalDestroyed ( sRef fref,
fileloc loc )
 

Definition at line 1198 of file aliasChecks.c.

Referenced by usymtab_checkFinalScope().

01199 {
01200   if (sRef_isObserver (fref) || sRef_isExposed (fref)
01201       || sRef_isPartial (fref))
01202     {
01203       ;
01204     }
01205   else
01206     {
01207       (void) checkCompletelyDestroyed (exprNode_undefined, fref, TRUE,
01208                                        loc, 0, DSC_LOCAL);
01209     }
01210 }

void checkLoseRef ( uentry actual )
 

Definition at line 1866 of file aliasChecks.c.

Referenced by usymtab_checkFinalScope().

01867 {
01868   checkLeaveTrans (actual, TT_LEAVETRANS);
01869 }

void checkParamReturn ( uentry actual )
 

Definition at line 1861 of file aliasChecks.c.

Referenced by usymtab_checkFinalScope().

01862 {
01863   checkLeaveTrans (actual, TT_PARAMRETURN);
01864 }

void checkPassTransfer ( exprNode fexp,
uentry arg,
bool isSpec,
exprNode fcn,
int argno,
int totargs )
 

Definition at line 1565 of file aliasChecks.c.

01567 {
01568   sRef tref = uentry_getSref (arg);
01569   sRef fref = exprNode_getSref (fexp);
01570   bool isOut = FALSE;
01571   bool isPartial = FALSE;
01572   bool isImpOut = FALSE;
01573   ctype ct = uentry_getType (arg);
01574 
01575   DPRINTF (("Check pass: %s -> %s",
01576             sRef_unparseFull (fref),
01577             sRef_unparseFull (tref)));
01578   
01579   atFunction = fcn;
01580   atArgNo = argno;
01581   atNumArgs = totargs;
01582 
01583   if (ctype_isElips (ct))
01584     {
01585       ct = ctype_unknown;
01586     }
01587   
01588   if (!ctype_isElips (ct) && 
01589       (ctype_isVoidPointer (ct) && uentry_isOut (arg) && sRef_isOnly (tref)))
01590     {
01591       if (ctype_isRealAP (ct))
01592         {
01593           if (sRef_aliasCheckSimplePred (sRef_isDead, fref))
01594             {
01595               if (optgenerror
01596                   (FLG_USERELEASED,
01597                    message ("Dead storage %qpassed as out parameter: %s",
01598                             sRef_unparseOpt (fref),
01599                             exprNode_unparse (fexp)),
01600                    exprNode_loc (fexp)))
01601                 {
01602                   if (sRef_isDead (fref))
01603                     {
01604                       sRef_showStateInfo (fref);
01605                     }
01606                 }
01607               
01608               sRef_setAllocated (fref, exprNode_loc (fexp));
01609             }
01610           else if (context_getFlag (FLG_STRICTUSERELEASED)
01611                    && sRef_aliasCheckSimplePred (sRef_isPossiblyDead, fref))
01612             {
01613               if (optgenerror2 
01614                   (FLG_USERELEASED, FLG_STRICTUSERELEASED,
01615                    message ("Possibly dead storage %qpassed as out parameter: %s",
01616                             sRef_unparseOpt (fref),
01617                             exprNode_unparse (fexp)),
01618                    exprNode_loc (fexp)))
01619                 {
01620                   if (sRef_isPossiblyDead (fref))
01621                     {
01622                       sRef_showStateInfo (fref);
01623                     }
01624                 }
01625               
01626               sRef_setAllocated (fref, exprNode_loc (fexp));
01627             }
01628           else if (sRef_aliasCheckSimplePred (sRef_isStateUndefined, fref) 
01629                    || sRef_aliasCheckSimplePred (sRef_isUnuseable, fref))
01630             {
01631               voptgenerror
01632                 (FLG_USEDEF,
01633                  message ("Unallocated storage %qpassed as out parameter: %s",
01634                           sRef_unparseOpt (fref),
01635                           exprNode_unparse (fexp)),
01636                  exprNode_loc (fexp));
01637 
01638               sRef_setAllocated (fref, exprNode_loc (fexp));
01639             }
01640           else
01641             {
01642               ;
01643             }
01644         }
01645       
01646       (void) checkCompletelyDestroyed (fexp, fref, TRUE, exprNode_loc (fexp),
01647                                        0, DSC_PARAM);
01648 
01649       /* make it defined now, so checkTransfer is okay */
01650       sRef_setDefined (fref, exprNode_loc (fexp)); 
01651     }
01652   else if (uentry_isOut (arg))
01653     {
01654       if (ctype_isRealAP (ct)
01655           && (sRef_isStateUndefined (fref) || sRef_isUnuseable (fref)))
01656         {
01657           voptgenerror
01658             (FLG_USEDEF,
01659              message ("Unallocated storage %qpassed as out parameter: %s",
01660                       sRef_unparseOpt (fref),
01661                       exprNode_unparse (fexp)),
01662              exprNode_loc (fexp));
01663           sRef_setAllocated (fref, exprNode_loc (fexp));
01664         }
01665       isOut = TRUE;
01666     }
01667   else if (uentry_isPartial (arg))
01668     {
01669       if (ctype_isRealAP (ct) 
01670           && (sRef_isStateUndefined (fref) || sRef_isUnuseable (fref)))
01671         {
01672           voptgenerror 
01673             (FLG_USEDEF,
01674              message ("Unallocated storage %qpassed as partial parameter: %s",
01675                       sRef_unparseOpt (fref),
01676                       exprNode_unparse (fexp)),
01677              exprNode_loc (fexp));
01678           sRef_setAllocated (fref, exprNode_loc (fexp));
01679         }
01680       isPartial = TRUE;
01681     }
01682   else if (uentry_isStateSpecial (arg))
01683     {
01684       uentry ue = exprNode_getUentry (fcn);
01685 
01686       if (ctype_isRealAP (ct) 
01687           && (sRef_isStateUndefined (fref) || sRef_isUnuseable (fref)))
01688         {
01689           voptgenerror 
01690             (FLG_USEDEF,
01691              message ("Unallocated storage %qpassed as special parameter: %s",
01692                       sRef_unparseOpt (fref),
01693                       exprNode_unparse (fexp)),
01694              exprNode_loc (fexp));
01695           sRef_setAllocated (fref, exprNode_loc (fexp));
01696         }
01697 
01698       if (uentry_hasSpecialClauses (ue))
01699         {
01700           checkPassSpecialClauses (ue, fexp, fref, argno);
01701         }
01702       
01703       return; /* ??? */
01704     }
01705   else if (sRef_isStateDefined (tref))
01706     {
01707       exprNode_checkUseParam (fexp);
01708     }
01709   else
01710     {
01711       if (isSpec || (!context_getFlag (FLG_IMPOUTS)))
01712         {
01713           exprNode_checkUseParam (fexp);
01714         }
01715       else
01716         {
01717           if (!sRef_isMacroParamRef (fref) 
01718               && (ctype_isRealAP (ct)))
01719             {
01720               if (sRef_isAddress (fref))
01721                 {
01722                   if (sRef_isStateUndefined (fref) || sRef_isUnuseable (fref))
01723                     {
01724                       voptgenerror 
01725                         (FLG_USEDEF,
01726                          message 
01727                          ("Unallocated address %qpassed as implicit "
01728                           "out parameter: %s",
01729                           sRef_unparseOpt (fref),
01730                           exprNode_unparse (fexp)),
01731                          exprNode_loc (fexp));
01732                       sRef_setAllocated (fref, exprNode_loc (fexp));
01733                     }
01734                 }
01735               
01736               /* yes, I really mean this! */
01737               tref = sRef_copy (tref);
01738               sRef_setAllocated (tref, exprNode_loc (fexp)); 
01739 
01740               isOut = TRUE;
01741               isImpOut = TRUE;
01742             }
01743           else 
01744             {
01745               exprNode_checkUseParam (fexp);
01746             }
01747         }
01748     }
01749 
01750   if (sRef_isNew (fref))
01751     {
01752       alkind tkind = sRef_getAliasKind (tref);
01753 
01754       if ((sRef_isFresh (fref) || sRef_isOnly (fref))
01755           && !alkind_isOnly (tkind) 
01756           && !alkind_isKeep (tkind) 
01757           && !alkind_isOwned (tkind)
01758           && !alkind_isError (tkind)
01759           && !uentry_isReturned (arg))
01760         
01761         {
01762           voptgenerror 
01763             (FLG_MUSTFREE,
01764              message ("New fresh storage %qpassed as %s (not released): %s",
01765                       sRef_unparseOpt (fref),
01766                       alkind_unparse (sRef_getAliasKind (tref)),
01767                       exprNode_unparse (fexp)),
01768              exprNode_loc (fexp));
01769         }
01770       else 
01771         {
01772           if (sRef_isNewRef (fref) && !sRef_isKillRef (tref))
01773             {
01774               alkind ak = sRef_getAliasKind (tref);
01775               
01776               if (!alkind_isError (ak))
01777                 {
01778                   voptgenerror 
01779                     (FLG_MUSTFREE,
01780                      message ("New reference %qpassed as %s (not released): %s",
01781                               sRef_unparseOpt (fref),
01782                               alkind_unparse (sRef_getAliasKind (tref)),
01783                               exprNode_unparse (fexp)),
01784                      exprNode_loc (fexp));
01785                 }
01786             }
01787         }
01788     }
01789   
01790   (void) checkTransfer (fexp, exprNode_getSref (fexp),
01791                         exprNode_undefined, tref,
01792                         exprNode_loc (fexp), TT_FCNPASS);
01793 
01794   setCodePoint ();
01795   fref = exprNode_getSref (fexp);
01796   
01797   if (isOut && !sRef_isDead (fref) && !sRef_isPossiblyDead (fref))
01798     {
01799       sRef base;
01800 
01801       if (ctype_isRealAP (sRef_getType (fref)))
01802         {
01803           base = sRef_makePointer (fref); 
01804         }
01805       else
01806         {
01807           base = fref;
01808         }
01809 
01810       if (isImpOut)
01811         {
01812           exprNode_checkMSet (fexp, base);
01813         }
01814       else
01815         {
01816           exprNode_checkSet (fexp, base);
01817         }
01818 
01819       if (sRef_isValid (base))
01820         {
01821           setCodePoint ();
01822 
01823           sRef_clearDerived (base);
01824           sRef_setDefined (base, exprNode_loc (fexp));
01825           usymtab_clearAlias (base);
01826           sRef_setNullUnknown (base, exprNode_loc (fexp));
01827         }
01828     }
01829 
01830   if (isPartial)
01831     {
01832       if (sRef_isValid (fref))
01833         {
01834           sRef_setPartial (fref, exprNode_loc (fexp)); 
01835         }
01836     }
01837 
01838   atFunction = exprNode_undefined;
01839   atArgNo = 0;
01840   atNumArgs = 0;
01841   
01842   /* need to fixup here: derived refs could be bogus */
01843   /* (better to change sRef to not add derivs for "protected" ref) */
01844 
01845   uentry_fixupSref (arg);
01846 
01847   setCodePoint ();
01848 
01849   DPRINTF (("Check pass: ==> %s",
01850             sRef_unparseFull (fref)));
01851 }

void checkReturnTransfer ( exprNode fexp,
uentry rval )
 

Definition at line 1410 of file aliasChecks.c.

Referenced by exprNode_checkMacroBody().

01411 {
01412   sRef uref = uentry_getSref (rval);
01413   sRef rref = sRef_makeNew (sRef_getType (uref), uref, cstring_undefined);
01414   
01415   if (sRef_isStateSpecial (rref))
01416     {
01417       uentry fcn = context_getHeader ();
01418       sRef fref = exprNode_getSref (fexp);
01419       specialClauses clauses = uentry_getSpecialClauses (fcn);
01420 
01421       specialClauses_postElements (clauses, cl)
01422         {
01423           sRefSet refs = specialClause_getRefs (cl);
01424           sRefTest tst = specialClause_getPostTestFunction (cl);
01425           sRefMod modf = specialClause_getReturnEffectFunction (cl);
01426 
01427           sRefSet_elements (refs, el)
01428             {
01429               sRef base = sRef_getRootBase (el);
01430               
01431               if (sRef_isResult (base))
01432                 {
01433                   sRef sr = sRef_fixBase (el, fref);
01434 
01435                   if (tst != NULL && !(tst (sr)))
01436                     {
01437                       if (optgenerror 
01438                           (specialClause_postErrorCode (cl),
01439                            message ("%s storage %q corresponds to "
01440                                     "storage listed in %q clause: %s",
01441                                     specialClause_postErrorString (cl, sr),
01442                                     sRef_unparse (sr),
01443                                     specialClause_unparseKind (cl),
01444                                     exprNode_unparse (fexp)),
01445                            exprNode_loc (fexp)))
01446                         {
01447                           sRefShower ss = specialClause_getPostTestShower (cl);
01448                           
01449                           if (ss != NULL)
01450                             {
01451                               ss (sr);
01452                             }
01453                         }
01454                     }
01455 
01456                   if (modf != NULL)
01457                     {
01458                       modf (sr, exprNode_loc (fexp));
01459                     }
01460                 }
01461               else
01462                 {
01463                   /* 
01464                   ** Non-results are checked in exit scope.
01465                   */
01466                 }
01467             } end_sRefSet_elements ;
01468         } end_specialClauses_postElements ;
01469 
01470       (void) checkTransfer (fexp, fref,
01471                             exprNode_undefined, rref, 
01472                             exprNode_loc (fexp), TT_FCNRETURN);
01473     }
01474   else
01475     {
01476       if (ctype_isRealSU (exprNode_getType (fexp)))
01477         {
01478           sRef fref = exprNode_getSref (fexp);
01479           
01480           checkStructTransfer (exprNode_undefined, rref, 
01481                                fexp, fref,
01482                                exprNode_loc (fexp),
01483                                TT_FCNRETURN);
01484         }
01485       else
01486         {
01487           (void) checkTransfer (fexp, exprNode_getSref (fexp),
01488                                 exprNode_undefined, rref, 
01489                                 exprNode_loc (fexp), TT_FCNRETURN);
01490         }
01491     }
01492 }

void checkStructDestroyed ( sRef fref,
fileloc loc )
 

Definition at line 1212 of file aliasChecks.c.

Referenced by usymtab_checkFinalScope().

01213 {
01214   if (sRef_isObserver (fref) || sRef_isExposed (fref)
01215       || sRef_isPartial (fref))
01216     {
01217       ;
01218     }
01219   else
01220     {
01221       (void) checkCompletelyDestroyed (exprNode_undefined, fref, TRUE, loc, 0, DSC_STRUCT);
01222     }
01223 }


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