X-Git-Url: http://andersk.mit.edu/gitweb/splint.git/blobdiff_plain/885824d34f6f6626fde2fb041801408cbaf1f6f1..3fbe4d6066e3f1d814e19d1e03d8cc6719cc0ad9:/src/ctbase.i diff --git a/src/ctbase.i b/src/ctbase.i index ed316bc..ebb1612 100644 --- a/src/ctbase.i +++ b/src/ctbase.i @@ -20,17 +20,17 @@ ** ctbase.i ** ** NOTE: This is not a stand-alone source file, but is included in ctype.c. -** (This is necessary becuase there is no other way in C to have a +** (This is necessary because there is no other way in C to have a ** hidden scope, besides at the file level.) */ /*@access cprim*/ -typedef /*@null@*/ struct __ctbase *ctbase; +abst_typedef /*@null@*/ struct s_ctbase *ctbase; -typedef struct _ctentry { +/*@private@*/ typedef struct { ctkind kind; - ctbase ctbase; + ctbase ctbase; ctype base; /* type I point to (or element of array) */ ctype ptr; /* type of pointer to me */ ctype array; /* type of array of me */ @@ -39,7 +39,7 @@ typedef struct _ctentry { typedef /*@only@*/ ctentry o_ctentry; -typedef struct _cttable { +typedef struct { int size; int nspace; /*@relnull@*/ /*@only@*/ o_ctentry *entries; @@ -114,14 +114,12 @@ static /*@notnull@*/ /*@only@*/ ctbase ctbase_createEnum (/*@keep@*/ cstring p_e static /*@notnull@*/ /*@only@*/ ctbase ctbase_createUnknown (void); static bool ctbase_match (ctbase p_c1, ctbase p_c2) /*@modifies nothing@*/; static bool ctbase_matchDef (ctbase p_c1, ctbase p_c2) /*@modifies nothing@*/; -static bool ctbase_genMatch (ctbase p_c1, ctbase p_c2, bool p_force, bool p_arg, bool p_def); +static bool ctbase_genMatch (ctbase p_c1, ctbase p_c2, bool p_force, bool p_arg, bool p_def, bool p_deep); static bool ctbase_isAbstract (/*@notnull@*/ ctbase p_c) /*@*/ ; static /*@notnull@*/ /*@only@*/ ctbase ctbase_makePointer (ctype p_b) /*@*/ ; static /*@notnull@*/ /*@only@*/ ctbase ctbase_makeArray (ctype p_b) /*@*/ ; static /*@notnull@*/ ctype ctbase_makeFunction (ctype p_b, /*@only@*/ uentryList p_p) /*@*/ ; -static /*@notnull@*/ /*@only@*/ ctbase - ctbase_makeRealFunction (ctype p_b, /*@dependent@*/ uentryList p_p) /*@*/ ; static /*@notnull@*/ /*@observer@*/ ctbase ctbase_realFunction (/*@notnull@*/ /*@dependent@*/ ctbase p_c) /*@*/ ; static ctype ctbase_baseArrayPtr (/*@notnull@*/ ctbase p_c) /*@*/ ; @@ -137,39 +135,38 @@ extern int cttable_lastIndex(); # define cttable_lastIndex() (cttab.size - 1) /*@=macroundef@*/ -typedef struct _cfcn +typedef struct { ctype rval; - /*@dependent@*/ uentryList params; /* params are owned if liveparams is TRUE */ - bool liveparams; + /*@only@*/ uentryList params; } *cfcn; -typedef struct _tsu +typedef struct { cstring name; uentryList fields; } *tsu; -typedef struct _tconj +typedef struct { ctype a; ctype b; bool isExplicit; } *tconj; -typedef struct _tenum +typedef struct { cstring tag; enumNameList members; } *tenum; -typedef struct _tfixed +typedef struct { ctype base; long size; } *tfixed; -typedef union _uconts +typedef union { cprim prim; /* primitive */ typeId tid; /* abstract, user */ @@ -181,7 +178,7 @@ typedef union _uconts tfixed farray; /* fixed array */ } uconts; -struct __ctbase +struct s_ctbase { ctuid type; uconts contents; @@ -283,11 +280,11 @@ static /*@notnull@*/ /*@only@*/ ctbase static ctype ctbase_getConjA (/*@notnull@*/ ctbase p_c) /*@*/ ; static ctype ctbase_getConjB (/*@notnull@*/ ctbase p_c) /*@*/ ; static bool ctbase_isExplicitConj (/*@notnull@*/ ctbase p_c) /*@*/ ; -static bool ctbase_forceMatch (ctbase p_c1, ctbase p_c2); +static bool ctbase_forceMatch (ctbase p_c1, ctbase p_c2) /*@modifies p_c1, p_c2@*/ ; static /*@notnull@*/ /*@only@*/ ctbase ctbase_expectFunction (ctype p_c); static bool ctbase_isVoidPointer(/*@notnull@*/ /*@dependent@*/ ctbase p_c) /*@*/ ; -static bool ctbase_isUnion (/*@notnull@*/ /*@dependent@*/ ctbase p_c) /*@*/ ; -static bool ctbase_isStruct (/*@notnull@*/ /*@dependent@*/ ctbase p_c) /*@*/ ; +static bool ctbase_isUnion (/*@notnull@*/ /*@temp@*/ ctbase p_c) /*@*/ ; +static bool ctbase_isStruct (/*@notnull@*/ /*@temp@*/ ctbase p_c) /*@*/ ; static /*@observer@*/ cstring ctbase_enumTag (/*@notnull@*/ ctbase p_ct) /*@*/ ; static /*@only@*/ cstring ctbase_unparseNotypes (ctbase p_c) /*@*/ ; @@ -295,7 +292,14 @@ static /*@out@*/ /*@notnull@*/ /*@only@*/ ctbase ctbase_new (void) /*@*/ ; static int nctbases = 0; static /*@notnull@*/ /*@only@*/ - ctbase ctbase_makeLiveFunction (ctype p_b, /*@owned@*/ uentryList p_p); + ctbase ctbase_makeLiveFunction (ctype p_b, /*@only@*/ uentryList p_p); + +static bool ctbase_isUnnamedSU (ctbase c) +{ + return (ctbase_isDefined (c) + && (ctbase_isStruct (c) || ctbase_isUnion (c)) + && isFakeTag (c->contents.su->name)); +} static /*@observer@*/ ctbase ctbase_realType (ctbase c) { @@ -365,7 +369,7 @@ ctbase_isStruct (/*@notnull@*/ ctbase c) } static bool -ctbase_isUnion (/*@notnull@*/ /*@dependent@*/ ctbase c) +ctbase_isUnion (/*@notnull@*/ ctbase c) { ctbase r = ctbase_realType (c); @@ -438,8 +442,15 @@ ctbase_typeId (ctbase c) } else { - llcontbug (message ("ctbase_typeId: bad call: %q", ctbase_unparse (c))); - return typeId_invalid; + if (ctbase_isConj (c)) + { + return ctbase_typeId (ctype_getCtbase (ctbase_getConjA (c))); + } + else + { + llcontbug (message ("ctbase_typeId: bad call: %q", ctbase_unparse (c))); + return typeId_invalid; + } } } @@ -493,7 +504,8 @@ ctbase_unparse (ctbase c) } else { - return (message ("struct { %q }", uentryList_unparseAbbrev (c->contents.su->fields))); + return (message ("struct { %q }", + uentryList_unparseAbbrev (c->contents.su->fields))); } case CT_UNION: if (cstring_isDefined (c->contents.su->name) && @@ -788,33 +800,33 @@ static ctbase ctbase_undump (d_char *c) case 'b': return (ctbase_createBool ()); case 'p': - res = ctbase_createPrim (cprim_fromInt (getInt (c))); - checkChar (c, '|'); + res = ctbase_createPrim (cprim_fromInt (reader_getInt (c))); + reader_checkChar (c, '|'); return res; case 's': - res = ctbase_createUser (typeId_fromInt (getInt (c))); - checkChar (c, '|'); + res = ctbase_createUser (typeId_fromInt (reader_getInt (c))); + reader_checkChar (c, '|'); return res; case 'a': - res = ctbase_createAbstract (typeId_fromInt (getInt (c))); - checkChar (c, '|'); + res = ctbase_createAbstract (typeId_fromInt (reader_getInt (c))); + reader_checkChar (c, '|'); return res; case 't': res = ctbase_makePointer (ctype_undump (c)); - checkChar (c, '|'); + reader_checkChar (c, '|'); return res; case 'y': res = ctbase_makeArray (ctype_undump (c)); - checkChar (c, '|'); + reader_checkChar (c, '|'); return res; case 'F': { ctype ct = ctype_undump (c); int size; - checkChar (c, '/'); - size = getInt (c); - checkChar (c, '|'); + reader_checkChar (c, '/'); + size = reader_getInt (c); + reader_checkChar (c, '|'); return (ctbase_makeFixedArray (ct, size)); } case 'f': @@ -911,12 +923,12 @@ static ctbase ctbase_undump (d_char *c) bool isExplicit; ctype c1, c2; - isExplicit = bool_fromInt (getInt (c)); - checkChar (c, '.'); + isExplicit = bool_fromInt (reader_getInt (c)); + reader_checkChar (c, '.'); c1 = ctype_undump (c); - checkChar (c, '/'); + reader_checkChar (c, '/'); c2 = ctype_undump (c); - checkChar (c, '|'); + reader_checkChar (c, '|'); return (ctbase_makeConj (c1, c2, isExplicit)); } @@ -981,6 +993,7 @@ ctbase_dump (ctbase c) ctype_dump (c->contents.farray->base), (int) c->contents.farray->size)); case CT_FCN: + DPRINTF (("Dump function: %s", ctbase_unparse (c))); return (message ("f%q (%q)", ctype_dump (c->contents.fcn->rval), uentryList_dumpParams (c->contents.fcn->params))); case CT_STRUCT: @@ -1113,17 +1126,7 @@ ctbase_free (/*@only@*/ ctbase c) sfree (c); break; case CT_FCN: - - if (c->contents.fcn->liveparams) - { - /* Because of liveparams, we know this can be released. */ - - /*@-dependenttrans@*/ /*@-unqualifiedtrans@*/ - uentryList_free (c->contents.fcn->params); - c->contents.fcn->params = NULL; - /*@=dependenttrans@*/ /*@=unqualifiedtrans@*/ - } - + /*@i32@*/ /* uentryList_free (c->contents.fcn->params); */ sfree (c); break; case CT_STRUCT: @@ -1158,7 +1161,7 @@ ctbase_expectFunction (ctype c) } static bool -ctbase_genMatch (ctbase c1, ctbase c2, bool force, bool arg, bool def) +ctbase_genMatch (ctbase c1, ctbase c2, bool force, bool arg, bool def, bool deep) { ctuid c1tid, c2tid; @@ -1172,23 +1175,26 @@ ctbase_genMatch (ctbase c1, ctbase c2, bool force, bool arg, bool def) c1 = ctbase_realType (c1); c2 = ctbase_realType (c2); + DPRINTF (("Matching: %s / %s", ctbase_unparse (c1), + ctbase_unparse (c2))); + c1tid = c1->type; c2tid = c2->type; if (c1tid == CT_CONJ) { return (ctbase_genMatch (ctype_getCtbase (c1->contents.conj->a), c2, - force, arg, def) + force, arg, def, deep) || ctbase_genMatch (ctype_getCtbase (c1->contents.conj->b), c2, - force, arg, def)); + force, arg, def, deep)); } if (c2tid == CT_CONJ) { return (ctbase_genMatch (c1, ctype_getCtbase (c2->contents.conj->a), - force, arg, def) + force, arg, def, deep) || ctbase_genMatch (c1, ctype_getCtbase (c2->contents.conj->b), - force, arg, def)); + force, arg, def, deep)); } /* @@ -1216,7 +1222,7 @@ ctbase_genMatch (ctbase c1, ctbase c2, bool force, bool arg, bool def) return (ctbase_genMatch (ctype_getCtbase (c1->contents.farray->base), ctype_getCtbase (c2->contents.base), - force, arg, def)); + force, arg, def, deep)); } @@ -1232,11 +1238,11 @@ ctbase_genMatch (ctbase c1, ctbase c2, bool force, bool arg, bool def) return (ctbase_genMatch (ctype_getCtbase (c1->contents.base), ctype_getCtbase (c2->contents.farray->base), - force, arg, def)); + force, arg, def, deep)); } - /* in most cases, bool and int are matched if FLG_BOOLINT */ - + /* evs 2000-07-25: Bool's may match user/abstract types */ + if ((c1tid == CT_BOOL && (c2tid == CT_PRIM && cprim_isInt (c2->contents.prim))) || (c2tid == CT_BOOL @@ -1245,6 +1251,18 @@ ctbase_genMatch (ctbase c1, ctbase c2, bool force, bool arg, bool def) return (context_msgBoolInt ()); } + if ((c1tid == CT_BOOL && (c2tid == CT_ABST || c2tid == CT_USER))) { + ctype t2c = c2->contents.base; + + return (ctype_isBool (t2c)); + } + + if ((c2tid == CT_BOOL && (c1tid == CT_ABST || c1tid == CT_USER))) { + ctype t1c = c1->contents.base; + + return (ctype_isBool (t1c)); + } + if ((c1tid == CT_ENUM && (c2tid == CT_PRIM && cprim_isInt (c2->contents.prim))) || (c2tid == CT_ENUM @@ -1352,7 +1370,11 @@ ctbase_genMatch (ctbase c1, ctbase c2, bool force, bool arg, bool def) case CT_UNKNOWN: return (TRUE); case CT_PRIM: - return (cprim_closeEnough (c1->contents.prim, c2->contents.prim)); + if (deep) { + return (cprim_closeEnoughDeep (c1->contents.prim, c2->contents.prim)); + } else { + return (cprim_closeEnough (c1->contents.prim, c2->contents.prim)); + } case CT_BOOL: return (TRUE); case CT_ABST: @@ -1388,9 +1410,9 @@ ctbase_genMatch (ctbase c1, ctbase c2, bool force, bool arg, bool def) { return FALSE; } - + return (ctype_genMatch (c1->contents.base, - c2->contents.base, force, arg, def)); + c2->contents.base, force, arg, def, TRUE)); } case CT_FIXEDARRAY: if (ctype_isVoid (c1->contents.farray->base) @@ -1398,33 +1420,54 @@ ctbase_genMatch (ctbase c1, ctbase c2, bool force, bool arg, bool def) return TRUE; return (ctype_genMatch (c1->contents.farray->base, c2->contents.farray->base, - force, arg, def)); + force, arg, def, deep)); case CT_ARRAY: if (ctype_isVoid (c1->contents.base) || ctype_isVoid (c2->contents.base)) return TRUE; - return (ctype_genMatch (c1->contents.base, c2->contents.base, force, arg, def)); + return (ctype_genMatch (c1->contents.base, c2->contents.base, force, arg, def, TRUE)); case CT_FCN: return (ctype_genMatch (c1->contents.fcn->rval, c2->contents.fcn->rval, - force, arg, def) + force, arg, def, TRUE) && uentryList_matchParams (c1->contents.fcn->params, c2->contents.fcn->params, force, TRUE)); case CT_STRUCT: case CT_UNION: - if (!cstring_isEmpty (c1->contents.su->name)) + DPRINTF (("Struct: %s / %s", + c1->contents.su->name, + c2->contents.su->name)); + + if (isFakeTag (c1->contents.su->name) + && isFakeTag (c2->contents.su->name)) { - return (cstring_equal (c1->contents.su->name, c2->contents.su->name)); + /* Both fake tags, check structure */ + if (cstring_equal (c1->contents.su->name, c2->contents.su->name)) + { + return TRUE; + } + else + { + return uentryList_matchFields (c1->contents.su->fields, + c2->contents.su->fields); + } } else { - if (!cstring_isEmpty (c2->contents.su->name)) + if (!cstring_isEmpty (c1->contents.su->name)) { - return FALSE; + return (cstring_equal (c1->contents.su->name, c2->contents.su->name)); + } + else + { + if (!cstring_isEmpty (c2->contents.su->name)) + { + return FALSE; + } + + llcontbuglit ("ctbase_genMatch: match fields"); + return (FALSE); } - - llcontbuglit ("ctbase_genMatch: match fields"); - return (FALSE); } default: llcontbug (message ("ctbase_genMatch: unknown type: %d\n", (int)c1tid)); @@ -1438,31 +1481,27 @@ ctbase_genMatch (ctbase c1, ctbase c2, bool force, bool arg, bool def) */ static bool -ctbase_forceMatch (ctbase c1, ctbase c2) +ctbase_forceMatch (ctbase c1, ctbase c2) /*@modifies c1, c2@*/ { - /* - ** modifies c1, c2 - */ - - return (ctbase_genMatch (c1, c2, TRUE, FALSE, FALSE)); + return (ctbase_genMatch (c1, c2, TRUE, FALSE, FALSE, FALSE)); } static bool ctbase_match (ctbase c1, ctbase c2) /*@modifies nothing@*/ { - return (ctbase_genMatch (c1, c2, FALSE, FALSE, FALSE)); + return (ctbase_genMatch (c1, c2, FALSE, FALSE, FALSE, FALSE)); } static bool ctbase_matchDef (ctbase c1, ctbase c2) /*@modifies nothing@*/ { - return (ctbase_genMatch (c1, c2, FALSE, FALSE, TRUE)); + return (ctbase_genMatch (c1, c2, FALSE, FALSE, TRUE, FALSE)); } static bool ctbase_matchArg (ctbase c1, ctbase c2) { - return (ctbase_genMatch (c1, c2, FALSE, TRUE, FALSE)); + return (ctbase_genMatch (c1, c2, FALSE, TRUE, FALSE, FALSE)); } static /*@out@*/ /*@only@*/ /*@notnull@*/ ctbase @@ -1652,14 +1691,12 @@ ctbase_makeFunction (ctype b, /*@only@*/ uentryList p) rval = ctype_makeFunction (ctb->contents.fcn->rval, p); c->contents.fcn->rval = rval; - c->contents.fcn->params = ctb->contents.fcn->params; - c->contents.fcn->liveparams = FALSE; + c->contents.fcn->params = uentryList_copy (ctb->contents.fcn->params); /* no copy before */ } else { c->contents.fcn->rval = b; - /*@i@*/ c->contents.fcn->params = p; - c->contents.fcn->liveparams = TRUE; + c->contents.fcn->params = uentryList_copy (p); /* no copy before */ /*@-branchstate@*/ /* p is really released on this branch */ } /*@=branchstate@*/ @@ -1697,15 +1734,12 @@ ctbase_makeNFFunction (ctype b, /*@only@*/ uentryList p) rval = ctype_makeNFParamsFunction (ctb->contents.fcn->rval, p); c->contents.fcn->rval = rval; - c->contents.fcn->params = ctb->contents.fcn->params; - c->contents.fcn->liveparams = FALSE; + c->contents.fcn->params = uentryList_copy (ctb->contents.fcn->params); } else { c->contents.fcn->rval = b; - /*@i@*/ c->contents.fcn->params = p; - c->contents.fcn->liveparams = TRUE; - + c->contents.fcn->params = uentryList_copy (p); /*@-branchstate@*/ } /*@=branchstate@*/ @@ -1715,7 +1749,7 @@ ctbase_makeNFFunction (ctype b, /*@only@*/ uentryList p) } static /*@only@*/ ctbase - ctbase_makeLiveFunction (ctype b, /*@owned@*/ uentryList p) + ctbase_makeLiveFunction (ctype b, /*@only@*/ uentryList p) { ctbase c = ctbase_new (); @@ -1724,26 +1758,10 @@ static /*@only@*/ ctbase c->contents.fcn = (cfcn) dmalloc (sizeof (*c->contents.fcn)); c->contents.fcn->rval = b; c->contents.fcn->params = p; - c->contents.fcn->liveparams = TRUE; /*@-mustfree@*/ return (c); /*@=mustfree@*/ } -static /*@only@*/ ctbase - ctbase_makeRealFunction (ctype b, /*@dependent@*/ uentryList p) -{ - ctbase c = ctbase_new (); - - c->type = CT_FCN; - - c->contents.fcn = (cfcn) dmalloc (sizeof (*c->contents.fcn)); - c->contents.fcn->rval = b; - c->contents.fcn->params = p; - c->contents.fcn->liveparams = FALSE; - - return (c); -} - static /*@observer@*/ /*@notnull@*/ ctbase ctbase_realFunction (/*@dependent@*/ /*@notnull@*/ ctbase c) { @@ -1920,7 +1938,7 @@ ctbase_baseisExpFcn (ctype c) if (cb->type == CT_FCN) { - c = ctype_removePointers (ctype_returnValue (c)); + c = ctype_removePointers (ctype_getReturnType (c)); cb = ctype_getCtbase (c); llassert (ctbase_isDefined (cb)); @@ -1943,13 +1961,13 @@ ctbase_newBase (ctype c, ctype p) DPRINTF (("New base: %s / %s", ctype_unparse (c), ctype_unparse (p))); - cb = ctype_getCtbase (c); - - if (ctype_isUndefined (c)) + if (ctype_isUndefined (c) || ctype_isUnknown (c)) { return p; } + cb = ctype_getCtbase (c); + if (ctype_isConj (p)) { ctbase pb = ctype_getCtbase (p); @@ -2005,7 +2023,7 @@ ctbase_newBase (ctype c, ctype p) case CT_ARRAY: return (ctype_makeArray (ctbase_newBase (cb->contents.base, p))); case CT_FCN: - return (ctype_makeRealFunction (ctbase_newBase (cb->contents.fcn->rval, p), + return (ctype_makeRawFunction (ctbase_newBase (cb->contents.fcn->rval, p), cb->contents.fcn->params)); case CT_CONJ: return (ctype_makeConjAux (ctbase_newBase (cb->contents.conj->a, p), @@ -2042,7 +2060,7 @@ ctbase_newBaseExpFcn (ctype c, ctype p) if (!ctbase_isFunction (cb)) llbuglit ("ctbase_newBaseExpFcn: expFcn -> not a function"); - tmpct = ctype_getBaseType (ctype_returnValue (c)); + tmpct = ctype_getBaseType (ctype_getReturnType (c)); /* ** pointers before expfcn -> p are pointers to function, not result @@ -2112,7 +2130,7 @@ ctbase_newBaseExpFcn (ctype c, ctype p) } exitLoop: - tmpct = ctype_returnValue (c); + tmpct = ctype_getReturnType (c); /* ** pointers to expf are pointers to return value @@ -2163,7 +2181,7 @@ ctbase_newBaseExpFcn (ctype c, ctype p) ** pointers to fp are pointers to function type */ - ret = ctype_makeRealFunction (p, ctargs); + ret = ctype_makeRawFunction (p, uentryList_copy (ctargs)); while (ctype_getCtKind (fp) > CTK_PLAIN) { @@ -2306,6 +2324,25 @@ ctbase_compare (ctbase c1, ctbase c2, bool strict) return (ctype_compare (c1->contents.base, c2->contents.base)); case CT_STRUCT: case CT_UNION: + /* evs 2000-07-28: this block was missing! */ + if (strict) { + int ncmp = cstring_compare (c1->contents.su->name, + c2->contents.su->name); + + if (ncmp != 0) { + if (isFakeTag (c1->contents.su->name) + && isFakeTag (c2->contents.su->name)) { + ; /* If they are both fake struct tags, don't require match. */ + } else { + return ncmp; + } + } + } + + DPRINTF (("Comparing fields: %s / %s", + ctbase_unparse (c1), + ctbase_unparse (c2))); + return (uentryList_compareFields (c1->contents.su->fields, c2->contents.su->fields)); case CT_CONJ: @@ -2452,3 +2489,17 @@ ctbase_almostEqual (ctbase c1, ctbase c2) return (FALSE); } } + +/*drl added July 02, 001 + called by ctype_getArraySize +*/ + +long int ctbase_getArraySize (ctbase ctb) +{ + llassert (ctbase_isDefined (ctb) ); + + llassert (ctbase_isFixedArray(ctb) ); + + return (ctb->contents.farray->size); + +}