/*
-** LCLint - annotation-assisted static program checker
-** Copyright (C) 1994-2001 University of Virginia,
+** Splint - annotation-assisted static program checker
+** Copyright (C) 1994-2002 University of Virginia,
** Massachusetts Institute of Technology
**
** This program is free software; you can redistribute it and/or modify it
** the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
** MA 02111-1307, USA.
**
-** For information on lclint: lclint-request@cs.virginia.edu
-** To report a bug: lclint-bug@cs.virginia.edu
-** For more information: http://lclint.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
*/
/*
** clabstract.c
**
*/
-# include "lclintMacros.nf"
+# include "splintMacros.nf"
# include "llbasic.h"
# include "cgrammar.h"
*/
/*drl*/
-/*@only@*/ static constraintList fcnConstraints = NULL;
-
-/*end drl*/
-
-/*drl */
-static /*@only@*/ constraintList implicitFcnConstraints = NULL;
-
-
-//static constraintList fcnPreConditions = NULL;
+static /*@only@*/ constraintList implicitFcnConstraints = NULL;
static void clabstract_prepareFunction (uentry p_e) /*@modifies p_e@*/ ;
static bool fcnNoGlobals = FALSE;
static /*@dependent@*/ uentryList currentParamList;
-/*drl added 3-28-2001*/
+/*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
chagned this is MaxSet(s) == 0 to MaxSet(s) >= 0 */
c = constraint_makeSRefWriteSafeInt (s, 0);
- // constraint_makeSRefSetBufferSize (s, 0);
+ /* constraint_makeSRefSetBufferSize (s, 0); */
implicitFcnConstraints = constraintList_add(implicitFcnConstraints , c);
}
end_uentryList_elements;
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));
uentry_setDefined (ue, g_currentloc);
uentry_checkParams (ue);
resetStorageClass ();
+
+ /* context_enterOldStyleScope (); */
+
return (ue);
}
llassert (ctype_isFunction (rt));
+ if (uentry_hasStateClauseList (e)
+ || uentry_hasConditions (e))
+ {
+ llfatalerror (message ("%q: Old-style function declaration uses a clause (rewrite with function parameters): %q",
+ fileloc_unparse (g_currentloc), uentry_unparse (e)));
+ }
+
e = usymtab_supGlobalEntryReturn (e);
context_enterFunction (e);
resetStorageClass ();
}
+static void oldStyleCompleteFunction (/*@only@*/ uentry e)
+{
+ uentryList params = saveParamList;
+ ctype rt = uentry_getType (e);
+
+ llassert (ctype_isFunction (rt));
+
+ if (uentry_hasStateClauseList (e)
+ || uentry_hasConditions (e))
+ {
+ llfatalerror (message ("%q: Old-style function declaration uses a clause (rewrite with function parameters): %q",
+ fileloc_unparse (g_currentloc), uentry_unparse (e)));
+ }
+
+ e = usymtab_supGlobalEntryReturn (e);
+
+ context_completeOldStyleFunction (e);
+ enterFunctionParams (params);
+ saveParamList = uentryList_undefined;
+ resetStorageClass ();
+}
+
void clabstract_declareFunction (idDecl tid) /*@globals undef saveFunction; @*/
{
uentry ue;
{
ue = globalDeclareOldStyleFunction (tid);
saveFunction = ue;
+ DPRINTF (("Set save function: %s", uentry_unparseFull (ue)));
}
else
{
uentry le = usymtab_getTypeEntry (llm);
uentry_setDeclared (e, g_currentloc);
- uentry_setSref (e, sRef_makeGlobal (llm, uentry_getType (le)));
+ uentry_setSref (e, sRef_makeGlobal (llm, uentry_getType (le), stateInfo_currentLoc ()));
DPRINTF (("Here we are: %s / %s",
n, context_getBoolName ()));
** Microsoft VC++. It is not supported by the ANSI standard.
**
** The inner fields are added to the outer structure. This is meaningful
-** for nesting structs inside unions, but lclint does no related
+** for nesting structs inside unions, but Splint does no related
** checking.
*/
return (uentryList_copy (res));
}
+ else if (ctype_isEnum (ct))
+ {
+ /* evans 2002-02-05: nothing to do for unnamed enum lists */
+ return uentryList_undefined;
+ }
else
{
BADBRANCHCONT;
}
void
-setProcessingTypedef (/*@only@*/ qtype q)
+setProcessingTypedef (qtype q)
{
ProcessingTypedef = TRUE;
}
void
-doneParams ()
+oldStyleDoneParams ()
{
if (ProcessingParams)
{
uentry_setType (saveFunction, ct2);
ProcessingParams = FALSE;
- oldStyleDeclareFunction (saveFunction);
+ oldStyleCompleteFunction (saveFunction);
saveFunction = uentry_undefined;
resetGlobals ();
}
ctype ct = ctype_getReturnType (uentry_getType (saveFunction));
ctype ct2;
+ DPRINTF (("save function: %s", uentry_unparseFull (saveFunction)));
+
uentryList_elements (saveParamList, current)
{
uentry_setType (current, ctype_int); /* all params are ints */
}
}
+void clabstract_declareType (/*@only@*/ exprNodeList decls, /*@only@*/ warnClause warn)
+{
+ llassert (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);
+ cstring uname = uentry_getName (ue);
+
+ DPRINTF (("Entry: %s", exprNode_unparse (el)));
+
+ /*
+ ** Need to lookup again to make sure we have the right one...
+ */
+
+ ue = usymtab_lookupExposeGlob (uname);
+
+ llassert (uentry_isValid (ue));
+ llassert (uentry_isDatatype (ue));
+
+ DPRINTF (("Warning for %s: %s",
+ 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;
+ }
+
+ warnClause_free (warn);
+ exprNodeList_free (decls);
+ unsetProcessingTypedef ();
+}
+
void
unsetProcessingTypedef ()
{
void checkConstant (qtype t, idDecl id)
{
uentry e;
-
+
id = idDecl_fixBase (id, t);
e = uentry_makeIdConstant (id);
-
+
reflectStorageClass (e);
resetStorageClass ();
+ DPRINTF (("Constant: %s", uentry_unparseFull (e)));
usymtab_supGlobalEntry (e);
}
{
uentry_mergeConstantValue (ue, multiVal_copy (exprNode_getValue (e)));
}
+ else
+ {
+ DPRINTF (("No value: %s", exprNode_unparse (e)));
+ }
}
}
+ DPRINTF (("Constant value: %s", uentry_unparseFull (ue)));
usymtab_supGlobalEntry (ue);
}
t = idDecl_fixBase (t, processingType);
DPRINTF (("Declare: %s", idDecl_unparse (t)));
-
+
if (ProcessingGlobals)
{
cstring id = idDecl_getName (t);
{
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_makeLiteral ("Old style function declaration"),
g_currentloc);
+ DPRINTF (("Handle old style params: %s", uentryList_unparseFull (params)));
+
uentryList_elements (params, current)
{
uentry_setParam (current);
- uentry_setSref (current, sRef_makeParam (paramno, ctype_unknown));
+ uentry_setSref (current, sRef_makeParam (paramno, ctype_unknown, stateInfo_makeLoc (uentry_whereLast (current))));
paramno++;
} end_uentryList_elements;
if (i >= 0)
{
- e = uentry_makeVariableSrefParam (id, c, sRef_makeParam (i, c));
+ fileloc loc = context_getSaveLocation ();
+ e = uentry_makeVariableSrefParam (id, c, loc, sRef_makeParam (i, c, stateInfo_makeLoc (loc)));
}
else
{
}
else
{
- if (ctype_isAbstract (ct))
+ if (ctype_isAbstract (rt))
{
voptgenerror
(FLG_ABSTRACT,
message
- ("Modifies clause in header file arrow accesses abstract "
+ ("Modifies clause arrow accesses inaccessible abstract "
"type %s (interface modifies clause should not depend "
"on or expose type representation): %q",
- ctype_unparse (ct),
+ ctype_unparse (rt),
sRef_unparse (s)),
g_currentloc);
}
{
voptgenerror
(FLG_COMMENTERROR,
- message ("Global variable %s used special clause. (Global variables "
- "are not recognized in special clauses. If there is "
+ message ("Global variable %s used state clause. (Global variables "
+ "are not recognized in state clauses. If there is "
"sufficient interest in support for this, it may be "
"added to a future release. Send mail to "
- "lclint@cs.virginia.edu.)",
+ "info@splint.org.)",
s),
g_currentloc);
sRef checkbufferConstraintClausesId (uentry ue)
{
cstring s = uentry_rawName (ue);
+
if (cstring_equalLit (s, "result"))
{
if (optgenerror
(FLG_SYNTAX,
- message ("Special clause list uses %s which is a variable and has special "
+ message ("Function clause list uses %s which is a variable and has special "
"meaning in a modifies list. (Special meaning assumed.)", s),
g_currentloc))
{
}
}
- return sRef_saveCopy( uentry_getSref (ue) );
+ DPRINTF (("constrant id: %s", uentry_unparseFull (ue)));
+ return sRef_saveCopy (uentry_getSref (ue)); /*@i523 why the saveCopy? */
}
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
if (cstring_equalLit (s, "result"))
{
- ret = sRef_makeResult ();
+ ret = sRef_makeResult (ctype_unknown);
}
else
{
"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 "
- "lclint@cs.virginia.edu.)",
+ "info@splint.org.)",
s),
g_currentloc);
}
else
{
- fileloc loc = fileloc_decColumn (g_currentloc, cstring_length (s));
+ /*@i222@*/
+ /*drl handle structure invariant */
+
+ /*@i222@*/
+ /*check that we're in a structure */
+# if 0\r
+ /*@unused@*/ uentryList ueL;
+ /*@unused@*/ uentry ue2;
+ /*@unused@*/ ctype ct;\r
+# endif
+ fileloc loc = fileloc_decColumn (g_currentloc, size_toInt (cstring_length (s)));
ret = sRef_undefined;
-
+# if 0
+ /*drl commenting this out for now
+ 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;
+ }
+ */\r
+# endif\r
+
voptgenerror
(FLG_UNRECOG,
message ("Unrecognized identifier in function clause: %s", s),
exprNode_free (e);
return sRef_copy (s);
}
-
-
-
-
-
-
-
-