X-Git-Url: http://andersk.mit.edu/gitweb/splint.git/blobdiff_plain/bf92e32cf4958be7a9035826b51d0ea8bba57ded..6970c11be2c0e175abf98c906a87115836e4f55f:/src/constraintTerm.c diff --git a/src/constraintTerm.c b/src/constraintTerm.c index 471dae7..bbba3b7 100644 --- a/src/constraintTerm.c +++ b/src/constraintTerm.c @@ -1,7 +1,9 @@ /* -** constraintTerm.c +** constraintExpr.c */ +//#define DEBUGPRINT 1 + # include /* for isdigit */ # include "lclintMacros.nf" # include "basic.h" @@ -9,226 +11,292 @@ # include "cgrammar_tokens.h" # include "exprChecks.h" -# include "aliasChecks.h" # include "exprNodeSList.h" -# include "exprData.i" -int constraintTerm_getValue (constraintTerm term) +/*@-czechfcns@*/ + +//#include "constraintExpr.h" + +/*@access exprNode @*/ + +bool constraintTerm_isDefined (constraintTerm t) { - if (term->kind == EXPRNODE) - { - return (multiVal_forceInt (term->value.expr->val) ); - } - if (term->kind == INTLITERAL ) + return t != NULL; +} + +/*@unused@*/ static bool constraintTerm_same (constraintTerm p_term1, constraintTerm p_term2) ; + +void constraintTerm_free (/*@only@*/ constraintTerm term) +{ + llassert (constraintTerm_isDefined (term)); + + fileloc_free (term->loc); + + switch (term->kind) { - return (term->value.intlit); + case EXPRNODE: + /* we don't free an exprNode*/ + break; + case SREF: + /* sref */ + sRef_free (term->value.sref); + break; + case INTLITERAL: + /* don't free an int */ + break; + case ERRORBADCONSTRAINTTERMTYPE: + default: + /* type was set incorrectly */ + llcontbug (message("constraintTerm_free type was set incorrectly")); } - llassert(FALSE); - return 0; + // term->value.intlit = 0; + term->kind = ERRORBADCONSTRAINTTERMTYPE; + free (term); } -/*@out@*/ static constraintTerm new_constraintTermExpr (void) +/*@only@*/ static/*@out@*/ constraintTerm new_constraintTermExpr (void) { constraintTerm ret; ret = dmalloc (sizeof (* ret ) ); + ret->value.intlit = 0; return ret; } -constraintTerm constraintTerm_simplify (constraintTerm term) + +bool constraintTerm_isIntLiteral (constraintTerm term) +{ + llassert(term != NULL); + + if (term->kind == INTLITERAL) + return TRUE; + + return FALSE; +} + + +bool constraintTerm_isInitBlock (/*@observer@*/ /*@temp@*/ constraintTerm c) /*@*/ { - if (term->constrType == VALUE) + llassert (c != NULL); + if (c->kind == EXPRNODE) { - if (term->kind == EXPRNODE) + + if (exprNode_isInitBlock(c->value.expr) ) { - if ( exprNode_knownIntValue (term->value.expr ) ) - { - int temp; - temp = exprNode_getLongValue (term->value.expr); - term->value.intlit = temp; - term->kind = INTLITERAL; - } - + return TRUE; } + } + return FALSE; +} + +int constraintTerm_getInitBlockLength (/*@observer@*/ /*@temp@*/ constraintTerm c) /*@*/ +{ + + exprNodeList list; + int ret; + llassert (c != NULL); + llassert (constraintTerm_isInitBlock (c) ); + llassert (c->kind == EXPRNODE); + + llassert(exprNode_isDefined(c->value.expr) ); + + if (exprNode_isUndefined(c->value.expr) ) + { + return 1; } - if (term->kind == CONSTRAINTEXPR ) + if (c->value.expr->edata == exprData_undefined) { - if ( (term->constrType == MAXREAD) || (term->constrType == MAXSET) ) - { - // ms(var + intlit) = ms (var) - intlit - if (term->value.constrExpr->expr == NULL) - return term; - - if (term->value.constrExpr->expr->term->kind == INTLITERAL) - { - if (term->constrType == MAXREAD) - term->value.constrExpr->term->constrType = MAXREAD; - else if (term->constrType == MAXSET) - term->value.constrExpr->term->constrType = MAXSET; - else - llassert(FALSE); - - term->constrType = VALUE; - - if (term->value.constrExpr->op == PLUS) - term->value.constrExpr->op = MINUS; - else - term->value.constrExpr->op = PLUS; - } - - } - + return 1; } - + list = exprData_getArgs(c->value.expr->edata); - return term; + ret = exprNodeList_size(list); + return ret; } -constraintTerm constraintTerm_copy (constraintTerm term) + + +bool constraintTerm_isStringLiteral (constraintTerm c) /*@*/ { - constraintTerm ret; - ret = new_constraintTermExpr(); - ret->constrType = term->constrType; - ret->loc = fileloc_copy (term->loc); - ret->value= term->value; - ret->kind = term->kind; - return ret; + llassert (c != NULL); + if (c->kind == EXPRNODE) + { + if (exprNode_knownStringValue(c->value.expr) ) + { + return TRUE; + } + } + return FALSE; } -constraintTerm exprNode_makeConstraintTerm (/*@only@*/ exprNode e) + + +cstring constraintTerm_getStringLiteral (constraintTerm c) { - constraintTerm ret = new_constraintTermExpr(); - ret->loc = exprNode_getfileloc(e); - ret->value.expr = e; - ret->kind = EXPRNODE; - return ret; + llassert (c != NULL); + llassert (constraintTerm_isStringLiteral (c) ); + llassert (c->kind == EXPRNODE); + + return (cstring_copy ( multiVal_forceString (exprNode_getValue (c->value.expr) ) ) ); } - -constraintTerm constraintTerm_makeMaxSetexpr (exprNode e) +constraintTerm constraintTerm_simplify (/*@returned@*/ constraintTerm term) /*@modifies term@*/ { - constraintTerm ret; - ret = exprNode_makeConstraintTerm (e); - ret->constrType = MAXSET; - return ret; + if (term->kind == EXPRNODE) + { + if ( exprNode_knownIntValue (term->value.expr ) ) + { + long int temp; + + temp = exprNode_getLongValue (term->value.expr); + term->value.intlit = (int)temp; + term->kind = INTLITERAL; + } + } + return term; } -constraintTerm constraintTerm_makeMinSetexpr (exprNode e) +fileloc constraintTerm_getFileloc (constraintTerm t) { - constraintTerm ret; - ret = exprNode_makeConstraintTerm (e); - ret->constrType = MINSET; - return ret; + llassert (constraintTerm_isDefined (t)); + return (fileloc_copy (t->loc) ); } -constraintTerm constraintTerm_makeMaxReadexpr (exprNode e) +constraintTermType constraintTerm_getKind (constraintTerm t) { - constraintTerm ret; - ret = exprNode_makeConstraintTerm (e); - ret->constrType = MAXREAD; - return ret; + llassert (constraintTerm_isDefined(t) ); + + return (t->kind); } -constraintTerm constraintTerm_makeMinReadexpr (exprNode e) +/*@exposed@*/ sRef constraintTerm_getSRef (constraintTerm t) { - constraintTerm ret; - ret = exprNode_makeConstraintTerm (e); - ret->constrType = MINREAD; - return ret; + llassert (constraintTerm_isDefined(t) ); + llassert (t->kind == SREF); + + return (t->value.sref); } -constraintTerm constraintTerm_makeValueexpr (exprNode e) +/*@only@*/ constraintTerm constraintTerm_makeExprNode (/*@dependent@*/ exprNode e) { - constraintTerm ret; - ret = exprNode_makeConstraintTerm (e); - ret->constrType = VALUE; - ret = constraintTerm_simplify (ret); + constraintTerm ret = new_constraintTermExpr(); + ret->loc = fileloc_copy(exprNode_getfileloc(e)); + ret->value.expr = e; + ret->kind = EXPRNODE; + ret = constraintTerm_simplify(ret); return ret; } - -constraintTerm intLit_makeConstraintTerm (int i) +/*@only@*/ constraintTerm constraintTerm_makesRef (/*@temp@*/ /*@observer@*/ sRef s) { constraintTerm ret = new_constraintTermExpr(); - ret->value.intlit = i; - ret->kind = INTLITERAL; ret->loc = fileloc_undefined; + ret->value.sref = sRef_saveCopy(s); + ret->kind = SREF; + ret = constraintTerm_simplify(ret); return ret; } -constraintTerm constraintTerm_makeIntLitValue (int i) + +constraintTerm constraintTerm_copy (constraintTerm term) { constraintTerm ret; - ret = intLit_makeConstraintTerm (i); - ret->constrType = VALUE; + ret = new_constraintTermExpr(); + ret->loc = fileloc_copy (term->loc); + + switch (term->kind) + { + case EXPRNODE: + ret->value.expr = term->value.expr; + break; + case INTLITERAL: + ret->value.intlit = term->value.intlit; + break; + + case SREF: + ret->value.sref = sRef_saveCopy(term->value.sref); + break; + default: + BADEXIT; + } + ret->kind = term->kind; return ret; - } -/* constraintTerm constraintTerm_makeMinSetexpr (int i) */ -/* { */ -/* constraintTerm ret; */ -/* ret = intLit_makeConstraintTerm (i); */ -/* ret->constrType = MINSET; */ -/* } */ - -/* constraintTerm constraintTerm_makeMaxReadexpr (int i) */ -/* { */ -/* constraintTerm ret; */ -/* ret = intLit_makeConstraintTerm (i); */ -/* ret->constrType = MAXREAD; */ -/* } */ -/* constraintTerm constraintTerm_makeMinReadexpr (int i) */ -/* { */ -/* constraintTerm ret; */ -/* ret = exprNode_makeConstraintTerm (i); */ -/* ret->constrType = MINREAD; */ -/* } */ +constraintTerm constraintTerm_setFileloc (/*@returned@*/ constraintTerm term, fileloc loc) +{ + llassert(term != NULL); + if ( fileloc_isDefined( term->loc ) ) + fileloc_free(term->loc); + term->loc = fileloc_copy(loc); + return term; +} -cstring constraintType_print (constraintType constrType) +static cstring constraintTerm_getName (constraintTerm term) { - cstring st = cstring_undefined; + cstring s; + s = cstring_undefined; - switch (constrType) + llassert (term != NULL); + + switch (term->kind) { - case VALUE: - st = cstring_makeLiteral("VALUE"); - break; - case CALLSAFE: - st = cstring_makeLiteral("CALLSAFE"); - break; - case MAXSET: - st = cstring_makeLiteral ("MAXSET"); + case EXPRNODE: + /*@i334*/ //wtf + s = message ("%s", exprNode_unparse (term->value.expr) ); break; - case MINSET: - st = cstring_makeLiteral ("MINSET"); + case INTLITERAL: + s = message (" %d ", (int) term->value.intlit); break; - case MAXREAD: - st = cstring_makeLiteral ("MAXREAD"); + + case SREF: + s = message ("%q", sRef_unparse (term->value.sref) ); + break; - case MINREAD: - st = cstring_makeLiteral ("MINREAD"); + default: + BADEXIT; + /*@notreached@*/ break; - case NULLTERMINATED: - st = cstring_makeLiteral ("NULLTERMINATED"); + } + + return s; +} + +constraintTerm +constraintTerm_doSRefFixBaseParam (/*@returned@*/constraintTerm term, exprNodeList arglist) /*@modifies term@*/ +{ + llassert (term != NULL); + + switch (term->kind) + { + case EXPRNODE: + /*@i334*/ //wtf + // s = message ("%s @ %s ", exprNode_unparse (term->value.expr), + // fileloc_unparse (term->loc) ); break; - case UNDEFINED: - st = cstring_makeLiteral (("Unhandled value for constraintType")); - llassert(FALSE); + case INTLITERAL: + // s = message (" %d ", term->value.intlit); + break; + + case SREF: + term->value.sref = sRef_fixBaseParam (term->value.sref, arglist); + // s = message ("%s ", sRef_unparse (term->value.sref) ); + break; default: - st = cstring_makeLiteral (("Unhandled value for constraintType")); - llassert(FALSE); + BADEXIT; } - return st; + return term; + } -cstring constraintTerm_print (constraintTerm term) + +cstring constraintTerm_print (constraintTerm term) /*@*/ { cstring s; s = cstring_undefined; @@ -239,50 +307,101 @@ cstring constraintTerm_print (constraintTerm term) { case EXPRNODE: /*@i334*/ //wtf - s = message ("%s @ %s ", exprNode_unparse (term->value.expr), + s = message ("%s @ %q ", exprNode_unparse (term->value.expr), fileloc_unparse (term->loc) ); break; case INTLITERAL: - { - s = message (" %d ", term->value.intlit); + s = message (" %d ", (int)term->value.intlit); break; - } + case SREF: - s = cstring_makeLiteral("Not Implemented\n"); - llassert(FALSE); + s = message ("%q ", sRef_unparseDebug (term->value.sref) ); + break; - case CONSTRAINTEXPR: - s = message ("%s ", constraintExpr_print (term->value.constrExpr) ); + default: + BADEXIT; } - s = message (" %s ( %s ) ", constraintType_print (term->constrType), s); - return s; + return s; } -bool constraintTerm_hasTerm (constraintTerm term, constraintTerm searchTerm) +constraintTerm constraintTerm_makeIntLiteral (long i) { - if (term->kind == CONSTRAINTEXPR) - return (constraintExpr_includesTerm (term->value.constrExpr, searchTerm) ); + constraintTerm ret = new_constraintTermExpr(); + ret->value.intlit = i; + ret->kind = INTLITERAL; + ret->loc = fileloc_undefined; + return ret; +} - if ( (term->kind == EXPRNODE) && (searchTerm->kind == EXPRNODE) ) +bool constraintTerm_canGetValue (constraintTerm term) +{ + if (term->kind == INTLITERAL) { - return sRef_same (term->value.expr->sref, searchTerm->value.expr->sref); + return TRUE; } - return FALSE; - -} + else if (term->kind == SREF) + { + if (sRef_hasValue (term->value.sref)) + { + multiVal mval = sRef_getValue (term->value.sref); -/* same and similar are similar but not the same*/ + return multiVal_isInt (mval); /* for now, only try to deal with int values */ + } + else + { + return FALSE; + } + } + else if (term->kind == EXPRNODE) + { + return FALSE; + } + else + { + return FALSE; + } +} -bool constraintTerm_same (constraintTerm term1, constraintTerm term2) +long constraintTerm_getValue (constraintTerm term) { - llassert (term1 !=NULL && term2 !=NULL); + llassert (constraintTerm_canGetValue (term)); - if (term1->constrType != term2->constrType) + if (term->kind == INTLITERAL) { - return FALSE; + return term->value.intlit; } + else if (term->kind == SREF) + { + if (sRef_hasValue (term->value.sref)) + { + multiVal mval = sRef_getValue (term->value.sref); + + return multiVal_forceInt (mval); /* for now, only try to deal with int values */ + } + else + { + BADBRANCH; + } + } + else if (term->kind == EXPRNODE) + { + BADBRANCH; + } + else + { + BADBRANCH; + } + + BADEXIT; +} + +/* same and similar are similar but not the same*/ +static bool constraintTerm_same (constraintTerm term1, constraintTerm term2) +{ + llassert (term1 !=NULL && term2 !=NULL); + if ( (term1->kind != term2->kind) || (term1->kind != EXPRNODE) ) { return FALSE; @@ -307,35 +426,265 @@ bool constraintTerm_same (constraintTerm term1, constraintTerm term2) } -bool constraintTerm_similar (constraintTerm term1, constraintTerm term2) +static /*@exposed@*/ sRef constraintTerm_getsRef (constraintTerm t) { - llassert (term1 !=NULL && term2 !=NULL); + llassert (t != NULL); + if (t->kind == EXPRNODE) + { + return exprNode_getSref(t->value.expr); + } - // if (term1->constrType != term2->constrType) - // { - // return FALSE; - // } - if ( (term1->kind != term2->kind) || (term1->kind != EXPRNODE) ) + if (t->kind == SREF) { - return FALSE; + return t->value.sref; } - + + return sRef_undefined; +} + +bool constraintTerm_probSame (constraintTerm term1, constraintTerm term2) +{ + cstring s1, s2; + + llassert (term1 !=NULL && term2 !=NULL); + DPRINTF ( (message ("Comparing srefs for %s and %s ", constraintTerm_print(term1), constraintTerm_print(term2) ) ) ); - - if (sRef_same (term1->value.expr->sref, term2->value.expr->sref) ) - { - DPRINTF ((message (" %s and %s are same", constraintTerm_print(term1), constraintTerm_print(term2) ) )); + + s1 = constraintTerm_getName (term1); + s2 = constraintTerm_getName (term2); + + if (cstring_equal (s1, s2) ) + { + DPRINTF ((message (" %q and %q are same", s1, s2 ) ) ); return TRUE; } - else - { - DPRINTF ((message (" %s and %s are not same", constraintTerm_print(term1), constraintTerm_print(term2) ) )); + else + { + DPRINTF ((message (" %q and %q are not same", s1, s2 ) ) ); return FALSE; - } - + } +} + +bool constraintTerm_similar (constraintTerm term1, constraintTerm term2) +{ + sRef s1, s2; + + llassert (term1 !=NULL && term2 !=NULL); + + if (constraintTerm_canGetValue (term1) && constraintTerm_canGetValue (term2)) + /* evans 2001-07-24: was (term1->kind == INTLITERAL) && (term2->kind == INTLITERAL) ) */ + { + long t1, t2; + + t1 = constraintTerm_getValue (term1); + t2 = constraintTerm_getValue (term2); + + return (t1 == t2); + } + + if (constraintTerm_canGetValue (term1) || constraintTerm_canGetValue (term2)) + { + /* evans 2001-07-24: is this right? */ /*@i534@*/ + return FALSE; + } + + s1 = constraintTerm_getsRef (term1); + s2 = constraintTerm_getsRef (term2); + + if (!(sRef_isValid(s1) && sRef_isValid(s2))) + { + return FALSE; + } + + DPRINTF( (message + ("Comparing srefs for %s and %s ", constraintTerm_print(term1), constraintTerm_print(term2) + ) + ) + ); + + if (sRef_similarRelaxed(s1, s2) || sRef_sameName (s1, s2) ) + { + DPRINTF ((message (" %s and %s are same", constraintTerm_print(term1), constraintTerm_print(term2) ) )); + return TRUE; + } + else + { + DPRINTF ((message (" %s and %s are not same", constraintTerm_print(term1), constraintTerm_print(term2) ) )); + return FALSE; + } } +void constraintTerm_dump ( /*@observer@*/ constraintTerm t, FILE *f) +{ + fileloc loc; + constraintTermValue value; + constraintTermType kind; + uentry u; + + loc = t->loc; + + value = t->value; + + kind = t->kind; + + fprintf(f, "%d\n", (int) kind); + + switch (kind) + { + + case EXPRNODE: + u = exprNode_getUentry(t->value.expr); + fprintf(f, "%s\n", cstring_toCharsSafe( uentry_rawName (u) ) + ); + break; + + case SREF: + { + sRef s; + + s = t->value.sref; + + if (sRef_isResult (s ) ) + { + fprintf(f, "Result\n"); + } + else if (sRef_isParam (s ) ) + { + int param; + ctype ct; + cstring ctString; + + + ct = sRef_getType (s); + param = sRef_getParam(s); + + ctString = ctype_dump(ct); + + fprintf(f, "Param %s %d\n", cstring_toCharsSafe(ctString), (int) param ); + cstring_free(ctString); + } + else + { + u = sRef_getUentry(s); + fprintf(f, "%s\n", cstring_toCharsSafe(uentry_rawName (u) ) ); + } + + } + break; + + case INTLITERAL: + fprintf (f, "%ld\n", t->value.intlit); + break; + + default: + BADEXIT; + } + +} + + +/*@only@*/ constraintTerm constraintTerm_undump ( FILE *f) +{ + constraintTermType kind; + constraintTerm ret; + + uentry ue; + + char *str; + char *os; + + str = mstring_create (MAX_DUMP_LINE_LENGTH); + os = str; + str = fgets (os, MAX_DUMP_LINE_LENGTH, f); + + kind = (constraintTermType) reader_getInt(&str); + str = fgets(os, MAX_DUMP_LINE_LENGTH, f); + + switch (kind) + { + + case SREF: + { + sRef s; + char * term; + term = reader_getWord(&str); + + if (strcmp (term, "Result") == 0 ) + { + s = sRef_makeResult (ctype_unknown); + } + else if (strcmp (term, "Param" ) == 0 ) + { + int param; + char *str2, *ostr2; + + ctype t; + + reader_checkChar(&str, ' '); + str2 = reader_getWord(&str); + param = reader_getInt(&str); + + ostr2 = str2; + t = ctype_undump(&str2) ; + s = sRef_makeParam (param, t, stateInfo_makeLoc (g_currentloc)); + free (ostr2); + } + else //This must be an identified that we can search for + // in usymTab + { + cstring termStr = cstring_makeLiteralTemp(term); + + ue = usymtab_lookup (termStr); + s = uentry_getSref(ue); + } + + ret = constraintTerm_makesRef(s); + + free(term); + } + break; + + case EXPRNODE: + { + sRef s; + char * term; + cstring termStr; + + term = reader_getWord(&str); + //This must be an identifier that we can search for + // in usymTab + termStr = cstring_makeLiteralTemp(term); + + ue = usymtab_lookup (termStr); + s = uentry_getSref(ue); + ret = constraintTerm_makesRef(s); + + free (term); + } + break; + + + case INTLITERAL: + { + int i; + + i = reader_getInt(&str); + ret = constraintTerm_makeIntLiteral (i); + } + break; + + default: + BADEXIT; + } + free (os); + + return ret; +} + + + +