X-Git-Url: http://andersk.mit.edu/gitweb/splint.git/blobdiff_plain/0e5499ac2451bd546330efbf1bd1e91a3c8dbb02..3dabb0778770a6ee8a2af1a104325e2651933ce1:/src/exprNode.c?ds=sidebyside diff --git a/src/exprNode.c b/src/exprNode.c index fbccd34..648c062 100644 --- a/src/exprNode.c +++ b/src/exprNode.c @@ -29,6 +29,7 @@ # include "splintMacros.nf" # include "basic.h" # include "cgrammar.h" +# include "cscanner.h" # include "cgrammar_tokens.h" # include "exprChecks.h" @@ -39,7 +40,7 @@ static bool exprNode_sameStorage (exprNode p_e1, exprNode p_e2) /*@*/ ; static bool exprNode_isEmptyStatement (exprNode p_e); static /*@exposed@*/ exprNode exprNode_firstStatement (/*@returned@*/ exprNode p_e); static bool exprNode_isFalseConstant (exprNode p_e) /*@*/ ; -static bool exprNode_isBlock (exprNode p_e); +static bool exprNode_isStatement (exprNode p_e); static void checkGlobUse (uentry p_glob, bool p_isCall, /*@notnull@*/ exprNode p_e); static void exprNode_addUse (exprNode p_e, /*@exposed@*/ sRef p_s); static bool exprNode_matchArgType (ctype p_ct, exprNode p_e); @@ -82,8 +83,7 @@ static /*@observer@*/ cstring exprNode_rootVarName (exprNode p_e); static /*@exposed@*/ exprNode exprNode_lastStatement (/*@returned@*/ exprNode p_e); -static /*@null@*/ sRef defref = sRef_undefined; -static /*@only@*/ exprNode mustExitNode = exprNode_undefined; +static /*@only@*/ exprNode s_mustExitNode = exprNode_undefined; static int checkArgsReal (uentry p_fcn, /*@dependent@*/ exprNode p_f, uentryList p_cl, @@ -138,8 +138,6 @@ void exprNode_initMod (void) ctypeType = ctype_unknown; filelocType = ctype_unknown; - defref = sRef_undefined; - if (usymtab_existsType (cstring_makeLiteralTemp ("cstring"))) { cstringType = usymtab_lookupAbstractType (cstring_makeLiteralTemp ("cstring")); @@ -217,24 +215,25 @@ void exprNode_initMod (void) void exprNode_destroyMod (void) /*@globals killed regArg, killed outArg, killed outStringArg, - killed mustExitNode, initMod @*/ + killed s_mustExitNode, initMod @*/ { if (initMod) { - uentry_free (regArg); - uentry_free (outArg); - uentry_free (outStringArg); + /* evans 2002-07-12: changed uentry_free to uentry_freeComplete */ + uentry_freeComplete (regArg); + uentry_freeComplete (outArg); + uentry_freeComplete (outStringArg); - exprNode_free (mustExitNode); + exprNode_free (s_mustExitNode); initMod = FALSE; - /*@-branchstate@*/ + /*@-branchstate@*/ } /*@=branchstate@*/ } static void exprNode_resetSref (/*@notnull@*/ exprNode e) { - e->sref = defref; + e->sref = sRef_undefined; } exprNode exprNode_fakeCopy (exprNode e) @@ -439,7 +438,7 @@ static /*@notnull@*/ /*@special@*/ exprNode e->typ = c; e->kind = XPR_EMPTY; e->val = multiVal_undefined; - e->sref = defref; + e->sref = sRef_undefined; e->etext = cstring_undefined; e->loc = fileloc_undefined; e->guards = guardSet_undefined; @@ -459,13 +458,13 @@ static /*@notnull@*/ /*@special@*/ exprNode /*@observer@*/ exprNode exprNode_makeMustExit (void) { - if (exprNode_isUndefined (mustExitNode)) + if (exprNode_isUndefined (s_mustExitNode)) { - mustExitNode = exprNode_createPlain (ctype_unknown); - mustExitNode->exitCode = XK_MUSTEXIT; + s_mustExitNode = exprNode_createPlain (ctype_unknown); + s_mustExitNode->exitCode = XK_MUSTEXIT; } - return mustExitNode; + return s_mustExitNode; } @@ -551,7 +550,7 @@ static /*@notnull@*/ /*@special@*/ exprNode } ret->kind = XPR_EMPTY; - ret->sref = defref; + ret->sref = sRef_undefined; ret->etext = cstring_undefined; ret->exitCode = XK_NEVERESCAPE; ret->canBreak = FALSE; @@ -603,7 +602,7 @@ static /*@notnull@*/ /*@special@*/ exprNode ret->val = multiVal_undefined; ret->kind = XPR_EMPTY; - ret->sref = defref; + ret->sref = sRef_undefined; ret->etext = cstring_undefined; ret->exitCode = XK_NEVERESCAPE; ret->canBreak = FALSE; @@ -640,7 +639,7 @@ static /*@notnull@*/ /*@special@*/ exprNode ret->msets = sRefSet_undefined; ret->kind = XPR_EMPTY; - ret->sref = defref; + ret->sref = sRef_undefined; ret->etext = cstring_undefined; ret->exitCode = XK_NEVERESCAPE; ret->canBreak = FALSE; @@ -676,7 +675,13 @@ exprNode_isUnknownConstant (/*@notnull@*/ exprNode e) while (e->kind == XPR_PARENS) { e = exprData_getUopNode (e->edata); - llassert (exprNode_isDefined (e)); + + if (!exprNode_isDefined (e)) + { + return FALSE; + } + + /* evans 2002-02-05: was llassert (exprNode_isDefined (e)); but this can fail */ } if (e->kind == XPR_CONST) @@ -809,17 +814,17 @@ exprNode_combineLiterals (exprNode e, exprNode rest) exprNode_rawStringLiteral (/*@only@*/ cstring t, /*@only@*/ fileloc loc) { exprNode e = exprNode_createLoc (ctype_string, loc); - int len = cstring_length (t); + size_t len = cstring_length (t); if (context_getFlag (FLG_STRINGLITERALLEN)) { - if (len > context_getValue (FLG_STRINGLITERALLEN)) + if (len > size_fromInt (context_getValue (FLG_STRINGLITERALLEN))) { voptgenerror (FLG_STRINGLITERALLEN, message ("String literal length (%d) exceeds maximum " "length (%d): \"%s\"", - len, + size_toInt (len), context_getValue (FLG_STRINGLITERALLEN), t), e->loc); @@ -849,19 +854,18 @@ exprNode_wideStringLiteral (/*@only@*/ cstring t, /*@only@*/ fileloc loc) { exprNode res = exprNode_stringLiteral (t, loc); res->typ = ctype_makeWideString (); - return res; } /*@only@*/ exprNode exprNode_stringLiteral (/*@only@*/ cstring t, /*@only@*/ fileloc loc) { - int len = cstring_length (t) - 2; + size_t len = size_fromInt (cstring_length (t) - 2); char *ts = cstring_toCharsSafe (t); char *s = cstring_toCharsSafe (cstring_create (len + 1)); llassert (*ts == '\"' && *(ts + len + 1) == '\"'); - strncpy (s, ts+1, size_fromInt (len)); + strncpy (s, ts+1, len); *(s + len) = '\0'; cstring_free (t); return exprNode_rawStringLiteral (cstring_fromCharsO (s), loc); @@ -880,7 +884,7 @@ exprNode exprNode_fromUIO (cstring c) } e->loc = loc; /* save loc was mangled */ - e->sref = defref; + e->sref = sRef_undefined; if (usymtab_exists (c)) { @@ -1015,8 +1019,7 @@ exprNode exprNode_createId (/*@observer@*/ uentry c) e->canBreak = FALSE; e->mustBreak = FALSE; - exprNode_defineConstraints(e); - + exprNode_defineConstraints (e); return e; } else @@ -1032,7 +1035,7 @@ exprNode_fromIdentifier (/*@observer@*/ uentry c) if (context_justPopped ()) /* watch out! c could be dead */ { - uentry ce = usymtab_lookupSafe (LastIdentifier ()); + uentry ce = usymtab_lookupSafe (cscanner_observeLastIdentifier ()); if (uentry_isValid (ce)) { @@ -1048,29 +1051,28 @@ exprNode_fromIdentifier (/*@observer@*/ uentry c) return ret; } - static void exprNode_checkStringLiteralLength (ctype t1, exprNode e2) { multiVal mval = exprNode_getValue (e2); cstring slit; - int len; + size_t len; if (ctype_isFixedArray (t1)) { - - int nelements = long_toInt (ctype_getArraySize (t1)); + size_t nelements = ctype_getArraySize (t1); llassert (multiVal_isString (mval)); slit = multiVal_forceString (mval); len = cstring_lengthExpandEscapes (slit); - + llassert (exprNode_isDefined (e2)); + if (len == nelements) { mstring temp; - temp = cstring_expandEscapes(slit); + temp = cstring_expandEscapes (slit); if (temp[len-1] == '\0') { @@ -1085,16 +1087,14 @@ static void exprNode_checkStringLiteralLength (ctype t1, exprNode e2) } else { - - - voptgenerror - (FLG_STRINGLITNOROOM, - message ("String literal with %d character%& " - "is assigned to %s (no room for null terminator): %s", - len + 1, - ctype_unparse (t1), - exprNode_unparse (e2)), - e2->loc); + voptgenerror + (FLG_STRINGLITNOROOM, + message ("String literal with %d character%& " + "is assigned to %s (no room for null terminator): %s", + len + 1, + ctype_unparse (t1), + exprNode_unparse (e2)), + e2->loc); } } else if (len > nelements) @@ -1649,8 +1649,11 @@ checkPrintfArgs (/*@notnull@*/ /*@dependent@*/ exprNode f, uentry fcn, case 'p': /* pointer */ expecttype = ctype_makePointer (ctype_void); - uentry_setDefState (regArg, SS_RELDEF); /* need not be defined */ - sRef_setPosNull (uentry_getSref (regArg), fileloc_undefined); /* could be null */ + /* need not be defined */ + uentry_setDefState (regArg, SS_RELDEF); + sRef_setPosNull (uentry_getSref (regArg), + fileloc_undefined); + /* could be null */ /*@switchbreak@*/ break; case 'n': /* pointer to int, modified by call! */ @@ -2043,7 +2046,7 @@ checkScanfArgs (/*@notnull@*/ /*@dependent@*/ exprNode f, uentry fcn, } else { - /* a->sref = defref; */ + /* a->sref = sRef_undefined; */ } } } @@ -2183,6 +2186,14 @@ checkMessageArgs (/*@notnull@*/ /*@dependent@*/ exprNode f, case 'f': expecttype = ctype_float; break; case 'b': expecttype = ctype_bool; break; case 't': expecttype = ctypeType; break; + case 'p': + expecttype = ctype_makePointer (ctype_void); + /* need not be defined */ + uentry_setDefState (regArg, SS_RELDEF); + sRef_setPosNull (uentry_getSref (regArg), + fileloc_undefined); + /* could be null */ + /*@switchbreak@*/ break; case 'l': expecttype = filelocType; break; case '&': /* a wee bit of a hack methinks */ expecttype = ctype_int; @@ -3293,7 +3304,9 @@ reflectEnsuresClause (exprNode ret, uentry le, exprNode f, exprNodeList args) sRefSet srs = stateClause_getRefs (cl); sRefModVal modf = stateClause_getEnsuresFunction (cl); int eparam = stateClause_getStateParameter (cl); - + + llassert (modf != NULL); + DPRINTF (("Reflect after clause: %s / %s", stateClause_unparse (cl), sRefSet_unparse (srs))); @@ -3667,6 +3680,8 @@ checkRequiresClause (uentry le, exprNode f, exprNodeList args) stateClause_unparse (cl), sRefSet_unparse (srs))); + llassert (modf != NULL); + sRefSet_elements (srs, sel) { sRef s; @@ -3764,7 +3779,7 @@ functionCallSafe (/*@only@*/ /*@notnull@*/ exprNode f, /* f->typ is already set to the return type */ DPRINTF (("Function: %s", uentry_unparseFull (le))); - ret->sref = uentry_returnedRef (le, args); + ret->sref = uentry_returnedRef (le, args, exprNode_loc (f)); DPRINTF (("Returned: %s / %s", uentry_unparseFull (le), sRef_unparseFull (ret->sref))); @@ -3873,7 +3888,7 @@ functionCallSafe (/*@only@*/ /*@notnull@*/ exprNode f, } else { - ret->sref = defref; + ret->sref = sRef_undefined; exprNode_checkSetAny (ret, uentry_rawName (le)); } @@ -3882,6 +3897,7 @@ functionCallSafe (/*@only@*/ /*@notnull@*/ exprNode f, reflectEnsuresClause (ret, le, f, args); setCodePoint (); + DPRINTF (("Here: %s", sRef_unparseFull (ret->sref))); return (ret); } @@ -3934,7 +3950,9 @@ exprNode_functionCall (/*@only@*/ exprNode f, /*@only@*/ exprNodeList args) { ctype t; - setCodePoint (); +# ifdef DEBUGSPLINT + usymtab_checkAllValid (); +# endif if (exprNode_isUndefined (f)) { @@ -4113,7 +4131,7 @@ exprNode_fieldAccess (/*@only@*/ exprNode s, /*@only@*/ lltok dot, /*@only@*/ cstring f) { exprNode res = exprNode_fieldAccessAux (s, lltok_getLoc (dot), f); - lltok_release (dot); + lltok_free (dot); return res; } @@ -4317,7 +4335,7 @@ exprNode_arrowAccess (/*@only@*/ exprNode s, /*@only@*/ cstring f) { exprNode res = exprNode_arrowAccessAux (s, lltok_getLoc (arrow), f); - lltok_release (arrow); + lltok_free (arrow); return res; } @@ -4956,7 +4974,7 @@ exprNode_cast (/*@only@*/ lltok tok, /*@only@*/ exprNode e, /*@only@*/ qtype q) if (exprNode_isError (e)) { qtype_free (q); - lltok_release (tok); + lltok_free (tok); return exprNode_undefined; } @@ -4972,28 +4990,18 @@ exprNode_cast (/*@only@*/ lltok tok, /*@only@*/ exprNode e, /*@only@*/ qtype q) ret->kind = XPR_CAST; ret->edata = exprData_makeCast (tok, e, q); - if (ctype_isRealSU (ctype_getBaseType (sRef_getType (e->sref)))) - { - /* - ** This is a bit of a hack to avoid a problem - ** when the code does, - ** (some other struct) x - ** ... - ** x->field - */ + ret->sref = sRef_copy (e->sref); + + DPRINTF (("Cast 2: -> %s", sRef_unparseFull (ret->sref))); - ret->sref = sRef_copy (e->sref); - usymtab_addForceMustAlias (ret->sref, e->sref); - sRef_setTypeFull (ret->sref, c); - DPRINTF (("Cast: %s -> %s", sRef_unparseFull (e->sref), - sRef_unparseFull (ret->sref))); - } - else + if (!sRef_isConst (e->sref)) { - ret->sref = e->sref; - sRef_setTypeFull (ret->sref, c); - DPRINTF (("Cast 2: -> %s", sRef_unparseFull (ret->sref))); + usymtab_addForceMustAlias (ret->sref, e->sref); } + + DPRINTF (("Cast 2: -> %s", sRef_unparseFull (ret->sref))); + sRef_setTypeFull (ret->sref, c); + DPRINTF (("Cast 2: -> %s", sRef_unparseFull (ret->sref))); /* ** we allow @@ -5005,7 +5013,18 @@ exprNode_cast (/*@only@*/ lltok tok, /*@only@*/ exprNode e, /*@only@*/ qtype q) if (ctype_isVoid (c)) /* cast to void is always okay --- discard value */ { - ; + /* evans 2002-07-19: added this warning */ + DPRINTF (("Checking: %s / %s", exprNode_unparse (ret), sRef_unparseFull (ret->sref))); + if (sRef_isFresh (ret->sref)) + { + voptgenerror + (FLG_MUSTFREEFRESH, + message ("New fresh storage %q(type %s) cast to void (not released): %s", + sRef_unparseOpt (ret->sref), + ctype_unparse (exprNode_getType (ret)), + exprNode_unparse (ret)), + exprNode_loc (ret)); + } } else if (ctype_isRealAP (c)) /* casting to array or pointer */ { @@ -5993,8 +6012,7 @@ void exprNode_checkAssignMod (exprNode e1, exprNode ret) } exprNode -exprNode_assign (/*@only@*/ exprNode e1, - /*@only@*/ exprNode e2, /*@only@*/ lltok op) +exprNode_assign (/*@only@*/ exprNode e1, /*@only@*/ exprNode e2, /*@only@*/ lltok op) { bool isalloc = FALSE; bool isjustalloc = FALSE; @@ -6015,13 +6033,17 @@ exprNode_assign (/*@only@*/ exprNode e1, ctype_unparse (e1->typ), ctype_unparse (e2->typ))); - if (ctype_isNumeric (e2->typ) - || ctype_isNumeric (e1->typ)) + if (exprNode_isDefined (e1) + && exprNode_isDefined (e2)) { - /* Its a pointer arithmetic expression like ptr += i */ - noalias = TRUE; - } - } + if (ctype_isNumeric (e2->typ) + || ctype_isNumeric (e1->typ)) + { + /* Its a pointer arithmetic expression like ptr += i */ + noalias = TRUE; + } + } + } else { ret = exprNode_createPartialCopy (e1); @@ -6121,7 +6143,17 @@ exprNode_assign (/*@only@*/ exprNode e1, ctype te1 = exprNode_getType (e1); ctype te2 = exprNode_getType (e2); - if (!ctype_forceMatch (te1, te2)) + if (ctype_isVoid (te2)) + { + (void) gentypeerror + (te2, e2, te1, e1, + message ("Assignment of void value to %t: %s %s %s", + te1, exprNode_unparse (e1), + lltok_unparse (op), + exprNode_unparse (e2)), + e1->loc); + } + else if (!ctype_forceMatch (te1, te2)) { if (exprNode_matchLiteral (te1, e2)) { @@ -6138,6 +6170,10 @@ exprNode_assign (/*@only@*/ exprNode e1, e1->loc); } } + else + { + /* Type checks okay */ + } } exprNode_mergeUSs (ret, e2); @@ -6686,6 +6722,7 @@ exprNode exprNode_concat (/*@only@*/ exprNode e1, /*@only@*/ exprNode e2) usymtab_setMustBreak (); } + DPRINTF (("==> %s", exprNode_unparse (ret))); return ret; } @@ -6702,7 +6739,7 @@ exprNode exprNode_statement (/*@only@*/ exprNode e, /*@only@*/ lltok t) { if (!exprNode_isError (e)) { - exprNode_checkStatement(e); + exprChecks_checkStatementEffect(e); } return (exprNode_statementError (e, t)); @@ -6757,6 +6794,36 @@ void exprNode_produceGuards (exprNode pred) } } +exprNode exprNode_compoundStatementExpression (/*@only@*/ lltok tlparen, /*@only@*/ exprNode e) +{ + exprNode laststmt; + + DPRINTF (("Compound: %s", exprNode_unparse (e))); + + if (!context_flagOn (FLG_GNUEXTENSIONS, exprNode_loc (e))) + { + (void) llgenhinterror + (FLG_SYNTAX, + message ("Compound statement expressions is not supported by ISO C99"), + message ("Use +gnuextensions to allow compound statement expressions (and other GNU language extensions) " + "without this warning"), + exprNode_loc (e)); + } + + /* + ** The type of a compoundStatementExpression is the type of the last statement + */ + + llassert (exprNode_isBlock (e)); + laststmt = exprNode_lastStatement (e); + + DPRINTF (("Last statement: %s / %s", exprNode_unparse (laststmt), ctype_unparse (exprNode_getType (laststmt)))); + DPRINTF (("e: %s", exprNode_unparse (e))); + e->typ = exprNode_getType (laststmt); + return exprNode_addParens (tlparen, e); +} + + exprNode exprNode_makeBlock (/*@only@*/ exprNode e) { exprNode ret = exprNode_createPartialCopy (e); @@ -6768,8 +6835,10 @@ exprNode exprNode_makeBlock (/*@only@*/ exprNode e) ret->mustBreak = e->mustBreak; } + DPRINTF (("Block e: %s", exprNode_unparse (e))); ret->edata = exprData_makeSingle (e); ret->kind = XPR_BLOCK; + DPRINTF (("Block: %s", exprNode_unparse (ret))); return ret; } @@ -6778,6 +6847,12 @@ bool exprNode_isBlock (exprNode e) return (exprNode_isDefined (e) && ((e)->kind == XPR_BLOCK)); } + +bool exprNode_isStatement (exprNode e) +{ + return (exprNode_isDefined (e) + && ((e)->kind == XPR_STMT)); +} bool exprNode_isAssign (exprNode e) { @@ -6796,6 +6871,22 @@ bool exprNode_isEmptyStatement (exprNode e) && (lltok_isSemi (exprData_getTok (e->edata)))); } +bool exprNode_isMultiStatement (exprNode e) +{ + return (exprNode_isDefined (e) + && ((e->kind == XPR_FOR) + || (e->kind == XPR_FORPRED) + || (e->kind == XPR_IF) + || (e->kind == XPR_IFELSE) + || (e->kind == XPR_WHILE) + || (e->kind == XPR_WHILEPRED) + || (e->kind == XPR_DOWHILE) + || (e->kind == XPR_BLOCK) + || (e->kind == XPR_STMT) + || (e->kind == XPR_STMTLIST) + || (e->kind == XPR_SWITCH))); +} + void exprNode_checkIfPred (exprNode pred) { exprNode_checkPred (cstring_makeLiteralTemp ("if"), pred); @@ -7035,6 +7126,9 @@ checkSwitchExpr (exprNode test, /*@dependent@*/ exprNode e, /*@out@*/ bool *allp exprNodeSList_elements (el, current) { + + DPRINTF ((message("checkSwitchExpr current = %s ", exprNode_unparse(current) ) )); + if (exprNode_isDefined (current)) { switch (current->kind) @@ -8129,7 +8223,7 @@ static bool exprNode_checkOneInit (/*@notnull@*/ exprNode el, exprNode val) if (ctype_isFixedArray (t1)) { - int nelements = long_toInt (ctype_getArraySize (t1)); + size_t nelements = ctype_getArraySize (t1); DPRINTF (("Checked array: %s / %d", ctype_unparse (t1), nelements)); @@ -8140,10 +8234,11 @@ static bool exprNode_checkOneInit (/*@notnull@*/ exprNode el, exprNode val) } else { - if (exprNodeList_size (vals) != nelements) + if (exprNodeList_size (vals) != size_toInt (nelements)) { hasError = optgenerror - (exprNodeList_size (vals) > nelements ? FLG_INITSIZE : FLG_INITALLELEMENTS, + (exprNodeList_size (vals) > size_toInt (nelements) + ? FLG_INITSIZE : FLG_INITALLELEMENTS, message ("Initializer block for " "%s has %d element%&, but declared as %s: %q", exprNode_unparse (el), @@ -8341,7 +8436,7 @@ static bool exprNode_checkOneInit (/*@notnull@*/ exprNode el, exprNode val) return hasError; } -static exprNode +static /*@notnull@*/ exprNode exprNode_makeInitializationAux (/*@temp@*/ idDecl t) { exprNode ret; @@ -8410,7 +8505,6 @@ exprNode_makeInitializationAux (/*@temp@*/ idDecl t) exprData_free (ret->edata, ret->kind); ret->edata = exprData_undefined; - ret->exitCode = XK_NEVERESCAPE; ret->mustBreak = FALSE; ret->kind = XPR_INIT; @@ -8431,14 +8525,15 @@ exprNode exprNode_makeInitialization (/*@only@*/ idDecl t, uentry ue = usymtab_lookup (idDecl_observeId (t)); exprNode ret = exprNode_makeInitializationAux (t); fileloc loc = exprNode_loc (e); - + + DPRINTF (("initialization: %s = %s", idDecl_unparse (t), exprNode_unparse (e))); + if (exprNode_isError (e)) { e = exprNode_createUnknown (); - idDecl_free (t); - /* error: assume initializer is defined */ sRef_setDefined (ret->sref, g_currentloc); + ret->edata = exprData_makeInit (t, e); } else { @@ -8454,6 +8549,7 @@ exprNode exprNode_makeInitialization (/*@only@*/ idDecl t, exprData_free (ret->edata, ret->kind); ret->edata = exprData_makeInit (t, e); + DPRINTF (("ret: %s", exprNode_unparse (ret))); exprNode_checkUse (ret, e->sref, e->loc); @@ -8506,14 +8602,42 @@ exprNode exprNode_makeInitialization (/*@only@*/ idDecl t, sRef_setDefState (ret->sref, SS_PARTIAL, fileloc_undefined); } - doAssign (ret, e, TRUE); + if (exprNode_isStringLiteral (e) + && (ctype_isArray (ct)) + && (ctype_isChar (ctype_realType (ctype_baseArrayPtr (ct))))) + { + /* + ** If t is a char [], the literal is copied. + */ + + exprNode_checkStringLiteralLength (ct, e); + sRef_setDefState (ret->sref, SS_DEFINED, e->loc); + ret->val = multiVal_copy (e->val); + + sRef_setNullTerminatedState (ret->sref); + + if (multiVal_isDefined (e->val)) + { + cstring slit = multiVal_forceString (e->val); + sRef_setLen (ret->sref, cstring_length (slit) + 1); + } + + if (ctype_isFixedArray (ct)) + { + sRef_setSize (ret->sref, size_toInt (ctype_getArraySize (ct))); + } + } + else + { + doAssign (ret, e, TRUE); + } if (uentry_isStatic (ue)) { sRef_setDefState (ret->sref, SS_DEFINED, fileloc_undefined); } } - + if (context_inIterDef ()) { /* should check if it is yield */ @@ -8525,6 +8649,15 @@ exprNode exprNode_makeInitialization (/*@only@*/ idDecl t, } exprNode_mergeUSs (ret, e); + DPRINTF (("Ret: %s %p %p", + exprNode_unparse (ret), + ret->requiresConstraints, + ret->ensuresConstraints)); + + DPRINTF (("Ret: %s %s %s", + exprNode_unparse (ret), + constraintList_unparse (ret->requiresConstraints), + constraintList_unparse (ret->ensuresConstraints))); return ret; } @@ -8608,7 +8741,7 @@ exprNode_iterNewId (/*@only@*/ cstring s) e->kind = XPR_VAR; e->val = multiVal_unknown (); e->guards = guardSet_new (); - e->sref = defref; + e->sref = sRef_undefined; e->isJumpPoint = FALSE; e->exitCode = XK_NEVERESCAPE; @@ -8799,8 +8932,7 @@ exprNode exprNode_iterStart (/*@observer@*/ uentry name, /*@only@*/ exprNodeList { if (exprNode_isDefined (e)) { - /*@access sRef@*/ - if (e->sref == defref) /*@noaccess sRef@*/ + if (sRef_isInvalid (e->sref)) { /*@-mods@*/ e->sref = sRef_makeUnknown (); @@ -8981,9 +9113,47 @@ static /*@only@*/ exprNode exprNode_effect (exprNode e) exprNode_effect (exprData_getPairB (data))); break; case XPR_OP: - ret = exprNode_op (exprNode_effect (exprData_getOpA (data)), - exprNode_effect (exprData_getOpB (data)), - exprData_getOpTok (data)); + /* + ** evans 2002-03-15: for && and ||, need to do the guards also + ** this is what cgrammar.y does - should be + ** able to avoid duplication, but need to + ** time with grammar productions. + */ + + DPRINTF (("Effect: %s", exprNode_unparse (e))); + + if (lltok_getTok (exprData_getOpTok (data)) == AND_OP) + { + exprNode e1 = exprNode_effect (exprData_getOpA (data)); + exprNode e2; + exprNode_produceGuards (e1); + context_enterAndClause (e1); + e2 = exprNode_effect (exprData_getOpB (data)); + + ret = exprNode_op (e1, e2, + exprData_getOpTok (data)); + + context_exitAndClause (ret, e2); + } + else if (lltok_getTok (exprData_getOpTok (data)) == OR_OP) + { + exprNode e1 = exprNode_effect (exprData_getOpA (data)); + exprNode e2; + exprNode_produceGuards (e1); + context_enterOrClause (e1); + e2 = exprNode_effect (exprData_getOpB (data)); + + ret = exprNode_op (e1, e2, + exprData_getOpTok (data)); + + context_exitOrClause (ret, e2); + } + else + { + ret = exprNode_op (exprNode_effect (exprData_getOpA (data)), + exprNode_effect (exprData_getOpB (data)), + exprData_getOpTok (data)); + } break; case XPR_POSTOP: @@ -9453,17 +9623,31 @@ static /*@only@*/ cstring exprNode_doUnparse (exprNode e) break; case XPR_BLOCK: - ret = message ("{ %s }", exprNode_unparseFirst (exprData_getSingle (data))); + ret = message ("{ %s }", exprNode_unparse (exprData_getSingle (data))); + /* evans 2002-02-20 was unparseFirst! */ break; case XPR_STMT: - ret = cstring_copy (exprNode_unparse (exprData_getUopNode (data))); + ret = message ("%s;", exprNode_unparse (exprData_getUopNode (data))); break; case XPR_STMTLIST: - ret = message ("%s; %s", - exprNode_unparse (exprData_getPairA (data)), - exprNode_unparse (exprData_getPairB (data))); + if (exprNode_isStatement (exprData_getPairA (data))) + { + /* + ** statement expressions already print the ; + */ + + ret = message ("%s %s", + exprNode_unparse (exprData_getPairA (data)), + exprNode_unparse (exprData_getPairB (data))); + } + else + { + ret = message ("%s; %s", + exprNode_unparse (exprData_getPairA (data)), + exprNode_unparse (exprData_getPairB (data))); + } break; case XPR_FTDEFAULT: