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

exprNode.c File Reference

#include <ctype.h>
#include "lclintMacros.nf"
#include "basic.h"
#include "cgrammar.h"
#include "cgrammar_tokens.h"
#include "exprChecks.h"
#include "aliasChecks.h"
#include "exprNodeSList.h"
#include "exprData.i"

Go to the source code of this file.

Functions

void exprNode_initMod (void)
void exprNode_destroyMod (void)
void exprNode_freeShallow ( exprNode e)
void exprNode_free (exprNode e)
exprNode exprNode_makeError ()
exprNode exprNode_makeMustExit (void)
bool exprNode_isNullValue (exprNode e)
exprNode exprNode_numLiteral (ctype c, cstring t, fileloc loc, long val)
exprNode exprNode_charLiteral (char c, cstring text, fileloc loc)
exprNode exprNode_floatLiteral (double d, ctype ct, cstring text, fileloc loc)
multiVal exprNode_getValue (exprNode e)
exprNode exprNode_stringLiteral ( cstring t, fileloc loc)
exprNode exprNode_fromUIO (cstring c)
exprNode exprNode_createId ( uentry c)
exprNode exprNode_fromIdentifier ( uentry c)
exprNode exprNode_arrayFetch ( exprNode e1, exprNode e2)
uentry exprNode_getUentry (exprNode e)
exprNode exprNode_makeInitBlock (lltok brace, exprNodeList inits)
exprNode exprNode_functionCall ( exprNode f, exprNodeList args)
exprNode exprNode_fieldAccess ( exprNode s, cstring f)
exprNode exprNode_addParens ( lltok lpar, exprNode e)
exprNode exprNode_arrowAccess ( exprNode s, cstring f)
exprNode exprNode_postOp ( exprNode e, lltok op)
exprNode exprNode_preOp ( exprNode e, lltok op)
exprNode exprNode_sizeofType ( qtype qt)
exprNode exprNode_alignofType ( qtype qt)
exprNode exprNode_offsetof (qtype qt, cstringList s)
exprNode exprNode_sizeofExpr ( exprNode e)
exprNode exprNode_alignofExpr ( exprNode e)
exprNode exprNode_cast ( lltok tok, exprNode e, qtype q)
exprNode exprNode_op ( exprNode e1, exprNode e2, lltok op)
exprNode exprNode_assign ( exprNode e1, exprNode e2, lltok op)
exprNode exprNode_cond ( exprNode pred, exprNode ifclause, exprNode elseclause)
exprNode exprNode_vaArg ( lltok tok, exprNode arg, qtype qt)
exprNode exprNode_labelMarker ( cstring label)
exprNode exprNode_notReached ( exprNode stmt)
bool exprNode_isDefaultMarker (exprNode e)
bool exprNode_isCaseMarker (exprNode e)
bool exprNode_isLabelMarker (exprNode e)
exprNode exprNode_caseMarker ( exprNode test, bool fallThrough)
exprNode exprNode_defaultMarker ( lltok def, bool fallThrough)
bool exprNode_mayEscape (exprNode e)
bool exprNode_mustEscape (exprNode e)
bool exprNode_errorEscape (exprNode e)
exprNode exprNode_concat ( exprNode e1, exprNode e2)
exprNode exprNode_createTok ( lltok t)
exprNode exprNode_statement ( exprNode e)
exprNode exprNode_checkExpr ( exprNode e)
void exprNode_produceGuards (exprNode pred)
exprNode exprNode_makeBlock ( exprNode e)
bool exprNode_isAssign (exprNode e)
exprNode exprNode_if ( exprNode pred, exprNode tclause)
exprNode exprNode_ifelse ( exprNode pred, exprNode tclause, exprNode eclause)
exprNode exprNode_switch ( exprNode e, exprNode s)
exprNode exprNode_while ( exprNode t, exprNode b)
exprNode exprNode_doWhile ( exprNode b, exprNode t)
exprNode exprNode_for ( exprNode inc, exprNode body)
guardSet exprNode_getForGuards (exprNode pred)
exprNode exprNode_whilePred ( exprNode test)
exprNode exprNode_forPred ( exprNode init, exprNode test, exprNode inc)
exprNode exprNode_goto ( cstring label)
exprNode exprNode_continue ( lltok l, int qcontinue)
exprNode exprNode_break ( lltok l, int bqual)
exprNode exprNode_nullReturn ( lltok t)
exprNode exprNode_return ( exprNode e)
exprNode exprNode_comma ( exprNode e1, exprNode e2)
exprNode exprNode_makeInitialization ( idDecl t, exprNode e)
exprNode exprNode_iter ( uentry name, exprNodeList alist, exprNode body, uentry end)
exprNode exprNode_iterNewId ( cstring s)
exprNode exprNode_iterExpr ( exprNode e)
exprNode exprNode_iterId ( uentry c)
exprNode exprNode_iterStart ( uentry name, exprNodeList alist)
sRef exprNode_getSref (exprNode e)
cstring exprNode_unparseFirst (exprNode e)
cstring exprNode_unparse (exprNode e)
fileloc exprNode_loc (exprNode e)
bool exprNode_isCharLit (exprNode e)
bool exprNode_isNumLit (exprNode e)
bool exprNode_matchLiteral (ctype expected, exprNode e)
bool exprNode_matchType (ctype expected, exprNode e)
void exprNode_checkSet (exprNode e, sRef s)
void exprNode_checkMSet (exprNode e, sRef s)
void exprNode_checkUseParam (exprNode current)
exprNode exprNode_updateLocation ( exprNode e, fileloc loc)
long exprNode_getLongValue (exprNode e)


Function Documentation

exprNode exprNode_addParens ( lltok lpar,
exprNode e )
 

Definition at line 3343 of file exprNode.c.

03344 {
03345   exprNode ret = exprNode_createPartialCopy (e);
03346 
03347   ret->loc = fileloc_update (ret->loc, lltok_getLoc (lpar));
03348   ret->kind = XPR_PARENS;
03349   ret->edata = exprData_makeUop (e, lpar);
03350 
03351   if (!exprNode_isError (e))
03352     {
03353       ret->exitCode = e->exitCode;
03354       ret->canBreak = e->canBreak;
03355       ret->mustBreak = e->mustBreak;
03356       ret->isJumpPoint = e->isJumpPoint;
03357       ret->sref = e->sref;
03358     }
03359 
03360   return ret;
03361 }

exprNode exprNode_alignofExpr ( exprNode e )
 

Definition at line 4042 of file exprNode.c.

04043 {
04044   exprNode ret;
04045 
04046   if (exprNode_isUndefined (e))
04047     {
04048       ret = exprNode_createLoc (ctype_unknown, fileloc_copy (g_currentloc));
04049     }
04050   else
04051     {
04052       ret = exprNode_createPartialCopy (e);
04053     }
04054 
04055   ret->edata = exprData_makeSingle (e);
04056   ret->typ = sizeof_resultType ();
04057   ret->kind = XPR_ALIGNOF;
04058   
04059   /*
04060   ** sizeof (x) doesn't "really" use x
04061   */
04062 
04063   return (ret);
04064 }

exprNode exprNode_alignofType ( qtype qt )
 

Definition at line 3905 of file exprNode.c.

03906 {
03907   exprNode ret = exprNode_create (sizeof_resultType ());
03908   ctype ct = qtype_getType (qt);
03909 
03910   ret->kind = XPR_ALIGNOFT;
03911   ret->edata = exprData_makeSizeofType (qt);
03912 
03913   voptgenerror (FLG_SIZEOFTYPE,
03914                 message ("Parameter to alignof is type %s: %s",
03915                          ctype_unparse (ct),
03916                          exprNode_unparse (ret)),
03917                 ret->loc);
03918   
03919   return (ret);
03920 }

exprNode exprNode_arrayFetch ( exprNode e1,
exprNode e2 )
 

Definition at line 976 of file exprNode.c.

00977 {
00978   /*
00979   ** error in arr, error propagates (no new messages)
00980   ** error in ind, assume valid and continue
00981   */
00982 
00983   if (exprNode_isError (e1))
00984     {
00985       exprNode_free (e2);
00986       return (exprNode_makeError ());
00987     }
00988   else
00989     {
00990       exprNode arr;
00991       exprNode ind;
00992       ctype carr = exprNode_getType (e1);
00993       ctype crarr = ctype_realType (carr);
00994  
00995       /*
00996       ** this sets up funny aliasing, that leads to spurious
00997       ** lclint errors.  Hence, the i2 comments.
00998       */
00999 
01000       if (!ctype_isRealArray (crarr) 
01001           && ctype_isRealNumeric (crarr) 
01002           && !exprNode_isError (e2)
01003           && ctype_isRealAP (exprNode_getType (e2)))  /* fetch like 3[a] */
01004         {
01005           arr = e2;
01006           ind = e1;
01007 
01008           carr = exprNode_getType (arr);
01009           crarr = ctype_realType (carr);
01010         }
01011       else
01012         {
01013           arr = e1;
01014           ind = e2;
01015         }
01016 
01017       if (sRef_possiblyNull (arr->sref))
01018         {
01019           if (!usymtab_isGuarded (arr->sref))
01020             {
01021               if (optgenerror (FLG_NULLDEREF,
01022                                message ("Index of %s pointer %q: %s", 
01023                                         sRef_nullMessage (arr->sref),
01024                                         sRef_unparse (arr->sref),
01025                                         exprNode_unparse (arr)),
01026                                arr->loc))
01027                 {
01028                   sRef_showNullInfo (arr->sref);
01029 
01030                   /* suppress future messages */
01031                   sRef_setNullError (arr->sref); 
01032                 }
01033             }
01034         }
01035 
01036       if (exprNode_isError (ind))
01037         {
01038           if ((ctype_isArrayPtr (crarr) 
01039                && !ctype_isFunction (crarr))
01040               || ctype_isUnknown (carr))
01041             {
01042               exprNode ret = exprNode_createPartialCopy (arr);
01043 
01044               if (ctype_isKnown (carr))
01045                 {
01046                   ret->typ = ctype_baseArrayPtr (crarr);
01047                 }
01048               else
01049                 {
01050                   ret->typ = ctype_unknown;
01051                 }
01052               
01053               ret->sref = sRef_makeArrayFetch (arr->sref);
01054               
01055               ret->kind = XPR_FETCH;
01056 
01057               /*
01058               ** Because of funny aliasing (when arr and ind are
01059               ** flipped) spurious errors would be reported here.
01060               */
01061          
01062               /*@i2@*/ ret->edata = exprData_makePair (arr, ind);             
01063               checkSafeUse (ret, arr->sref);
01064               return (ret);
01065             }
01066           else
01067             {
01068               voptgenerror (FLG_TYPE,
01069                             message ("Array fetch from non-array (%t): %s[%s]", carr, 
01070                                      exprNode_unparse (e1), exprNode_unparse (e2)),
01071                             arr->loc);
01072               exprNode_free (arr);
01073               return (exprNode_makeError ());
01074             }
01075         }
01076       else
01077         {
01078           if (!ctype_isForceRealInt (&(ind->typ)))
01079             {
01080               ctype rt = ctype_realType (ind->typ);
01081 
01082               if (ctype_isChar (rt))
01083                 {
01084                   vnoptgenerror
01085                     (FLG_CHARINDEX,
01086                      message ("Array fetch using non-integer, %t: %s[%s]",
01087                               ind->typ, 
01088                               exprNode_unparse (e1), exprNode_unparse (e2)),
01089                      arr->loc);
01090                 }
01091               else if (ctype_isEnum (rt))
01092                 {
01093                   vnoptgenerror
01094                     (FLG_ENUMINDEX,
01095                      message ("Array fetch using non-integer, %t: %s[%s]",
01096                               ind->typ, 
01097                               exprNode_unparse (e1), exprNode_unparse (e2)),
01098                      arr->loc);
01099                 }
01100               else
01101                 {
01102                   voptgenerror 
01103                     (FLG_TYPE,
01104                      message ("Array fetch using non-integer, %t: %s[%s]",
01105                               ind->typ, 
01106                               exprNode_unparse (e1), exprNode_unparse (e2)),
01107                      arr->loc);
01108                 }
01109 
01110               multiVal_free (ind->val);
01111               ind->val = multiVal_unknown ();
01112             }
01113           
01114           if (ctype_isArrayPtr (crarr) && !ctype_isFunction (crarr))
01115             {
01116               exprNode ret = exprNode_createSemiCopy (arr);
01117               multiVal m = exprNode_getValue (ind);
01118               
01119               ret->typ = ctype_baseArrayPtr (crarr);
01120               ret->kind = XPR_FETCH;
01121               
01122               if (multiVal_isInt (m))
01123                 {
01124                   int i = (int) multiVal_forceInt (m);
01125                   
01126                   if (sRef_isValid (arr->sref)) {
01127                     ret->sref = sRef_makeArrayFetchKnown (arr->sref, i);
01128                   } else {
01129                     ret->sref = sRef_undefined;
01130                   }
01131                 }
01132               else
01133                 {
01134                                   ret->sref = sRef_makeArrayFetch (arr->sref);
01135                 }
01136               
01137               ret->sets = sRefSet_realNewUnion (arr->sets, ind->sets);
01138               ret->msets = sRefSet_realNewUnion (arr->msets, ind->msets);
01139               ret->uses = sRefSet_realNewUnion (arr->uses, ind->uses);
01140               
01141               /* (see comment on spurious errors above) */
01142               /*@i2@*/ ret->edata = exprData_makePair (arr, ind);
01143               
01144               exprNode_checkUse (ret, ind->sref, ind->loc);
01145               exprNode_checkUse (ret, arr->sref, arr->loc);
01146               
01147               return (ret);
01148             }
01149           else
01150             {
01151               if (ctype_isUnknown (carr))
01152                 {
01153                   exprNode ret = exprNode_createPartialCopy (arr);
01154                   
01155                   ret->kind = XPR_FETCH;
01156                   ret->typ = ctype_unknown;
01157                   ret->sets = sRefSet_union (ret->sets, ind->sets);
01158                   ret->msets = sRefSet_union (ret->msets, ind->msets);
01159                   ret->uses = sRefSet_union (ret->uses, ind->uses);
01160 
01161                   /* (see comment on spurious errors above) */            
01162                   /*@i2@*/ ret->edata = exprData_makePair (arr, ind);
01163                   
01164                   exprNode_checkUse (ret, ind->sref, ind->loc);
01165                   exprNode_checkUse (ret, arr->sref, arr->loc);
01166                   return (ret);
01167                 }
01168               else
01169                 {
01170                   voptgenerror
01171                     (FLG_TYPE,
01172                      message ("Array fetch from non-array (%t): %s[%s]", carr, 
01173                               exprNode_unparse (e1), exprNode_unparse (e2)),
01174                      arr->loc);
01175 
01176                   exprNode_free (arr);
01177                   exprNode_free (ind);
01178 
01179                   return (exprNode_makeError ());
01180                 }
01181             }
01182         }
01183     }
01184   BADEXIT;
01185 }

exprNode exprNode_arrowAccess ( exprNode s,
cstring f )
 

Definition at line 3364 of file exprNode.c.

03365 {
03366   exprNode ret = exprNode_createPartialCopy (s);
03367 
03368   ret->edata = exprData_makeField (s, f);
03369   ret->kind = XPR_ARROW;
03370 
03371   if (exprNode_isError (s))
03372     {
03373       return (ret);
03374     }
03375   else
03376     {
03377        ctype t = exprNode_getType (s);
03378        ctype tr = ctype_realType (t);
03379 
03380        checkMacroParen (s);
03381 
03382        (void) ctype_fixArrayPtr (tr); /* REWRITE THIS */
03383 
03384        if (ctype_isRealPointer (tr)) 
03385          {
03386            ctype b = ctype_realType (ctype_baseArrayPtr (tr));
03387            
03388            if (ctype_isStructorUnion (b))
03389              {
03390                uentry fentry = uentryList_lookupField (ctype_getFields (b), f);
03391                
03392                if (sRef_isKnown (s->sref) && sRef_possiblyNull (s->sref))
03393                  {
03394                    if (!usymtab_isGuarded (s->sref) && !context_inProtectVars ())
03395                      {
03396                        if (optgenerror 
03397                            (FLG_NULLDEREF,
03398                             message ("Arrow access from %s pointer%q: %s", 
03399                                      sRef_nullMessage (s->sref),
03400                                      sRef_unparsePreOpt (s->sref),
03401                                      exprNode_unparse (ret)),
03402                             s->loc))
03403                          {
03404                            sRef_showNullInfo (s->sref);
03405                            sRef_setNullError (s->sref);
03406                          }
03407                      }
03408                  }
03409                
03410                if (uentry_isUndefined (fentry))
03411                  {
03412                    voptgenerror 
03413                      (FLG_TYPE,
03414                       message ("Access non-existent field %s of %t: %s", 
03415                                f, t, exprNode_unparse (ret)),
03416                       s->loc);
03417                    ret->typ = ctype_unknown;
03418                    
03419                    return (ret);
03420                  }
03421                else
03422                  {
03423                    /*
03424                    ** was safeUse: shouldn't be safe!
03425                    **
03426                    ** to do rec->field
03427                    ** rec must be defined,
03428                    ** *rec must be allocated
03429                    ** rec->field need only be defined it if is an rvalue
03430                    */
03431                    
03432                    uentry_setUsed (fentry, exprNode_loc (ret));
03433                    ret->typ = uentry_getType (fentry);
03434                    
03435                    exprNode_checkUse (ret, s->sref, s->loc);
03436                    
03437                    /* exprNode_checkUse (ret, sRef_makePointer (s->sref), s->loc); */
03438                    ret->sref = sRef_makeArrow (s->sref, uentry_rawName (fentry));
03439                    return (ret);
03440                  }
03441              }
03442            else /* Pointer to something that is not a struct or union*/
03443              {
03444                if (ctype_isRealAbstract (tr))
03445                  {
03446                    ctype xrt = ctype_forceRealType (tr);
03447                    
03448                    voptgenerror 
03449                      (FLG_ABSTRACT,
03450                       message ("Arrow access field of abstract type (%t): %s->%s", 
03451                                t, exprNode_unparse (s), f),
03452                       s->loc);
03453                    
03454                    /*
03455                    ** Set the state correctly, as if the abstraction is broken.
03456                    */
03457                    
03458                    if (ctype_isRealPointer (xrt) &&
03459                        (b = ctype_realType (ctype_baseArrayPtr (xrt)),
03460                         ctype_isStructorUnion (b)))
03461                      {
03462                        uentry fentry = uentryList_lookupField (ctype_getFields (b), f);
03463                        ret->typ = uentry_getType (fentry);
03464                        ret->sref = sRef_makeArrow (s->sref, uentry_rawName (fentry));
03465                      }
03466                    else
03467                      {
03468                        ret->typ = ctype_unknown;
03469                        ret->sref = sRef_undefined;
03470                      }
03471                  }
03472                else /* not a struct, union or abstract */
03473                  {
03474                    if (ctype_isUnknown (tr)) {
03475                      cstring sn = cstring_copy (f);
03476                      
03477                      DPRINTF (("Here: %s", exprNode_unparse (s)));
03478                      
03479                      exprNode_checkUse (ret, s->sref, s->loc);
03480                      exprNode_checkUse (ret, sRef_makePointer (s->sref), s->loc);
03481                      
03482                      cstring_markOwned (sn);
03483                      ret->sref = sRef_makeArrow (s->sref, sn);
03484                      
03485                      ret->kind = XPR_ARROW;
03486                      return (ret);
03487                    } else {
03488                      voptgenerror 
03489                        (FLG_TYPE,
03490                         message ("Arrow access field of non-struct or union "
03491                                  "pointer (%t): %s->%s",
03492                                  t, exprNode_unparse (s), f),
03493                         s->loc);
03494                      
03495                      ret->typ = ctype_unknown;
03496                      ret->sref = sRef_undefined;
03497                    }
03498                  }
03499              }
03500          }
03501        else /* its not a pointer */
03502          {
03503            if (!ctype_isUnknown (tr))
03504              {
03505                voptgenerror 
03506                  (FLG_TYPE,
03507                   message ("Arrow access of non-pointer (%t): %s->%s",
03508                            t, exprNode_unparse (s), f),
03509                   s->loc);
03510                
03511                ret->typ = ctype_unknown;
03512                ret->sref = sRef_undefined;
03513              }
03514            else
03515              {
03516                cstring sn = cstring_copy (f);
03517                
03518                DPRINTF (("Here: %s", exprNode_unparse (s)));
03519                
03520                exprNode_checkUse (ret, s->sref, s->loc);
03521                exprNode_checkUse (ret, sRef_makePointer (s->sref), s->loc);
03522                
03523                cstring_markOwned (sn);
03524                ret->sref = sRef_makeArrow (s->sref, sn);
03525                
03526                ret->kind = XPR_ARROW;
03527                return (ret);
03528              }
03529          }
03530 
03531       return (ret);
03532     }
03533   BADEXIT;
03534 }

exprNode exprNode_assign ( exprNode e1,
exprNode e2,
lltok op )
 

Definition at line 4932 of file exprNode.c.

04934 {
04935   bool isalloc = FALSE;
04936   bool isjustalloc = FALSE;
04937   exprNode ret;
04938 
04939   DPRINTF (("%s [%s] <- %s [%s]",
04940             exprNode_unparse (e1),
04941             ctype_unparse (e1->typ),
04942             exprNode_unparse (e2),
04943             ctype_unparse (e2->typ)));
04944 
04945   if (lltok_getTok (op) != TASSIGN) 
04946     {
04947       ret = exprNode_makeOp (e1, e2, op);
04948     } 
04949   else 
04950     {
04951       ret = exprNode_createPartialCopy (e1);
04952       ret->kind = XPR_ASSIGN;
04953       ret->edata = exprData_makeOp (e1, e2, op);
04954 
04955       if (!exprNode_isError (e2)) 
04956         {
04957           ret->sets = sRefSet_union (ret->sets, e2->sets);
04958           ret->msets = sRefSet_union (ret->msets, e2->msets);
04959           ret->uses = sRefSet_union (ret->uses, e2->uses);
04960         }
04961     }
04962 
04963   checkExpressionDefined (e1, e2, op);
04964 
04965   if (exprNode_isError (e1))
04966     {
04967       if (!exprNode_isError (e2)) 
04968         {
04969           ret->loc = fileloc_update (ret->loc, e2->loc);
04970         }
04971       else
04972         {
04973           ret->loc = fileloc_update (ret->loc, g_currentloc);
04974         }
04975     }
04976 
04977   if (!exprNode_isError (e2))
04978     {
04979       checkMacroParen (e2);
04980     }
04981 
04982   if (exprNode_isDefined (e1))
04983     {
04984       if (sRef_isMacroParamRef (e1->sref))
04985         {
04986           if (context_inIterDef ())
04987             {
04988               uentry ue = sRef_getUentry (e1->sref);
04989               
04990               if (uentry_isYield (ue))
04991                 {
04992                   ;
04993                 }
04994               else
04995                 {
04996                   if (fileloc_isDefined (e1->loc))
04997                     {
04998                       voptgenerror
04999                         (FLG_MACROPARAMS,
05000                          message ("Assignment to non-yield iter parameter: %q", 
05001                                   sRef_unparse (e1->sref)),
05002                          e1->loc);
05003                     }
05004                   else
05005                     {
05006                       voptgenerror 
05007                         (FLG_MACROPARAMS,
05008                          message ("Assignment to non-yield iter parameter: %q", 
05009                                   sRef_unparse (e1->sref)),
05010                          g_currentloc);
05011                     }
05012                 }
05013             }
05014           else
05015             {
05016               if (fileloc_isDefined (e1->loc))
05017                 {
05018                   voptgenerror
05019                     (FLG_MACROASSIGN,
05020                      message ("Assignment to macro parameter: %q", 
05021                               sRef_unparse (e1->sref)),
05022                      e1->loc);
05023                 }
05024               else
05025                 {
05026                   voptgenerror 
05027                     (FLG_MACROASSIGN,
05028                      message ("Assignment to macro parameter: %q", 
05029                               sRef_unparse (e1->sref)),
05030                      g_currentloc);
05031                 }
05032             }
05033         }
05034       else
05035         {
05036           exprNode_checkAssignMod (e1, ret);
05037         }
05038 
05039       if (exprNode_isDefined (e2))
05040         {
05041           if (lltok_getTok (op) == TASSIGN) 
05042             {
05043               ctype te1 = exprNode_getType (e1);
05044               ctype te2 = exprNode_getType (e2);
05045               
05046               if (!ctype_forceMatch (te1, te2))
05047                 {
05048                   if (exprNode_matchLiteral (te1, e2))
05049                     {
05050                       ;
05051                     }
05052                   else
05053                     {
05054                       (void) gentypeerror 
05055                         (te2, e2, te1, e1,
05056                          message ("Assignment of %t to %t: %s %s %s", 
05057                                   te2, te1, exprNode_unparse (e1),
05058                                   lltok_unparse (op), 
05059                                   exprNode_unparse (e2)),
05060                          e1->loc);
05061                     }
05062                 }
05063             }
05064          
05065           exprNode_mergeUSs (ret, e2);
05066           exprNode_checkUse (ret, e2->sref, e2->loc);
05067           
05068           doAssign (e1, e2, FALSE); 
05069           ret->sref = e1->sref;
05070         }
05071       else
05072         {
05073           if (exprNode_isDefined (e2))
05074             {
05075               exprNode_mergeUSs (ret, e2);
05076                       exprNode_checkUse (ret, e2->sref, e2->loc);
05077             }
05078         }
05079 
05080       if (sRef_isPointer (e1->sref) && !sRef_isMacroParamRef (e1->sref))
05081         {
05082           exprNode_checkUse (ret, sRef_getBase (e1->sref), e1->loc);
05083         }
05084 
05085       isjustalloc = sRef_isJustAllocated (e1->sref);
05086       isalloc = sRef_isAllocated (e1->sref);
05087 
05088       if (sRef_isField (e1->sref))
05089         {
05090           sRef root = sRef_getRootBase (sRef_getBase (e1->sref));
05091           
05092           if (!sRef_isAllocated (root) && !sRef_isMacroParamRef (root))
05093             {
05094               exprNode_checkUse (ret, root, e1->loc);
05095             }
05096           
05097         }
05098   
05099       /*
05100       ** be careful!  this defines e1->sref.
05101       */
05102    
05103       if (!sRef_isMacroParamRef (e1->sref))
05104         {
05105           exprNode_checkSet (ret, e1->sref);
05106         }
05107       
05108       if (isjustalloc) 
05109         {
05110           sRef_setAllocatedComplete (e1->sref, exprNode_isDefined (e2)
05111                                      ? e2->loc : e1->loc);
05112         }
05113       else 
05114         {
05115           if (isalloc)
05116             {
05117               sRef_setAllocatedShallowComplete (e1->sref, exprNode_loc (e2));
05118             }
05119         }
05120     }
05121   
05122   return ret;
05123 }

exprNode exprNode_break ( lltok l,
int bqual )
 

Definition at line 6670 of file exprNode.c.

06671 {
06672   exprNode ret = exprNode_createLoc (ctype_unknown, fileloc_copy (lltok_getLoc (l)));
06673   clause breakClause = context_breakClause ();
06674   
06675   ret->kind = XPR_BREAK;
06676   ret->edata = exprData_makeTok (l);
06677   ret->canBreak = TRUE;
06678   ret->mustBreak = TRUE;
06679   
06680   if (breakClause == NOCLAUSE)
06681     {
06682       voptgenerror 
06683         (FLG_SYNTAX,
06684          cstring_makeLiteral ("Break not inside while, for or switch statement"),
06685          exprNode_loc (ret));
06686     }
06687   else
06688     {
06689       if (bqual != BADTOK)
06690         {
06691           switch (bqual)
06692             {
06693             case QSAFEBREAK:
06694               break;
06695             case QINNERBREAK:
06696               if (breakClause == SWITCHCLAUSE)
06697                 {
06698                   if (!context_inDeepSwitch ())
06699                     {
06700                       voptgenerror (FLG_SYNTAX,
06701                                     cstring_makeLiteral 
06702                                     ("Break preceded by innerbreak is not in a deep switch"),
06703                                     exprNode_loc (ret));
06704                     }
06705                 }
06706               else 
06707                 {
06708                   if (!context_inDeepLoop ())
06709                     {
06710                       voptgenerror (FLG_SYNTAX,
06711                                     cstring_makeLiteral 
06712                                     ("Break preceded by innerbreak is not in a deep loop"),
06713                                     exprNode_loc (ret));
06714                     }
06715                 }
06716               break;
06717             case QLOOPBREAK:
06718               if (breakClause == SWITCHCLAUSE)
06719                 {
06720                   voptgenerror (FLG_SYNTAX,
06721                                 cstring_makeLiteral 
06722                                 ("Break preceded by loopbreak is breaking a switch"),
06723                                 exprNode_loc (ret));
06724                 }
06725               break;
06726             case QSWITCHBREAK:
06727               if (breakClause != SWITCHCLAUSE)
06728                 {
06729                   voptgenerror 
06730                     (FLG_SYNTAX,
06731                      message ("Break preceded by switchbreak is breaking %s",
06732                               cstring_makeLiteralTemp 
06733                               ((breakClause == WHILECLAUSE
06734                                 || breakClause == DOWHILECLAUSE) ? "a while loop"
06735                                : (breakClause == FORCLAUSE) ? "a for loop"
06736                                : (breakClause == ITERCLAUSE) ? "an iterator"
06737                                : "<error loop>")),
06738                      exprNode_loc (ret));
06739                 }
06740               break;
06741             BADDEFAULT;
06742             }
06743         }
06744       else
06745         {
06746           if (breakClause == SWITCHCLAUSE)
06747             {
06748               clause nextBreakClause = context_nextBreakClause ();
06749 
06750               switch (nextBreakClause)
06751                 {
06752                 case NOCLAUSE: break;
06753                 case WHILECLAUSE:
06754                 case DOWHILECLAUSE:
06755                 case FORCLAUSE:
06756                 case ITERCLAUSE:
06757                   voptgenerror 
06758                     (FLG_LOOPSWITCHBREAK,
06759                      cstring_makeLiteral ("Break statement in switch inside loop"),
06760                      exprNode_loc (ret));
06761                   break;
06762                 case SWITCHCLAUSE:
06763                   voptgenerror 
06764                     (FLG_SWITCHSWITCHBREAK,
06765                      cstring_makeLiteral ("Break statement in switch inside switch"),
06766                      exprNode_loc (ret));
06767                   break;
06768                 BADDEFAULT;
06769                 }
06770             }
06771           else
06772             {
06773               if (context_inDeepLoop ())
06774                 {
06775                   voptgenerror 
06776                     (FLG_LOOPLOOPBREAK,
06777                      cstring_makeLiteral ("Break statement in nested loop"),
06778                      exprNode_loc (ret));
06779                 }
06780               else 
06781                 {
06782                   if (context_inDeepLoopSwitch ())
06783                     {
06784                       voptgenerror 
06785                         (FLG_SWITCHLOOPBREAK,
06786                          cstring_makeLiteral ("Break statement in loop inside switch"),
06787                          exprNode_loc (ret));
06788                     }
06789                 }
06790             }
06791         }
06792     }
06793 
06794   return ret;
06795 }

exprNode exprNode_caseMarker ( exprNode test,
bool fallThrough )
 

Definition at line 5373 of file exprNode.c.

05374 {
05375   exprNode ret = exprNode_createPartialCopy (test);
05376 
05377   ret->kind = fallThrough ? XPR_FTCASE : XPR_CASE;
05378 
05379   if (exprNode_isError (test)) {
05380     return ret;
05381   }
05382 
05383   exprNode_checkUse (ret, test->sref, test->loc);
05384   
05385   usymtab_setExitCode (ret->exitCode);
05386   
05387   if (ret->mustBreak)
05388     {
05389       usymtab_setMustBreak ();
05390     }
05391 
05392   ret->edata = exprData_makeSingle (test);
05393   ret->isJumpPoint = TRUE;
05394   
05395   return ret;
05396 }

exprNode exprNode_cast ( lltok tok,
exprNode e,
qtype q )
 

Definition at line 4067 of file exprNode.c.

04068 {
04069   ctype c;
04070   ctype t;
04071   exprNode ret;
04072 
04073   if (exprNode_isError (e))
04074     {
04075       qtype_free (q);
04076       lltok_release (tok);
04077       return exprNode_undefined;
04078     }
04079 
04080   checkMacroParen (e);
04081 
04082   c = qtype_getType (q);
04083   t = exprNode_getType (e);
04084 
04085   ret = exprNode_createPartialCopy (e);
04086   
04087   ret->loc = fileloc_update (ret->loc, lltok_getLoc (tok));
04088   ret->typ = c;
04089   ret->kind = XPR_CAST;
04090   ret->edata = exprData_makeCast (tok, e, q);
04091 
04092   if (ctype_isRealSU (ctype_getBaseType (sRef_getType (e->sref))))
04093     {
04094       /* 
04095       ** This is a bit of a hack to avoid a problem
04096       ** when the code does,
04097       **          (some other struct) x
04098       **          ...
04099       **          x->field
04100       */
04101 
04102       ret->sref = sRef_copy (e->sref);
04103       usymtab_addForceMustAlias (ret->sref, e->sref);
04104       sRef_setTypeFull (ret->sref, c);
04105       DPRINTF (("Cast: %s -> %s", sRef_unparseFull (e->sref),
04106                 sRef_unparseFull (ret->sref)));
04107     }
04108   else
04109     {
04110       ret->sref = e->sref;
04111       sRef_setTypeFull (ret->sref, c);
04112       DPRINTF (("Cast 2: -> %s", sRef_unparseFull (ret->sref)));
04113     }
04114 
04115   /*
04116   ** we allow
04117   **       abstract  -> void
04118   **              0 <-> abstract * 
04119   **         void * <-> abstract *  (if FLG_ABSTVOIDP)
04120   **     abstract * <-> void *      (if FLG_ABSTVOIDP)
04121   */
04122 
04123   if (ctype_isVoid (c)) /* cast to void is always okay --- discard value */
04124     {
04125       ;
04126     }
04127   else if (ctype_isRealAP (c)) /* casting to array or pointer */
04128     {
04129       ctype bc = ctype_getBaseType (c);
04130       ctype bt = ctype_getBaseType (t);
04131       ctype rt = ctype_realType (t);
04132 
04133       if (ctype_isFunction (ctype_baseArrayPtr (ctype_realType (c)))
04134           && (ctype_isArrayPtr (rt)
04135               && !ctype_isFunction (ctype_realType (ctype_baseArrayPtr (rt)))))
04136         {
04137           voptgenerror
04138             (FLG_CASTFCNPTR,
04139              message ("Cast from function pointer type (%t) to "
04140                       "non-function pointer (%t): %s",
04141                       c, t, exprNode_unparse (ret)),
04142              e->loc);     
04143         }
04144 
04145       if (!ctype_isFunction (ctype_baseArrayPtr (c))
04146           && (ctype_isArrayPtr (rt)
04147               && ctype_isFunction (ctype_realType (ctype_baseArrayPtr (rt)))))
04148         {
04149           voptgenerror
04150             (FLG_CASTFCNPTR,
04151              message ("Cast from non-function pointer type (%t) to "
04152                       "function pointer (%t): %s",
04153                       c, t, exprNode_unparse (ret)),
04154              e->loc);     
04155         }
04156 
04157       if (exprNode_isZero (e) && context_getFlag (FLG_ZEROPTR) &&
04158           !(ctype_isRealAbstract (bc)
04159             && context_hasAccess (ctype_typeId (bc))))
04160         {
04161          ; /* okay to cast zero */
04162         }
04163       else
04164         {
04165           if (ctype_isRealAbstract (bc)
04166               && !context_hasAccess (ctype_typeId (bc)))
04167             {
04168               if (ctype_isVoidPointer (t) || ctype_isUnknown (t))
04169                 {
04170                   vnoptgenerror
04171                     (FLG_ABSTVOIDP,
04172                      message ("Cast to underlying abstract type %t: %s",
04173                               c, exprNode_unparse (ret)),
04174                      e->loc);
04175                 }
04176               else
04177                 {
04178                   voptgenerror
04179                     (FLG_ABSTRACT,
04180                      message ("Cast to underlying abstract type %t: %s",
04181                               c, exprNode_unparse (ret)),
04182                      e->loc);     
04183                 }
04184             }
04185 
04186           if (ctype_isRealAbstract (bt)
04187               && !context_hasAccess (ctype_typeId (bt)))
04188             {
04189               if (ctype_isUnknown (c) || ctype_isVoidPointer (c))
04190                 {
04191                   vnoptgenerror
04192                     (FLG_ABSTVOIDP,
04193                      message ("Cast from underlying abstract type %t: %s",
04194                               t, exprNode_unparse (ret)),
04195                      e->loc);
04196                 }
04197               else
04198                 {
04199                   voptgenerror
04200                     (FLG_ABSTRACT,
04201                      message ("Cast from underlying abstract type %t: %s",
04202                               t, exprNode_unparse (ret)),
04203                      e->loc);
04204                 }
04205             }
04206         }
04207     }
04208   else
04209     {
04210       ctype bt = ctype_realType (ctype_getBaseType (t));
04211       ctype bc = ctype_realType (ctype_getBaseType (c));
04212 
04213       if (ctype_isAbstract (bt) && !context_hasAccess (ctype_typeId (bt)))
04214         {
04215           if (ctype_match (c, t))
04216             {
04217               if (ctype_equal (c, t))
04218                 {
04219                   voptgenerror
04220                     (FLG_TYPE, 
04221                      message ("Redundant cast involving abstract type %t: %s",
04222                               bt, exprNode_unparse (ret)),
04223                      e->loc);
04224                 }
04225             }
04226           else
04227             {
04228               voptgenerror
04229                 (FLG_ABSTRACT,
04230                  message ("Cast from abstract type %t: %s", 
04231                           bt, exprNode_unparse (ret)),
04232                  e->loc);
04233             }
04234         }
04235       
04236       if (ctype_isAbstract (bc) 
04237           && !context_hasAccess (ctype_typeId (bc)))
04238         {
04239           if (ctype_match (c, t))
04240             {
04241              ;
04242             }
04243           else
04244             {
04245               voptgenerror 
04246                 (FLG_ABSTRACT,
04247                  message ("Cast to abstract type %t: %s", bc, 
04248                           exprNode_unparse (ret)),
04249                  e->loc);
04250             }
04251         }
04252     }
04253 
04254   if (ctype_isAbstract (c))
04255     {
04256       if (sRef_isExposed (e->sref) || sRef_isOnly (e->sref))
04257         {
04258           /* okay, cast exposed to abstract */
04259           sRef_clearExKindComplete (ret->sref, fileloc_undefined);
04260         }
04261       else 
04262         {
04263           if (ctype_isVisiblySharable (t) 
04264               && sRef_isExternallyVisible (e->sref)
04265               && !(ctype_isAbstract (t) 
04266                    && context_hasAccess (ctype_typeId (t))))
04267             {
04268               voptgenerror 
04269                 (FLG_CASTEXPOSE,
04270                  message ("Cast to abstract type from externally visible "
04271                           "mutable storage exposes rep of %s: %s",
04272                           ctype_unparse (c),
04273                           exprNode_unparse (e)),
04274                  e->loc);
04275             }
04276         }
04277     }
04278 
04279   return (ret);
04280 }

exprNode exprNode_charLiteral ( char c,
cstring text,
fileloc loc )
 

Definition at line 665 of file exprNode.c.

00666 {
00667   exprNode e = exprNode_createLoc (ctype_char, loc);
00668 
00669   if (context_getFlag (FLG_CHARINTLITERAL))
00670     {
00671       e->typ = ctype_makeConj (ctype_char, ctype_int);
00672     }
00673 
00674   e->kind = XPR_NUMLIT;
00675   e->val = multiVal_makeChar (c);
00676 
00677   e->edata = exprData_makeLiteral (cstring_copy (text));
00678   return (e);
00679 }

exprNode exprNode_checkExpr ( exprNode e )
 

Definition at line 5642 of file exprNode.c.

05643 {
05644   if (!exprNode_isError (e))
05645     {
05646       if (e->kind != XPR_ASSIGN)
05647         {
05648           exprNode_checkUse (e, e->sref, e->loc);
05649         }
05650     }
05651 
05652   return e;
05653 }

void exprNode_checkMSet ( exprNode e,
sRef s )
 

Definition at line 8804 of file exprNode.c.

Referenced by checkPassTransfer().

08805 {
08806   if (sRef_isValid (s) && !sRef_isNothing (s))
08807     {
08808       uentry ue = sRef_getBaseUentry (s);
08809 
08810       if (uentry_isValid (ue))
08811         {
08812           uentry_setLset (ue);
08813         }
08814 
08815       if (!ynm_toBoolStrict (sRef_isWriteable (s)))
08816         {
08817           voptgenerror (FLG_USEDEF,
08818                         message ("Attempt to set unuseable storage: %q", sRef_unparse (s)),
08819                         exprNode_loc (e));
08820         }
08821       
08822       if (sRef_isMeaningful (s))
08823         {
08824           sRef_setDefinedComplete (s, exprNode_loc (e));
08825         }
08826       
08827       if (exprNode_isDefined (e))
08828         {
08829           e->msets = sRefSet_insert (e->msets, s);
08830         }
08831     }
08832 }

void exprNode_checkSet ( exprNode e,
sRef s )
 

Definition at line 8701 of file exprNode.c.

Referenced by checkPassTransfer(), exprNode_assign(), exprNode_postOp(), exprNode_preOp(), and exprNode_vaArg().

08702 {
08703   sRef defines = sRef_undefined;
08704 
08705   if (sRef_isValid (s) && !sRef_isNothing (s))
08706     {
08707       uentry ue = sRef_getBaseUentry (s);
08708 
08709       if (uentry_isValid (ue))
08710         {
08711           uentry_setLset (ue);
08712         }
08713 
08714       if (!ynm_toBoolStrict (sRef_isWriteable (s)))
08715         {
08716           voptgenerror (FLG_USEDEF,
08717                         message ("Attempt to set unuseable storage: %q", 
08718                                  sRef_unparse (s)),
08719                         exprNode_loc (e));
08720         }
08721      
08722       if (sRef_isMeaningful (s))
08723         {
08724           
08725           if (sRef_isDead (s))
08726             {
08727               sRef base = sRef_getBaseSafe (s);
08728 
08729               if (sRef_isValid (base) 
08730                   && sRef_isDead (base))
08731                 {
08732                   sRef_setPartial (s, exprNode_loc (e));
08733                 }
08734               
08735               defines = s; /* okay - modifies for only param */
08736             }
08737           else if (sRef_isPartial (s))
08738             {
08739               sRef eref = exprNode_getSref (e);
08740 
08741               if (!sRef_isPartial (eref))
08742                 {
08743                   /*
08744                   ** should do something different here???
08745                   */
08746                   
08747                   sRef_setDefinedComplete (eref, exprNode_loc (e));               
08748                 }
08749               else
08750                 {
08751                   sRef_setPartialDefinedComplete (eref, exprNode_loc (e));
08752                 }
08753 
08754               if (sRef_isMeaningful (eref))
08755                 {
08756                   defines = eref;
08757                 }
08758               else
08759                 {                
08760                   defines = s;
08761                 }
08762             }
08763           else if (sRef_isAllocated (s))
08764             {
08765               sRef eref = exprNode_getSref (e);
08766 
08767               
08768               if (!sRef_isAllocated (eref))
08769                 {
08770                   sRef_setDefinedComplete (eref, exprNode_loc (e));
08771                 }
08772               else
08773                 {
08774                   sRef base = sRef_getBaseSafe (eref);
08775                   
08776                   if (sRef_isValid (base))
08777                     {
08778                       sRef_setPdefined (base, exprNode_loc (e)); 
08779                     }
08780                 }
08781 
08782               defines = s;
08783             }
08784           else 
08785             {
08786               sRef_setDefinedNCComplete (s, exprNode_loc (e));
08787               defines = s;
08788             }
08789 
08790         }
08791       else /* not meaningful...but still need to insert it */
08792         {
08793           defines = s;
08794         }
08795     }
08796 
08797   if (exprNode_isDefined (e) && sRef_isValid (defines))
08798     {
08799       e->sets = sRefSet_insert (e->sets, defines); 
08800     }
08801 }

void exprNode_checkUseParam ( exprNode current )
 

Definition at line 9066 of file exprNode.c.

Referenced by checkPassTransfer().

09067 {
09068   if (exprNode_isDefined (current))
09069     {
09070       exprNode_checkUse (current, current->sref, current->loc);
09071     }
09072 }

exprNode exprNode_comma ( exprNode e1,
exprNode e2 )
 

Definition at line 6835 of file exprNode.c.

06836 {
06837   exprNode ret;
06838 
06839   if (exprNode_isError (e1)) 
06840     {
06841       if (exprNode_isError (e2))
06842         {
06843           ret = exprNode_createLoc (ctype_unknown, g_currentloc);
06844         }
06845       else
06846         {
06847           ret = exprNode_createPartialCopy (e2);
06848           exprNode_checkUse (ret, e2->sref, e2->loc);
06849           ret->sref = e2->sref;
06850         }
06851     }
06852   else
06853     {
06854       ret = exprNode_createPartialCopy (e1);
06855 
06856       exprNode_checkUse (ret, e1->sref, e1->loc);
06857 
06858       if (!exprNode_isError (e2))
06859         {
06860           exprNode_mergeUSs (ret, e2);
06861           exprNode_checkUse (ret, e2->sref, e2->loc);
06862           ret->sref = e2->sref;
06863         }
06864     }
06865 
06866   ret->kind = XPR_COMMA;
06867   ret->edata = exprData_makePair (e1, e2);
06868   
06869   if (exprNode_isDefined (e1))
06870     {
06871       if (exprNode_isDefined (e2))
06872         {
06873           ret->typ = e2->typ; 
06874 
06875           if (exprNode_mustEscape (e1) || e1->mustBreak)
06876             {
06877               voptgenerror 
06878                 (FLG_UNREACHABLE,
06879                  message ("Second clause of comma expression is unreachable: %s",
06880                           exprNode_unparse (e2)), 
06881                  exprNode_loc (e2));
06882             }
06883           
06884           ret->exitCode = exitkind_combine (e1->exitCode, e2->exitCode);
06885           ret->mustBreak = e1->mustBreak || e2->mustBreak;
06886           ret->canBreak = e1->canBreak || e2->canBreak;
06887         }
06888       else
06889         {
06890           if (exprNode_mustEscape (e1) || e1->mustBreak)
06891             {
06892               voptgenerror 
06893                 (FLG_UNREACHABLE,
06894                  message ("Second clause of comma expression is unreachable: %s",
06895                           exprNode_unparse (e2)), 
06896                  exprNode_loc (e2));
06897             }
06898           
06899           ret->exitCode = e1->exitCode;
06900           ret->canBreak = e1->canBreak;
06901         }
06902     }
06903   else
06904     {
06905       if (exprNode_isDefined (e2))
06906         {
06907           ret->exitCode = e2->exitCode;
06908           ret->mustBreak = e2->mustBreak;
06909           ret->canBreak = e2->canBreak;
06910         }
06911     }
06912 
06913   return (ret);
06914 }

exprNode exprNode_concat ( exprNode e1,
exprNode e2 )
 

Definition at line 5488 of file exprNode.c.

05489 {
05490   exprNode ret = exprNode_createPartialCopy (e1);
05491 
05492   ret->edata = exprData_makePair (e1, e2);
05493   ret->kind = XPR_STMTLIST;
05494 
05495   if (exprNode_isDefined (e1))
05496     {
05497       ret->isJumpPoint = e1->isJumpPoint;
05498       ret->canBreak = e1->canBreak;
05499     }
05500   else
05501     {
05502       if (exprNode_isDefined (e2))
05503         {
05504           ret->loc = fileloc_update (ret->loc, e2->loc);
05505         }
05506     }
05507 
05508   if (exprNode_isDefined (e2))
05509     {
05510       ret->exitCode = e2->exitCode;
05511       ret->mustBreak = e2->mustBreak;
05512       if (e2->canBreak) ret->canBreak = TRUE;
05513     }
05514 
05515   /* 
05516   ** if e1 must return, then e2 is unreachable!
05517   */
05518 
05519   if (exprNode_isDefined (e1) && exprNode_isDefined (e2))
05520     {
05521       if ((exprNode_mustEscape (e1) || exprNode_mustBreak (e1)) 
05522           && !(e2->isJumpPoint))
05523         {
05524           if (context_getFlag (FLG_UNREACHABLE))
05525             {
05526               exprNode nr = e2;
05527 
05528               if (e2->kind == XPR_STMT)
05529                 {
05530                   nr = exprData_getSingle (e2->edata);
05531                 }
05532 
05533               if ((nr->kind == XPR_TOK 
05534                    && lltok_isSemi (exprData_getTok (nr->edata))))
05535                 {
05536                   /* okay to have unreachable ";" */
05537                   ret->exitCode = XK_MUSTEXIT;
05538                   ret->canBreak = TRUE;
05539                 }
05540               else
05541                 {
05542                   if (optgenerror (FLG_UNREACHABLE,
05543                                    message ("Unreachable code: %s", 
05544                                             exprNode_unparseFirst (nr)),
05545                                    exprNode_loc (nr)))
05546                     {
05547                       ret->isJumpPoint = TRUE;                
05548                       ret->mustBreak = FALSE;
05549                       ret->exitCode = XK_ERROR;
05550                       DPRINTF (("Jump point: %s", exprNode_unparse (ret)));
05551                     }
05552                   else
05553                     {
05554                       ret->exitCode = XK_MUSTEXIT;
05555                       ret->canBreak = TRUE;
05556                     }
05557 
05558                 }
05559             }
05560         }
05561       else
05562         {
05563           if ((e2->kind == XPR_CASE || e2->kind == XPR_DEFAULT))
05564             {
05565               /*
05566               ** We want a warning anytime we have:
05567               **         case xxx: ...  
05568               **                   yyy;  <<<- no break or return
05569               **         case zzz: ...
05570               */
05571               
05572               exprNode lastStmt = exprNode_lastStatement (e1);
05573               
05574               if (exprNode_isDefined (lastStmt) 
05575                   && !exprNode_mustEscape (lastStmt)
05576                   && !exprNode_mustBreak (lastStmt)
05577                   && !exprNode_isCaseMarker (lastStmt)
05578                   && !exprNode_isDefaultMarker (lastStmt)
05579                   && !exprNode_isLabelMarker (lastStmt))
05580                 {
05581                   voptgenerror (FLG_CASEBREAK,
05582                                 cstring_makeLiteral 
05583                                 ("Fall through case (no preceeding break)"),
05584                                 e2->loc);
05585                 }
05586             }
05587         }
05588     }
05589 
05590   exprNode_mergeUSs (ret, e2);
05591   
05592   usymtab_setExitCode (ret->exitCode);
05593   
05594   if (ret->mustBreak)
05595     {
05596       usymtab_setMustBreak ();
05597     }
05598 
05599   return ret;
05600 }

exprNode exprNode_cond ( exprNode pred,
exprNode ifclause,
exprNode elseclause )
 

Definition at line 5126 of file exprNode.c.

05128 {
05129   exprNode ret;
05130 
05131   if (!exprNode_isError (pred))
05132     {
05133       ret = exprNode_createPartialCopy (pred);
05134       checkMacroParen (pred);
05135       exprNode_checkPred (cstring_makeLiteralTemp ("conditional"), pred);
05136       
05137       if (!exprNode_isError (ifclause))
05138         {
05139           checkMacroParen (ifclause);   /* update macro counts! */
05140 
05141           if (!exprNode_isError (elseclause))
05142             {
05143               checkMacroParen (elseclause);
05144               
05145               if (!exprNode_matchTypes (ifclause, elseclause))
05146                 {
05147                   if (gentypeerror 
05148                       (exprNode_getType (ifclause),
05149                        ifclause,
05150                        exprNode_getType (elseclause),
05151                        elseclause,
05152                        message ("Conditional clauses are not of same type: "
05153                                 "%s (%t), %s (%t)", 
05154                                 exprNode_unparse (ifclause), 
05155                                 exprNode_getType (ifclause),
05156                                 exprNode_unparse (elseclause), 
05157                                 exprNode_getType (elseclause)),
05158                        ifclause->loc))
05159                     {
05160                       ret->sref = sRef_undefined;
05161                       ret->typ = ctype_unknown;
05162                     }
05163                 }
05164               else
05165                 {
05166                   /* for now...should merge the states */
05167                   ret->sref = ifclause->sref;
05168                   ret->typ = ifclause->typ;
05169 
05170                   if (exprNode_isNullValue (ifclause))
05171                     {
05172                       ret->typ = elseclause->typ;
05173                     }
05174                 }
05175               
05176               exprNode_checkUse (ret, pred->sref, pred->loc);
05177               exprNode_checkUse (ifclause, ifclause->sref, ifclause->loc);
05178               exprNode_checkUse (elseclause, elseclause->sref, elseclause->loc);
05179 
05180               exprNode_mergeCondUSs (ret, ifclause, elseclause);
05181 
05182             }
05183           else
05184             {
05185               ret->typ = ifclause->typ;
05186               
05187               exprNode_checkUse (pred, pred->sref, pred->loc);
05188               exprNode_checkUse (ifclause, ifclause->sref, ifclause->loc);
05189               
05190               exprNode_mergeCondUSs (ret, ifclause, exprNode_undefined);
05191             }
05192         }
05193       else 
05194         {
05195           if (!exprNode_isError (elseclause))
05196             {
05197               ret->typ = elseclause->typ;
05198               
05199               exprNode_checkUse (pred, pred->sref, pred->loc);
05200               exprNode_checkUse (elseclause, elseclause->sref, elseclause->loc);
05201               
05202               exprNode_mergeCondUSs (ret, exprNode_undefined, elseclause);
05203             }
05204         }
05205     }
05206   else /* pred is error */
05207     {
05208       if (!exprNode_isError (ifclause))
05209         {
05210           ret = exprNode_createSemiCopy (ifclause);
05211 
05212           checkMacroParen (ifclause);   /* update macro counts! */
05213           
05214           if (!exprNode_isError (elseclause))
05215             {
05216               checkMacroParen (elseclause);
05217               
05218               ret->typ = ifclause->typ;
05219                       
05220               if (!ctype_forceMatch (ifclause->typ, elseclause->typ))
05221                 {
05222                   if (gentypeerror 
05223                       (exprNode_getType (ifclause),
05224                        ifclause,
05225                        exprNode_getType (elseclause),
05226                        elseclause,
05227                        message ("Conditional clauses are not of same type: "
05228                                 "%s (%t), %s (%t)", 
05229                                 exprNode_unparse (ifclause), 
05230                                 exprNode_getType (ifclause),
05231                                 exprNode_unparse (elseclause), 
05232                                 exprNode_getType (elseclause)),
05233                        ifclause->loc))
05234                     {
05235                       ret->typ = ctype_unknown;
05236                     }
05237                 }
05238                       
05239               exprNode_checkUse (ifclause, ifclause->sref, ifclause->loc);
05240               exprNode_checkUse (elseclause, elseclause->sref, elseclause->loc);
05241               
05242               exprNode_mergeCondUSs (ret, ifclause, elseclause);
05243             }
05244         }
05245       else if (!exprNode_isError (elseclause)) /* pred, if errors */
05246         {
05247           ret = exprNode_createSemiCopy (ifclause);
05248 
05249           ret->typ = elseclause->typ;
05250           checkMacroParen (elseclause);
05251           
05252           exprNode_checkUse (elseclause, elseclause->sref, elseclause->loc);
05253           exprNode_mergeCondUSs (ret, exprNode_undefined, elseclause);
05254         }
05255       else /* all errors! */
05256         {
05257           ret = exprNode_createLoc (ctype_unknown, g_currentloc);
05258         }
05259     }
05260   
05261   ret->kind = XPR_COND;
05262   ret->edata = exprData_makeCond (pred, ifclause, elseclause);  
05263 
05264   if (exprNode_isDefined (ifclause) && exprNode_isDefined (elseclause))
05265     {
05266       exprNode_combineControl (ret, ifclause, elseclause);
05267     }
05268 
05269   return (ret);
05270 }

exprNode exprNode_continue ( lltok l,
int qcontinue )
 

Definition at line 6628 of file exprNode.c.

06629 {
06630   exprNode ret = exprNode_createLoc (ctype_unknown, fileloc_copy (lltok_getLoc (l)));
06631 
06632   ret->kind = XPR_CONTINUE;
06633   ret->edata = exprData_makeTok (l);
06634   ret->canBreak = TRUE;
06635   ret->mustBreak = TRUE;
06636 
06637   if (qcontinue == QSAFEBREAK)
06638     {
06639       ; /* no checking */
06640     }
06641   else if (qcontinue == QINNERCONTINUE)
06642     {
06643       if (!context_inDeepLoop ())
06644         {
06645           voptgenerror 
06646             (FLG_LOOPLOOPCONTINUE,
06647              cstring_makeLiteral ("Continue statement marked with innercontinue "
06648                                   "is not inside a nested loop"),
06649              exprNode_loc (ret));
06650         }
06651     }
06652   else if (qcontinue == BADTOK)
06653     {
06654       if (context_inDeepLoop ())
06655         {
06656           voptgenerror 
06657             (FLG_LOOPLOOPCONTINUE,
06658              cstring_makeLiteral ("Continue statement in nested loop"),
06659              exprNode_loc (ret));
06660         }
06661     }
06662   else
06663     {
06664       llbuglit ("exprNode_continue: bad qcontinue");
06665     }
06666 
06667   return ret;
06668 }

exprNode exprNode_createId ( uentry c )
 

Definition at line 824 of file exprNode.c.

Referenced by exprNode_makeInitialization().

00825 {
00826   if (uentry_isValid (c))
00827     {
00828       exprNode e = exprNode_new ();
00829       
00830       e->typ = uentry_getType (c);
00831 
00832       if (uentry_isFunction (c)
00833           && !sRef_isLocalVar (uentry_getSref (c)))
00834         {
00835           e->sref = sRef_undefined;
00836         }
00837       else
00838         {
00839           e->sref = uentry_getSref (c); 
00840         }
00841 
00842       if (sRef_isStateUnknown (e->sref) && uentry_isNonLocal (c))
00843         {
00844           sRef_setDefined (e->sref, fileloc_undefined);
00845         }
00846       
00847       /*
00848       ** yoikes!  leaving this out was a heinous bug...that would have been
00849       ** caught if i had lclint working first.  gag!
00850       */
00851       
00852       e->etext = cstring_undefined;
00853       
00854       if (uentry_isEitherConstant (c))
00855         {
00856           e->kind = XPR_CONST;
00857           e->val = multiVal_copy (uentry_getConstantValue (c));
00858         }
00859       else
00860         {
00861           e->kind = XPR_VAR;
00862           e->val = multiVal_unknown ();
00863         }
00864       
00865       e->edata = exprData_makeId (c);
00866       e->loc = context_getSaveLocation ();
00867       
00868       if (fileloc_isUndefined (e->loc))
00869         {
00870           fileloc_free (e->loc);
00871           e->loc = fileloc_copy (g_currentloc);
00872         }
00873 
00874       e->guards = guardSet_new ();
00875       e->sets = sRefSet_new ();
00876       e->msets = sRefSet_new ();
00877       e->uses = sRefSet_new ();
00878       
00879       /*> missing fields, detected by lclint <*/
00880       e->exitCode = XK_NEVERESCAPE;
00881       e->isJumpPoint = FALSE;
00882       e->canBreak = FALSE;
00883       e->mustBreak = FALSE;
00884       
00885       return e;
00886     }
00887   else
00888     {
00889             return exprNode_createUnknown ();
00890     }
00891 }

exprNode exprNode_createTok ( lltok t )
 

Definition at line 5602 of file exprNode.c.

Referenced by exprNode_defaultMarker().

05603 {
05604   exprNode ret = exprNode_create (ctype_unknown);
05605   ret->kind = XPR_TOK;
05606   ret->edata = exprData_makeTok (t);
05607   return ret;
05608 }

exprNode exprNode_defaultMarker ( lltok def,
bool fallThrough )
 

Definition at line 5437 of file exprNode.c.

05438 {
05439   exprNode ret = exprNode_createTok (def);
05440   
05441   ret->isJumpPoint = TRUE;
05442   ret->kind = fallThrough ? XPR_FTDEFAULT : XPR_DEFAULT;
05443   return (ret);
05444 }

void exprNode_destroyMod ( void )
 

Definition at line 203 of file exprNode.c.

Referenced by llexit().

00206 {
00207   if (initMod)
00208     {
00209       uentry_free (regArg);
00210       uentry_free (outArg);
00211       uentry_free (outStringArg);
00212       
00213       exprNode_free (mustExitNode);
00214       initMod = FALSE;
00215     /*@-branchstate@*/ 
00216     } 
00217   /*@=branchstate@*/
00218 }

exprNode exprNode_doWhile ( exprNode b,
exprNode t )
 

Definition at line 6355 of file exprNode.c.

06356 {
06357   exprNode ret;
06358   
06359   if (exprNode_isError (t))
06360     {
06361       if (exprNode_isError (b))
06362         {
06363           ret = exprNode_createLoc (ctype_unknown, g_currentloc);
06364         }
06365       else
06366         {
06367           ret = exprNode_createPartialCopy (b);
06368 
06369           ret->exitCode = exitkind_makeConditional (b->exitCode);
06370           exprNode_checkUse (ret, b->sref, b->loc);
06371           ret->exitCode = b->exitCode;
06372           ret->canBreak = b->canBreak;
06373           ret->mustBreak = b->mustBreak;
06374         }
06375     }
06376   else
06377     {
06378       ret = exprNode_createPartialCopy (t);
06379       exprNode_checkPred (cstring_makeLiteralTemp ("while"), t);
06380       
06381       if (!exprNode_isError (b)) 
06382         {
06383           /*
06384           ** forgot the copy's --- why wasn't this detected??
06385           */
06386 
06387           ret->sets = sRefSet_copy (ret->sets, b->sets);
06388           ret->msets = sRefSet_copy (ret->msets, b->msets);
06389           ret->uses = sRefSet_copy (ret->uses, b->uses);  
06390 
06391           /* left this out --- causes and aliasing bug (infinite loop)
06392              should be detected?? */
06393 
06394           exprNode_checkUse (ret, b->sref, b->loc);
06395           exprNode_mergeUSs (ret, t);
06396           exprNode_checkUse (ret, t->sref, t->loc);
06397 
06398           ret->exitCode = b->exitCode;
06399           ret->canBreak = b->canBreak;
06400           ret->mustBreak = b->mustBreak;
06401         }
06402     }
06403   
06404   context_exitDoWhileClause (t);
06405 
06406   ret->kind = XPR_DOWHILE;
06407   ret->edata = exprData_makePair (t, b);
06408     return ret;
06409 }

bool exprNode_errorEscape ( exprNode e )
 

Definition at line 5478 of file exprNode.c.

Referenced by exprNode_checkFunctionBody().

05479 {
05480   if (exprNode_isDefined (e))
05481     {
05482       return exitkind_isError (e->exitCode);
05483     }
05484 
05485   return FALSE;
05486 }

exprNode exprNode_fieldAccess ( exprNode s,
cstring f )
 

Definition at line 3257 of file exprNode.c.

03258 {
03259   exprNode ret = exprNode_createPartialCopy (s);
03260 
03261   ret->kind = XPR_FACCESS;
03262 
03263   if (exprNode_isError (s))
03264     {
03265       ret->edata = exprData_makeField (s, f);
03266       return ret;
03267     }
03268   else
03269     {
03270       ctype t = exprNode_getType (s);
03271       ctype tr = ctype_realType (t);
03272       
03273       checkMacroParen (s);
03274 
03275       ret->edata = exprData_makeField (s, f);
03276       
03277       if (ctype_isStructorUnion (tr))
03278         {
03279           uentry tf = uentryList_lookupField (ctype_getFields (tr), f);
03280 
03281           if (uentry_isUndefined (tf))
03282             {
03283               voptgenerror (FLG_TYPE,
03284                             message ("Access non-existent field %s of %t: %s", f, t, 
03285                                      exprNode_unparse (ret)),
03286                             s->loc);
03287               
03288               return (ret);
03289             }
03290           else
03291             {
03292               uentry_setUsed (tf, exprNode_loc (ret));
03293 
03294               ret->typ = uentry_getType (tf); 
03295               checkSafeUse (ret, s->sref);
03296               
03297               ret->sref = sRef_makeField (s->sref, uentry_rawName (tf));
03298               return (ret);
03299             }
03300         }
03301       else /* isStructorUnion */
03302         {
03303           if (ctype_isRealAbstract (tr))
03304             {
03305               voptgenerror
03306                 (FLG_ABSTRACT,
03307                  message ("Access field of abstract type (%t): %s.%s", 
03308                           t, exprNode_unparse (s), f),
03309                  s->loc);
03310               ret->typ = ctype_unknown;
03311             }
03312           else
03313             {
03314               if (ctype_isKnown (tr))
03315                 {
03316                   voptgenerror 
03317                     (FLG_TYPE,
03318                      message
03319                      ("Access field of non-struct or union (%t): %s.%s",
03320                       t, exprNode_unparse (s), f),
03321                      s->loc);
03322 
03323                   ret->typ = ctype_unknown;
03324                 }
03325               else
03326                 {
03327                   cstring sn = cstring_copy (f);
03328 
03329                   checkSafeUse (ret, s->sref);
03330                   cstring_markOwned (sn);
03331                   ret->sref = sRef_makeField (s->sref, sn);
03332 
03333                   return (ret);
03334                 }
03335             }
03336           return (ret);
03337         }
03338     }
03339   BADEXIT;
03340 }

exprNode exprNode_floatLiteral ( double d,
ctype ct,
cstring text,
fileloc loc )
 

Definition at line 682 of file exprNode.c.

00683 {
00684   exprNode e = exprNode_createLoc (ct, loc);
00685 
00686   e->kind = XPR_NUMLIT;
00687     e->val = multiVal_makeDouble (d);
00688   e->edata = exprData_makeLiteral (cstring_copy (text));
00689   return (e);
00690 }

exprNode exprNode_for ( exprNode inc,
exprNode body )
 

Definition at line 6411 of file exprNode.c.

06412 {
06413   exprNode ret;
06414   bool emptyErr = FALSE;
06415 
06416   if (context_maybeSet (FLG_FOREMPTY))
06417     {
06418       if (exprNode_isEmptyStatement (body))
06419         {
06420           emptyErr = optgenerror 
06421             (FLG_FOREMPTY,
06422              cstring_makeLiteral
06423              ("Body of for statement is empty"),
06424              exprNode_loc (body));
06425         }
06426     }
06427 
06428   if (!emptyErr && context_maybeSet (FLG_FORBLOCK))
06429     {
06430       if (exprNode_isDefined (body)
06431           && !exprNode_isBlock (body))
06432         {
06433           if (context_inIterDef ()
06434               && (body->kind == XPR_STMTLIST
06435                   || body->kind == XPR_TOK))
06436             {
06437               ; /* no error */
06438             }
06439           else
06440             {
06441               voptgenerror (FLG_FORBLOCK,
06442                             message
06443                             ("Body of for statement is not a block: %s",
06444                              exprNode_unparse (body)),
06445                             exprNode_loc (body));
06446             }
06447         }
06448     }
06449 
06450   /*
06451   ** for ud purposes:  (alreadly) init -> test -> (now) LOOP: body + inc + test
06452   */
06453 
06454   if (exprNode_isError (body))
06455     {
06456       ret = exprNode_createPartialCopy (inc);
06457     }
06458   else
06459     {
06460       ret = exprNode_createPartialCopy (body);
06461       
06462       ret->exitCode = exitkind_makeConditional (body->exitCode);
06463 
06464             exprNode_mergeUSs (inc, body);
06465       
06466       if (exprNode_isDefined (inc))
06467         {
06468           exprNode tmp;
06469 
06470           context_setMessageAnnote (cstring_makeLiteral ("in post loop increment"));
06471      
06472           
06473           tmp = exprNode_effect (exprData_getTripleInc (inc->edata));
06474           exprNode_freeShallow (tmp); 
06475 
06476           context_clearMessageAnnote ();
06477           context_setMessageAnnote (cstring_makeLiteral ("in post loop test"));
06478 
06479           tmp = exprNode_effect (exprData_getTripleTest (inc->edata));
06480           exprNode_freeShallow (tmp);
06481 
06482           context_clearMessageAnnote ();
06483 
06484           ret->uses = sRefSet_copy (ret->uses, inc->uses);
06485           ret->sets = sRefSet_copy (ret->sets, inc->sets);
06486           ret->msets = sRefSet_copy (ret->msets, inc->msets);
06487         }
06488     }
06489 
06490   ret->kind = XPR_FOR;
06491   ret->edata = exprData_makePair (inc, body);
06492 
06493   if (exprNode_isDefined (inc)) {
06494     exprNode test = exprData_getTripleTest (inc->edata);
06495 
06496     if (exprNode_isUndefined (test)) {
06497       if (exprNode_isDefined (body)) {
06498         if (!body->canBreak) {
06499           /* Really, it means never reached. */
06500           ret->exitCode = XK_MUSTEXIT;
06501         }
06502       }
06503     }
06504   }
06505 
06506   return (ret);
06507 }

exprNode exprNode_forPred ( exprNode init,
exprNode test,
exprNode inc )
 

Definition at line 6558 of file exprNode.c.

06560 {
06561   exprNode ret;
06562   
06563   /*
06564   ** for ud purposes:  init -> test -> LOOP: [ body, inc ]
06565   */
06566   
06567   exprNode_checkPred (cstring_makeLiteralTemp ("for"), test);
06568 
06569   if (!exprNode_isError (inc)) 
06570     {
06571       ret = exprNode_createPartialCopy (inc);
06572     }
06573   else 
06574     {
06575       if (!exprNode_isError (init)) 
06576         {
06577           ret = exprNode_createPartialCopy (init);
06578         }
06579       else if (!exprNode_isError (test)) 
06580         {
06581           ret = exprNode_createPartialCopy (test);
06582         }
06583       else 
06584         {
06585           ret = exprNode_createUnknown ();
06586         }
06587     }
06588 
06589   exprNode_mergeUSs (ret, init);
06590 
06591   if (exprNode_isDefined (init))
06592     {
06593       exprNode_checkUse (ret, init->sref, init->loc);
06594     }
06595 
06596   exprNode_mergeUSs (ret, test);
06597 
06598   if (exprNode_isDefined (test))
06599     {
06600       exprNode_checkUse (ret, test->sref, test->loc);
06601     }
06602 
06603   ret->kind = XPR_FORPRED;
06604   ret->edata = exprData_makeFor (init, test, inc); 
06605   return (ret);
06606 }

void exprNode_free ( exprNode e )
 

Definition at line 341 of file exprNode.c.

Referenced by exprNodeList_free(), exprNode_arrayFetch(), exprNode_checkFunction(), exprNode_checkIterBody(), exprNode_checkIterEnd(), exprNode_checkMacroBody(), exprNode_destroyMod(), exprNode_functionCall(), and exprNode_makeInitialization().

00342 {
00343   if (!exprNode_isError (e))
00344     {
00345       if (!inEffect)
00346         {
00347           multiVal_free (e->val);
00348           cstring_free (e->etext);
00349           fileloc_free (e->loc);
00350           sRefSet_free (e->uses);
00351           sRefSet_free (e->sets);
00352           sRefSet_free (e->msets);
00353           guardSet_free (e->guards);
00354           exprData_free (e->edata, e->kind);
00355           
00356           nowalloc--;
00357           sfree (e);
00358           /*@-branchstate@*/ 
00359         } /*@=branchstate@*/
00360     }
00361 }

void exprNode_freeShallow ( exprNode e )
 

Definition at line 297 of file exprNode.c.

Referenced by exprNodeList_freeShallow(), and exprNode_for().

00298 {
00299   if (!exprNode_isError (e))
00300     {
00301       if (shallowKind (e->kind))
00302         {
00303                 }
00304       else
00305         {
00306           if (!inEffect)
00307             {
00308               if (e->kind == XPR_EMPTY
00309                   || e->kind == XPR_BODY
00310                   || e->kind == XPR_STRINGLITERAL
00311                   || e->kind == XPR_NUMLIT
00312                   || e->kind == XPR_NODE
00313                   || e->kind == XPR_OFFSETOF
00314                   || e->kind == XPR_ALIGNOFT
00315                   || e->kind == XPR_ALIGNOF
00316                   || e->kind == XPR_SIZEOFT
00317                   || e->kind == XPR_SIZEOF)
00318                 {
00319                   /* don't free anything */
00320                 }
00321               else
00322                 {
00323                   /* multiVal_free (e->val);  */
00324                   cstring_free (e->etext);
00325                   fileloc_free (e->loc);
00326                   sRefSet_free (e->uses);
00327                   sRefSet_free (e->sets);
00328                   sRefSet_free (e->msets);
00329                   guardSet_free (e->guards);
00330                   exprData_freeShallow (e->edata, e->kind); 
00331                   nowalloc--;
00332                   /*@-compdestroy@*/ sfree (e); /*@=compdestroy@*/
00333                   /*@-branchstate@*/
00334                 }
00335             }
00336         } /*@=branchstate@*/
00337     }
00338   }

exprNode exprNode_fromIdentifier ( uentry c )
 

Definition at line 894 of file exprNode.c.

00895 {
00896   exprNode ret;
00897 
00898   if (context_justPopped ()) /* watch out! c could be dead */
00899     { 
00900       uentry ce = usymtab_lookupSafe (LastIdentifier ());
00901 
00902       if (uentry_isValid (ce)) 
00903         {
00904           c = ce;
00905         }
00906       else
00907         {
00908           llbuglit ("Looks like Aunt Millie forgot to walk to dog again.");
00909         }
00910     }
00911 
00912   ret = exprNode_fromIdentifierAux (c);
00913   
00914   return ret;
00915 }

exprNode exprNode_fromUIO ( cstring c )
 

Definition at line 754 of file exprNode.c.

00755 {
00756   fileloc loc = context_getSaveLocation ();
00757   exprNode e  = exprNode_createPlain (ctype_unknown);
00758 
00759   e->kind = XPR_VAR;
00760 
00761   if (fileloc_isUndefined (loc))
00762     {
00763       loc = fileloc_copy (g_currentloc);
00764     }
00765 
00766   e->loc = loc; /* save loc was mangled */
00767   e->sref = defref;
00768 
00769   if (usymtab_exists (c))
00770     {
00771       uentry ue = usymtab_lookupEither (c);
00772 
00773       if (uentry_isDatatype (ue) 
00774           && uentry_isSpecified (ue))
00775         {
00776           llfatalerror
00777             (message ("%q: Specified datatype %s used in code, but not defined. "
00778                       "(Cannot continue reasonably from this error.)",
00779                       fileloc_unparse (e->loc), c));
00780         }
00781       else
00782         {
00783           BADBRANCH; 
00784         }
00785     }
00786   
00787   llassertprint (!usymtab_exists (c), ("Entry exists: %s", c));
00788 
00789   /*
00790   ** was supercedeGlobalEntry...is this better?
00791   */
00792 
00793   if (!context_inIterEnd ())
00794     {
00795       if (context_inMacro ())
00796         {
00797           if (context_getFlag (FLG_UNRECOG))
00798             {
00799               voptgenerror 
00800                 (FLG_MACROUNDEF, 
00801                  message ("Unrecognized identifier in macro definition: %s", c), e->loc);
00802             }
00803           else
00804             {
00805               flagcode_recordSuppressed (FLG_UNRECOG);
00806             }
00807         }
00808       else
00809         {
00810           voptgenerror 
00811             (FLG_UNRECOG, message ("Unrecognized identifier: %s", c),
00812              e->loc);
00813         }
00814     }
00815   
00816   e->edata = exprData_makeId (uentry_makeUnrecognized (c, fileloc_copy (loc)));
00817 
00818   /* No alias errors for unrecognized identifiers */
00819   sRef_setAliasKind (e->sref, AK_ERROR, loc); 
00820 
00821   return (e);
00822 }

exprNode exprNode_functionCall ( exprNode f,
exprNodeList args )
 

Definition at line 3166 of file exprNode.c.

03167 {
03168   ctype t;
03169 
03170   setCodePoint ();
03171 
03172   if (exprNode_isUndefined (f))
03173     {
03174       exprNode_free (f);
03175       exprNodeList_free (args);
03176       return exprNode_undefined;
03177     }
03178 
03179   t = exprNode_getType (f);
03180 
03181   if (sRef_isLocalVar (f->sref))
03182     {
03183       exprNode_checkUse (f, f->sref, f->loc);
03184 
03185       if (sRef_possiblyNull (f->sref))
03186         {
03187           if (!usymtab_isGuarded (f->sref))
03188             {
03189               if (optgenerror (FLG_NULLDEREF,
03190                                message ("Function call using %s pointer %q", 
03191                                         sRef_nullMessage (f->sref),
03192                                         sRef_unparse (f->sref)),
03193                                f->loc))
03194                 {
03195                   sRef_showNullInfo (f->sref);
03196                   sRef_setNullError (f->sref);
03197                 }
03198             }
03199         }
03200     }
03201 
03202   setCodePoint ();
03203 
03204   if (ctype_isRealFunction (t))
03205     {
03206       exprNode ret = functionCallSafe (f, t, args);
03207       setCodePoint ();
03208       return ret;
03209     }
03210   else if (ctype_isUnknown (t))
03211     {
03212       exprNode ret = exprNode_createPartialCopy (f);
03213       cstring tstring;
03214 
03215       setCodePoint ();
03216       
03217       ret->typ = t;
03218       exprNodeList_elements (args, current)
03219         {
03220           if (exprNode_isDefined (current))
03221             {
03222               exprNode_checkUse (ret, current->sref, ret->loc);
03223 
03224               /* 
03225               ** also, anything derivable from current->sref may be used 
03226               */
03227 
03228               exprNode_addUse (ret, sRef_makeDerived (current->sref));
03229               exprNode_mergeUSs (ret, current);
03230             }
03231         } end_exprNodeList_elements;
03232 
03233       ret->edata = exprData_makeCall (f, args);
03234       ret->kind = XPR_CALL;
03235 
03236       tstring = cstring_copy (exprNode_unparse (f));
03237 
03238       cstring_markOwned (tstring);
03239       exprNode_checkSetAny (ret, tstring);
03240 
03241       return (ret);
03242     }
03243   else
03244     {
03245       voptgenerror (FLG_TYPE,
03246                     message ("Call to non-function (type %t): %s", t, 
03247                              exprNode_unparse (f)),
03248                     f->loc);
03249       exprNode_free (f);
03250       exprNodeList_free (args);
03251 
03252       return (exprNode_makeError ());
03253     }
03254 }

guardSet exprNode_getForGuards ( exprNode pred )
 

Definition at line 6520 of file exprNode.c.

06521 {
06522   exprNode test;
06523 
06524   if (exprNode_isError (pred)) return guardSet_undefined;
06525 
06526   llassert (pred->kind == XPR_FORPRED);
06527 
06528   test = exprData_getTripleTest (pred->edata);
06529 
06530   if (!exprNode_isError (test))
06531     {
06532       return (test->guards);
06533     }
06534 
06535   return guardSet_undefined;
06536 }

long exprNode_getLongValue ( exprNode e )
 

Definition at line 9752 of file exprNode.c.

09752                                         {
09753   long value;
09754 
09755   if (exprNode_hasValue (e) 
09756       && multiVal_isInt (exprNode_getValue (e)))
09757     {
09758       value = multiVal_forceInt (exprNode_getValue (e));
09759     }
09760   else
09761     {
09762       value = 0;
09763     }
09764   
09765   return value;
09766 }

sRef exprNode_getSref ( exprNode e )
 

Definition at line 7474 of file exprNode.c.

Referenced by checkAssignTransfer(), checkInitTransfer(), checkPassTransfer(), checkReturnTransfer(), exprNode_checkSet(), sRef_fixBaseParam(), and uentry_returnedRef().

07475 {
07476   if (exprNode_isDefined (e))
07477     {
07478       /*@access sRef@*/
07479       if (e->sref == defref) /*@noaccess sRef@*/
07480         {
07481           /*@-mods@*/
07482           e->sref = sRef_makeUnknown (); 
07483           sRef_setAliasKind (e->sref, AK_ERROR, fileloc_undefined);
07484           /*@=mods@*/
07485           return e->sref;
07486         }
07487       else
07488         {
07489           return e->sref;
07490         }
07491     }
07492   else
07493     {
07494       return sRef_undefined;
07495     }
07496 }

uentry exprNode_getUentry ( exprNode e )
 

Definition at line 3138 of file exprNode.c.

Referenced by checkPassTransfer(), exprNode_checkMacroBody(), exprNode_iterStart(), and exprNode_sizeofExpr().

03139 {
03140   if (exprNode_isError (e))
03141     {
03142       return uentry_undefined;
03143     }
03144   else
03145     {
03146       cstring s = exprNode_rootVarName (e);
03147       uentry ue = usymtab_lookupSafe (s);
03148 
03149       return ue;
03150     }
03151 }

multiVal exprNode_getValue ( exprNode e )
 

Definition at line 692 of file exprNode.c.

Referenced by exprNode_arrayFetch(), exprNode_isNullValue(), and exprNode_matchLiteral().

00693 {
00694   while (exprNode_isInParens (e)) {
00695     if (e->edata != NULL) {
00696       e = exprData_getUopNode (e->edata);
00697     } else {
00698       break;
00699     }
00700   }
00701 
00702   if (exprNode_isDefined (e)) {
00703     return e->val; 
00704   } else {
00705     return multiVal_undefined;
00706   }
00707 }

exprNode exprNode_goto ( cstring label )
 

Definition at line 6608 of file exprNode.c.

06609 {
06610   exprNode ret = exprNode_createUnknown ();
06611 
06612   if (context_inMacro ())
06613     {
06614       voptgenerror (FLG_MACROSTMT,
06615                     message ("Macro %s uses goto (not functional)", 
06616                              context_inFunctionName ()),
06617                     g_currentloc);
06618     }
06619   
06620   ret->kind = XPR_GOTO;
06621   ret->edata = exprData_makeLiteral (label);
06622   ret->mustBreak = TRUE;
06623   ret->exitCode = XK_GOTO;
06624   ret->canBreak = TRUE;
06625   return ret;
06626 }

exprNode exprNode_if ( exprNode pred,
exprNode tclause )
 

Definition at line 5708 of file exprNode.c.

05709 {
05710   exprNode ret;
05711   bool emptyErr = FALSE;
05712 
05713   if (context_maybeSet (FLG_IFEMPTY))
05714     {
05715       if (exprNode_isEmptyStatement (tclause))
05716         {
05717           emptyErr = optgenerror (FLG_IFEMPTY,
05718                                   cstring_makeLiteral
05719                                   ("Body of if statement is empty"),
05720                                   exprNode_loc (tclause));
05721         }
05722     }
05723 
05724   if (!emptyErr && context_maybeSet (FLG_IFBLOCK))
05725     {
05726       if (exprNode_isDefined (tclause)
05727           && !exprNode_isBlock (tclause))
05728         {
05729           voptgenerror (FLG_IFBLOCK,
05730                         message
05731                         ("Body of if statement is not a block: %s",
05732                          exprNode_unparse (tclause)),
05733                         exprNode_loc (tclause));
05734         }
05735     }
05736 
05737   if (exprNode_isError (pred))
05738     {
05739       if (exprNode_isError (tclause))
05740         {
05741           ret = exprNode_createLoc (ctype_unknown, g_currentloc);
05742         }
05743       else
05744         {
05745           ret = exprNode_createPartialCopy (tclause);
05746         }
05747     }
05748   else
05749     {
05750       if (exprNode_mustEscape (pred))
05751         {
05752           voptgenerror 
05753             (FLG_UNREACHABLE,
05754              message ("Predicate always exits: %s", exprNode_unparse (pred)),
05755              exprNode_loc (pred));
05756         }
05757 
05758       exprNode_checkPred (cstring_makeLiteralTemp ("if"), pred);
05759       exprNode_checkUse (pred, pred->sref, pred->loc);
05760       
05761       if (!exprNode_isError (tclause))
05762         {
05763           exprNode_mergeCondUSs (pred, tclause, exprNode_undefined);
05764         }
05765       
05766       ret = exprNode_createPartialCopy (pred);
05767     }
05768 
05769   ret->kind = XPR_IF;
05770   ret->edata = exprData_makePair (pred, tclause);
05771 
05772   ret->exitCode = XK_UNKNOWN;
05773 
05774   if (exprNode_isDefined (tclause))
05775     {
05776       ret->exitCode = exitkind_makeConditional (tclause->exitCode);
05777       ret->canBreak = tclause->canBreak;
05778       ret->sets = sRefSet_union (ret->sets, tclause->sets);
05779       ret->msets = sRefSet_union (ret->msets, tclause->msets);
05780       ret->uses = sRefSet_union (ret->uses, tclause->uses);
05781     }
05782 
05783   ret->mustBreak = FALSE;
05784 
05785   return ret;
05786 }

exprNode exprNode_ifelse ( exprNode pred,
exprNode tclause,
exprNode eclause )
 

Definition at line 5788 of file exprNode.c.

05791 {
05792   exprNode ret;
05793   bool tEmptyErr = FALSE;
05794   bool eEmptyErr = FALSE;
05795 
05796   if (context_maybeSet (FLG_IFEMPTY))
05797     {
05798       if (exprNode_isEmptyStatement (tclause))
05799         {
05800           tEmptyErr = optgenerror 
05801             (FLG_IFEMPTY,
05802              cstring_makeLiteral
05803              ("Body of if clause of if statement is empty"),
05804              exprNode_loc (tclause));
05805         }
05806 
05807       if (exprNode_isEmptyStatement (eclause))
05808         {
05809           eEmptyErr = optgenerror 
05810             (FLG_IFEMPTY,
05811              cstring_makeLiteral
05812              ("Body of else clause of if statement is empty"),
05813              exprNode_loc (eclause));
05814         }
05815     }
05816 
05817   if (context_maybeSet (FLG_IFBLOCK))
05818     {
05819       if (!tEmptyErr
05820           && exprNode_isDefined (tclause)
05821           && !exprNode_isBlock (tclause))
05822         {
05823           voptgenerror (FLG_IFBLOCK,
05824                         message
05825                         ("Body of if clause of if statement is not a block: %s",
05826                          exprNode_unparse (tclause)),
05827                         exprNode_loc (tclause));
05828         }
05829 
05830       if (!eEmptyErr
05831           && exprNode_isDefined (eclause)
05832           && !exprNode_isBlock (eclause)
05833           && !(eclause->kind == XPR_IF)
05834           && !(eclause->kind == XPR_IFELSE))
05835         {
05836           voptgenerror
05837             (FLG_IFBLOCK,
05838              message
05839              ("Body of else clause of if statement is not a block: %s",
05840               exprNode_unparse (eclause)),
05841              exprNode_loc (eclause));
05842         }
05843     }
05844 
05845   if (context_maybeSet (FLG_ELSEIFCOMPLETE))
05846     {
05847       if (exprNode_isDefined (eclause)
05848           && (eclause->kind == XPR_IF))
05849         {
05850           voptgenerror (FLG_ELSEIFCOMPLETE,
05851                         message ("Incomplete else if logic (no final else): %s",
05852                                  exprNode_unparse (eclause)),
05853                         exprNode_loc (eclause));
05854         }
05855     }
05856 
05857   if (exprNode_isError (pred))
05858     {
05859       if (exprNode_isError (tclause))
05860         {
05861           if (exprNode_isError (eclause))
05862             {
05863               ret = exprNode_createLoc (ctype_unknown, g_currentloc);
05864             }
05865           else
05866             {
05867               ret = exprNode_createPartialCopy (eclause);
05868             }
05869         }
05870       else 
05871         {
05872           ret = exprNode_createPartialCopy (tclause);
05873         }
05874     }
05875   else /* pred is okay */
05876     {
05877       ret = exprNode_createPartialCopy (pred);
05878 
05879       if (exprNode_mustEscape (pred))
05880         {
05881           voptgenerror
05882             (FLG_UNREACHABLE,
05883              message ("Predicate always exits: %s", exprNode_unparse (pred)),
05884              exprNode_loc (pred));
05885         }
05886       
05887       exprNode_checkPred (cstring_makeLiteralTemp ("if"), pred);
05888       exprNode_checkUse (ret, pred->sref, pred->loc);
05889       
05890       exprNode_mergeCondUSs (ret, tclause, eclause);
05891     }
05892 
05893   ret->kind = XPR_IFELSE;
05894   ret->edata = exprData_makeCond (pred, tclause, eclause);
05895 
05896   if (exprNode_isDefined (tclause) && exprNode_isDefined (eclause))
05897     {
05898       exprNode_combineControl (ret, tclause, eclause);
05899       ret->loc = fileloc_update (ret->loc, eclause->loc);
05900     }
05901 
05902   return ret;
05903 }

void exprNode_initMod ( void )
 

Definition at line 113 of file exprNode.c.

Referenced by main().

00117 {
00118   uentry ue;
00119   idDecl tmp;
00120   
00121   initMod = TRUE;
00122   cstringType = ctype_unknown;
00123   ctypeType = ctype_unknown;
00124   filelocType = ctype_unknown;
00125 
00126   defref = sRef_undefined;
00127   
00128   if (usymtab_existsType (cstring_makeLiteralTemp ("cstring")))
00129     {
00130       cstringType = usymtab_lookupAbstractType (cstring_makeLiteralTemp ("cstring"));
00131     }
00132  
00133   if (usymtab_existsType (cstring_makeLiteralTemp ("ctype")))
00134     {
00135       ctypeType = usymtab_lookupAbstractType (cstring_makeLiteralTemp ("ctype"));
00136     }
00137 
00138   if (usymtab_existsType (cstring_makeLiteralTemp ("fileloc")))
00139     {
00140       filelocType = usymtab_lookupAbstractType (cstring_makeLiteralTemp ("fileloc"));
00141     }
00142 
00143   if (usymtab_existsGlob (cstring_makeLiteralTemp ("stdin")))
00144     {
00145       ue = usymtab_lookupGlob (cstring_makeLiteralTemp ("stdin"));
00146     }
00147   else /* define stdin */
00148     {
00149       ue = uentry_makeVariable (cstring_makeLiteralTemp ("stdin"), 
00150                                 ctype_unknown, 
00151                                 fileloc_getBuiltin (), 
00152                                 FALSE);
00153       uentry_setHasNameError (ue); 
00154       ue = usymtab_supGlobalEntryReturn (ue);
00155     }
00156 
00157   stdinRef = sRef_makePointer (uentry_getSref (ue));
00158   
00159   if (usymtab_existsGlob (cstring_makeLiteralTemp ("stdout")))
00160     {
00161       ue = usymtab_lookupGlob (cstring_makeLiteralTemp ("stdout"));
00162     }
00163   else
00164     {
00165       ue = uentry_makeVariable (cstring_makeLiteralTemp ("stdout"), 
00166                                 ctype_unknown, 
00167                                 fileloc_getBuiltin (), 
00168                                 FALSE);
00169       uentry_setHasNameError (ue); 
00170       ue = usymtab_supGlobalEntryReturn (ue);
00171     }
00172   
00173   stdoutRef = sRef_makePointer (uentry_getSref (ue));
00174 
00175   tmp = idDecl_create (cstring_undefined, qtype_create (ctype_unknown));
00176 
00177   regArg = uentry_makeParam (tmp, PARAMUNKNOWN);
00178 
00179   idDecl_setTyp (tmp, 
00180                  qtype_addQual (qtype_create (ctype_makePointer (ctype_unknown)),
00181                                 qual_createOut ()));
00182 
00183   outArg = uentry_makeParam (tmp, PARAMUNKNOWN);
00184 
00185   idDecl_setTyp (tmp, qtype_addQual (qtype_create (ctype_string), 
00186                                      qual_createOut ()));
00187   
00188   outStringArg = uentry_makeParam (tmp, PARAMUNKNOWN);
00189   
00190   idDecl_setTyp (tmp, qtype_addQual (qtype_addQual (qtype_create (cstringType), 
00191                                                     qual_createOnly ()),
00192                                      qual_createNull ()));
00193   
00194   csOnlyArg = uentry_makeParam (tmp, PARAMUNKNOWN);
00195   
00196   idDecl_setTyp (tmp, qtype_addQual (qtype_create (cstringType), qual_createNull ()));
00197   csArg = uentry_makeParam (tmp, PARAMUNKNOWN);
00198   
00199   idDecl_free (tmp);
00200 }

bool exprNode_isAssign ( exprNode e )
 

Definition at line 5691 of file exprNode.c.

Referenced by exprNode_checkPred().

05692 {
05693   if (exprNode_isDefined (e))
05694     {
05695       return (e->kind == XPR_ASSIGN);
05696     }
05697 
05698   return FALSE;
05699 }

bool exprNode_isCaseMarker ( exprNode e )
 

Definition at line 5353 of file exprNode.c.

Referenced by exprNode_concat(), and exprNode_switch().

05354 {
05355   if (exprNode_isDefined (e))
05356     {
05357       return (e->kind == XPR_FTCASE || e->kind == XPR_CASE);
05358     }
05359 
05360   return FALSE;
05361 }

bool exprNode_isCharLit ( exprNode e )
 

Definition at line 8190 of file exprNode.c.

08191 {
08192   if (exprNode_isDefined (e))
08193     {
08194       return (multiVal_isChar (exprNode_getValue (e)));
08195     }
08196   else
08197     {
08198       return FALSE;
08199     }
08200 }

bool exprNode_isDefaultMarker ( exprNode e )
 

Definition at line 5343 of file exprNode.c.

Referenced by exprNode_concat(), and exprNode_switch().

05344 {
05345   if (exprNode_isDefined (e))
05346     {
05347       return (e->kind == XPR_DEFAULT || e->kind == XPR_FTDEFAULT);
05348     }
05349 
05350   return FALSE;
05351 }

bool exprNode_isLabelMarker ( exprNode e )
 

Definition at line 5363 of file exprNode.c.

Referenced by exprNode_concat(), and exprNode_switch().

05364 {
05365   if (exprNode_isDefined (e))
05366     {
05367       return (e->kind == XPR_LABEL);
05368     }
05369 
05370   return FALSE;
05371 }

bool exprNode_isNullValue ( exprNode e )
 

Definition at line 605 of file exprNode.c.

Referenced by exprNode_checkMacroBody(), and exprNode_cond().

00606 {
00607   if (exprNode_isDefined (e))
00608     {
00609       multiVal m = exprNode_getValue (e);
00610       
00611       if (multiVal_isInt (m))
00612         {
00613           return (multiVal_forceInt (m) == 0);
00614         }
00615     }
00616   
00617   return FALSE;
00618 }

bool exprNode_isNumLit ( exprNode e )
 

Definition at line 8203 of file exprNode.c.

08204 {
08205   if (exprNode_isDefined (e))
08206     {
08207       return (multiVal_isInt (exprNode_getValue (e)));
08208     }
08209   else
08210     {
08211       return FALSE;
08212     }
08213 }

exprNode exprNode_iter ( uentry name,
exprNodeList alist,
exprNode body,
uentry end )
 

Definition at line 7209 of file exprNode.c.

07213 {
07214   exprNode ret;
07215   cstring iname;
07216 
07217   llassert (uentry_isValid (name));
07218 
07219   uentry_setUsed (name, exprNode_loc (body));
07220 
07221   ret = exprNode_createPartialCopy (body);
07222   iname = uentry_getName (name);
07223 
07224   if (uentry_isInvalid (end))
07225     {
07226       llerror (FLG_ITER,
07227                message ("Iter %s not balanced with end_%s", iname, iname));
07228     }
07229   else
07230     {
07231       cstring ename = uentry_getName (end);
07232 
07233       if (!cstring_equalPrefix (ename, "end_"))
07234         {
07235           llerror (FLG_ITER, message ("Iter %s not balanced with end_%s: %s", 
07236                                       iname, iname, ename));
07237         }
07238       else
07239         {
07240           if (!cstring_equal (iname, cstring_suffix (ename, 4)))
07241             {
07242               llerror (FLG_ITER, 
07243                        message ("Iter %s not balanced with end_%s: %s", 
07244                                 iname, iname, ename));
07245             }
07246         }
07247 
07248       cstring_free (ename);
07249     }
07250 
07251   context_exitIterClause (body);
07252   
07253   ret->kind = XPR_ITER;
07254   ret->edata = exprData_makeIter (name, alist, body, end);
07255 
07256   if (uentry_isIter (name))
07257     {
07258       (void) checkArgsReal (name, body, 
07259                             uentry_getParams (name), alist, TRUE, ret);
07260     }
07261 
07262   cstring_free (iname);
07263 
07264   return ret;
07265 }

exprNode exprNode_iterExpr ( exprNode e )
 

Definition at line 7351 of file exprNode.c.

07352 {
07353   if (!processingIterVars ())
07354     {
07355       llcontbuglit ("checkIterParam: not in iter");
07356       return e;
07357     }
07358   
07359   if (uentry_isYield (uentryList_getN (uentry_getParams (getCurrentIter ()), 
07360                                        iterParamNo ())))
07361     {
07362       if (exprNode_isDefined (e))
07363         {
07364           if (fileloc_isDefined (e->loc))
07365             {
07366               voptgenerror
07367                 (FLG_ITER,
07368                  message ("Yield parameter is not simple identifier: %s", 
07369                           exprNode_unparse (e)),
07370                  e->loc);
07371             }
07372           else
07373             {
07374               voptgenerror
07375                 (FLG_ITER,
07376                  message ("Yield parameter is not simple identifier: %s",
07377                           exprNode_unparse (e)),
07378                  g_currentloc);
07379               
07380             }
07381         }
07382     }
07383   return e;
07384 }

exprNode exprNode_iterId ( uentry c )
 

Definition at line 7387 of file exprNode.c.

07388 {
07389   uentry ue;
07390 
07391   llassert (processingIterVars ());
07392 
07393   ue = uentryList_getN (uentry_getParams (getCurrentIter ()), 
07394                         iterParamNo ());
07395 
07396   if (uentry_isYield (ue))
07397     {
07398       ctype ct = uentry_getType (ue);
07399       exprNode e = exprNode_createPlain (ct);
07400       cstring name = uentry_getName (c);
07401       uentry le = uentry_makeVariable (name, ct, fileloc_undefined, FALSE);
07402 
07403       uentry_setUsed (ue, g_currentloc);
07404       uentry_setHasNameError (ue); 
07405       
07406       cstring_free (name);
07407       
07408       e->kind = XPR_VAR;
07409       e->edata = exprData_makeId (le);
07410       e->loc = context_getSaveLocation ();
07411       e->sref = uentry_getSref (le);
07412 
07413       usymtab_supEntrySref (le);
07414 
07415       if (!context_inHeader ())
07416         {
07417           if (optgenerror
07418               (FLG_ITER,
07419                message ("Yield parameter shadows local declaration: %q",
07420                         uentry_getName (c)),
07421                fileloc_isDefined (e->loc) ? e->loc : g_currentloc))
07422             {
07423               uentry_showWhereDeclared (c);
07424             }
07425         }
07426 
07427       return e;
07428     }
07429 
07430   return (exprNode_fromIdentifierAux (c));
07431 }

exprNode exprNode_iterNewId ( cstring s )
 

Definition at line 7268 of file exprNode.c.

07269 {
07270   exprNode e = exprNode_new ();
07271   uentry ue = uentryList_getN (uentry_getParams (getCurrentIter ()), iterParamNo ());
07272 
07273   llassert (processingIterVars ());
07274 
07275   e->loc = context_getSaveLocation ();
07276 
07277   if (fileloc_isUndefined (e->loc))
07278     {
07279       fileloc_free (e->loc);
07280       e->loc = fileloc_copy (g_currentloc);
07281     }
07282 
07283   e->uses = sRefSet_new ();
07284   e->sets = sRefSet_new ();
07285   e->msets = sRefSet_new ();
07286   e->kind = XPR_VAR;
07287   e->val = multiVal_unknown ();
07288   e->guards = guardSet_new ();
07289   e->sref = defref;
07290   e->isJumpPoint = FALSE;
07291   e->exitCode = XK_NEVERESCAPE;
07292 
07293   /*> missing fields, detected by lclint <*/
07294   e->canBreak = FALSE;
07295   e->mustBreak = FALSE;
07296   e->etext = cstring_undefined;
07297 
07298   if (uentry_isYield (ue))
07299     {
07300       uentry uue = uentry_makeVariable (s, uentry_getType (ue), 
07301                                         fileloc_copy (e->loc), 
07302                                         FALSE);
07303       sRef sr;
07304 
07305       uue = usymtab_supEntrySrefReturn (uue);
07306 
07307       sr = uentry_getSref (uue);
07308       sRef_mergeStateQuiet (sr, uentry_getSref (ue));
07309       sr = uentry_getSref (uue);
07310       sRef_setDefined (sr, e->loc);
07311 
07312       e->typ = uentry_getType (uue);      
07313       e->sref = sr;
07314       e->edata = exprData_makeId (uue);
07315       uentry_setUsed (uue, g_currentloc);
07316     }
07317   else
07318     {
07319       uentry uue;
07320 
07321       sRef_setGlobalScope ();
07322       uue = uentry_makeVariableLoc (s, ctype_unknown);
07323 
07324       e->typ = ctype_unknown;
07325       e->edata = exprData_makeId (uue);
07326 
07327       uentry_setUsed (uue, e->loc);
07328       uentry_setHasNameError (uue); 
07329 
07330       if (context_getFlag (FLG_REPEATUNRECOG))
07331         {
07332           uentry_markOwned (uue);
07333         }
07334       else
07335         {
07336           usymtab_supGlobalEntry (uue);      
07337         }
07338 
07339       sRef_clearGlobalScope ();
07340 
07341       voptgenerror (FLG_UNRECOG, message ("Unrecognized identifier: %s", s),
07342                     e->loc);
07343     }
07344 
07345 
07346   cstring_free (s);
07347   return (e);
07348 }

exprNode exprNode_iterStart ( uentry name,
exprNodeList alist )
 

Definition at line 7433 of file exprNode.c.

07434 {
07435   exprNode ret = exprNode_create (ctype_unknown);
07436 
07437   ret->kind = XPR_ITERCALL;
07438   ret->edata = exprData_makeIterCall (name, alist);
07439   
07440   if (uentry_isIter (name))
07441     {
07442       uentryList params = uentry_getParams (name);
07443 
07444       if (context_inIterDef () 
07445           && uentryList_size (params) == exprNodeList_size (alist))
07446         {
07447           int i = 0;
07448           
07449           exprNodeList_elements (alist, arg)
07450             {
07451               uentry parg = uentryList_getN (params, i);
07452 
07453               if (uentry_isYield (parg))
07454                 {
07455                   uentry ue = exprNode_getUentry (arg);
07456 
07457                   if (uentry_isValid (ue))
07458                     {
07459                       ;
07460                     }
07461                 }
07462 
07463               i++;
07464             } end_exprNodeList_elements;
07465         }
07466 
07467       (void) checkArgsReal (name, ret, params, alist, TRUE, ret);
07468       checkUnspecCall (ret, params, alist);
07469     }
07470 
07471   return ret;
07472 }

exprNode exprNode_labelMarker ( cstring label )
 

Definition at line 5320 of file exprNode.c.

05321 {
05322   exprNode ret = exprNode_createPlain (ctype_undefined);
05323   ret->kind = XPR_LABEL;
05324   ret->edata = exprData_makeLiteral (label);
05325   ret->isJumpPoint = TRUE;
05326 
05327   return (ret); /* for now, ignore label */
05328 }

fileloc exprNode_loc ( exprNode e )
 

Definition at line 7555 of file exprNode.c.

Referenced by checkAssignTransfer(), checkInitTransfer(), checkPassTransfer(), checkReturnTransfer(), checkValueConstant(), exprNode_break(), exprNode_checkMSet(), exprNode_checkSet(), exprNode_comma(), exprNode_concat(), exprNode_continue(), exprNode_for(), exprNode_if(), exprNode_ifelse(), exprNode_makeInitialization(), exprNode_while(), uentry_checkMatchParam(), uentry_makeEnumInitializedConstant(), and usymtab_popBranches().

07556 {
07557   if (exprNode_isError (e))
07558     {
07559       return (g_currentloc);
07560     }
07561   else
07562     {
07563       return (e->loc);
07564     }
07565 }

exprNode exprNode_makeBlock ( exprNode e )
 

Definition at line 5669 of file exprNode.c.

05670 {
05671   exprNode ret = exprNode_createPartialCopy (e);
05672 
05673   if (!exprNode_isError (e))
05674     {
05675       ret->exitCode = e->exitCode;
05676       ret->canBreak = e->canBreak;
05677       ret->mustBreak = e->mustBreak;
05678     }
05679   
05680   ret->edata = exprData_makeSingle (e);
05681   ret->kind = XPR_BLOCK;
05682   return ret;
05683 }

exprNode exprNode_makeError ( )
 

Definition at line 364 of file exprNode.c.

Referenced by exprNode_arrayFetch(), and exprNode_functionCall().

00365 {
00366   return exprNode_undefined;
00367 }

exprNode exprNode_makeInitBlock ( lltok brace,
exprNodeList inits )
 

Definition at line 3154 of file exprNode.c.

03155 {
03156   exprNode ret = exprNode_createPlain (ctype_unknown);
03157 
03158   ret->kind = XPR_INITBLOCK;
03159   ret->edata = exprData_makeCall (exprNode_undefined, inits);
03160   ret->loc = fileloc_update (ret->loc, lltok_getLoc (brace));
03161 
03162   return (ret);
03163 }

exprNode exprNode_makeInitialization ( idDecl t,
exprNode e )
 

Definition at line 7083 of file exprNode.c.

07085 {
07086   uentry ue = usymtab_lookup (idDecl_observeId (t));
07087   bool isUsed = uentry_isUsed (ue);
07088   exprNode ret = exprNode_fromIdentifierAux (ue);
07089   ctype ct = ctype_realishType (ret->typ);
07090   fileloc loc;
07091   
07092   if (ctype_isUnknown (ct)) 
07093     {
07094       voptgenerror (FLG_IMPTYPE,
07095                     message ("Variable has unknown (implicitly int) type: %s",
07096                              idDecl_getName (t)),
07097                     exprNode_isDefined (e) ? exprNode_loc (e) : g_currentloc);
07098       
07099       ct = ctype_int;
07100     }
07101 
07102   if (exprNode_isError (e)) 
07103     {
07104       e = exprNode_createUnknown ();
07105       loc = g_currentloc;
07106 
07107       /* error: assume initializer is defined */
07108       sRef_setDefined (ret->sref, loc);
07109     }
07110   else
07111     {
07112       loc = exprNode_loc (e);
07113       
07114       /*
07115       ** evs - 9 Apr 1995
07116       **
07117       ** was addSafeUse --- what's the problem?
07118       **
07119       **   int x = 3, y = x ?
07120       */
07121 
07122       exprNode_checkUse (ret, e->sref, e->loc);
07123       
07124       if (ctype_isUnknown (e->typ) && uentry_isValid (ue))
07125         {
07126           exprNode lhs = exprNode_createId (ue);
07127 
07128           /*
07129           ** static storage should be undefined before initializing
07130           */
07131 
07132           if (uentry_isStatic (ue))
07133             {
07134               sRef_setDefState (lhs->sref, SS_PARTIAL, fileloc_undefined);
07135             }
07136 
07137           (void) exprNode_checkOneInit (lhs, e);
07138 
07139           if (uentry_isStatic (ue))
07140             {
07141               sRef_setDefState (lhs->sref, SS_DEFINED, fileloc_undefined);
07142             }
07143 
07144           exprNode_free (lhs);
07145         }
07146       else
07147         {
07148           if (!exprNode_matchType (ct, e))
07149             {
07150               if (exprNode_isZero (e) && ctype_isArrayPtr (ct)) 
07151                 {
07152                   ;
07153                 }
07154               else
07155                 {
07156                   (void) gentypeerror 
07157                     (exprNode_getType (e), e, exprNode_getType (ret), ret,
07158                      message 
07159                      ("Variable %s initialized to type %t, expects %t: %s",
07160                       exprNode_unparse (ret), exprNode_getType (e), 
07161                       exprNode_getType (ret),
07162                       exprNode_unparse (e)),
07163                      e->loc);
07164                 }
07165             }
07166         }
07167       
07168       if (uentry_isStatic (ue))
07169         {
07170           sRef_setDefState (ret->sref, SS_PARTIAL, fileloc_undefined);
07171         }
07172 
07173       doAssign (ret, e, TRUE);
07174 
07175       if (uentry_isStatic (ue))
07176         {
07177           sRef_setDefState (ret->sref, SS_DEFINED, fileloc_undefined);
07178         }
07179     }
07180 
07181   if (context_inIterDef ())
07182     {
07183       /* should check if it is yield */
07184       uentry_setUsed (ue, loc);
07185     }
07186   else
07187     {
07188       if (!isUsed) /* could be @unused@-qualified variable */
07189         {
07190           uentry_setNotUsed (ue);  
07191         }
07192     }
07193 
07194   ret->exitCode = XK_NEVERESCAPE;
07195   ret->mustBreak = FALSE;
07196 
07197   /*
07198   ** Must be before new kind is assigned!
07199   */
07200 
07201   exprData_free (ret->edata, ret->kind); 
07202 
07203   ret->kind = XPR_INIT;
07204   ret->edata = exprData_makeInit (t, e);
07205   exprNode_mergeUSs (ret, e);
07206   return ret;
07207 }

exprNode exprNode_makeMustExit ( void )
 

Definition at line 413 of file exprNode.c.

00414 {
00415   if (exprNode_isUndefined (mustExitNode))
00416     {
00417       mustExitNode = exprNode_createPlain (ctype_unknown);
00418       mustExitNode->exitCode = XK_MUSTEXIT;
00419     }
00420 
00421   return mustExitNode;
00422 }

bool exprNode_matchLiteral ( ctype expected,
exprNode e )
 

Definition at line 8232 of file exprNode.c.

Referenced by exprNode_assign(), and exprNode_matchType().

08233 {
08234   if (exprNode_isDefined (e))
08235     {
08236       multiVal m = exprNode_getValue (e);
08237       
08238       if (multiVal_isDefined (m))
08239         {
08240           if (multiVal_isInt (m))
08241             {
08242               long int val = multiVal_forceInt (m);
08243               
08244               if (ctype_isDirectBool (ctype_realishType (expected)))
08245                 {
08246                   if (val == 0) 
08247                     {
08248                       return FALSE; /* really?! return TRUE; allow use of 0 for FALSE */
08249                     }
08250                   else 
08251                     {
08252                       return FALSE;
08253                     }
08254                 }
08255               
08256               if (ctype_isRealInt (expected))
08257                 {
08258                   /*
08259                   ** unsigned <- [ constant >= 0 is okay ]
08260                   */
08261                   
08262                   if (ctype_isUnsigned (expected))
08263                     {
08264                       if (val < 0)
08265                         {
08266                           return FALSE;
08267                         }
08268                     }
08269                   
08270                   /*
08271                   ** No checks on sizes of integers...maybe add
08272                   ** these later.
08273                   */
08274 
08275                   DPRINTF (("Here: %s => %s", exprNode_unparse (e), ctype_unparse (expected)));
08276                   DPRINTF (("Type: %s / %s", ctype_unparse (exprNode_getType (e)),
08277                             bool_unparse (ctype_isInt (exprNode_getType (e)))));
08278 
08279                   if (context_getFlag (FLG_NUMLITERAL) 
08280                       && (ctype_isRegularInt (exprNode_getType (e)) || val == 0)) {
08281                     return TRUE;
08282                   } else {
08283                     if (val == 0) {
08284                       return TRUE;
08285                     } else {
08286                       return FALSE; /* evs 2000-05-17: previously, always returned TRUE */
08287                     }
08288                   }
08289                 }
08290               else if (ctype_isChar (expected))
08291                 {
08292                   return FALSE;
08293                 }
08294               else if (ctype_isArrayPtr (expected))
08295                 {
08296                   return (val == 0);
08297                 }
08298               else if (ctype_isAnyFloat (expected))
08299                 {
08300                   return (context_getFlag (FLG_NUMLITERAL));
08301                 }
08302               else
08303                 {
08304                   return FALSE;
08305                 }
08306             }
08307           else if (multiVal_isDouble (m))
08308             {
08309               if (ctype_isAnyFloat (expected))
08310                 {
08311                   return TRUE;
08312                 }
08313             }
08314           else if (multiVal_isChar (m))
08315             {
08316               char val = multiVal_forceChar (m);          
08317               
08318               if (ctype_isChar (expected))
08319                 {
08320                   if (ctype_isUnsigned (expected) && ((int)val) < 0)
08321                     {
08322                       return FALSE;
08323                     }
08324                   else
08325                     {
08326                       return TRUE;
08327                     }
08328                 }
08329             }
08330           else
08331             {
08332               return FALSE;
08333             }
08334         }
08335     }
08336   
08337   return FALSE;
08338 }

bool exprNode_matchType ( ctype expected,
exprNode e )
 

Definition at line 8341 of file exprNode.c.

Referenced by checkValueConstant(), exprNode_checkMacroBody(), and exprNode_makeInitialization().

08342 {
08343   ctype actual;
08344   
08345   if (!exprNode_isDefined (e)) return TRUE;
08346 
08347   actual = ctype_realishType (exprNode_getType (e));
08348 
08349   if (ctype_match (ctype_realishType (expected), actual))
08350     {
08351       return TRUE;
08352     }
08353 
08354   llassert (!exprNode_isError (e));
08355   return (exprNode_matchLiteral (expected, e));
08356 }

bool exprNode_mayEscape ( exprNode e )
 

Definition at line 5447 of file exprNode.c.

Referenced by exprNode_checkStatement().

05448 {
05449   if (exprNode_isDefined (e))
05450     {
05451       return exitkind_couldEscape (e->exitCode);
05452     }
05453   return FALSE;
05454 }

bool exprNode_mustEscape ( exprNode e )
 

Definition at line 5467 of file exprNode.c.

Referenced by exprNode_checkFunctionBody(), exprNode_comma(), exprNode_concat(), exprNode_if(), exprNode_ifelse(), exprNode_while(), usymtab_exitScope(), usymtab_popBranches(), and usymtab_popOrBranch().

05468 {
05469   if (exprNode_isDefined (e))
05470     {
05471       return exitkind_mustEscape (e->exitCode) || exprNode_mustBreak (e);
05472     }
05473 
05474   return FALSE;
05475 }

exprNode exprNode_notReached ( exprNode stmt )
 

Definition at line 5330 of file exprNode.c.

05331 {
05332   if (exprNode_isDefined (stmt))
05333     {
05334       stmt->isJumpPoint = TRUE;
05335 
05336       /* This prevent stray no return path errors, etc. */
05337       stmt->exitCode = XK_MUSTEXIT;
05338     }
05339 
05340   return (stmt); 
05341 }

exprNode exprNode_nullReturn ( lltok t )
 

Definition at line 6797 of file exprNode.c.

06798 {
06799   fileloc loc = lltok_getLoc (t);
06800   exprNode ret = exprNode_createLoc (ctype_unknown, fileloc_copy (loc));
06801   
06802   context_returnFunction ();
06803   exprChecks_checkNullReturn (loc);
06804 
06805   ret->kind = XPR_NULLRETURN;
06806   ret->edata = exprData_makeTok (t);
06807   ret->exitCode = XK_MUSTRETURN;
06808   return ret;
06809 }

exprNode exprNode_numLiteral ( ctype c,
cstring t,
fileloc loc,
long val )
 

Definition at line 643 of file exprNode.c.

00645 {
00646   exprNode e = exprNode_createLoc (c, loc);
00647 
00648   e->kind = XPR_NUMLIT;
00649   
00650   llassert (multiVal_isUndefined (e->val));
00651   e->val = multiVal_makeInt (val);
00652   e->edata = exprData_makeLiteral (cstring_copy (t));
00653 
00654   if (val == 0)
00655     {
00656       e->sref = sRef_makeUnknown ();
00657       sRef_setDefNull (e->sref, e->loc);
00658     }
00659 
00660   DPRINTF (("Num lit: %s / %s", exprNode_unparse (e), ctype_unparse (exprNode_getType (e))));
00661   return (e);
00662 }

exprNode exprNode_offsetof ( qtype qt,
cstringList s )
 

Definition at line 3922 of file exprNode.c.

03923 {
03924   exprNode ret = exprNode_create (sizeof_resultType ());
03925   ctype ct = qtype_getType (qt);
03926 
03927   ret->kind = XPR_OFFSETOF;
03928   ret->edata = exprData_makeOffsetof (qt, s);
03929 
03930   if (!ctype_isRealSU (ct))
03931     {
03932       voptgenerror (FLG_TYPE,
03933                     message ("First parameter to offsetof is not a "
03934                              "struct or union type (type %s): %s",
03935                              ctype_unparse (ct),
03936                              exprNode_unparse (ret)),
03937                     ret->loc);
03938     }
03939   else
03940     {
03941       ctype lt = ct;
03942 
03943       cstringList_elements (s, el) {
03944         uentryList fields;
03945         uentry fld;
03946 
03947         if (ctype_isUndefined (lt))
03948           {
03949             break;
03950           } 
03951         else if (!ctype_isRealSU (lt))
03952           {
03953             voptgenerror (FLG_TYPE,
03954                           message ("Inner offsetof type is not a "
03955                                    "struct or union type (type %s before field %s): %s",
03956                                    ctype_unparse (lt), el,
03957                                    exprNode_unparse (ret)),
03958                           ret->loc);
03959             break;
03960           }
03961         else 
03962           {
03963             fields = ctype_getFields (ctype_realType (lt));
03964             fld = uentryList_lookupField (fields, el);
03965             DPRINTF (("Try: %s / %s", ctype_unparse (lt), el));
03966             
03967             if (uentry_isUndefined (fld))
03968               {
03969                 if (ctype_equal (lt, ct)) {
03970                   voptgenerror (FLG_TYPE,
03971                                 message ("Field %s in offsetof is not the "
03972                                          "name of a field of %s: %s",
03973                                          el,
03974                                          ctype_unparse (ct),
03975                                          exprNode_unparse (ret)),
03976                                 ret->loc);
03977                 } else {
03978                   voptgenerror (FLG_TYPE,
03979                                 message ("Deep field %s in offsetof is not the "
03980                                          "name of a field of %s: %s",
03981                                          el,
03982                                          ctype_unparse (lt),
03983                                          exprNode_unparse (ret)),
03984                                 ret->loc);
03985                 }
03986               }
03987             else 
03988               {
03989                 lt = uentry_getType (fld);
03990               }
03991           }
03992       } end_cstringList_elements;
03993 
03994       /* Should report error if its a bit field - behavior is undefined! */
03995     }
03996   
03997   return (ret);
03998 }

exprNode exprNode_op ( exprNode e1,
exprNode e2,
lltok op )
 

Definition at line 4878 of file exprNode.c.

04880 {
04881   exprNode ret;
04882 
04883   checkMacroParen (e1);
04884   checkMacroParen (e2);
04885 
04886   if (evaluationOrderUndefined (op) && context_maybeSet (FLG_EVALORDER))
04887     {
04888       checkExpressionDefined (e1, e2, op);
04889     }
04890 
04891   ret = exprNode_makeOp (e1, e2, op);
04892   return (ret);
04893 }

exprNode exprNode_postOp ( exprNode e,
lltok op )
 

Definition at line 3541 of file exprNode.c.

03542 {
03543   /* check modification also */
03544   /* cstring opname = lltok_unparse (op);*/
03545   ctype t;
03546   exprNode ret = exprNode_createPartialCopy (e);
03547 
03548   ret->loc = fileloc_update (ret->loc, lltok_getLoc (op));
03549   ret->kind = XPR_POSTOP;
03550   ret->edata = exprData_makeUop (e, op);
03551 
03552   if (!exprNode_isDefined (e))
03553     {
03554       return ret;
03555     }
03556 
03557   checkMacroParen (e);
03558 
03559   exprNode_checkUse (ret, e->sref, e->loc);
03560   exprNode_checkSet (ret, e->sref);
03561 
03562   t = exprNode_getType (e);
03563 
03564   if (sRef_isUnsafe (e->sref))
03565     {
03566       voptgenerror (FLG_MACROPARAMS,
03567                     message ("Operand of %s is macro parameter (non-functional): %s%s", 
03568                              lltok_unparse (op), exprNode_unparse (e), lltok_unparse (op)),
03569                     e->loc);
03570       sRef_makeSafe (e->sref);
03571       sRef_makeSafe (ret->sref);
03572     }
03573 
03574   if (ctype_isForceRealNumeric (&t) || ctype_isRealAP (t))
03575     {
03576       ret->typ = e->typ;
03577     }
03578   else
03579     {
03580       if (ctype_isRealAbstract (t))
03581         {
03582           voptgenerror 
03583             (FLG_ABSTRACT,
03584              message ("Operand of %s is abstract type (%t): %s",
03585                       lltok_unparse (op), t, exprNode_unparse (e)),
03586              e->loc);
03587         }
03588       else
03589         {
03590           voptgenerror 
03591             (FLG_TYPE,
03592              message ("Operand of %s is non-numeric (%t): %s",
03593                       lltok_unparse (op), t, exprNode_unparse (e)),
03594              e->loc);
03595         }
03596       ret->typ = ctype_unknown;
03597     }
03598 
03599   /* if (ctype_isZero (t)) e->typ = ctype_int; */
03600 
03601   exprNode_checkModify (e, ret);
03602 
03603   return ret;
03604 }

exprNode exprNode_preOp ( exprNode e,
lltok op )
 

Definition at line 3607 of file exprNode.c.

03608 {
03609   bool checkMod = FALSE;
03610   ctype te, tr;
03611   int opid = lltok_getTok (op);
03612   exprNode ret = exprNode_createSemiCopy (e);
03613 
03614   exprNode_copySets (ret, e);
03615 
03616   multiVal_free (ret->val);
03617   ret->val = multiVal_undefined;
03618   ret->loc = fileloc_update (ret->loc, lltok_getLoc (op));
03619   ret->kind = XPR_PREOP;  
03620   ret->edata = exprData_makeUop (e, op);
03621   
03622   if (exprNode_isError (e))
03623     {
03624       return ret;
03625     }
03626   
03627   checkMacroParen (e);
03628   
03629   te = exprNode_getType (e);
03630   tr = ctype_realType (te);
03631   
03632   if (opid != TAMPERSAND)
03633     {
03634       exprNode_checkUse (ret, e->sref, e->loc);
03635       
03636       if (ctype_isRealAbstract (tr)
03637           && (!(ctype_isRealBool (te) && (opid == TEXCL))))
03638         {
03639           if (optgenerror (FLG_ABSTRACT,
03640                            message ("Operand of %s is abstract type (%t): %s",
03641                                     lltok_unparse (op), tr,
03642                                     exprNode_unparse (ret)),
03643                            e->loc))
03644             {
03645               tr = te = ctype_unknown;
03646               ret->typ = ctype_unknown;
03647               sRef_setNullError (e->sref);
03648             }
03649         }
03650     }
03651   
03652   switch (opid)
03653     {
03654     case INC_OP:
03655     case DEC_OP:                /* should also check modification! */
03656       if (sRef_isMacroParamRef (e->sref))
03657         {
03658           voptgenerror 
03659             (FLG_MACROPARAMS,
03660              message ("Operand of %s is macro parameter (non-functional): %s", 
03661                       lltok_unparse (op), exprNode_unparse (ret)),
03662              e->loc);
03663         }
03664       else
03665         {
03666           exprNode_checkSet (ret, e->sref);
03667         }
03668       
03669       if (ctype_isForceRealNumeric (&tr) || ctype_isRealAP (tr))
03670         {
03671         }
03672       else
03673         {
03674           if (context_msgStrictOps ())
03675             {
03676               voptgenerror 
03677                 (FLG_STRICTOPS,
03678                  message ("Operand of %s is non-numeric (%t): %s",
03679                           lltok_unparse (op), te, exprNode_unparse (ret)),
03680                  e->loc);
03681             }
03682           ret->typ = ctype_int;
03683         }
03684       
03685       checkMod = TRUE;
03686       break;
03687       
03688     case TMINUS:
03689     case TPLUS:
03690       if (ctype_isForceRealNumeric (&tr))
03691         {
03692           if (opid == TMINUS)
03693             {
03694               ret->val = multiVal_invert (exprNode_getValue (e));
03695             }
03696           else
03697             {
03698               ret->val = multiVal_copy (exprNode_getValue (e));
03699             }
03700         }
03701       else
03702         {
03703           if (context_msgStrictOps ())
03704             {
03705               voptgenerror 
03706                 (FLG_STRICTOPS,
03707                  message ("Operand of %s is non-numeric (%t): %s",
03708                           lltok_unparse (op), te, exprNode_unparse (ret)),
03709                  e->loc);
03710             }
03711 
03712           ret->typ = ctype_int;
03713         }
03714       break;
03715       
03716     case TEXCL:         /* maybe this should be restricted */
03717       guardSet_flip (ret->guards);      
03718 
03719       if (ctype_isRealBool (te))
03720         {
03721          ;
03722         }
03723       else
03724         {
03725           if (ctype_isRealPointer (tr))
03726             {
03727               if (sRef_isKnown (e->sref))
03728                 {
03729                   ret->guards = guardSet_addFalseGuard (ret->guards, e->sref);
03730                 }
03731 
03732               voptgenerror2n
03733                 (FLG_BOOLOPS, FLG_PTRNEGATE,
03734                  message ("Operand of %s is non-boolean (%t): %s",
03735                           lltok_unparse (op), te, exprNode_unparse (ret)),
03736                  e->loc);
03737             }
03738           else
03739             {
03740               voptgenerror
03741                 (FLG_BOOLOPS,
03742                  message ("Operand of %s is non-boolean (%t): %s",
03743                           lltok_unparse (op), te, exprNode_unparse (ret)),
03744                  e->loc);
03745             }
03746           
03747           ret->typ = ctype_bool;
03748         }
03749       break;
03750       
03751     case TTILDE:
03752       if (ctype_isForceRealInt (&tr))
03753         {
03754         }
03755       else
03756         {
03757           if (context_msgStrictOps ())
03758             {
03759               voptgenerror 
03760                 (FLG_STRICTOPS,
03761                  message ("Operand of %s is non-integer (%t): %s",
03762                           lltok_unparse (op), te, exprNode_unparse (ret)), 
03763                  e->loc);
03764             }
03765 
03766           if (ctype_isInt (e->typ))
03767             {
03768               ret->typ = e->typ;
03769             }
03770           else
03771             {
03772               ret->typ = ctype_int;
03773             }
03774         }       
03775       break;
03776       
03777     case TAMPERSAND:
03778       ret->typ = ctype_makePointer (e->typ);
03779 
03780       if (sRef_isKnown (e->sref))
03781         {
03782           ret->sref = sRef_makeAddress (e->sref);
03783         }
03784       
03785       break;
03786       
03787     case TMULT:
03788       
03789       if (ctype_isAP (tr))
03790         {
03791           ret->typ = ctype_baseArrayPtr (e->typ);
03792         }
03793       else
03794         {
03795           if (ctype_isKnown (te))
03796             {
03797               if (ctype_isFunction (te))
03798                 {
03799                   ret->typ = e->typ;
03800 
03801                   voptgenerror
03802                     (FLG_FCNDEREF,
03803                      message ("Dereference of function type (%t): %s",
03804                               te, exprNode_unparse (ret)),
03805                      e->loc);
03806                 }
03807               else
03808                 {
03809                   voptgenerror (FLG_TYPE,
03810                                 message ("Dereference of non-pointer (%t): %s",
03811                                          te, exprNode_unparse (ret)),
03812                                 e->loc);
03813                   ret->typ = ctype_unknown;
03814                 }
03815             }
03816           else
03817             {
03818               ret->typ = ctype_unknown;
03819             }
03820           
03821         }
03822       
03823       if (sRef_isKnown (e->sref))
03824         {
03825           if (sRef_possiblyNull (e->sref))
03826             {
03827               if (!usymtab_isGuarded (e->sref) && !context_inProtectVars ())
03828                 {
03829                   if (optgenerror 
03830                       (FLG_NULLDEREF,
03831                        message ("Dereference of %s pointer %q: %s", 
03832                                 sRef_nullMessage (e->sref),
03833                                 sRef_unparse (e->sref),
03834                                 exprNode_unparse (ret)),
03835                        e->loc))
03836                     {
03837                       sRef_showNullInfo (e->sref);
03838                       sRef_setNotNull (e->sref, e->loc); /* suppress future messages */
03839                     }
03840                 }
03841             }
03842           
03843           ret->sref = sRef_makePointer (e->sref);
03844         }
03845       break;
03846       
03847     default:
03848       llbug (message ("exprNode_preOp: unhandled op: %s", lltok_unparse (op)));
03849     }
03850 
03851   if (checkMod)
03852     {
03853       exprNode_checkModify (e, ret);
03854     }
03855 
03856   return ret;
03857 }

void exprNode_produceGuards ( exprNode pred )
 

Definition at line 5655 of file exprNode.c.

Referenced by exprNode_whilePred().

05656 {
05657   if (!exprNode_isError (pred))
05658     {
05659       if (ctype_isRealPointer (pred->typ))
05660         {
05661           pred->guards = guardSet_addTrueGuard (pred->guards, pred->sref);
05662         }
05663       
05664       exprNode_checkUse (pred, pred->sref, pred->loc);
05665       exprNode_resetSref (pred);
05666     }
05667 }

exprNode exprNode_return ( exprNode e )
 

Definition at line 6811 of file exprNode.c.

06812 {
06813   exprNode ret;
06814   
06815   if (exprNode_isError (e))
06816     {
06817       ret = exprNode_createUnknown ();
06818     }
06819   else
06820     {
06821       ret = exprNode_createLoc (ctype_unknown, fileloc_copy (e->loc));
06822 
06823       exprNode_checkUse (ret, e->sref, e->loc);
06824       exprNode_checkReturn (e);
06825     }
06826 
06827   context_returnFunction ();
06828   ret->kind = XPR_RETURN;
06829   ret->edata = exprData_makeSingle (e);
06830   ret->exitCode = XK_MUSTRETURN;
06831 
06832   return (ret);
06833 }

exprNode exprNode_sizeofExpr ( exprNode e )
 

Definition at line 4001 of file exprNode.c.

04002 {
04003   exprNode ret;
04004 
04005   if (exprNode_isUndefined (e))
04006     {
04007       ret = exprNode_createLoc (ctype_unknown, fileloc_copy (g_currentloc));
04008       ret->edata = exprData_makeSingle (e);
04009       ret->typ = sizeof_resultType ();
04010       ret->kind = XPR_SIZEOF;
04011     }
04012   else
04013     {
04014       uentry u = exprNode_getUentry (e);
04015 
04016       ret = exprNode_createPartialCopy (e);
04017       ret->edata = exprData_makeSingle (e);
04018 
04019       ret->typ = sizeof_resultType ();
04020       ret->kind = XPR_SIZEOF;
04021 
04022       if (uentry_isValid (u) 
04023           && uentry_isRefParam (u)
04024           && ctype_isRealArray (uentry_getType (u)))
04025         {
04026           voptgenerror
04027             (FLG_SIZEOFFORMALARRAY,
04028              message ("Parameter to sizeof is an array-type function parameter: %s",
04029                       exprNode_unparse (ret)),
04030              ret->loc);
04031         }
04032     }
04033 
04034   /*
04035   ** sizeof (x) doesn't "really" use x
04036   */
04037 
04038   return (ret);
04039 }

exprNode exprNode_sizeofType ( qtype qt )
 

Definition at line 3887 of file exprNode.c.

03888 {
03889   exprNode ret = exprNode_create (sizeof_resultType ());
03890   ctype ct = qtype_getType (qt);
03891 
03892   ret->kind = XPR_SIZEOFT;
03893   ret->edata = exprData_makeSizeofType (qt);
03894 
03895   voptgenerror (FLG_SIZEOFTYPE,
03896                 message ("Parameter to sizeof is type %s: %s",
03897                          ctype_unparse (ct),
03898                          exprNode_unparse (ret)),
03899                 ret->loc);
03900   
03901   return (ret);
03902 }

exprNode exprNode_statement ( exprNode e )
 

Definition at line 5610 of file exprNode.c.

05611 {
05612   if (!exprNode_isError (e))
05613     {
05614       exprNode_checkStatement(e);
05615     }
05616 
05617   return (exprNode_statementError (e));
05618 }

exprNode exprNode_stringLiteral ( cstring t,
fileloc loc )
 

Definition at line 710 of file exprNode.c.

00711 {
00712   exprNode e = exprNode_createLoc (ctype_string, loc);
00713   int len = cstring_length (t) - 2;
00714   char *ts = cstring_toCharsSafe (t);
00715   char *s = cstring_toCharsSafe (cstring_create (len + 1));
00716 
00717   if (context_getFlag (FLG_STRINGLITERALLEN))
00718     {
00719       if (len > context_getValue (FLG_STRINGLITERALLEN))
00720         {
00721           voptgenerror (FLG_STRINGLITERALLEN,
00722                         message
00723                         ("String literal length (%d) exceeds maximum "
00724                          "length (%d): %s",
00725                          len,
00726                          context_getValue (FLG_STRINGLITERALLEN),
00727                          t),
00728                         e->loc);
00729         }
00730     }
00731 
00732   strncpy (s, ts+1, size_fromInt (len));
00733   *(s + len) = '\0';
00734 
00735   
00736   e->kind = XPR_STRINGLITERAL;
00737   e->val = multiVal_makeString (cstring_fromCharsO (s));
00738   e->edata = exprData_makeLiteral (t);
00739   e->sref = sRef_makeType (ctype_string);
00740 
00741   if (context_getFlag (FLG_READONLYSTRINGS))
00742     {
00743       sRef_setAliasKind (e->sref, AK_STATIC, fileloc_undefined);
00744       sRef_setExKind (e->sref, XO_OBSERVER, loc);
00745     }
00746   else
00747     {
00748       sRef_setAliasKind (e->sref, AK_ERROR, fileloc_undefined);
00749     }
00750 
00751   return (e); /* s released */
00752 }

exprNode exprNode_switch ( exprNode e,
exprNode s )
 

Definition at line 6064 of file exprNode.c.

06065 {
06066   exprNode ret = exprNode_createPartialCopy (e);
06067   bool allpaths;
06068 
06069   DPRINTF (("Switch: %s", exprNode_unparse (s)));
06070 
06071   ret->kind = XPR_SWITCH;
06072   ret->edata = exprData_makePair (e, s);
06073   
06074   if (!exprNode_isError (s))
06075     {
06076       exprNode fs = exprNode_firstStatement (s);
06077       ret->loc = fileloc_update (ret->loc, s->loc);
06078 
06079       if (exprNode_isUndefined (fs) 
06080           || exprNode_isCaseMarker (fs) || exprNode_isLabelMarker (fs)
06081           || exprNode_isDefaultMarker (fs)) {
06082         ;
06083       } else {
06084         voptgenerror (FLG_FIRSTCASE,
06085                       message
06086                       ("Statement after switch is not a case: %s", exprNode_unparse (fs)),
06087                       fs->loc);
06088       }
06089     }
06090 
06091   if (!exprNode_isError (e)) 
06092     {
06093       if (checkSwitchExpr (e, s, &allpaths))
06094         {
06095           ret->exitCode = XK_MUSTRETURN;
06096         }
06097       else
06098         {
06099           ret->exitCode = e->exitCode;
06100         }
06101 
06102       ret->canBreak = e->canBreak;
06103       ret->mustBreak = e->mustBreak;
06104     }
06105   /*
06106   ** forgot this!
06107   **   exprNode.c:3883,32: Variable allpaths used before definition
06108   */
06109   else 
06110     {
06111       allpaths = FALSE;
06112     }
06113   
06114   DPRINTF (("Context exit switch!"));
06115   context_exitSwitch (ret, allpaths);
06116   DPRINTF (("Context exit switch done!"));
06117 
06118   return ret;
06119 }

cstring exprNode_unparse ( exprNode e )
 

Definition at line 7532 of file exprNode.c.

Referenced by checkAssignTransfer(), checkPassTransfer(), checkReturnTransfer(), checkValueConstant(), exprNode_alignofType(), exprNode_arrayFetch(), exprNode_arrowAccess(), exprNode_assign(), exprNode_cast(), exprNode_checkMacroBody(), exprNode_checkPred(), exprNode_cond(), exprNode_fieldAccess(), exprNode_ifelse(), exprNode_makeInitialization(), exprNode_offsetof(), exprNode_postOp(), exprNode_preOp(), exprNode_sizeofType(), uentry_checkMatchParam(), and uentry_makeEnumInitializedConstant().

07533 {
07534   if (exprNode_isError (e))
07535     {
07536       return cstring_makeLiteralTemp ("<error>");
07537     }
07538 
07539   if (cstring_isDefined (e->etext))
07540     {
07541       return e->etext;
07542     }
07543   else
07544     {
07545       cstring ret = exprNode_doUnparse (e);
07546 
07547       /*@-modifies@*/ /* benevolent */
07548       e->etext = ret; 
07549       /*@=modifies@*/
07550       return ret;
07551     }
07552 }

cstring exprNode_unparseFirst ( exprNode e )
 

Definition at line 7499 of file exprNode.c.

Referenced by exprNode_checkStatement().

07500 {
07501   if (exprNode_isDefined (e))
07502     {
07503       cstring ret;
07504 
07505       if (e->kind == XPR_STMTLIST
07506           || e->kind == XPR_COMMA || e->kind == XPR_COND)
07507         {
07508           exprNode first = exprData_getPairA (e->edata);
07509 
07510           if (exprNode_isDefined (first))
07511             {
07512               return (exprNode_unparseFirst (exprData_getPairA (e->edata)));
07513             }
07514           else
07515             {
07516               return (cstring_makeLiteralTemp ("..."));
07517             }
07518         }
07519 
07520       ret = cstring_elide (exprNode_unparse (e), 20);
07521       cstring_markOwned (ret);
07522       
07523       return (ret);
07524     }
07525   else
07526     {
07527       return cstring_makeLiteralTemp ("<error>");
07528     }
07529 }

exprNode exprNode_updateLocation ( exprNode e,
fileloc loc )
 

Definition at line 9627 of file exprNode.c.

09628 {
09629   if (exprNode_isDefined (e))
09630     {
09631       e->loc = fileloc_update (e->loc, loc);
09632     }
09633   else
09634     {
09635       e = exprNode_createLoc (ctype_unknown, fileloc_copy (loc));
09636     }
09637 
09638   return (e);
09639 }

exprNode exprNode_vaArg ( lltok tok,
exprNode arg,
qtype qt )
 

Definition at line 5273 of file exprNode.c.

05274 {
05275   ctype totype = qtype_getType (qt);
05276   exprNode ret =
05277     exprNode_createPartialLocCopy (arg, fileloc_copy (lltok_getLoc (tok)));
05278   ctype targ;
05279 
05280   /*
05281   ** check use of va_arg : <valist>, type -> type
05282   */
05283 
05284   if (exprNode_isError (arg))
05285     {
05286     }
05287   else
05288     {
05289       targ = exprNode_getType (arg);
05290 
05291       /*
05292       ** arg should have be a pointer
05293       */
05294 
05295       if (!ctype_isUA (targ) ||
05296           (!usymId_equal (ctype_typeId (targ), 
05297                          usymtab_getTypeId (cstring_makeLiteralTemp ("va_list")))))
05298         {
05299           voptgenerror
05300             (FLG_TYPE,
05301              message ("First argument to va_arg is not a va_list (type %t): %s",
05302                       targ, exprNode_unparse (arg)),
05303              arg->loc);
05304         }
05305 
05306       exprNode_checkSet (ret, arg->sref);
05307     }
05308   
05309   /*
05310   ** return type is totype
05311   */
05312 
05313   ret->typ = totype;
05314   ret->kind = XPR_VAARG;
05315   ret->edata = exprData_makeCast (tok, arg, qt);
05316 
05317   return (ret);
05318 }

exprNode exprNode_while ( exprNode t,
exprNode b )
 

Definition at line 6224 of file exprNode.c.

06225 {
06226   exprNode ret;
06227   bool emptyErr = FALSE;
06228   
06229   if (context_maybeSet (FLG_WHILEEMPTY))
06230     {
06231       if (exprNode_isEmptyStatement (b))
06232         {
06233           emptyErr = optgenerror 
06234             (FLG_WHILEEMPTY,
06235              cstring_makeLiteral
06236              ("Body of while statement is empty"),
06237              exprNode_loc (b));
06238         }
06239     }
06240 
06241   if (!emptyErr && context_maybeSet (FLG_WHILEBLOCK))
06242     {
06243       if (exprNode_isDefined (b)
06244           && !exprNode_isBlock (b))
06245         {
06246           if (context_inIterDef ()
06247               && (b->kind == XPR_STMTLIST
06248                   || b->kind == XPR_TOK))
06249             {
06250               ; /* no error */
06251             }
06252           else
06253             {
06254               voptgenerror (FLG_WHILEBLOCK,
06255                             message
06256                             ("Body of while statement is not a block: %s",
06257                              exprNode_unparse (b)),
06258                             exprNode_loc (b));
06259             }
06260         }
06261     }
06262   
06263   if (exprNode_isError (t))
06264     {
06265       if (exprNode_isError (b))
06266         {
06267           ret = exprNode_createLoc (ctype_unknown, g_currentloc);
06268         }
06269       else
06270         {
06271           ret = exprNode_createPartialCopy (b);
06272         }
06273     }
06274   else
06275     {
06276       exprNode test;
06277 
06278       ret = exprNode_createPartialCopy (t);
06279       
06280       llassert (t->kind == XPR_WHILEPRED);
06281 
06282       test = exprData_getSingle (t->edata);
06283 
06284       if (!exprNode_isError (b) && exprNode_isDefined (test))
06285         {
06286           if (context_maybeSet (FLG_INFLOOPS)
06287               || context_maybeSet (FLG_INFLOOPSUNCON))
06288             {
06289               /*
06290               ** check that some variable in the predicate is set by the body
06291               ** if the predicate uses any variables
06292               */
06293               
06294               checkInfiniteLoop (test, b);
06295             }
06296 
06297           exprNode_mergeUSs (ret, b);
06298 
06299           if (exprNode_isDefined (b))
06300             {
06301               ret->exitCode = exitkind_makeConditional (b->exitCode);
06302             }
06303         }
06304     }
06305   
06306   ret->edata = exprData_makePair (t, b);
06307   ret->kind = XPR_WHILE;
06308 
06309   if (exprNode_isDefined (t) && exprNode_mustEscape (t))
06310     {
06311       voptgenerror
06312         (FLG_CONTROL,
06313          message ("Predicate always exits: %s", exprNode_unparse (t)),
06314          exprNode_loc (t));
06315     }
06316 
06317   ret->exitCode = XK_NEVERESCAPE;
06318 
06319   /*
06320   ** If loop is infinite, and there is no break inside, 
06321   ** exit code is never reach. 
06322   */
06323 
06324   if (exprNode_knownIntValue (t))
06325     {
06326       if (!exprNode_isZero (t)) 
06327         {
06328           if (exprNode_isDefined (b)) 
06329             {
06330               if (!b->canBreak) 
06331                 {
06332                   /* Really, it means never reached. */
06333                   ret->exitCode = XK_MUSTEXIT;
06334                 }
06335             }
06336         }
06337     } 
06338   else 
06339     {
06340       ;
06341     }
06342 
06343   ret->canBreak = FALSE;
06344   ret->mustBreak = FALSE;
06345 
06346   return ret; 
06347 }

exprNode exprNode_whilePred ( exprNode test )
 

Definition at line 6538 of file exprNode.c.

06539 {
06540   exprNode ret = exprNode_createSemiCopy (test);
06541 
06542   if (exprNode_isDefined (test))
06543     {
06544       exprNode_copySets (ret, test);
06545       exprNode_checkPred (cstring_makeLiteralTemp ("while"), test);
06546       exprNode_checkUse (ret, test->sref, test->loc);
06547       
06548       exprNode_produceGuards (test);
06549       
06550       ret->guards = guardSet_copy (test->guards);
06551     }
06552 
06553   ret->edata = exprData_makeSingle (test);
06554   ret->kind = XPR_WHILEPRED;
06555   return ret;
06556 }


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