/*
-** LCLint - annotation-assisted static program checker
-** Copyright (C) 1994-2001 University of Virginia,
+** Splint - annotation-assisted static program checker
+** Copyright (C) 1994-2003 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
*/
/*
** transferChecks.c
*/
-# include "lclintMacros.nf"
+# include "splintMacros.nf"
# include "basic.h"
# include "transferChecks.h"
+/* transfer types: */
+typedef enum
+{
+ TT_FCNRETURN,
+ TT_DOASSIGN,
+ TT_FIELDASSIGN,
+ TT_FCNPASS,
+ TT_GLOBPASS,
+ TT_GLOBRETURN,
+ TT_PARAMRETURN,
+ TT_LEAVETRANS,
+ TT_GLOBINIT
+} transferKind;
+
static void checkStructTransfer (exprNode p_lhs, sRef p_slhs, exprNode p_rhs, sRef p_srhs,
fileloc p_loc, transferKind p_tt);
static void checkMetaStateConsistent (/*@exposed@*/ sRef p_fref, sRef p_tref,
static void checkLeaveTrans (uentry p_actual, transferKind p_transferType);
static void checkTransfer (exprNode p_fexp, /*@dependent@*/ sRef p_fref,
exprNode p_texp, /*@dependent@*/ sRef p_tref,
+ exprNode p_fcn, /* for printing better error messages */
fileloc p_loc, transferKind p_transferType);
static void checkGlobTrans (uentry p_glob, transferKind p_type);
}
static /*@only@*/ cstring
-transferErrorExcerpt (transferKind transferType, exprNode fexp, exprNode texp) /*@*/
+transferErrorExcerpt (transferKind transferType, exprNode fexp, exprNode texp, exprNode fcn) /*@*/
{
switch (transferType)
{
case TT_GLOBINIT:
return (message ("%s = %s", exprNode_unparse (texp), exprNode_unparse (fexp)));
case TT_FCNPASS:
- /*@i32 make it so called fcn is known here! */
- return cstring_copy (exprNode_unparse (fexp));
+ if (exprNode_isDefined (fcn))
+ {
+ return message ("%s(..., %s, ...)",
+ exprNode_unparse (fcn),
+ exprNode_unparse (fexp));
+ }
+ else
+ {
+ return cstring_copy (exprNode_unparse (fexp));
+ }
BADDEFAULT;
}
BADEXIT;
("Check definition limit exceeded, checking %q. "
"This either means there is a variable with at least "
"%d indirections apparent in the program text, or "
- "there is a bug in LCLint.",
+ "there is a bug in Splint.",
sRef_unparse (fref),
MAXDEPTH));
{
; /* no error (will be a definition error) */
}
- else if (transferType == TT_DOASSIGN)
+ else if (transferType == TT_DOASSIGN
+ || transferType == TT_FIELDASSIGN) /* evans 2002-02-05 - added TT_FIELDASSIGN */
{
; /* no error */
}
else
{
llassert (transferType == TT_DOASSIGN
+ || transferType == TT_FIELDASSIGN /* evans 2002-02-05: no warnings for local fields */
|| transferType == TT_GLOBINIT
|| transferType == TT_LEAVETRANS);
}
{
sRef rb = sRef_getRootBase (fref);
sRef_showStateInfo (fref);
-
- DPRINTF (("fref: %s", sRef_unparseFull (fref)));
- DPRINTF (("rb: %s", sRef_unparseFull (rb)));
- sRef_setDefinedComplete (rb, loc);
+
+ sRef_setDefinedCompleteDirect (rb, loc);
}
}
}
sRef_unparse (fref)),
loc);
}
+ /* evans 2001-08-21: added this branch for global returns */
+ else if (transferType == TT_GLOBRETURN)
+ {
+ voptgenerror
+ (FLG_UNIONDEF,
+ message ("Union %q reachable from global %q has "
+ "no defined field",
+ sRef_unparse (fref),
+ sRef_unparse (sRef_getRootBase (fref))),
+ loc);
+ }
else if (transferType == TT_DOASSIGN
|| transferType == TT_FIELDASSIGN
|| transferType == TT_GLOBINIT)
}
static bool
- checkCompletelyDestroyed (exprNode p_fexp, sRef p_fref, bool p_topLevel,
- fileloc p_loc, int p_depth, dscCode p_desc,
- bool p_hideErrors);
+checkCompletelyDestroyed (exprNode p_fexp, sRef p_fref, bool p_topLevel, bool p_isField,
+ fileloc p_loc, int p_depth, dscCode p_desc,
+ bool p_hideErrors);
-bool checkGlobalDestroyed (sRef fref, fileloc loc)
+bool transferChecks_globalDestroyed (sRef fref, fileloc loc)
{
- return (checkCompletelyDestroyed (exprNode_undefined, fref, TRUE,
+ DPRINTF (("Global destroyed: %s", sRef_unparseFull (fref)));
+ return (checkCompletelyDestroyed (exprNode_undefined, fref, TRUE, FALSE,
loc, 0, DSC_GLOB, FALSE));
}
-void checkLocalDestroyed (sRef fref, fileloc loc)
+void transferChecks_localDestroyed (sRef fref, fileloc loc)
{
if (sRef_isObserver (fref) || sRef_isExposed (fref)
|| sRef_isPartial (fref))
}
else
{
- (void) checkCompletelyDestroyed (exprNode_undefined, fref, TRUE,
+ (void) checkCompletelyDestroyed (exprNode_undefined, fref, TRUE, FALSE,
loc, 0, DSC_LOCAL, FALSE);
}
}
-void checkStructDestroyed (sRef fref, fileloc loc)
+void transferChecks_structDestroyed (sRef fref, fileloc loc)
{
DPRINTF (("Check struct destroyed: %s", sRef_unparse (fref)));
}
else
{
- (void) checkCompletelyDestroyed (exprNode_undefined, fref, TRUE,
+ (void) checkCompletelyDestroyed (exprNode_undefined, fref, TRUE, FALSE,
loc, 0, DSC_STRUCT, FALSE);
}
}
static bool
- checkCompletelyDestroyed (exprNode fexp, sRef fref, bool topLevel,
- fileloc loc, int depth,
- dscCode desc, bool hideErrors)
+checkCompletelyDestroyed (exprNode fexp, sRef fref, bool topLevel, bool isField,
+ fileloc loc, int depth,
+ dscCode desc, bool hideErrors)
{
ctype ct;
-
- DPRINTF (("Check completely destroyed: %s", sRef_unparseFull (fref)));
+
+ DPRINTF (("Check completely destroyed: %s / %s",
+ sRef_unparse (fref),
+ bool_unparse (hideErrors)));
if (depth > MAXDEPTH)
{
}
}
- if (sRef_isPdefined (fref) && !context_getFlag (FLG_STRICTDESTROY))
+ ct = ctype_realType (sRef_getType (fref));
+
+ if (sRef_isPdefined (fref)
+ && ctype_isAP (ct)
+ && !isField
+ && !context_getFlag (FLG_STRICTDESTROY))
{
- DPRINTF (("Partial: %s", sRef_unparseFull (fref)));
- hideErrors = TRUE; /* Don't report any more errors, but still change ownership. */
- }
+ /*
+ ** Don't report errors for array elements (unless strictdestroy)
+ ** when at least one appears to have been destroyed.
+ */
+ DPRINTF (("Partial: %s / hiding errors: %s", sRef_unparseFull (fref),
+ ctype_unparse (ct)));
+ hideErrors = TRUE;
+ /* Don't report any more errors, but still change ownership. */
+ }
+
if (usymtab_isDefinitelyNull (fref))
{
DPRINTF (("Probably null!"));
return TRUE;
}
- if (!context_getFlag (FLG_COMPDESTROY)) return TRUE;
- if (!context_getFlag (FLG_MUSTFREE)) return TRUE;
+ /*
+ ** evans 2002-01-02: removed this
+ ** if (!context_flagOn (FLG_COMPDESTROY, loc))
+ ** {
+ ** return TRUE;
+ ** }
+ **
+ ** if (!context_getFlag (FLG_MUSTFREEONLY)) return TRUE;
+ */
- ct = ctype_realType (sRef_getType (fref));
-
DPRINTF (("Here: %s", ctype_unparse (ct)));
if (!topLevel)
return FALSE;
}
- if (/*! evs-2001-03-24 sRef_isAnyDefined (fref) || */
+ if (/*! evs-2002-03-24 sRef_isAnyDefined (fref) || */
sRef_isDead (fref)
|| (sRef_isPdefined (fref)
&& sRefSet_isEmpty (sRef_derivedFields (fref))))
sRef fptr = sRef_constructDeadDeref (fref);
bool res;
- res = checkCompletelyDestroyed (fexp, fptr, FALSE, loc,
- depth + 1, desc, hideErrors);
+ res = checkCompletelyDestroyed (fexp, fptr, FALSE, FALSE,
+ loc, depth + 1, desc, hideErrors);
return res;
}
{
sRef farr = sRef_constructDeadDeref (fref);
- return (checkCompletelyDestroyed (fexp, farr, FALSE, loc,
- depth + 1, desc, hideErrors));
+ return (checkCompletelyDestroyed (fexp, farr, FALSE, FALSE,
+ loc, depth + 1, desc, hideErrors));
}
}
else if (ctype_isStruct (ct))
DPRINTF (("Check field: %s", sRef_unparseFull (field)));
- isOk = (checkCompletelyDestroyed (fexp, field, FALSE, loc,
- depth + 1, desc, hideErrors)
+ isOk = (checkCompletelyDestroyed (fexp, field, FALSE, TRUE,
+ loc, depth + 1, desc, hideErrors)
&& isOk);
} end_uentryList_elements;
}
-
+
return isOk;
}
else
}
void
-checkReturnTransfer (exprNode fexp, uentry rval)
+transferChecks_return (exprNode fexp, uentry rval)
{
sRef uref = uentry_getSref (rval);
sRef rref = sRef_makeNew (sRef_getType (uref), uref, cstring_undefined);
{
if (stateClause_isGlobal (cl))
{
- ; /*@i32@*/
+ ;
}
else if (stateClause_setsMetaState (cl))
{
exprNode_loc (fexp)))
{
sRef_showAliasInfo (sr);
- /*@i32@*/
}
}
}
DPRINTF (("el: %s / %s", sRef_unparse (el),
sRef_unparse (base)));
- if (sRef_isResult (base))
+ if (sRef_isResult (base)
+ && !sRef_isDefinitelyNull (fref)) /* evans 2002-07-22: don't report allocation errors for null results */
{
sRef sr = sRef_fixBase (el, fref);
{
(void) checkTransfer (fexp, exprNode_getSref (fexp),
exprNode_undefined, rref,
+ exprNode_undefined,
exprNode_loc (fexp), TT_FCNRETURN);
}
}
*/
void
-checkPassTransfer (exprNode fexp, uentry arg, bool isSpec,
- /*@dependent@*/ exprNode fcn, int argno, int totargs)
+transferChecks_passParam (exprNode fexp, uentry arg, bool isSpec,
+ /*@dependent@*/ exprNode fcn, int argno, int totargs)
{
sRef tref = uentry_getSref (arg);
sRef fref = exprNode_getSref (fexp);
}
}
- (void) checkCompletelyDestroyed (fexp, fref, TRUE, exprNode_loc (fexp),
- 0, DSC_PARAM, FALSE);
+ (void) checkCompletelyDestroyed (fexp, fref, TRUE, FALSE,
+ exprNode_loc (fexp), 0, DSC_PARAM, FALSE);
/* make it defined now, so checkTransfer is okay */
sRef_setDefined (fref, exprNode_loc (fexp));
{
voptgenerror
- (FLG_MUSTFREE,
+ (FLG_MUSTFREEFRESH,
message ("New fresh storage %q(type %s) passed as %s (not released): %s",
sRef_unparseOpt (fref),
ctype_unparse (sRef_getType (fref)),
alkind_unparse (sRef_getAliasKind (tref)),
exprNode_unparse (fexp)),
exprNode_loc (fexp));
+
DPRINTF (("Fresh: %s", sRef_unparseFull (fref)));
}
else
if (!alkind_isError (ak))
{
voptgenerror
- (FLG_MUSTFREE,
+ (FLG_MUSTFREEFRESH,
message ("New reference %q(type %s) passed as %s (not released): %s",
sRef_unparseOpt (fref),
ctype_unparse (sRef_getType (fref)),
(void) checkTransfer (fexp, exprNode_getSref (fexp),
exprNode_undefined, tref,
+ fcn,
exprNode_loc (fexp), TT_FCNPASS);
setCodePoint ();
}
void
-checkGlobReturn (uentry glob)
+transferChecks_globalReturn (uentry glob)
{
sRef_protectDerivs ();
checkGlobTrans (glob, TT_GLOBRETURN);
sRef_clearProtectDerivs ();
}
-void checkParamReturn (uentry actual)
+void transferChecks_paramReturn (uentry actual)
{
checkLeaveTrans (actual, TT_PARAMRETURN);
}
-void checkLoseRef (uentry actual)
+void transferChecks_loseReference (uentry actual)
{
checkLeaveTrans (actual, TT_LEAVETRANS);
}
checkGlobTrans (uentry glob, transferKind type)
{
sRef eref = uentry_getOrigSref (glob);
-
- (void) checkCompletelyDefined (exprNode_undefined, uentry_getSref (glob), uentry_getSref (glob),
+
+ DPRINTF (("Completely defined: %s", uentry_unparseFull (glob)));
+
+ (void) checkCompletelyDefined (exprNode_undefined, uentry_getSref (glob),
+ uentry_getSref (glob),
exprNode_undefined, eref,
TRUE, FALSE, FALSE,
g_currentloc, type, 0, TRUE);
sRef lfld = sRef_makeField (slhs, fieldname);
(void) checkTransfer (rhs, sr, lhs, lfld,
+ exprNode_undefined,
exprNode_loc (lhs), tt);
}
} end_sRefSet_realElements ;
{
sRef rfld = sRef_makeField (srhs, uentry_rawName (field));
sRef lfld = sRef_makeField (slhs, uentry_rawName (field));
- (void) checkTransfer (rhs, rfld, lhs, lfld, exprNode_loc (lhs), tt);
+ (void) checkTransfer (rhs, rfld, lhs, lfld,
+ exprNode_undefined,
+ exprNode_loc (lhs), tt);
} end_uentryList_elements ;
}
}
void
-checkInitTransfer (exprNode lhs, exprNode rhs)
+transferChecks_initialization (exprNode lhs, exprNode rhs)
{
sRef slhs = exprNode_getSref (lhs);
if (sRef_isFileOrGlobalScope (slhs) || (!sRef_isCvar (slhs)))
{
(void) checkTransfer (rhs, exprNode_getSref (rhs),
- lhs, slhs, exprNode_loc (rhs), TT_GLOBINIT);
+ lhs, slhs,
+ exprNode_undefined,
+ exprNode_loc (rhs), TT_GLOBINIT);
}
else
{
- checkAssignTransfer (lhs, rhs);
+ transferChecks_assign (lhs, rhs);
}
}
void
-checkAssignTransfer (exprNode lhs, exprNode rhs)
+transferChecks_assign (exprNode lhs, exprNode rhs)
{
sRef slhs = exprNode_getSref (lhs);
sRef srhs = exprNode_getSref (rhs);
DPRINTF (("lhs: %s", sRef_unparseFull (slhs)));
DPRINTF (("rhs: %s", sRef_unparseFull (srhs)));
(void) checkTransfer (rhs, srhs, lhs, slhs,
+ exprNode_undefined,
exprNode_loc (lhs), TT_DOASSIGN);
DPRINTF (("lhs: %s", sRef_unparseFull (slhs)));
DPRINTF (("rhs: %s", sRef_unparseFull (srhs)));
if (sRef_isNotNull (tref))
{
if (optgenerror
- (FLG_SYNTAX, /*@i432 kuldge flag... */
+ (FLG_NULLINIT, /* kuldge flag... */
message ("%s %q initialized to %s value: %q",
sRef_getScopeName (tref),
sRef_unparse (tref),
&& !(sRef_same (fref, tref)) /* okay to assign to self (returned params) */
&& !(usymtab_isDefinitelyNull (tref)))
{
- if (context_getFlag (FLG_MUSTFREE))
+ if (transferChecks_canLoseReference (tref, loc))
{
- if (canLoseReference (tref, loc))
+ ; /* no error */
+ }
+ else
+ {
+ flagcode flg = sRef_isFresh (tref) ? FLG_MUSTFREEFRESH : FLG_MUSTFREEONLY;
+
+ if (sRef_hasLastReference (tref))
{
- ; /* no error */
+ if (optgenerror
+ (flg,
+ message ("Last reference %q to %s storage %q(type %s) not released "
+ "before assignment: %q",
+ sRef_unparse (tref),
+ alkind_unparse (tkind),
+ sRef_unparseOpt (sRef_getAliasInfoRef (tref)),
+ ctype_unparse (sRef_getType (tref)),
+ generateText (fexp, texp, tref, transferType)),
+ loc))
+ {
+ sRef_showRefLost (tref);
+ }
}
else
{
- if (sRef_hasLastReference (tref))
+ if (context_inGlobalScope ())
{
- if (optgenerror
- (FLG_MUSTFREE,
- message ("Last reference %q to %s storage %q(type %s) not released "
- "before assignment: %q",
- sRef_unparse (tref),
- alkind_unparse (tkind),
- sRef_unparseOpt (sRef_getAliasInfoRef (tref)),
- ctype_unparse (sRef_getType (tref)),
- generateText (fexp, texp, tref, transferType)),
- loc))
- {
- sRef_showRefLost (tref);
- }
+ /* no errors for static initializations */
}
- else
+ else
{
- if (context_inGlobalScope ())
- {
- /* no errors for static initializations */
- }
- else
+ /*
+ ** don't report this error for a[i], since it could
+ ** be a new element.
+ */
+
+ if (alkind_isNewRef (tkind))
{
- /*
- ** don't report this error for a[i], since it could
- ** be a new element.
- */
-
- if (alkind_isNewRef (tkind))
- {
- if (optgenerror
- (FLG_MUSTFREE,
- message
- ("%q %q(type %s) not released before assignment: %q",
- cstring_makeLiteral
- (alkind_isKillRef (sRef_getOrigAliasKind (tref))
- ? "Kill reference parameter" : "New reference"),
- sRef_unparseOpt (tref),
- ctype_unparse (sRef_getType (tref)),
- generateText (fexp, texp, tref, transferType)),
- loc))
- {
- sRef_showAliasInfo (tref);
- sRef_setAliasKind (tref, AK_ERROR, loc);
- }
- }
- else if
- (!(sRef_isUnknownArrayFetch (tref)
- && !context_getFlag (FLG_STRICTDESTROY))
- && !sRef_isUnionField (tref)
- && !sRef_isRelDef (tref)
- && optgenerror
- (FLG_MUSTFREE,
- message
- ("%s storage %q(type %s) not released before assignment: %q",
- alkind_capName (tkind),
- sRef_unparseOpt (tref),
- ctype_unparse (sRef_getType (tref)),
- generateText (fexp, texp, tref, transferType)),
- loc))
- {
- sRef_showAliasInfo (tref);
- }
- else
+ if (optgenerror
+ (flg,
+ message
+ ("%q %q(type %s) not released before assignment: %q",
+ cstring_makeLiteral
+ (alkind_isKillRef (sRef_getOrigAliasKind (tref))
+ ? "Kill reference parameter" : "New reference"),
+ sRef_unparseOpt (tref),
+ ctype_unparse (sRef_getType (tref)),
+ generateText (fexp, texp, tref, transferType)),
+ loc))
{
- ;
+ sRef_showAliasInfo (tref);
+ sRef_setAliasKind (tref, AK_ERROR, loc);
}
}
+ else if
+ (!(sRef_isUnknownArrayFetch (tref)
+ && !context_getFlag (FLG_STRICTDESTROY))
+ && !sRef_isUnionField (tref)
+ && !sRef_isRelDef (tref)
+ && optgenerror
+ (flg,
+ message
+ ("%s storage %q(type %s) not released before assignment: %q",
+ alkind_capName (tkind),
+ sRef_unparseOpt (tref),
+ ctype_unparse (sRef_getType (tref)),
+ generateText (fexp, texp, tref, transferType)),
+ loc))
+ {
+ sRef_showAliasInfo (tref);
+ }
+ else
+ {
+ ;
+ }
}
}
}
;
}
}
- else if (transferType == TT_DOASSIGN)
+ else if (transferType == TT_DOASSIGN
+ /* evans 2001-10-05: added TT_FIELDASSIGN: */
+ || transferType == TT_FIELDASSIGN)
{
if (!(sRef_isExposed (tref)
|| !sRef_isCvar (tref)
&& ctype_isMutable (exprNode_getType (fexp))
&& (!iseitherassign || sRef_isReference (tref)))
{
- if (canLoseReference (fref, loc))
+ if (transferChecks_canLoseReference (fref, loc))
{
;
}
}
else
{
- /*@i#!@!!@*/
DPRINTF (("Cannot find meta state for: %s / to: %s / %s", sRef_unparseFull (fref),
sRef_unparseFull (tref),
fkey));
if (nval == stateValue_error)
{
- llassert (cstring_isDefined (msg));
-
if (transferType == TT_LEAVETRANS)
{
BADBRANCH;
if (optgenerror
(FLG_STATETRANSFER,
message
- ("Function returns with global %q in inconsistent state (%q is %q, should be %q): %q",
+ ("Function returns with global %q in inconsistent state (%q is %q, should be %q)%q",
sRef_unparse (sRef_getRootBase (fref)),
sRef_unparse (fref),
stateValue_unparseValue (fval, minfo),
stateValue_unparseValue (tval, minfo),
- msg),
+ cstring_isDefined (msg)
+ ? message (": %s", msg) : cstring_undefined),
loc))
{
sRef_showMetaStateInfo (fref, fkey);
if (optgenerror
(FLG_STATETRANSFER,
message
- ("Function called with global %q in inconsistent state (%q is %q, should be %q): %q",
+ ("Function called with global %q in inconsistent state (%q is %q, should be %q)%q",
sRef_unparse (sRef_getRootBase (fref)),
stateValue_unparseValue (fval, minfo),
sRef_unparse (fref),
stateValue_unparseValue (tval, minfo),
- msg),
+ cstring_isDefined (msg)
+ ? message (": %s", msg) : cstring_undefined),
loc))
{
sRef_showMetaStateInfo (fref, fkey);
if (optgenerror
(FLG_STATETRANSFER,
message
- ("Function returns with parameter %q in inconsistent state (%q is %q, should be %q): %q",
+ ("Function returns with parameter %q in inconsistent state (%q is %q, should be %q)%q",
sRef_unparse (sRef_getRootBase (fref)),
+ sRef_unparse (fref),
stateValue_unparseValue (fval, minfo),
- sRef_unparse (fref),
stateValue_unparseValue (tval, minfo),
- msg),
+ cstring_isDefined (msg)
+ ? message (": %s", msg) : cstring_undefined),
loc))
{
sRef_showMetaStateInfo (fref, fkey);
if (optgenerror
(FLG_STATETRANSFER,
message
- ("Invalid transfer from %q %x to %q (%q): %q",
+ ("Invalid transfer from %q %x to %q (%q)%q",
stateValue_unparseValue (fval, minfo),
sRef_unparse (fref),
stateValue_unparseValue (tval, minfo),
sRef_unparse (tref),
- msg),
+ cstring_isDefined (msg)
+ ? message (": %s", msg) : cstring_undefined),
loc))
{
sRef_showMetaStateInfo (fref, fkey);
}
}
-
+
if (stateValue_getValue (fval) != nval)
{
stateValue_updateValueLoc (fval, nval, loc);
static void
checkMetaStateTransfer (exprNode fexp, sRef fref, exprNode texp, sRef tref,
- fileloc loc, transferKind /*@i32@*/ transferType)
+ exprNode fcn,
+ fileloc loc, transferKind transferType)
{
valueTable fvalues = sRef_getValueTable (fref);
valueTable tvalues = sRef_getValueTable (tref);
}
else
{
- /*@i#!@!!@*/
DPRINTF (("Metastate transfer: %s => %s",
exprNode_unparse (fexp), exprNode_unparse (texp)));
DPRINTF (("Cannot find meta state for: %s / to: %s / %s", sRef_unparseFull (fref),
}
else
{
- if (cstring_isDefined (msg))
+ if (nval == stateValue_error)
{
- /*@i32 print extra info for assignments@*/
-
if (optgenerror
(FLG_STATETRANSFER,
message
- ("Invalid transfer from %q %x to %q (%s): %q",
+ ("Invalid transfer from %q %x to %q%q: %q",
stateValue_unparseValue (fval, minfo),
sRef_unparse (fref),
stateValue_unparseValue (tval, minfo),
- msg,
- transferErrorExcerpt (transferType, fexp, texp)),
+ cstring_isDefined (msg)
+ ? message (" (%s)", msg) : cstring_undefined,
+ transferErrorExcerpt (transferType, fexp, texp, fcn)),
loc))
{
sRef_showMetaStateInfo (fref, fkey);
+ sRef_showMetaStateInfo (tref, fkey);
}
else
{
static void
checkTransfer (exprNode fexp, /*@dependent@*/ sRef fref,
exprNode texp, /*@dependent@*/ sRef tref,
+ exprNode fcn,
fileloc loc, transferKind transferType)
{
setCodePoint ();
exprNode_unparse (fexp),
exprNode_unparse (texp)));
- checkMetaStateTransfer (fexp, fref, texp, tref, loc, transferType);
+ checkMetaStateTransfer (fexp, fref, texp, tref, fcn,
+ loc, transferType);
/*
** for local references, we need to check
return sRef_undefined;
}
-bool canLoseReference (/*@dependent@*/ sRef sr, fileloc loc)
+bool transferChecks_canLoseReference (/*@dependent@*/ sRef sr, fileloc loc)
{
bool gotone = FALSE;
sRefSet ab = usymtab_aliasedBy (sr); /* yes, really mean aliasedBy */