X-Git-Url: http://andersk.mit.edu/gitweb/splint.git/blobdiff_plain/517a2db3da924ba77ae313404da5e12fda798947..HEAD:/src/uentry.c diff --git a/src/uentry.c b/src/uentry.c index ce029e8..6f6c090 100644 --- a/src/uentry.c +++ b/src/uentry.c @@ -753,6 +753,10 @@ void uentry_checkParams (uentry ue) if (ctype_isFixedArray (ct)) { + DPRINTF (("Array: %s / %s", + ctype_unparse (ct), + ctype_unparse (ctype_baseArrayPtr (ct)))); + if (ctype_isArray (ctype_baseArrayPtr (ct)) && !ctype_isFixedArray (ctype_baseArrayPtr (ct))) { @@ -3068,41 +3072,48 @@ uentry_isSpecialFunction (uentry ue) /*@notnull@*/ uentry uentry_makeParam (idDecl t, int i) { ctype ct = idDecl_getCtype (t); - ctype base = ct; fileloc loc = setLocation (); sRef pref = sRef_makeParam (i, ct, stateInfo_makeLoc (loc, SA_CREATED)); uentry ue = uentry_makeVariableSrefParam (idDecl_observeId (t), ct, loc, pref); DPRINTF (("Make param: %s", uentry_unparseFull (ue))); + DPRINTF (("Base: %s [%d]", ctype_unparse (ct), ctype_isFixedArray (ct))); uentry_reflectQualifiers (ue, idDecl_getQuals (t)); uentry_implicitParamAnnots (ue); - /* Parameter type [][] or [x][] is invalid */ + if (ctype_isArray (ct)) + { + /* Parameter type [][] or [x][] is invalid, but [][x] is okay */ + ctype base = ctype_baseArrayPtr (ct); - while (ctype_isFixedArray (base)) { - base = ctype_baseArrayPtr (base); - } - - if (ctype_isIncompleteArray (base)) { - base = ctype_baseArrayPtr (base); - - if (ctype_isArray (base)) { - if (!uentry_hasName (ue)) { - (void) optgenerror (FLG_INCOMPLETETYPE, - message ("Unnamed function parameter %d is incomplete type (inner array must have bounds): %s", - i + 1, - ctype_unparse (ct)), - uentry_whereLast (ue)); - } else { - (void) optgenerror (FLG_INCOMPLETETYPE, - message ("Function parameter %q is incomplete type (inner array must have bounds): %s", - uentry_getName (ue), - ctype_unparse (ct)), - uentry_whereLast (ue)); - } + DPRINTF (("Check array: %s / Base: %s", ctype_unparse (ct), + ctype_unparse (base))); + + if (ctype_isIncompleteArray (base)) + { + if (!uentry_hasName (ue)) + { + voptgenerror + (FLG_INCOMPLETETYPE, + message ("Unnamed function parameter %d is incomplete type " + "(inner array must have bounds): %s", + i + 1, + ctype_unparse (ct)), + uentry_whereLast (ue)); + } + else + { + voptgenerror + (FLG_INCOMPLETETYPE, + message ("Function parameter %q is incomplete type " + "(inner array must have bounds): %s", + uentry_getName (ue), + ctype_unparse (ct)), + uentry_whereLast (ue)); + } + } } - } - + DPRINTF (("Param: %s", uentry_unparseFull (ue))); return ue; } @@ -3346,7 +3357,6 @@ uentry uentry_makeVariableAux (cstring n, ctype t, sRef_setStateFromType (e->sref, rt); } - DPRINTF (("Here we are: %s", sRef_unparseFull (e->sref))); e->info->var->defstate = sRef_getDefState (e->sref); e->info->var->nullstate = sRef_getNullState (e->sref); @@ -3367,6 +3377,8 @@ uentry uentry_makeVariableAux (cstring n, ctype t, }/* end else */ /* end modification */ + DPRINTF (("New variable: %s", sRef_unparseFull (e->sref))); + return (e); } @@ -6441,8 +6453,12 @@ ctype uentry_getRealType (uentry e) { return ctype_unknown; } - - llassertprint (uentry_isDatatype (e), ("not datatype: %s", uentry_unparse (e))); + + if (!uentry_isDatatype (e)) + { + /* This shouldn't happen, except when types are redeclared in strange ways */ + return ctype_unknown; + } if (uentry_isAnyTag (e)) { @@ -8303,6 +8319,29 @@ void uentry_checkMatchParam (uentry u1, uentry u2, int paramno, exprNode e) } } +static void uentry_convertIntoFunction (/*@notnull@*/ uentry old) +{ + /* + ** Convert old into a function + */ + + old->ukind = KFCN; + old->utype = ctype_unknown; + old->info->fcn = (ufinfo) dmalloc (sizeof (*old->info->fcn)); + old->info->fcn->hasMods = FALSE; + old->info->fcn->hasGlobs = FALSE; + old->info->fcn->exitCode = XK_UNKNOWN; + old->info->fcn->nullPred = qual_createUnknown (); + old->info->fcn->specialCode = SPC_NONE; + old->info->fcn->access = typeIdSet_undefined; + old->info->fcn->globs = globSet_undefined; + old->info->fcn->defparams = uentryList_undefined; + old->info->fcn->mods = sRefSet_undefined; + old->info->fcn->specclauses = NULL; + old->info->fcn->preconditions = NULL; + old->info->fcn->postconditions = NULL; +} + static void checkFunctionConformance (/*@unique@*/ /*@notnull@*/ uentry old, /*@notnull@*/ uentry unew, @@ -8332,8 +8371,26 @@ checkFunctionConformance (/*@unique@*/ /*@notnull@*/ uentry old, if (ctype_isKnown (oldType)) { - llassert (ctype_isFunction (oldType)); - oldRetType = ctype_getReturnType (oldType); + if (ctype_isFunction (oldType)) + { + oldRetType = ctype_getReturnType (oldType); + } + else + { + if (optgenerror + (FLG_INCONDEFS, + message ("%s %q declared as function, but previously declared as %s", + ekind_capName (unew->ukind), + uentry_getName (unew), + ekind_unparseLong (old->ukind)), + uentry_whereDeclared (unew))) + { + uentry_showWhereLast (old); + } + + uentry_convertIntoFunction (old); + return; + } } if (ctype_isKnown (newType)) @@ -9433,8 +9490,7 @@ uentry_mergeEntries (uentry spec, /*@only@*/ uentry def) llassert (uentry_isFunction (spec)); } - DPRINTF (("Merge entries: %s / %s", - uentry_unparseFull (spec), + DPRINTF (("Merge entries: %s / %s", uentry_unparseFull (spec), uentry_unparseFull (def))); uentry_mergeConstraints (spec, def); @@ -9591,7 +9647,22 @@ uentry_mergeDefinition (uentry old, /*@only@*/ uentry unew) uentry_convertVarFunction (old); } - llassert (uentry_isFunction (old)); + if (!uentry_isFunction (old)) + { + if (optgenerror + (FLG_INCONDEFS, + message ("%s %q declared as function, but previously declared as %s", + ekind_capName (unew->ukind), + uentry_getName (unew), + ekind_unparseLong (old->ukind)), + uentry_whereDeclared (unew))) + { + uentry_showWhereLast (old); + } + + uentry_convertIntoFunction (old); + return; + } } DPRINTF (("uentry merge: %s / %s",