/*
-** 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
*/
/*
** uentry.c
*/
-# include "lclintMacros.nf"
+# include "splintMacros.nf"
# include "basic.h"
# include "structNames.h"
# include "nameChecks.h"
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@*/ ;
uentry_makeVariableAux (cstring p_n, ctype p_t, /*@keep@*/ fileloc p_f,
/*@exposed@*/ sRef p_s, bool p_priv, vkind p_kind);
+static /*@only@*/ /*@notnull@*/ uentry
+ uentry_makeConstantAux (cstring p_n, ctype p_t,
+ /*@keep@*/ fileloc p_f, bool p_priv, bool p_macro,
+ /*@only@*/ multiVal p_m) /*@*/ ;
+
static void uentry_convertVarFunction (uentry ue) /*@modifies ue@*/
{
if (uentry_isVariable (ue)
{
functionConstraint constraint;
- DPRINTF( (message ("called uentry_getFcnPostconditions on %s",
+ DPRINTF((message ("called uentry_getFcnPostconditions on %s",
uentry_unparse (ue) ) ) );
if (uentry_isVariable (ue) && ctype_isFunction (uentry_getType (ue)))
{
- DPRINTF( (message ("called uentry_getFunctionConditions on nonfunction %s",
+ DPRINTF((message ("called uentry_getFunctionConditions on nonfunction %s",
uentry_unparse (ue) ) ) );
if (!uentry_isFunction (ue) )
{
if (!uentry_isFunction(ue))
{
- DPRINTF( (message ("called uentry_getFunctionConditions on non function %s",
+ DPRINTF((message ("called uentry_getFunctionConditions on non function %s",
uentry_unparse (ue) ) ) );
return constraintList_undefined;
}
}
+static void uentry_setConstantValue (uentry ue, /*@only@*/ multiVal val)
+{
+ llassert (uentry_isEitherConstant (ue));
+ sRef_setValue (ue->sref, val);
+}
+
/*@notnull@*/ uentry uentry_makeEnumConstant (cstring n, ctype t)
{
fileloc loc = setLocation ();
}
else
{
+ DPRINTF (("Taking globs: %s", globalsClause_unparse (glc)));
uentry_setGlobals (ue, globalsClause_takeGlobs (glc));
+ DPRINTF (("Taking globs after: %s", globalsClause_unparse (glc)));
}
}
else if (functionClause_isModifies (el))
}
static /*@only@*/ /*@notnull@*/ uentry
-uentry_makeVariableParamAux (cstring n, ctype t, /*@dependent@*/ sRef s, sstate defstate) /*@i32 exposed*/
+uentry_makeVariableParamAux (cstring n, ctype t, /*@dependent@*/ sRef s,
+ /*@only@*/ fileloc loc, sstate defstate) /*@i32 exposed*/
{
cstring pname = makeParam (n);
uentry e;
DPRINTF (("Sref: %s", sRef_unparseFull (s)));
- e = uentry_makeVariableAux (pname, t, setLocation (), s, FALSE, VKPARAM);
+ e = uentry_makeVariableAux (pname, t, loc, s, FALSE, VKPARAM);
cstring_free (pname);
DPRINTF (("Param: %s", uentry_unparseFull (e)));
}
uentry
-uentry_makeVariableSrefParam (cstring n, ctype t, /*@exposed@*/ sRef s)
+uentry_makeVariableSrefParam (cstring n, ctype t, /*@only@*/ fileloc loc, /*@exposed@*/ sRef s)
{
- return (uentry_makeVariableParamAux (n, t, s, SS_UNKNOWN));
+ return (uentry_makeVariableParamAux (n, t, s, loc, SS_UNKNOWN));
}
void
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-2002
+ 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);
}
}
else
{
- llfatalbug ( (message("uentry_setPreconditions called with invalid uentry") ));
+ llfatalbug ((message("uentry_setPreconditions called with invalid uentry") ));
}
}
}
else
{
- llfatalbug ( (message("uentry_setPostconditions called with invalid uentry") ));
+ llfatalbug ((message("uentry_setPostconditions called with invalid uentry") ));
}
}
{
if (optgenerror
(FLG_ANNOTATIONERROR,
- message ("Meta state anntation %s used in inconsistent context: %q",
+ message ("Attribute annotation %s used in inconsistent context: %q",
qual_unparse (qel),
uentry_unparse (ue)),
uentry_whereLast (ue)))
{
ctype ct = idDecl_getCtype (t);
ctype base = ct;
- sRef pref = sRef_makeParam (i, ct);
- uentry ue = uentry_makeVariableSrefParam (idDecl_observeId (t), ct, pref);
+ fileloc loc = setLocation ();
+ sRef pref = sRef_makeParam (i, ct, stateInfo_makeLoc (loc));
+ uentry ue = uentry_makeVariableSrefParam (idDecl_observeId (t), ct, loc, pref);
+ DPRINTF (("Make param: %s", uentry_unparseFull (ue)));
uentry_reflectQualifiers (ue, idDecl_getQuals (t));
uentry_implicitParamAnnots (ue);
}
# ifndef NOLCL
-/*@notnull@*/ uentry uentry_makeVariableParam (cstring n, ctype t)
+/*@notnull@*/ uentry uentry_makeVariableParam (cstring n, ctype t, fileloc loc)
{
- return (uentry_makeVariableParamAux (n, t, sRef_makeType (t), SS_DEFINED));
+ return (uentry_makeVariableParamAux (n, t, sRef_makeType (t), fileloc_copy (loc), SS_DEFINED));
}
# endif
** constants
*/
-/*@only@*/ /*@notnull@*/
+static /*@only@*/ /*@notnull@*/
uentry uentry_makeConstantAux (cstring n, ctype t,
- /*@keep@*/ fileloc f, bool priv,
+ /*@keep@*/ fileloc f, bool priv, bool macro,
/*@only@*/ multiVal m)
{
uentry e = uentry_alloc ();
e->info = (uinfo) dmalloc (sizeof (*e->info));
e->info->uconst = (ucinfo) dmalloc (sizeof (*e->info->uconst));
- e->info->uconst->val = m;
e->info->uconst->access = typeIdSet_undefined;
+ e->info->uconst->macro = macro;
uentry_setSpecDef (e, f);
sRef_setDefNull (e->sref, uentry_whereDeclared (e));
}
+ uentry_setConstantValue (e, m);
+
return (e);
}
/*@notnull@*/ uentry uentry_makeConstant (cstring n, ctype t, fileloc f)
{
- return (uentry_makeConstantAux (n, t, f, FALSE, multiVal_unknown ()));
+ return (uentry_makeConstantAux (n, t, f, FALSE, FALSE, multiVal_unknown ()));
+}
+
+/*@notnull@*/ uentry uentry_makeConstantValue (cstring n, ctype t, fileloc f, bool priv, multiVal val)
+{
+ return (uentry_makeConstantAux (n, t, f, priv, FALSE, val));
+}
+
+/*@notnull@*/ uentry uentry_makeMacroConstant (cstring n, ctype t, fileloc f)
+{
+ return (uentry_makeConstantAux (n, t, f, FALSE, TRUE, multiVal_unknown ()));
}
/*@notnull@*/ uentry uentry_makeIdConstant (idDecl t)
ue->whereDeclared = setLocation ();
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)));
e->info->var->defstate = sRef_getDefState (e->sref);
e->info->var->nullstate = sRef_getNullState (e->sref);
-/* start modifications */
-/* This function sets the uentry for a pointer or array variable declaration,
- it allocates memory and sets the fields. We check if the type of the variable
- is a pointer or array and allocate a `bbufinfo' struct accordingly */
-
+ /* start modifications */
+ /* This function sets the uentry for a pointer or array variable declaration,
+ it allocates memory and sets the fields. We check if the type of the variable
+ is a pointer or array and allocate a `bbufinfo' struct accordingly */
+
if( ctype_isArray (t) || ctype_isPointer(t)) {
/*@i222@*/e->info->var->bufinfo = dmalloc( sizeof(*e->info->var->bufinfo) );
e->info->var->bufinfo->bufstate = BB_NOTNULLTERMINATED;
llassert (uentry_isVariable (ue));
oldInfo = ue->info->var;
- llassert (ctype_isUnknown (ue->utype) || ctype_isFunction (ue->utype));
+ DPRINTF (("ue: %s", uentry_unparseFull (ue)));
+ llassert (ctype_isUnknown (ue->utype) || ctype_isFunction (ctype_realType (ue->utype)));
/*
- ** expanded macro is marked used (until I write a pre-processor)
+ ** expanded macro is marked used
*/
ue->used = ue->used || (oldInfo->kind == VKEXPMACRO);
/*@=mustfree@*/
}
- /*@i23 ???
+ /*@i23*/
+ /* ??? - evans 2001-09-09 not sure what's going on here...?
if (globSet_hasStatic (globs))
{
context_recordFileGlobals (globs);
{
case KINVALID:
case KELIPSMARKER:
- /* bug detected by lclint:
+ /* bug detected by splint:
** uentry.c:753,14: Return value type bool does not match declared type int: TRUE
*/
return 0;
case KENUMCONST:
case KCONST:
- return (multiVal_compare (u1->info->uconst->val,
- u2->info->uconst->val));
+ return (multiVal_compare (uentry_getConstantValue (u1),
+ uentry_getConstantValue (u2)));
case KSTRUCTTAG:
case KUNIONTAG:
case KENUMTAG:
** 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;
}
e->info = (uinfo) dmalloc (sizeof (*e->info));
e->info->uconst = (ucinfo) dmalloc (sizeof (*e->info->uconst));
- e->info->uconst->val = m;
e->info->uconst->access = access;
-
+ e->info->uconst->macro = FALSE; /*@i523! fix this when macro info added to library */
+ uentry_setConstantValue (e, m);
sRef_storeState (e->sref);
return (e);
{
cstring sdump;
- if (multiVal_isUnknown (v->info->uconst->val)
+ if (multiVal_isUnknown (uentry_getConstantValue (v))
&& typeIdSet_isEmpty (uentry_accessType (v))
&& (sRef_getNullState (v->sref) == NS_UNKNOWN))
{
else
{
sdump = message ("@%q@%q@%d",
- multiVal_dump (v->info->uconst->val),
+ multiVal_dump (uentry_getConstantValue (v)),
typeIdSet_dump (uentry_accessType (v)),
(int) sRef_getNullState (v->sref));
}
DPRINTF (("sref: %s", sRef_unparseDebug (v->sref)));
/* DPRINTF (("sref: %s", sRef_unparseDeep (v->sref))); */
}
+ else if (uentry_isConstant (v))
+ {
+ res = message ("%q = %q",
+ res, multiVal_unparse (uentry_getConstantValue (v)));
+ }
else
{
res = message ("%q :: %q", res, uentry_unparse (v));
/*@observer@*/ multiVal uentry_getConstantValue (uentry e)
{
- llassert (uentry_isEitherConstant (e));
-
- return (e->info->uconst->val);
+ llassert (uentry_isEitherConstant (e));
+ return (sRef_getValue (e->sref));
}
/*@observer@*/ uentryList
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));
e->whereDeclared = f;
e->whereDefined = fileloc_undefined;
}
+
+ llassert (fileloc_storable (f));
}
static void
ucinfo_free (/*@only@*/ ucinfo u)
{
- multiVal_free (u->val);
sfree (u);
}
ucinfo_copy (ucinfo u)
{
ucinfo ret = (ucinfo) dmalloc (sizeof (*ret));
-
- ret->val = multiVal_copy (u->val);
ret->access = u->access;
-
+ ret->macro = u->macro;
return ret;
}
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)
{
if (hasError)
{
+ DPRINTF (("Here: %s / %s",
+ uentry_unparseFull (oldCurrent),
+ uentry_unparseFull (newCurrent)));
+
if (!uentry_isUndefined (oldCurrent))
{
if (!uentry_isUndefined (newCurrent)
uentryList oldParams = uentry_getParams (old);
uentryList newParams = uentry_getParams (unew);
ctype newType = unew->utype;
- ctype oldType = old->utype;
+ ctype oldType = ctype_realType (old->utype);
ctype oldRetType = ctype_unknown;
ctype newRetType = ctype_unknown;
if (ctype_isKnown (oldType))
{
llassert (ctype_isFunction (oldType));
-
oldRetType = ctype_getReturnType (oldType);
}
if (ctype_isKnown (newType))
{
llassert (ctype_isFunction (newType));
-
newRetType = ctype_getReturnType (newType);
}
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));
}
paramno++;
/*
- ** Forgot this! detected by lclint:
+ ** Forgot this! detected by splint:
** uentry.c:1257,15: Suspected infinite loop
*/
}
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)
llassert (uentry_isValid (ue));
llassert (uentry_isEitherConstant (ue));
- uval = ue->info->uconst->val;
+ DPRINTF (("Constant value: %s / %s", uentry_unparse (ue), multiVal_unparse (m)));
+ uval = uentry_getConstantValue (ue);
if (multiVal_isDefined (uval))
{
}
else
{
- ue->info->uconst->val = m;
- multiVal_free (uval);
+ uentry_setConstantValue (ue, m);
}
}
bool mustConform,
/*@unused@*/ bool completeConform)
{
- multiVal oldVal = old->info->uconst->val;
- multiVal newVal = unew->info->uconst->val;
+ multiVal oldval = uentry_getConstantValue (old);
+ multiVal newval = uentry_getConstantValue (unew);
- if (multiVal_isDefined (oldVal))
+ if (multiVal_isDefined (oldval))
{
- if (multiVal_isDefined (newVal))
+ if (multiVal_isDefined (newval))
{
- if (!multiVal_equiv (oldVal, newVal))
+ if (!multiVal_equiv (oldval, newval))
{
if (mustConform
&& optgenerror
ekind_capName (unew->ukind),
uentry_getName (unew),
uentry_isDeclared (old),
- multiVal_unparse (newVal)),
+ multiVal_unparse (newval)),
uentry_whereDeclared (unew)))
{
- uentry_showWhereLastExtra (old, multiVal_unparse (oldVal));
+ uentry_showWhereLastExtra (old, multiVal_unparse (oldval));
}
}
- unew->info->uconst->val = multiVal_copy (oldVal);
- multiVal_free (newVal);
+ uentry_setConstantValue (unew, multiVal_copy (oldval));
}
else
{
}
else
{
- old->info->uconst->val = multiVal_copy (newVal);
+ uentry_setConstantValue (old, multiVal_copy (newval));
}
}
void
uentry_mergeDefinition (uentry old, /*@only@*/ uentry unew)
{
- fileloc olddef = uentry_whereDeclared (old);
+ fileloc olddef = uentry_whereDeclared (old);
fileloc unewdef = uentry_whereDeclared (unew);
bool mustConform;
bool wasForward;
}
else
{
- if (!uentry_isExtern (unew) && !uentry_isForward (old)
+ if (!uentry_isExtern (unew)
+ && !uentry_isForward (old)
&& !fileloc_equal (olddef, unewdef)
&& !fileloc_isUndefined (olddef)
&& !fileloc_isUndefined (unewdef)
}
else
{
- uentry_setDefined (old, unewdef);
+ uentry_setDeclared (old, unewdef); /* evans 2001-07-23 was setDefined */
}
}
}
uentry_unparseFull (unew)));
uentry_mergeConstraints (old, unew);
+ DPRINTF (("uentry merge: %s / %s",
+ uentry_unparseFull (old),
+ uentry_unparseFull (unew)));
+
uentry_checkConformance (old, unew, mustConform, FALSE);
+ DPRINTF (("uentry merge: %s / %s",
+ uentry_unparseFull (old),
+ uentry_unparseFull (unew)));
old->used = old->used || unew->used;
old->uses = filelocList_append (old->uses, unew->uses);
fileloc_undefined);
}
+ DPRINTF (("here: %s", uentry_unparseFull (old)));
+
/*
** No redeclaration errors for functions here, since we
** don't know if this is the definition of the function.
uentry_checkName (old);
}
+ DPRINTF (("After: %s", uentry_unparseFull (old)));
llassert (!ctype_isUndefined (old->utype));
}
llassert (uentry_isValid (unew));
llassert (uentry_isValid (old));
+ DPRINTF (("Update into: %s / %s", uentry_unparseFull (unew), uentry_unparseFull (old)));
+
unew->ukind = old->ukind;
llassert (cstring_equal (unew->uname, old->uname));
unew->utype = old->utype;
unew->whereDeclared = fileloc_copy (old->whereDeclared);
}
+ DPRINTF (("Update into: %s / %s", uentry_unparseFull (unew), uentry_unparseFull (old)));
+
unew->sref = sRef_saveCopy (old->sref); /* Memory leak! */
unew->used = old->used;
unew->lset = FALSE;
}
}
-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);
+
+ DPRINTF (("Merge ==> %s", uentry_unparseFull (res)));
}
void uentry_setUsed (uentry e, fileloc loc)
}
}
-/*@exposed@*/ uentry uentry_makeUnrecognized (cstring c, /*@keep@*/ fileloc loc)
+/*@exposed@*/ uentry uentry_makeUnrecognized (cstring c, /*@only@*/ fileloc loc)
{
uentry ue;
fileloc tloc;
/*
- ** Can't but unrecognized ids in macros in global scope, because srefs will break! */
+ ** Can't but unrecognized ids in macros in global scope, because srefs will break!
+ */
+
if (!context_inMacro ())
{
sRef_setGlobalScopeSafe ();
fileloc_free (tloc);
uentry_setHasNameError (ue);
- if (context_getFlag (FLG_REPEATUNRECOG))
+ if (context_getFlag (FLG_REPEATUNRECOG) || (context_inOldSytleScope() ) )
{
uentry_markOwned (ue);
}
&& (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)