X-Git-Url: http://andersk.mit.edu/gitweb/splint.git/blobdiff_plain/1b8ae6904556859bbe91aadf35b8adcc1a0611ce..061ece7d6fedbde47030222fea74b575c12707dc:/src/clabstract.c diff --git a/src/clabstract.c b/src/clabstract.c index e804f35..3bf4168 100644 --- a/src/clabstract.c +++ b/src/clabstract.c @@ -1,6 +1,6 @@ /* ** Splint - annotation-assisted static program checker -** Copyright (C) 1994-2002 University of Virginia, +** Copyright (C) 1994-2003 University of Virginia, ** Massachusetts Institute of Technology ** ** This program is free software; you can redistribute it and/or modify it @@ -17,8 +17,8 @@ ** the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, ** MA 02111-1307, USA. ** -** For information on splint: splint@cs.virginia.edu -** To report a bug: splint-bug@cs.virginia.edu +** For information on splint: info@splint.org +** To report a bug: splint-bug@splint.org ** For more information: http://www.splint.org */ /* @@ -29,16 +29,15 @@ */ # include "splintMacros.nf" -# include "llbasic.h" +# include "basic.h" # include "cgrammar.h" - -# ifndef NOLCL # include "usymtab_interface.h" -# endif # include "structNames.h" # include "nameChecks.h" +# include "cscannerHelp.h" + # ifdef SANITIZER # include "sgrammar_tokens.h" # else @@ -56,11 +55,13 @@ static /*@only@*/ constraintList implicitFcnConstraints = NULL; static void clabstract_prepareFunction (uentry p_e) /*@modifies p_e@*/ ; static bool fcnNoGlobals = FALSE; -static bool ProcessingVars = FALSE; -static bool ProcessingParams = FALSE; -static bool ProcessingGlobals = FALSE; -static bool ProcessingTypedef = FALSE; -static bool ProcessingIterVars = FALSE; +static void processVariable (/*@temp@*/ idDecl p_t) /*@modifies internalState@*/ ; + +static bool s_processingVars = FALSE; +static bool s_processingParams = FALSE; +static bool s_processingGlobals = FALSE; +static bool s_processingTypedef = FALSE; +static bool s_processingIterVars = FALSE; static /*@only@*/ qtype processingType = qtype_undefined; static uentry currentIter = uentry_undefined; static /*@dependent@*/ uentryList saveParamList; /* for old style functions */ @@ -296,13 +297,13 @@ extern void declareCIter (cstring name, /*@owned@*/ uentryList params) extern void nextIterParam (void) { - llassert (ProcessingIterVars); + llassert (s_processingIterVars); saveIterParamNo++; } extern int iterParamNo (void) { - llassert (ProcessingIterVars); + llassert (s_processingIterVars); return saveIterParamNo; } @@ -496,46 +497,76 @@ static /*@dependent@*/ uentryList currentParamList; /*drl added 3-28-2002*/ /* this function takes a list of paramentar and generates a list of constraints. - Currently the only constraints gnerated are MaxSet(p) >= 0 for all pointers */ -void setImplictfcnConstraints (void) +/* drl modified 10/23/2002 + +The current semantics are generated constraints of the form MaxSet(p) >= 0 and MaxRead(p) >= 0 for all pointers +unless the @out@ annotation has been applied to a parameter, then we only want to generate maxSet(p) > = 0 +*/ + +void setImplicitfcnConstraints (void) { uentryList params; sRef s; constraint c; params = currentParamList; - if (constraintList_isDefined(implicitFcnConstraints) ) - constraintList_free(implicitFcnConstraints); - - implicitFcnConstraints = constraintList_makeNew(); + if (constraintList_isDefined (implicitFcnConstraints)) + { + constraintList_free (implicitFcnConstraints); + } + + implicitFcnConstraints = constraintList_makeNew(); uentryList_elements (params, el) { - DPRINTF((message("setImplictfcnConstraints doing: %s", uentry_unparse(el) ) )); + DPRINTF (("setImplicitfcnConstraints doing: %s", uentry_unparse(el))); - s = uentry_getSref(el); - if (sRef_isReference (s) ) + if (uentry_isVariable (el)) { - DPRINTF((message ("%s is a pointer", sRef_unparse(s) ) )); + s = uentry_getSref(el); + + if (sRef_isReference (s)) + { + DPRINTF((message ("%s is a pointer", sRef_unparse(s) ) )); + /*drl 4/26/01 + chagned this from MaxSet(s) == 0 to MaxSet(s) >= 0 */ + c = constraint_makeSRefWriteSafeInt (s, 0); + + implicitFcnConstraints = constraintList_add (implicitFcnConstraints , c); + + /*drl 10/23/2002 added support for out*/ + + if (!uentry_isOut(el)) + { + c = constraint_makeSRefReadSafeInt (s, 0); + implicitFcnConstraints = constraintList_add (implicitFcnConstraints , c); + } + } + else + { + DPRINTF((message ("%s is NOT a pointer", sRef_unparse(s) ) )); + } + } /*end uentry_isVariable*/ + else if (uentry_isElipsisMarker (el) ) + { + /* just ignore these*/ + ; } + else { - DPRINTF((message ("%s is NOT a pointer", sRef_unparse(s) ) )); + /* just ignore this + I'm not sure if this is possible though + */ + ; } - /*drl 4/26/01 - chagned this is MaxSet(s) == 0 to MaxSet(s) >= 0 */ - - c = constraint_makeSRefWriteSafeInt (s, 0); - /* constraint_makeSRefSetBufferSize (s, 0); */ - implicitFcnConstraints = constraintList_add(implicitFcnConstraints , c); - } - end_uentryList_elements; + } end_uentryList_elements; } -/*@observer@*/ constraintList getImplicitFcnConstraints (void) +/*@observer@*/ constraintList getImplicitFcnConstraints (void) { return implicitFcnConstraints; } @@ -547,7 +578,7 @@ void setCurrentParams (/*@dependent@*/ uentryList ue) void clearCurrentParams (void) { - currentParamList = uentryList_undefined; + currentParamList = uentryList_undefined; } /* @@ -609,32 +640,28 @@ static /*@exposed@*/ uentry clabstract_globalDeclareFunction (idDecl tid) ue = uentry_makeIdFunction (tid); reflectSpecialCode (ue); reflectArgsUsed (ue); + reflectStorageClass (ue); + uentry_checkParams (ue); + + DPRINTF (("Supercede function: %s", uentry_unparseFull (ue))); + + ue = usymtab_supGlobalEntryReturn (ue); + DPRINTF (("After supercede function: %s", uentry_unparseFull (ue))); + + DPRINTF (("Enter function: %s", uentry_unparseFull (ue))); + context_enterFunction (ue); + enterFunctionParams (uentry_getParams (ue)); + + resetStorageClass (); + DPRINTF (("Function: %s", uentry_unparseFull (ue))); + return (ue); } else { - llparseerror (message ("Inconsistent function declaration: %q", + llparseerror (message ("Non-function declaration: %q", idDecl_unparse (tid))); - - tid = idDecl_replaceCtype - (tid, ctype_makeFunction (ctype_unknown, uentryList_undefined)); - ue = uentry_makeIdFunction (tid); + return (uentry_undefined); } - - reflectStorageClass (ue); - uentry_checkParams (ue); - - DPRINTF (("Supercede function: %s", uentry_unparseFull (ue))); - - ue = usymtab_supGlobalEntryReturn (ue); - DPRINTF (("After supercede function: %s", uentry_unparseFull (ue))); - - DPRINTF (("Enter function: %s", uentry_unparseFull (ue))); - context_enterFunction (ue); - enterFunctionParams (uentry_getParams (ue)); - - resetStorageClass (); - DPRINTF (("Function: %s", uentry_unparseFull (ue))); - return (ue); } /* @@ -718,49 +745,67 @@ void clabstract_declareFunction (idDecl tid) /*@globals undef saveFunction; @*/ DPRINTF (("Declare function: %s", idDecl_unparse (tid))); - if (ProcessingParams) + if (ctype_isUnknown (idDecl_getCtype (tid))) { - ue = globalDeclareOldStyleFunction (tid); - saveFunction = ue; - DPRINTF (("Set save function: %s", uentry_unparseFull (ue))); + /* + ** No type, its really a plain name (int) declaration + */ + + voptgenerror (FLG_IMPTYPE, + message ("No type before declaration name (implicit int type): %q", + idDecl_unparse (tid)), + g_currentloc); + tid = idDecl_replaceCtype (tid, ctype_int); + processVariable (tid); + saveFunction = uentry_undefined; } else { - saveFunction = uentry_undefined; - - if (context_inRealFunction ()) + if (s_processingParams) { - ue = uentry_makeVariableLoc (idDecl_observeId (tid), ctype_unknown); - - llparseerror (message ("Function declared inside function: %q", - idDecl_unparse (tid))); - - context_quietExitFunction (); - ue = usymtab_supEntryReturn (ue); + ue = globalDeclareOldStyleFunction (tid); + saveFunction = ue; + DPRINTF (("Set save function: %s", uentry_unparseFull (ue))); } else { - if (context_inInnerScope ()) + saveFunction = uentry_undefined; + + if (context_inRealFunction ()) { - llparseerror (message ("Declaration in inner context: %q", + ue = uentry_makeVariableLoc (idDecl_observeId (tid), ctype_unknown); + + llparseerror (message ("Function declared inside function: %q", idDecl_unparse (tid))); - sRef_setGlobalScope (); - ue = uentry_makeVariableLoc (idDecl_observeId (tid), - ctype_unknown); - ue = usymtab_supGlobalEntryReturn (ue); - sRef_clearGlobalScope (); + context_quietExitFunction (); + ue = usymtab_supEntryReturn (ue); } else { - ue = clabstract_globalDeclareFunction (tid); + if (context_inInnerScope ()) + { + llparseerror (message ("Declaration in inner context: %q", + idDecl_unparse (tid))); + + sRef_setGlobalScope (); + ue = uentry_makeVariableLoc (idDecl_observeId (tid), + ctype_unknown); + ue = usymtab_supGlobalEntryReturn (ue); + sRef_clearGlobalScope (); + } + else + { + ue = clabstract_globalDeclareFunction (tid); + } } + + resetGlobals (); } - - resetGlobals (); + + resetStorageClass (); } - resetStorageClass (); idDecl_free (tid); } @@ -770,7 +815,7 @@ void declareStaticFunction (idDecl tid) /*@globals undef saveFunction; @*/ DPRINTF (("Declare static funciton: %s", idDecl_unparse (tid))); - if (ProcessingParams) + if (s_processingParams) { ue = globalDeclareOldStyleFunction (tid); saveFunction = ue; @@ -828,6 +873,7 @@ void declareStaticFunction (idDecl tid) /*@globals undef saveFunction; @*/ } else { + DPRINTF (("Here we are!")); llparseerror (message ("Inconsistent function declaration: %q", idDecl_unparse (tid))); @@ -895,8 +941,8 @@ checkTypeDecl (uentry e, ctype rep) vgenhinterror (FLG_SYNTAX, message ("Member of boolean enumerated type definition " - "does not match name set to represent TRUE " - "or FALSE: %s", + "does not match name set to represent true " + "or false: %s", ye), message ("Use -boolfalse and -booltrue to set the " "name of false and true boolean values."), @@ -909,7 +955,7 @@ checkTypeDecl (uentry e, ctype rep) if (usymtab_exists (n)) { usymId llm = usymtab_getId (n); - uentry le = usymtab_getTypeEntry (llm); + uentry le = usymtab_getTypeEntry (typeId_fromUsymId (llm)); uentry_setDeclared (e, g_currentloc); uentry_setSref (e, sRef_makeGlobal (llm, uentry_getType (le), stateInfo_currentLoc ())); @@ -940,12 +986,23 @@ checkTypeDecl (uentry e, ctype rep) uentry ue = usymtab_lookupSafe (ye); llassert (uentry_isEitherConstant (ue)); - llassertprint (ctype_match (uentry_getType (ue), rrep), - ("Bad enum: %s / %s", - uentry_unparse (ue), - ctype_unparse (rrep))); - - uentry_setType (ue, at); + + /* evans 2002-04-22 */ + if (ctype_isBool (uentry_getType (ue))) + { + /* + ** If set using -booltrue or -boolfalse, don't change the type. + */ + } + else + { + llassertprint (ctype_match (uentry_getType (ue), rrep), + ("Bad enum: %s / %s", + uentry_unparse (ue), + ctype_unparse (rrep))); + + uentry_setType (ue, at); + } } } end_enumNameList_elements; } @@ -1088,13 +1145,19 @@ fixUnnamedDecl (qtype q) if (ctype_isStruct (ct) || ctype_isUnion (ct)) { - uentryList res = ctype_getFields (ct); - - return (uentryList_copy (res)); + return uentryList_single (uentry_makeUnnamedVariable (ct)); + } + else if (ctype_isEnum (ct)) + { + /* evans 2002-02-05: nothing to do for unnamed enum lists */ + return uentryList_undefined; } else - { - BADBRANCHCONT; + { + voptgenerror + (FLG_SYNTAX, + message ("Type name in field declarations: %s", qtype_unparse (q)), + g_currentloc); } return uentryList_undefined; @@ -1108,7 +1171,7 @@ void setStorageClass (storageClassCode sc) void setProcessingIterVars (uentry iter) { - ProcessingIterVars = TRUE; + s_processingIterVars = TRUE; currentIter = iter; saveIterParamNo = 0; } @@ -1116,7 +1179,7 @@ setProcessingIterVars (uentry iter) void setProcessingGlobalsList () { - ProcessingGlobals = TRUE; + s_processingGlobals = TRUE; fcnNoGlobals = FALSE; } @@ -1142,20 +1205,20 @@ isProcessingGlobMods () static void resetGlobals (void) { - ProcessingGlobals = FALSE; + s_processingGlobals = FALSE; fcnNoGlobals = FALSE; } void unsetProcessingGlobals () { - ProcessingGlobals = FALSE; + s_processingGlobals = FALSE; } void setProcessingVars (/*@only@*/ qtype q) { - ProcessingVars = TRUE; + s_processingVars = TRUE; qtype_free (processingType); processingType = q; } @@ -1163,14 +1226,14 @@ setProcessingVars (/*@only@*/ qtype q) static void setGenericParamList (/*@dependent@*/ uentryList pm) { - ProcessingParams = TRUE; + s_processingParams = TRUE; saveParamList = pm; } void setProcessingTypedef (qtype q) { - ProcessingTypedef = TRUE; + s_processingTypedef = TRUE; qtype_free (processingType); processingType = q; @@ -1180,13 +1243,13 @@ void unsetProcessingVars () { resetStorageClass (); - ProcessingVars = FALSE; + s_processingVars = FALSE; } void oldStyleDoneParams () { - if (ProcessingParams) + if (s_processingParams) { if (uentry_isInvalid (saveFunction)) { @@ -1199,7 +1262,7 @@ oldStyleDoneParams () ctype ct2 = ctype_makeFunction (ct, params); uentry_setType (saveFunction, ct2); - ProcessingParams = FALSE; + s_processingParams = FALSE; oldStyleCompleteFunction (saveFunction); saveFunction = uentry_undefined; @@ -1239,7 +1302,7 @@ checkDoneParams () ct2 = ctype_makeParamsFunction (ct, uentryList_copy (saveParamList)); uentry_setType (saveFunction, ct2); - ProcessingParams = FALSE; + s_processingParams = FALSE; oldStyleDeclareFunction (saveFunction); saveFunction = uentry_undefined; @@ -1248,10 +1311,15 @@ checkDoneParams () void clabstract_declareType (/*@only@*/ exprNodeList decls, /*@only@*/ warnClause warn) { - llassert (ProcessingTypedef); + llassert (s_processingTypedef); + + DPRINTF (("Declare type: %s", exprNodeList_unparse (decls))); if (warnClause_isDefined (warn)) { + DPRINTF (("Has a warn clause!")); + DPRINTF (("Warn: %s", warnClause_unparse (warn))); + exprNodeList_elements (decls, el) { uentry ue = exprNode_getUentry (el); @@ -1272,6 +1340,7 @@ void clabstract_declareType (/*@only@*/ exprNodeList decls, /*@only@*/ warnClaus uentry_unparse (ue), warnClause_unparse (warn))); uentry_addWarning (ue, warnClause_copy (warn)); + DPRINTF (("After add warning: %s", uentry_unparseFull (ue))); cstring_free (uname); } end_exprNodeList_elements; } @@ -1284,7 +1353,7 @@ void clabstract_declareType (/*@only@*/ exprNodeList decls, /*@only@*/ warnClaus void unsetProcessingTypedef () { - ProcessingTypedef = FALSE; + s_processingTypedef = FALSE; } void checkConstant (qtype t, idDecl id) @@ -1341,206 +1410,217 @@ void checkValueConstant (qtype t, idDecl id, exprNode e) usymtab_supGlobalEntry (ue); } -void processNamedDecl (idDecl t) +static void processVariable (idDecl t) { - if (qtype_isUndefined (processingType)) - { - llparseerror (message ("No type before declaration name: %q", idDecl_unparse (t))); - - processingType = qtype_create (ctype_unknown); - } - - t = idDecl_fixBase (t, processingType); - - DPRINTF (("Declare: %s", idDecl_unparse (t))); + uentry e; + ctype ct; - if (ProcessingGlobals) + ct = ctype_realType (idDecl_getCtype (t)); + + if (s_processingParams) { cstring id = idDecl_getName (t); - uentry ue = usymtab_lookupSafe (id); + int paramno = uentryList_lookupRealName (saveParamList, id); - if (!uentry_isValid (ue)) + if (paramno >= 0) { - llerror (FLG_UNRECOG, - message ("Variable used in globals list is undeclared: %s", id)); + uentry cparam = uentryList_getN (saveParamList, paramno); + + DPRINTF (("Processing param: %s", uentry_unparseFull (cparam))); + uentry_setType (cparam, idDecl_getCtype (t)); + uentry_reflectQualifiers (cparam, idDecl_getQuals (t)); + uentry_setDeclaredOnly (cparam, context_getSaveLocation ()); + DPRINTF (("Processing param: %s", uentry_unparseFull (cparam))); } else { - if (!ctype_match (uentry_getType (ue), idDecl_getCtype (t))) - { - voptgenerror - (FLG_INCONDEFS, - message ("Variable %s used in globals list declared %s, " - "but listed as %s", - id, ctype_unparse (uentry_getType (ue)), - ctype_unparse (idDecl_getCtype (t))), - g_currentloc); - } - else - { - sRef sr = sRef_copy (uentry_getSref (ue)); - reflectGlobalQualifiers (sr, idDecl_getQuals (t)); - } + llfatalerrorLoc + (message ("Old style declaration uses unlisted parameter: %s", + id)); } } - else if (ProcessingVars) + else { - uentry e; - ctype ct; + fileloc loc; - ct = ctype_realType (idDecl_getCtype (t)); - - if (ProcessingParams) + if (context_inIterDef ()) { - cstring id = idDecl_getName (t); - int paramno = uentryList_lookupRealName (saveParamList, id); - - if (paramno >= 0) - { - uentry cparam = uentryList_getN (saveParamList, paramno); - - DPRINTF (("Processing param: %s", uentry_unparseFull (cparam))); - uentry_setType (cparam, idDecl_getCtype (t)); - uentry_reflectQualifiers (cparam, idDecl_getQuals (t)); - uentry_setDeclaredOnly (cparam, context_getSaveLocation ()); - DPRINTF (("Processing param: %s", uentry_unparseFull (cparam))); - } - else + cstring pname = makeParam (idDecl_observeId (t)); + uentry p = usymtab_lookupSafe (pname); + + cstring_free (pname); + + if (uentry_isYield (p)) { - llfatalerrorLoc - (message ("Old style declaration uses unlisted parameter: %s", - id)); + e = uentry_makeParam (t, sRef_getParam (uentry_getSref (p))); + uentry_checkYieldParam (p, e); + usymtab_supEntrySref (e); + return; } } + + if ((hasSpecialCode () || argsUsed) + && ctype_isFunction (idDecl_getCtype (t))) + { + e = uentry_makeIdFunction (t); + reflectSpecialCode (e); + reflectArgsUsed (e); + } else { - fileloc loc; - - if (context_inIterDef ()) - { - cstring pname = makeParam (idDecl_observeId (t)); - uentry p = usymtab_lookupSafe (pname); - - cstring_free (pname); - - if (uentry_isYield (p)) - { - e = uentry_makeParam (t, sRef_getParam (uentry_getSref (p))); - uentry_checkYieldParam (p, e); - usymtab_supEntrySref (e); - return; - } - } - - if ((hasSpecialCode () || argsUsed) - && ctype_isFunction (idDecl_getCtype (t))) - { - e = uentry_makeIdFunction (t); - reflectSpecialCode (e); - reflectArgsUsed (e); - } - else - { - e = uentry_makeIdVariable (t); - } - - loc = uentry_whereDeclared (e); - - /* - if (context_inGlobalScope ()) - { - uentry_checkParams was here! - } - */ + e = uentry_makeIdVariable (t); + } + + loc = uentry_whereDeclared (e); + + /* + if (context_inGlobalScope ()) + { + uentry_checkParams was here! + } + */ + + if (ctype_isFunction (uentry_getType (e))) + { + clabstract_prepareFunction (e); + } + + DPRINTF (("Superceding... %s", uentry_unparseFull (e))); + e = usymtab_supEntrySrefReturn (e); + DPRINTF (("After superceding... %s", uentry_unparseFull (e))); + + if (uentry_isExtern (e) && !context_inGlobalScope ()) + { + voptgenerror + (FLG_NESTEDEXTERN, + message ("Declaration using extern inside function scope: %q", + uentry_unparse (e)), + g_currentloc); - if (ctype_isFunction (uentry_getType (e))) + uentry_setDefined (e, fileloc_getExternal ()); + sRef_setDefined (uentry_getSref (e), fileloc_getExternal ()); + } + + if (uentry_isFunction (e)) + { + if (!context_inXHFile ()) { - clabstract_prepareFunction (e); + checkParamNames (e); } + } + + if (uentry_isVar (e) && uentry_isCheckedUnknown (e)) + { + sRef sr = uentry_getSref (e); - DPRINTF (("Superceding... %s", uentry_unparseFull (e))); - e = usymtab_supEntrySrefReturn (e); - DPRINTF (("After superceding... %s", uentry_unparseFull (e))); - - if (uentry_isExtern (e) && !context_inGlobalScope ()) + if (sRef_isLocalVar (sr)) { - voptgenerror - (FLG_NESTEDEXTERN, - message ("Declaration using extern inside function scope: %q", - uentry_unparse (e)), - g_currentloc); - - uentry_setDefined (e, fileloc_getExternal ()); - sRef_setDefined (uentry_getSref (e), fileloc_getExternal ()); + if (context_getFlag (FLG_IMPCHECKMODINTERNALS)) + { + uentry_setCheckMod (e); + } + else + { + uentry_setUnchecked (e); + } } - - if (uentry_isFunction (e)) + else if (sRef_isFileStatic (sr)) { - if (!context_inXHFile ()) + if (context_getFlag (FLG_IMPCHECKEDSTRICTSTATICS)) + { + uentry_setCheckedStrict (e); + } + else if (context_getFlag (FLG_IMPCHECKEDSTATICS)) + { + uentry_setChecked (e); + } + else if (context_getFlag (FLG_IMPCHECKMODSTATICS)) { - checkParamNames (e); + uentry_setCheckMod (e); + } + else + { + ; } } - - if (uentry_isVar (e) && uentry_isCheckedUnknown (e)) + else /* real global */ { - sRef sr = uentry_getSref (e); + llassert (sRef_isRealGlobal (sr)); - if (sRef_isLocalVar (sr)) + if (context_getFlag (FLG_IMPCHECKEDSTRICTGLOBALS)) { - if (context_getFlag (FLG_IMPCHECKMODINTERNALS)) - { - uentry_setCheckMod (e); - } - else - { - uentry_setUnchecked (e); - } + uentry_setCheckedStrict (e); } - else if (sRef_isFileStatic (sr)) + else if (context_getFlag (FLG_IMPCHECKEDGLOBALS)) { - if (context_getFlag (FLG_IMPCHECKEDSTRICTSTATICS)) - { - uentry_setCheckedStrict (e); - } - else if (context_getFlag (FLG_IMPCHECKEDSTATICS)) - { - uentry_setChecked (e); - } - else if (context_getFlag (FLG_IMPCHECKMODSTATICS)) - { - uentry_setCheckMod (e); - } - else - { - ; - } + uentry_setChecked (e); } - else /* real global */ + else if (context_getFlag (FLG_IMPCHECKMODGLOBALS)) { - llassert (sRef_isRealGlobal (sr)); - - if (context_getFlag (FLG_IMPCHECKEDSTRICTGLOBALS)) - { - uentry_setCheckedStrict (e); - } - else if (context_getFlag (FLG_IMPCHECKEDGLOBALS)) - { - uentry_setChecked (e); - } - else if (context_getFlag (FLG_IMPCHECKMODGLOBALS)) - { - uentry_setCheckMod (e); - } - else - { - ; - } + uentry_setCheckMod (e); } + else + { + ; + } + } + } + } +} + +void processNamedDecl (idDecl t) +{ + if (qtype_isUndefined (processingType)) + { + processingType = qtype_create (ctype_int); + t = idDecl_fixBase (t, processingType); + + voptgenerror (FLG_IMPTYPE, + message ("No type before declaration name (implicit int type): %q", + idDecl_unparse (t)), + g_currentloc); + } + else + { + t = idDecl_fixBase (t, processingType); + } + + DPRINTF (("Declare: %s", idDecl_unparse (t))); + + if (s_processingGlobals) + { + cstring id = idDecl_getName (t); + uentry ue = usymtab_lookupSafe (id); + + if (!uentry_isValid (ue)) + { + llerror (FLG_UNRECOG, + message ("Variable used in globals list is undeclared: %s", id)); + } + else + { + if (!ctype_match (uentry_getType (ue), idDecl_getCtype (t))) + { + voptgenerror + (FLG_INCONDEFS, + message ("Variable %s used in globals list declared %s, " + "but listed as %s", + id, ctype_unparse (uentry_getType (ue)), + ctype_unparse (idDecl_getCtype (t))), + g_currentloc); + } + else + { + sRef sr = sRef_copy (uentry_getSref (ue)); + reflectGlobalQualifiers (sr, idDecl_getQuals (t)); } } } - else if (ProcessingTypedef) + else if (s_processingVars) + { + processVariable (t); + } + else if (s_processingTypedef) { ctype ct = idDecl_getCtype (t); uentry e; @@ -1636,6 +1716,8 @@ declareUnnamedStruct (/*@only@*/ uentryList f) ctype declareUnnamedUnion (/*@only@*/ uentryList f) { + DPRINTF (("Unnamed union: %s", uentryList_unparse (f))); + if (context_maybeSet (FLG_NUMSTRUCTFIELDS)) { int num = uentryList_size (f); @@ -1661,7 +1743,8 @@ ctype declareStruct (cstring id, /*@only@*/ uentryList f) uentry ue; int num = uentryList_size (f); - DPRINTF (("Declare struct: %s / %s", id, uentryList_unparse (f))); + DPRINTF (("Declare struct: %s / %s [%d]", id, uentryList_unparse (f), + uentryList_size (f))); ct = ctype_createStruct (cstring_copy (id), f); @@ -1756,13 +1839,13 @@ handleEnum (cstring id) } else { - return (declareEnum (id, enumNameList_new ())); + return (ctype_createForwardEnum (id)); } } bool processingIterVars (void) { - return ProcessingIterVars; + return s_processingIterVars; } uentry getCurrentIter (void) @@ -1796,12 +1879,14 @@ void setNewStyle () { flipNewStyle = TRUE; } uentryList_elements (params, current) { uentry_setParam (current); - uentry_setSref (current, sRef_makeParam (paramno, ctype_unknown, stateInfo_makeLoc (uentry_whereLast (current)))); + uentry_setSref (current, sRef_makeParam + (paramno, ctype_unknown, + stateInfo_makeLoc (uentry_whereLast (current), SA_DECLARED))); paramno++; } end_uentryList_elements; setGenericParamList (params); - g_expectingTypeName = TRUE; + cscannerHelp_setExpectingTypeName (); return params; } @@ -1818,7 +1903,7 @@ void setNewStyle () { flipNewStyle = TRUE; } setGenericParamList (params); flipOldStyle = FALSE; - g_expectingTypeName = TRUE; + cscannerHelp_setExpectingTypeName (); } return (params); @@ -1831,14 +1916,16 @@ doVaDcl () cstring id = cstring_makeLiteral ("va_alist"); uentry e; - if (ProcessingParams) + if (s_processingParams) { int i = uentryList_lookupRealName (saveParamList, id); if (i >= 0) { fileloc loc = context_getSaveLocation (); - e = uentry_makeVariableSrefParam (id, c, loc, sRef_makeParam (i, c, stateInfo_makeLoc (loc))); + e = uentry_makeVariableSrefParam + (id, c, loc, + sRef_makeParam (i, c, stateInfo_makeLoc (loc, SA_DECLARED))); } else { @@ -2070,10 +2157,12 @@ sRef checkStateClausesId (uentry ue) voptgenerror (FLG_COMMENTERROR, message ("Global variable %s used state clause. (Global variables " - "are not recognized in state clauses. If there is " + "are not recognized in state clauses. If they are present " + "they are ignored. " + " If there is " "sufficient interest in support for this, it may be " "added to a future release. Send mail to " - "splint@cs.virginia.edu.)", + "info@splint.org.)", s), g_currentloc); @@ -2111,6 +2200,7 @@ sRef checkStateClausesId (uentry ue) sRef checkbufferConstraintClausesId (uentry ue) { + sRef sr; cstring s = uentry_rawName (ue); if (cstring_equalLit (s, "result")) @@ -2125,8 +2215,20 @@ sRef checkbufferConstraintClausesId (uentry ue) } } - DPRINTF (("constrant id: %s", uentry_unparseFull (ue))); - return sRef_saveCopy (uentry_getSref (ue)); /*@i523 why the saveCopy? */ + sr = uentry_getSref (ue); + + if (sRef_isInvalid (sr)) + { + llfatalerrorLoc (cstring_makeLiteral ("Macro defined constants can not be used in function " + "constraints unless they are specifed with the constant " + "annotation. To use a macro defined constant include an " + "annotation of the form /*@constant =@*/ " + "somewhere before the function constraint. This restriction " + "may be removed in future releases.")); + } + + /* saveCopy to used to mitigate danger of accessing freed memory*/ + return sRef_saveCopy (sr); } void checkModifiesId (uentry ue) @@ -2194,7 +2296,7 @@ void checkModifiesId (uentry ue) } else { - fileloc loc = fileloc_decColumn (g_currentloc, cstring_length (s)); + fileloc loc = fileloc_decColumn (g_currentloc, size_toInt (cstring_length (s))); ret = sRef_undefined; voptgenerror @@ -2251,7 +2353,7 @@ sRef fixStateClausesId (cstring s) "are not recognized in function clauses. If there is " "sufficient interest in support for this, it may be " "added to a future release. Send mail to " - "splint@cs.virginia.edu.)", + "info@splint.org.)", s), g_currentloc); @@ -2260,9 +2362,43 @@ sRef fixStateClausesId (cstring s) } else { - fileloc loc = fileloc_decColumn (g_currentloc, cstring_length (s)); + + /* drl This is the code for structure invariants + + It is no yet stable enough to be included in a Splint release. + */ + + /*check that we're in a structure */ +#if 0 + /*@unused@*/ uentryList ueL; + /*@unused@*/ uentry ue2; + /*@unused@*/ ctype ct; +#endif + fileloc loc = fileloc_decColumn (g_currentloc, size_toInt (cstring_length (s))); ret = sRef_undefined; +# if 0 + + ct = context_getLastStruct ( ct ); + + llassert( ctype_isStruct(ct) ); + + ueL = ctype_getFields (ct); + + ue2 = uentryList_lookupField (ueL, s); + + if (!uentry_isUndefined(ue2) ) + { + ret = uentry_getSref(ue2); + + DPRINTF(( + message("Got field in structure in the annotation constraint: %s (or sref: %s)", s, sRef_unparse(ret) ) + )); + + return ret; + } +#endif + voptgenerror (FLG_UNRECOG, message ("Unrecognized identifier in function clause: %s", s),