X-Git-Url: http://andersk.mit.edu/gitweb/splint.git/blobdiff_plain/a779b61ede06125b00b12afe408f1ef829720862..a9ec328054b628447830161535f4915f715f49cd:/src/constraintTerm.c?ds=sidebyside diff --git a/src/constraintTerm.c b/src/constraintTerm.c index 3c4a6c1..60fe051 100644 --- a/src/constraintTerm.c +++ b/src/constraintTerm.c @@ -1,11 +1,35 @@ /* -** constraintExpr.c +** Splint - annotation-assisted static program checker +** Copyright (C) 1994-2003 University of Virginia, +** Massachusetts Institute of Technology +** +** This program is free software; you can redistribute it and/or modify it +** under the terms of the GNU General Public License as published by the +** Free Software Foundation; either version 2 of the License, or (at your +** option) any later version. +** +** This program is distributed in the hope that it will be useful, but +** WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +** General Public License for more details. +** +** The GNU General Public License is available from http://www.gnu.org/ or +** the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, +** MA 02111-1307, USA. +** +** For information on splint: info@splint.org +** To report a bug: splint-bug@splint.org +** For more information: http://www.splint.org */ -//#define DEBUGPRINT 1 +/* +** constraintTerm.c +*/ + +/* #define DEBUGPRINT 1 */ # include /* for isdigit */ -# include "lclintMacros.nf" +# include "splintMacros.nf" # include "basic.h" # include "cgrammar.h" # include "cgrammar_tokens.h" @@ -13,19 +37,11 @@ # include "exprChecks.h" # include "exprNodeSList.h" -/*@-czechfcns@*/ - -//#include "constraintExpr.h" - -/*@access exprNode @*/ - bool constraintTerm_isDefined (constraintTerm t) { return t != NULL; } -/*@unused@*/ static bool constraintTerm_same (constraintTerm p_term1, constraintTerm p_term2) ; - void constraintTerm_free (/*@only@*/ constraintTerm term) { llassert (constraintTerm_isDefined (term)); @@ -34,23 +50,23 @@ void constraintTerm_free (/*@only@*/ constraintTerm term) switch (term->kind) { - case EXPRNODE: + case CTT_EXPR: /* we don't free an exprNode*/ break; - case SREF: + case CTT_SREF: /* sref */ sRef_free (term->value.sref); break; - case INTLITERAL: + case CTT_INTLITERAL: /* don't free an int */ break; - case ERRORBADCONSTRAINTTERMTYPE: + case CTT_ERRORBADCONSTRAINTTERMTYPE: default: /* type was set incorrectly */ llcontbug (message("constraintTerm_free type was set incorrectly")); } - // term->value.intlit = 0; - term->kind = ERRORBADCONSTRAINTTERMTYPE; + + term->kind = CTT_ERRORBADCONSTRAINTTERMTYPE; free (term); } @@ -67,7 +83,7 @@ bool constraintTerm_isIntLiteral (constraintTerm term) { llassert(term != NULL); - if (term->kind == INTLITERAL) + if (term->kind == CTT_INTLITERAL) return TRUE; return FALSE; @@ -77,10 +93,10 @@ bool constraintTerm_isIntLiteral (constraintTerm term) bool constraintTerm_isInitBlock (/*@observer@*/ /*@temp@*/ constraintTerm c) /*@*/ { llassert (c != NULL); - if (c->kind == EXPRNODE) + + if (c->kind == CTT_EXPR) { - - if (exprNode_isInitBlock(c->value.expr) ) + if (exprNode_isInitBlock (c->value.expr)) { return TRUE; } @@ -92,22 +108,22 @@ bool constraintTerm_isInitBlock (/*@observer@*/ /*@temp@*/ constraintTerm c) /*@ bool constraintTerm_isExprNode (/*@observer@*/ /*@temp@*/ constraintTerm c) /*@*/ { llassert (c != NULL); - if (c->kind == EXPRNODE) + + if (c->kind == CTT_EXPR) { return TRUE; } return FALSE; } - +/*@access exprNode@*/ int constraintTerm_getInitBlockLength (/*@observer@*/ /*@temp@*/ constraintTerm c) /*@*/ { - - exprNodeList list; + exprNodeList list; int ret; llassert (c != NULL); llassert (constraintTerm_isInitBlock (c) ); - llassert (c->kind == EXPRNODE); + llassert (c->kind == CTT_EXPR); llassert(exprNode_isDefined(c->value.expr) ); @@ -126,13 +142,13 @@ int constraintTerm_getInitBlockLength (/*@observer@*/ /*@temp@*/ constraintTerm return ret; } - +/*@noaccess exprNode@*/ bool constraintTerm_isStringLiteral (constraintTerm c) /*@*/ { llassert (c != NULL); - if (c->kind == EXPRNODE) + if (c->kind == CTT_EXPR) { if (exprNode_knownStringValue(c->value.expr) ) { @@ -148,14 +164,14 @@ cstring constraintTerm_getStringLiteral (constraintTerm c) { llassert (c != NULL); llassert (constraintTerm_isStringLiteral (c) ); - llassert (c->kind == EXPRNODE); + llassert (c->kind == CTT_EXPR); return (cstring_copy ( multiVal_forceString (exprNode_getValue (c->value.expr) ) ) ); } constraintTerm constraintTerm_simplify (/*@returned@*/ constraintTerm term) /*@modifies term@*/ { - if (term->kind == EXPRNODE) + if (term->kind == CTT_EXPR) { if ( exprNode_knownIntValue (term->value.expr ) ) { @@ -163,7 +179,7 @@ constraintTerm constraintTerm_simplify (/*@returned@*/ constraintTerm term) /*@m temp = exprNode_getLongValue (term->value.expr); term->value.intlit = (int)temp; - term->kind = INTLITERAL; + term->kind = CTT_INTLITERAL; } } return term; @@ -185,27 +201,27 @@ constraintTermType constraintTerm_getKind (constraintTerm t) /*@exposed@*/ sRef constraintTerm_getSRef (constraintTerm t) { llassert (constraintTerm_isDefined(t) ); - llassert (t->kind == SREF); + llassert (t->kind == CTT_SREF); return (t->value.sref); } -/*@only@*/ constraintTerm constraintTerm_makeExprNode (/*@dependent@*/ exprNode e) +/*@only@*/ constraintTerm constraintTerm_makeExprNode (/*@dependent@*/ exprNode e) { - constraintTerm ret = new_constraintTermExpr(); - ret->loc = fileloc_copy(exprNode_getfileloc(e)); + constraintTerm ret = new_constraintTermExpr (); + ret->loc = fileloc_copy (exprNode_loc (e)); ret->value.expr = e; - ret->kind = EXPRNODE; - ret = constraintTerm_simplify(ret); + ret->kind = CTT_EXPR; + ret = constraintTerm_simplify (ret); return ret; } -/*@only@*/ constraintTerm constraintTerm_makesRef (/*@temp@*/ /*@observer@*/ sRef s) +/*@only@*/ constraintTerm constraintTerm_makesRef (/*@temp@*/ /*@observer@*/ sRef s) { constraintTerm ret = new_constraintTermExpr(); ret->loc = fileloc_undefined; ret->value.sref = sRef_saveCopy(s); - ret->kind = SREF; + ret->kind = CTT_SREF; ret = constraintTerm_simplify(ret); return ret; } @@ -220,14 +236,14 @@ constraintTerm constraintTerm_copy (constraintTerm term) switch (term->kind) { - case EXPRNODE: + case CTT_EXPR: ret->value.expr = term->value.expr; break; - case INTLITERAL: + case CTT_INTLITERAL: ret->value.intlit = term->value.intlit; break; - case SREF: + case CTT_SREF: ret->value.sref = sRef_saveCopy(term->value.sref); break; default: @@ -258,15 +274,15 @@ static cstring constraintTerm_getName (constraintTerm term) switch (term->kind) { - case EXPRNODE: - /*@i334*/ //wtf + case CTT_EXPR: + s = message ("%s", exprNode_unparse (term->value.expr) ); break; - case INTLITERAL: + case CTT_INTLITERAL: s = message (" %d ", (int) term->value.intlit); break; - case SREF: + case CTT_SREF: s = message ("%q", sRef_unparse (term->value.sref) ); break; @@ -286,19 +302,14 @@ constraintTerm_doSRefFixBaseParam (/*@returned@*/constraintTerm term, exprNodeLi switch (term->kind) { - case EXPRNODE: - /*@i334*/ //wtf - // s = message ("%s @ %s ", exprNode_unparse (term->value.expr), - // fileloc_unparse (term->loc) ); + case CTT_EXPR: + + break; + case CTT_INTLITERAL: break; - case INTLITERAL: - // s = message (" %d ", term->value.intlit); - break; - case SREF: + case CTT_SREF: term->value.sref = sRef_fixBaseParam (term->value.sref, arglist); - // s = message ("%s ", sRef_unparse (term->value.sref) ); - break; default: BADEXIT; @@ -307,7 +318,7 @@ constraintTerm_doSRefFixBaseParam (/*@returned@*/constraintTerm term, exprNodeLi } -cstring constraintTerm_print (constraintTerm term) /*@*/ +cstring constraintTerm_unparse (constraintTerm term) /*@*/ { cstring s; s = cstring_undefined; @@ -316,16 +327,16 @@ cstring constraintTerm_print (constraintTerm term) /*@*/ switch (term->kind) { - case EXPRNODE: - /*@i334*/ //wtf + case CTT_EXPR: + s = message ("%s @ %q", exprNode_unparse (term->value.expr), fileloc_unparse (term->loc) ); break; - case INTLITERAL: + case CTT_INTLITERAL: s = message ("%d", (int)term->value.intlit); break; - case SREF: + case CTT_SREF: s = message ("%q", sRef_unparseDebug (term->value.sref) ); break; @@ -341,18 +352,18 @@ constraintTerm constraintTerm_makeIntLiteral (long i) { constraintTerm ret = new_constraintTermExpr(); ret->value.intlit = i; - ret->kind = INTLITERAL; + ret->kind = CTT_INTLITERAL; ret->loc = fileloc_undefined; return ret; } bool constraintTerm_canGetValue (constraintTerm term) { - if (term->kind == INTLITERAL) + if (term->kind == CTT_INTLITERAL) { return TRUE; } - else if (term->kind == SREF) + else if (term->kind == CTT_SREF) { if (sRef_hasValue (term->value.sref)) { @@ -365,7 +376,7 @@ bool constraintTerm_canGetValue (constraintTerm term) return FALSE; } } - else if (term->kind == EXPRNODE) + else if (term->kind == CTT_EXPR) { return FALSE; } @@ -375,15 +386,27 @@ bool constraintTerm_canGetValue (constraintTerm term) } } +void constraintTerm_setValue (constraintTerm term, long value) +{ + if (term->kind == CTT_INTLITERAL) + { + term->value.intlit = value; + } + else + { + BADBRANCH; + } +} + long constraintTerm_getValue (constraintTerm term) { llassert (constraintTerm_canGetValue (term)); - if (term->kind == INTLITERAL) + if (term->kind == CTT_INTLITERAL) { return term->value.intlit; } - else if (term->kind == SREF) + else if (term->kind == CTT_SREF) { if (sRef_hasValue (term->value.sref)) { @@ -396,7 +419,7 @@ long constraintTerm_getValue (constraintTerm term) BADBRANCH; } } - else if (term->kind == EXPRNODE) + else if (term->kind == CTT_EXPR) { BADBRANCH; } @@ -408,44 +431,28 @@ long constraintTerm_getValue (constraintTerm term) BADEXIT; } -/* same and similar are similar but not the same*/ -static bool constraintTerm_same (constraintTerm term1, constraintTerm term2) +/*drl added this 10.30.001 + */ + +/*@exposed@*/ exprNode constraintTerm_getExprNode (constraintTerm t) { - llassert (term1 !=NULL && term2 !=NULL); + llassert (t != NULL); + + llassert (t->kind == CTT_EXPR); + + return t->value.expr; - if ( (term1->kind != term2->kind) || (term1->kind != EXPRNODE) ) - { - return FALSE; - } - - 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) ) )); - return TRUE; - } - else - { - DPRINTF ((message (" %s and %s are not same", constraintTerm_print(term1), constraintTerm_print(term2) ) )); - return FALSE; - } - } -static /*@exposed@*/ sRef constraintTerm_getsRef (constraintTerm t) + /*@exposed@*/ sRef constraintTerm_getsRef (constraintTerm t) { llassert (t != NULL); - if (t->kind == EXPRNODE) + if (t->kind == CTT_EXPR) { return exprNode_getSref(t->value.expr); } - if (t->kind == SREF) + if (t->kind == CTT_SREF) { return t->value.sref; } @@ -459,7 +466,7 @@ bool constraintTerm_probSame (constraintTerm term1, constraintTerm term2) llassert (term1 !=NULL && term2 !=NULL); - DPRINTF ( (message + DPRINTF ((message ("Comparing srefs for %s and %s ", constraintTerm_print(term1), constraintTerm_print(term2) ) ) @@ -487,7 +494,9 @@ bool constraintTerm_similar (constraintTerm term1, constraintTerm term2) llassert (term1 !=NULL && term2 !=NULL); if (constraintTerm_canGetValue (term1) && constraintTerm_canGetValue (term2)) - /* evans 2001-07-24: was (term1->kind == INTLITERAL) && (term2->kind == INTLITERAL) ) */ + + /*3/30/2003 comment updated to reflect name change form INTLITERAL to CTT_INTLITERAL*/ + /* evans 2001-07-24: was (term1->kind == CTT_INTLITERAL) && (term2->kind == CTT_INTLITERAL) ) */ { long t1, t2; @@ -496,10 +505,16 @@ bool constraintTerm_similar (constraintTerm term1, constraintTerm term2) return (t1 == t2); } - + + /*drl this if statement handles the case where constraintTerm_canGetValue only returns + true for term1 or term2 but no both + if constraintTerm_canGetValue returned tru for both we would have returned in the previous if statement + I suppose this could be done with xor but I've never used xor and don't feel like starting now + besides this way is more effecient. + */ if (constraintTerm_canGetValue (term1) || constraintTerm_canGetValue (term2)) { - /* evans 2001-07-24: is this right? */ /*@i534@*/ + return FALSE; } @@ -511,7 +526,7 @@ bool constraintTerm_similar (constraintTerm term1, constraintTerm term2) return FALSE; } - DPRINTF( (message + DPRINTF((message ("Comparing srefs for %s and %s ", constraintTerm_print(term1), constraintTerm_print(term2) ) ) @@ -529,7 +544,7 @@ bool constraintTerm_similar (constraintTerm term1, constraintTerm term2) } } -void constraintTerm_dump ( /*@observer@*/ constraintTerm t, FILE *f) +void constraintTerm_dump (/*@observer@*/ constraintTerm t, FILE *f) { fileloc loc; constraintTermValue value; @@ -547,13 +562,12 @@ void constraintTerm_dump ( /*@observer@*/ constraintTerm t, FILE *f) switch (kind) { - case EXPRNODE: + case CTT_EXPR: u = exprNode_getUentry(t->value.expr); - fprintf(f, "%s\n", cstring_toCharsSafe( uentry_rawName (u) ) - ); + fprintf (f, "%s\n", cstring_toCharsSafe (uentry_rawName (u))); break; - case SREF: + case CTT_SREF: { sRef s; @@ -563,7 +577,7 @@ void constraintTerm_dump ( /*@observer@*/ constraintTerm t, FILE *f) { fprintf(f, "Result\n"); } - else if (sRef_isParam (s ) ) + else if (sRef_isParam (s)) { int param; ctype ct; @@ -578,16 +592,20 @@ void constraintTerm_dump ( /*@observer@*/ constraintTerm t, FILE *f) fprintf(f, "Param %s %d\n", cstring_toCharsSafe(ctString), (int) param ); cstring_free(ctString); } + else if (sRef_isField (s) ) + { + fprintf(f, "sRef_dump %s\n", cstring_toCharsSafe(sRef_dump(s)) ); + } else { u = sRef_getUentry(s); - fprintf(f, "%s\n", cstring_toCharsSafe(uentry_rawName (u) ) ); + fprintf (f, "%s\n", cstring_toCharsSafe (uentry_rawName (u))); } } break; - case INTLITERAL: + case CTT_INTLITERAL: fprintf (f, "%ld\n", t->value.intlit); break; @@ -598,7 +616,7 @@ void constraintTerm_dump ( /*@observer@*/ constraintTerm t, FILE *f) } -/*@only@*/ constraintTerm constraintTerm_undump ( FILE *f) +/*@only@*/ constraintTerm constraintTerm_undump (FILE *f) { constraintTermType kind; constraintTerm ret; @@ -608,22 +626,30 @@ void constraintTerm_dump ( /*@observer@*/ constraintTerm t, FILE *f) char *str; char *os; - str = mstring_create (MAX_DUMP_LINE_LENGTH); - os = str; + os = mstring_create (MAX_DUMP_LINE_LENGTH); + str = fgets (os, MAX_DUMP_LINE_LENGTH, f); + llassert (str != NULL); + kind = (constraintTermType) reader_getInt(&str); str = fgets(os, MAX_DUMP_LINE_LENGTH, f); + llassert (str != NULL); + switch (kind) { - case SREF: + case CTT_SREF: { sRef s; char * term; term = reader_getWord(&str); - + + if (term == NULL) + { + llfatalbug (message ("Library file appears to be corrupted.") ); + } if (strcmp (term, "Result") == 0 ) { s = sRef_makeResult (ctype_unknown); @@ -639,13 +665,22 @@ void constraintTerm_dump ( /*@observer@*/ constraintTerm t, FILE *f) str2 = reader_getWord(&str); param = reader_getInt(&str); + if (str2 == NULL) + { + llfatalbug (message ("Library file appears to be corrupted.") ); + } + ostr2 = str2; t = ctype_undump(&str2) ; - s = sRef_makeParam (param, t, stateInfo_makeLoc (g_currentloc)); + s = sRef_makeParam (param, t, stateInfo_makeLoc (g_currentloc, SA_CREATED)); free (ostr2); } - else //This must be an identified that we can search for - // in usymTab + else if (strcmp (term, "sRef_dump" ) == 0 ) + { + reader_checkChar(&str, ' '); + s = sRef_undump (&str); + } + else /* This must be an identified that we can search for in usymTab */ { cstring termStr = cstring_makeLiteralTemp(term); @@ -659,15 +694,20 @@ void constraintTerm_dump ( /*@observer@*/ constraintTerm t, FILE *f) } break; - case EXPRNODE: + case CTT_EXPR: { sRef s; char * term; cstring termStr; term = reader_getWord(&str); - //This must be an identifier that we can search for - // in usymTab + + if (term == NULL) + { + llfatalbug (message ("Library file appears to be corrupted.") ); + } + + /* This must be an identifier that we can search for in usymTab */ termStr = cstring_makeLiteralTemp(term); ue = usymtab_lookup (termStr); @@ -679,7 +719,7 @@ void constraintTerm_dump ( /*@observer@*/ constraintTerm t, FILE *f) break; - case INTLITERAL: + case CTT_INTLITERAL: { int i; @@ -698,4 +738,61 @@ void constraintTerm_dump ( /*@observer@*/ constraintTerm t, FILE *f) +/* drl added sometime before 10/17/001*/ +ctype constraintTerm_getCType (constraintTerm term) +{ + ctype ct; + + switch (term->kind) + { + case CTT_EXPR: + ct = exprNode_getType (term->value.expr); + break; + case CTT_INTLITERAL: + ct = ctype_signedintegral; + break; + + case CTT_SREF: + ct = sRef_getType (term->value.sref) ; + break; + default: + BADEXIT; + } + return ct; +} + +bool constraintTerm_isConstantOnly (constraintTerm term) +{ + switch (term->kind) + { + case CTT_EXPR: + if (exprNode_isNumLiteral (term->value.expr) || + exprNode_isStringLiteral (term->value.expr) || + exprNode_isCharLiteral (term->value.expr) ) + { + return TRUE; + } + else + { + return FALSE; + } + + case CTT_INTLITERAL: + return TRUE; + + case CTT_SREF: + if ( sRef_isConst (term->value.sref) ) + { + return TRUE; + } + else + { + return FALSE; + } + default: + BADEXIT; + } + + BADEXIT; +}