/*
-** LCLint - annotation-assisted static program checker
+** Splint - annotation-assisted static program checker
** Copyright (C) 1994-2001 University of Virginia,
** Massachusetts Institute of Technology
**
**
** 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 more information: http://www.splint.org
*/
/*
** uentry.c
static void uentry_checkIterArgs (uentry p_ue);
static cstring uentry_dumpAux (uentry p_v, bool p_isParam);
+static void uentry_showWhereLastKind (uentry p_spec) /*@modifies g_msgstream@*/ ;
+
static void uentry_combineModifies (uentry p_ue, /*@owned@*/ sRefSet p_sr)
/*@modifies p_ue@*/ ;
if (uentry_isVariable (ue))
{
+ /*@i634 ue->sref = sRef_saveCopyShallow (ue->info->var->origsref); */
sRef_setDefState (sr, ue->info->var->defstate, fileloc_undefined);
sRef_setNullState (sr, ue->info->var->nullstate, fileloc_undefined);
}
if (functionConstraint_isDefined (ue->info->fcn->preconditions))
{
- BADBRANCH; /* should conjoin constraints? */
+ /* drl 11-29-2001
+ I changed this so it didn't appear as a Splint bug
+ among other things this gets triggered when there is
+ a function with two requires clauses. Now Splint
+ prints an error and tries to conjoin the lists.
+ */
+ llparseerror
+ (message ("Duplicate precondition list"
+ "Attemping the conjoin the requires clauses"
+ ));
+
+
+ /* should conjoin constraints? */
/*@notreached@*/
ue->info->fcn->preconditions = functionConstraint_conjoin (ue->info->fcn->preconditions, preconditions);
}
{
if (optgenerror
(FLG_ANNOTATIONERROR,
- message ("Meta state annotation %s used in inconsistent context: %q",
+ message ("Attribute annotation %s used in inconsistent context: %q",
qual_unparse (qel),
uentry_unparse (ue)),
uentry_whereLast (ue)))
uentry_reflectQualifiers (ue, idDecl_getQuals (t));
DPRINTF (("Constant: %s", uentry_unparseFull (ue)));
+ DPRINTF (("Value: %s", multiVal_unparse (uentry_getConstantValue (ue))));
return ue;
}
e->info->var = (uvinfo) dmalloc (sizeof (*e->info->var));
e->info->var->kind = kind;
+ /*@i523 e->info->var->origsref = sRef_saveCopy (e->sref); */
e->info->var->checked = CH_UNKNOWN;
DPRINTF (("Here we are: %s", sRef_unparseFull (e->sref)));
/*@=mustfree@*/
}
- /*@i23 ???
+ /*@i23*/
+ /* ??? - evans 2001-09-09 not sure what's going on here...?
if (globSet_hasStatic (globs))
{
context_recordFileGlobals (globs);
** Functions are never equivalent
*/
- if ((int) u1 < (int) u2)
+ if (u1 - u2 < 0) /* evans 2001-08-21: was: ((int) u1 < (int) u2), changed to remove gcc warning */
{
return -1;
}
sRef uentry_getOrigSref (uentry e)
{
+ /*@i523*/ /* evans 2001-09-09 - need to fix this
+ if (uentry_isValid (e))
+ {
+ if (uentry_isVariable (e))
+ {
+ return e->info->var->origsref;
+ }
+ else
+ {
+ sRef sr = sRef_copy (uentry_getSref (e));
+
+ sRef_resetState (sr);
+ sRef_clearDerived (sr);
+ return (sr);
+ }
+ }
+ else
+ {
+ return sRef_undefined;
+ }
+ */
+
if (uentry_isValid (e))
{
sRef sr = sRef_copy (uentry_getSref (e));
ret->defstate = u->defstate;
ret->checked = u->checked;
+ /*@i523 ret->origsref = sRef_copy (u->origsref); */
+
/* drl added 07-02-001 */
/* copy null terminated information */
uentry_getName (unew),
ekind_unparseLong (unew->ukind),
unew->utype),
- uentry_whereDeclared (unew)))
+ uentry_whereLast (unew))) /* evans 2001-12-30: was uentry_whereDeclared */
{
- uentry_showWhereLast (old);
+ uentry_showWhereLastKind (old);
}
}
else
uentry_getName (unew),
ekind_unparseLong (unew->ukind),
unew->utype),
- uentry_whereDeclared (unew)))
+ uentry_whereLast (unew))) /* evans 2001-12-30: was uentry_whereDeclared */
{
- uentry_showWhereLast (old);
+ uentry_showWhereLastKind (old);
}
}
}
{
llassert (uentry_isDeclared (unew));
+ DPRINTF (("Old: \n\t%s", uentry_unparseFull (old)));
+ DPRINTF (("New: \n\t%s", uentry_unparseFull (unew)));
+
if (optgenerror
(FLG_INCONDEFS,
message ("%s %q inconsistently redeclared as %s",
ekind_capName (old->ukind),
uentry_getName (unew),
ekind_unparseLong (unew->ukind)),
- uentry_whereDeclared (unew)))
+ uentry_whereLast (unew))) /* evans 2001-12-30: was uentry_whereDeclared */
{
- uentry_showWhereLast (old);
+ uentry_showWhereLastKind (old);
}
}
}
{
if (fileloc_isDefined (spec->whereDefined)
&& !fileloc_isLib (spec->whereDefined)
- && !fileloc_isPreproc (spec->whereDefined))
+ /*!! && !fileloc_isPreproc (spec->whereDefined) */ )
{
llgenindentmsg (message ("Previous definition of %q: %t",
uentry_getName (spec),
}
}
+static void
+uentry_showWhereLastKind (uentry spec)
+{
+ if (uentry_isValid (spec))
+ {
+ if (fileloc_isDefined (spec->whereDefined)
+ && !fileloc_isLib (spec->whereDefined)
+ /*!! && !fileloc_isPreproc (spec->whereDefined) */ )
+ {
+ llgenindentmsg (message ("Previous definition of %q as %s: %t",
+ uentry_getName (spec),
+ ekind_unparseLong (spec->ukind),
+ uentry_getType (spec)),
+ uentry_whereDefined (spec));
+ }
+ else if (uentry_isDeclared (spec))
+ {
+ llgenindentmsg (message ("Previous declaration of %q as %s: %t",
+ uentry_getName (spec),
+ ekind_unparseLong (spec->ukind),
+ uentry_getType (spec)),
+ uentry_whereDeclared (spec));
+ }
+ else if (uentry_isSpecified (spec))
+ {
+ if (uentry_hasName (spec))
+ {
+ llgenindentmsg (message ("Specification of %q as %s: %t",
+ uentry_getName (spec),
+ ekind_unparseLong (spec->ukind),
+ uentry_getType (spec)),
+ uentry_whereSpecified (spec));
+ }
+ else
+ {
+ llgenindentmsg (message ("Specification as %s: %t",
+ ekind_unparseLong (spec->ukind),
+ uentry_getType (spec)),
+ uentry_whereSpecified (spec));
+ }
+ }
+ else
+ {
+ /* nothing to show */
+ }
+ }
+}
+
void
uentry_showDefSpecInfo (uentry ce, fileloc fwhere)
{
cstring nnamefix;
if (cstring_isDefined (pfx)
- && cstring_equalPrefix (oldname, cstring_toCharsSafe (pfx)))
+ && cstring_equalPrefix (oldname, pfx))
{
oname = cstring_suffix (oldname, cstring_length (pfx));
}
/*@-branchstate@*/ } /*@=branchstate@*/
if (cstring_isDefined (pfx)
- && cstring_equalPrefix (nname, cstring_toCharsSafe (pfx)))
+ && cstring_equalPrefix (nname, pfx))
{
nnamefix = cstring_suffix (nname, cstring_length (pfx));
}
unew->info->fcn->specclauses = stateClauseList_undefined;
/*@-branchstate@*/
}
- /*@=branchstate@*/ /*@i23 shouldn't need this@*/
}
+ /*@=branchstate@*/ /*@i23 shouldn't need this@*/
if (fileloc_isUndefined (old->whereDeclared))
{
{
/* no change */
}
-}
+/*@i523 @*/ }
void
uentry_mergeConstantValue (uentry ue, /*@only@*/ multiVal m)
}
}
-static bool incompatibleStates (sRef rs, sRef os)
+static bool uentry_incompatibleMemoryStates (sRef rs, sRef os)
{
alkind rk = sRef_getAliasKind (rs);
alkind ok = sRef_getAliasKind (os);
bool mustReturn, bool flip, bool opt,
clause cl)
{
+ sRef rs = res->sref;
+ sRef os = other->sref;
+
DPRINTF (("Merge alias states: %s / %s",
uentry_unparseFull (res),
uentry_unparseFull (other)));
- if (sRef_isValid (res->sref))
+ if (sRef_isValid (rs))
{
if (!mustReturn)
{
- DPRINTF (("1"));
- if (incompatibleStates (res->sref, other->sref))
+ if (uentry_incompatibleMemoryStates (rs, os))
{
- DPRINTF (("2"));
+ DPRINTF (("Incompatible: \n\t%s / \n\t%s",
+ sRef_unparseFull (rs), sRef_unparseFull (os)));
- if (sRef_isThroughArrayFetch (res->sref)
+ if (sRef_isThroughArrayFetch (rs)
&& !context_getFlag (FLG_STRICTBRANCHSTATE))
{
- if (sRef_isKept (res->sref) || sRef_isKept (other->sref))
+ if (sRef_isKept (rs) || sRef_isKept (os))
{
- sRef_maybeKill (res->sref, loc);
+ sRef_maybeKill (rs, loc);
}
- else if (sRef_isPossiblyDead (other->sref))
+ else if (sRef_isPossiblyDead (os))
{
- sRef_maybeKill (res->sref, loc);
+ sRef_maybeKill (rs, loc);
}
else
{
}
else
{
- if (uentry_relevantReference (other->sref, flip))
+ if (uentry_relevantReference (os, flip))
{
- DPRINTF (("4"));
- if (sRef_isLocalParamVar (res->sref)
- && (sRef_isLocalState (other->sref)
- || sRef_isDependent (other->sref)))
+ if (sRef_isLocalParamVar (rs)
+ && (sRef_isLocalState (os)
+ || sRef_isDependent (os)))
{
- if (sRef_isDependent (res->sref))
+ if (sRef_isDependent (rs))
{
- sRef_setDependent (other->sref, loc);
+ sRef_setDependent (os, loc);
}
else
{
- sRef_setDefState (res->sref, SS_UNUSEABLE, loc);
+ sRef_setDefState (rs, SS_UNUSEABLE, loc);
}
}
else
}
}
- if (sRef_isKept (res->sref))
+ if (sRef_isKept (rs))
{
- sRef_setKept (other->sref, loc);
+ DPRINTF (("Setting kept: %s", sRef_unparseFull (os)));
+ sRef_setKept (os, loc);
}
}
else
{
- if (incompatibleStates (other->sref, res->sref))
+ if (uentry_incompatibleMemoryStates (os, rs))
{
- if (uentry_relevantReference (res->sref, !flip))
+ if (uentry_relevantReference (rs, !flip))
{
- if (sRef_isLocalParamVar (res->sref)
- && (sRef_isDependent (res->sref)
- || sRef_isLocalState (res->sref)))
+ if (sRef_isLocalParamVar (rs)
+ && (sRef_isDependent (rs)
+ || sRef_isLocalState (rs)))
{
- if (sRef_isDependent (other->sref))
+ if (sRef_isDependent (os))
{
- sRef_setDependent (res->sref, loc);
+ sRef_setDependent (rs, loc);
}
else
{
- sRef_setDefState (res->sref, SS_UNUSEABLE, loc);
+ sRef_setDefState (rs, SS_UNUSEABLE, loc);
}
}
else
{
- if (sRef_isParam (other->sref))
+ if (sRef_isParam (os))
{
/*
** If the local variable associated
uentry uvar = usymtab_lookupSafe (other->uname);
if (uentry_isValid (uvar)
- && ((sRef_isDead (other->sref)
+ && ((sRef_isDead (os)
&& sRef_isOnly (uvar->sref))
- || (sRef_isDependent (other->sref)
+ || (sRef_isDependent (os)
&& sRef_isOwned (uvar->sref))))
{
/* no error */
}
}
- if (sRef_isKept (other->sref))
+ if (sRef_isKept (os))
{
- sRef_setKept (res->sref, loc);
+ sRef_setKept (rs, loc);
}
}
if (opt)
{
DPRINTF (("Merge opt..."));
- sRef_mergeOptState (res->sref, other->sref, cl, loc);
+ sRef_mergeOptState (rs, os, cl, loc);
DPRINTF (("Done!"));
}
else
{
- sRef_mergeState (res->sref, other->sref, cl, loc);
+ DPRINTF (("Merging states: \n\t%s / \n\t%s", sRef_unparseFull (rs), sRef_unparseFull (os)));
+ sRef_mergeState (rs, os, cl, loc);
+ DPRINTF (("After merging : \n\t%s / \n\t%s", sRef_unparseFull (rs), sRef_unparseFull (os)));
}
}
else
{
- if (sRef_isModified (other->sref))
+ if (sRef_isModified (os))
{
- sRef_setModified (res->sref);
+ sRef_setModified (rs);
}
}
}
+
+ DPRINTF (("After merge: %s", sRef_unparseFull (res->sref)));
}
static void
-uentry_mergeValueStates (uentry res, uentry other, fileloc loc)
+uentry_mergeValueStates (uentry res, uentry other, fileloc loc, bool mustReturn, /*@unused@*/ bool flip)
{
valueTable rvalues;
valueTable ovalues;
DPRINTF (("Merge values: %s / %s", sRef_unparseFull (res->sref), sRef_unparseFull (other->sref)));
+ if (mustReturn)
+ {
+ return;
+ }
+ /* flip? */
+
rvalues = sRef_getValueTable (res->sref);
ovalues = sRef_getValueTable (other->sref);
{
sRef_setMetaStateValueComplete (res->sref,
fkey, stateValue_getValue (fval),
- loc);
+ stateValue_getLoc (fval));
DPRINTF (("Setting res: %s", sRef_unparseFull (res->sref)));
}
else if (stateValue_isError (tval)
{
DPRINTF (("Other branch is definitely null!"));
}
+ else if (sRef_isStateUndefined (res->sref)
+ || sRef_isDead (res->sref))
+ {
+ ; /* Combination state doesn't matter if it is undefined or dead */
+ }
else
{
DPRINTF (("Check: %s / %s / %s / %s", fkey,
DPRINTF (("nval: %d / %d / %d", nval,
stateValue_getValue (fval), stateValue_getValue (tval)));
- if (cstring_isDefined (msg))
+ if (nval == stateValue_error)
{
/*@i32 print extra info for assignments@*/
if (optgenerror
(FLG_STATEMERGE,
message
- ("Control branches merge with incompatible global states (%s and %s): %s",
+ ("Control branches merge with incompatible global states (%s and %s)%q",
metaStateInfo_unparseValue (minfo, stateValue_getValue (fval)),
metaStateInfo_unparseValue (minfo, stateValue_getValue (tval)),
- msg),
+ cstring_isDefined (msg)
+ ? message (": %s", msg) : cstring_undefined),
loc))
{
sRef_showMetaStateInfo (res->sref, fkey);
if (optgenerror
(FLG_STATEMERGE,
message
- ("Control branches merge with incompatible states for %q (%s and %s): %s",
+ ("Control branches merge with incompatible states for %q (%s and %s)%q",
uentry_getName (res),
metaStateInfo_unparseValue (minfo, stateValue_getValue (fval)),
metaStateInfo_unparseValue (minfo, stateValue_getValue (tval)),
- msg),
+ cstring_isDefined (msg)
+ ? message (": %s", msg) : cstring_undefined),
loc))
{
sRef_showMetaStateInfo (res->sref, fkey);
uentry_unparseFull (other)));
uentry_mergeAliasStates (res, other, loc, mustReturn, flip, opt, cl);
- uentry_mergeValueStates (res, other, loc);
+ uentry_mergeValueStates (res, other, loc, mustReturn, flip);
uentry_mergeSetStates (res, other, loc, flip, cl);
}
&& (cstring_equal (uentry_rawName (ue), GLOBAL_MARKER_NAME)));
}
-
-//
/* new start modifications */
-/*@ignore@*/
-
-
-# if 0
-
-static void uentry_testInRange (uentry p_e, uentry cconstant) {
- if (uentry_isValid(p_e)) {
- if (sRef_isValid (p_e->sref)) {
- /* char * t = cstring_toCharsSafe (uentry_unparse(cconstant) );
- int index = atoi( t );
- free (t);
- */
- long index = multiVal_forceInt (uentry_getConstantValue (cconstant));
- // usymtab_testInRange (p_e->sref, index);
- }//end if
- }//endif
-}
-
-
-/* void uentry_setStringLength (uentry p_e, uentry cconstant) { */
-/* if( uentry_isValid(p_e) ) { */
-/* if( p_e->info != NULL) { */
-/* if( p_e->info->var != NULL) { */
-/* char *t = cstring_toCharsSafe (uentry_unparse(cconstant)); */
-/* int length = atoi( t ); */
-/* free (t); */
-/* p_e->info->var->bufinfo->len = length; */
-/* p_e->sref->bufinfo.len = length; */
-/* printf("Set string length of buff to %d \n", p_e->sref->bufinfo.size); */
-/* }//end if */
-/* }//endif */
-/* }//end if */
-/* } */
-
-
-static void uentry_setBufferSize (uentry p_e, exprNode cconstant) {
-if( uentry_isValid(p_e) ) {
- if( p_e->info != NULL) {
- if( p_e->info->var != NULL) {
- int size = atoi(cstring_toCharsSafe(exprNode_unparse(cconstant) ) );
- p_e->info->var->bufinfo->size = size;
- p_e->sref->bufinfo.size = size;
- printf("Set buffer size to %d \n", p_e->sref->bufinfo.size);
- // fprintf(stderr, "For %s and %s\n", uentry_unparse(p_e) );
- // fprintf(stderr, "and %d\n", size );
-
- }//end if
- }//endif
-}//end if
-}
-
-# endif
-
-
/* start modifications */
/*
requires: p_e is defined, is a ptr/array variable
void uentry_setPossiblyNullTerminatedState (uentry p_e) {
+ /*@access sRef@*/ /*i523 shouldn't do this! */
if( uentry_isValid(p_e) ) {
if( p_e->info != NULL) {
if( p_e->info->var != NULL) {
p_e->info->var->bufinfo->bufstate = BB_POSSIBLYNULLTERMINATED;
p_e->sref->bufinfo.bufstate = BB_POSSIBLYNULLTERMINATED;
return;
- }/* End if */
- }/* End if */
- }/* End if */
+ }
+ }
+ }
+ /*@noaccess sRef@*/
fprintf(stderr, "uentry:Error in setPossiblyNullTerminatedState\n");
}
if( p_e->info != NULL) {
if( p_e->info->var != NULL) {
p_e->info->var->bufinfo->bufstate = BB_NULLTERMINATED;
+ /*@access sRef@*/ /*@i523 bad!*/
p_e->sref->bufinfo.bufstate = BB_NULLTERMINATED;
+ /*@noaccess sRef@*/
return;
- }//End if
- }//End if
- }//End if
+ }
+ }
+ }
fprintf(stderr, "uentry:Error in setNullTerminatedState\n");
}
-
-/*
-requires: p_e is defined, is a ptr/array variable
-modifies: p_e
-effects: sets the state of the variable
-*/
-
-/* void uentry_setNotNullTerminatedState (uentry p_e) { */
-/* if( uentry_isValid(p_e) ) { */
-/* if( p_e->info != NULL) { */
-/* if( p_e->info->var != NULL) { */
-/* p_e->info->var->bufinfo->bufstate = BB_NOTNULLTERMINATED; */
-/* p_e->sref->bufinfo.bufstate = BB_NOTNULLTERMINATED; */
-/* return; */
-/* }//End if */
-/* }//End if */
-/* }//End if */
-
-/* fprintf(stderr, "uentry:Error in setNotNullTerminatedState\n"); */
-/* } */
-
-
/*
requires: p_e is defined, is a ptr/array variable
modifies: p_e
if( p_e->info != NULL) {
if( p_e->info->var != NULL) {
p_e->info->var->bufinfo->size = size;
+ /*@access sRef@*/ /*@i523 bad!*/
p_e->sref->bufinfo.size = size;
+ /*@noaccess sRef@*/
return;
- }//End if
- }//End if
- }//End if
+ }
+ }
+ }
fprintf(stderr, "uentry:Error in setSize\n");
}
effects: sets the length of the buffer
*/
- void uentry_setLen (uentry p_e, int len) {
+void uentry_setLen (uentry p_e, int len) {
if( uentry_isValid(p_e) ) {
if( p_e->info != NULL) {
if( p_e->info->var != NULL) {
p_e->info->var->bufinfo->len = len;
+ /*@access sRef@*/ /*@i523 bad!*/
p_e->sref->bufinfo.len = len;
+ /*@noaccess sRef@*/
return;
- }//End if
- }//End if
- }//End if
-
+ }
+ }
+ }
+
fprintf(stderr, "uentry:Error in setLen\n");
}
-/*@end@*/
+
/*@=type*/
bool uentry_hasMetaStateEnsures (uentry e)