]> andersk Git - splint.git/blobdiff - src/uentry.c
Removed .lh .lcs .lcd files in test directory from distribution tar ball as suggested...
[splint.git] / src / uentry.c
index d9dcc43c988e9c435e9822e13e06646749a79aac..2624510c9d2c4d3989dfbfdf5f97d841eae0e93d 100644 (file)
 ** 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 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"
@@ -43,7 +43,7 @@ static bool uentry_isReallySpecified (uentry p_e) /*@*/ ;
 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_showWhereLastKind (uentry p_spec) /*@modifies g_warningstream@*/ ; 
 
 static void uentry_combineModifies (uentry p_ue, /*@owned@*/ sRefSet p_sr) 
      /*@modifies p_ue@*/ ;
@@ -66,10 +66,8 @@ static void checkVarConformance (/*@notnull@*/ uentry p_old,
                                 bool p_mustConform, bool p_completeConform) 
    /*@modifies p_old, p_unew@*/;
 
-# ifndef NOLCL
 static void uentry_setHasMods (uentry p_ue) /*@modifies p_ue@*/;
 static void uentry_setHasGlobs (uentry p_ue) /*@modifies p_ue@*/;
-# endif
 
 static void uentry_reallyFree (/*@notnull@*/ /*@only@*/ uentry p_e);
 
@@ -86,16 +84,16 @@ static void
   paramTypeError (/*@notnull@*/ uentry p_old, /*@notnull@*/ uentry p_oldCurrent,
                  ctype p_oldType, /*@notnull@*/ uentry p_unew,
                  /*@notnull@*/ uentry p_newCurrent, 
-                 ctype p_newType, int p_paramno) /*@modifies g_msgstream@*/ ;
+                 ctype p_newType, int p_paramno) /*@modifies g_warningstream@*/ ;
 
 static /*@only@*/ /*@notnull@*/ uentry 
   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 /*@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@*/
 {
@@ -577,12 +575,12 @@ static constraintList uentry_getFunctionConditions (uentry ue, bool isPost)
     {
       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) )
            {
@@ -598,7 +596,7 @@ static constraintList uentry_getFunctionConditions (uentry ue, bool isPost)
       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;
          
@@ -687,7 +685,6 @@ static void uentry_setConstantValue (uentry ue, /*@only@*/ multiVal val)
   return ue;
 }
 
-# ifndef NOLCL
 /*@notnull@*/ uentry uentry_makeSpecEnumConstant (cstring n, ctype t, fileloc loc)
 {
   uentry ue = uentry_makeConstant (n, t, loc);
@@ -695,19 +692,21 @@ static void uentry_setConstantValue (uentry ue, /*@only@*/ multiVal val)
   ue->ukind = KENUMCONST;
   return ue;
 }
-# endif
 
 /*@notnull@*/ uentry uentry_makeVariableLoc (cstring n, ctype t)
 {
   return uentry_makeVariable (n, t, setLocation (), FALSE);
 }
 
-# ifndef NOLCL
+bool uentry_isUnnamedVariable (uentry ue)
+{
+  return uentry_isVariable (ue) && cstring_isUndefined (ue->uname);
+}
+
 /*@notnull@*/ /*@only@*/ uentry uentry_makeUnnamedVariable (ctype t)
 {
   return uentry_makeVariable (cstring_undefined, t, setLocation (), FALSE);
 }
-# endif
 
 /*@notnull@*/ uentry uentry_makeIdDatatype (idDecl id)
 {
@@ -741,9 +740,12 @@ void uentry_checkParams (uentry ue)
       if (uentry_isRealFunction (ue))
        {
          uentryList params = uentry_getParams (ue);
+         int paramno = 0;
 
          uentryList_elements (params, current)
            {
+             paramno++;
+
              if (uentry_isValid (current))
                {
                  ctype ct = current->utype;                  
@@ -757,24 +759,48 @@ void uentry_checkParams (uentry ue)
                        }
                      else
                        {
-                         voptgenerror 
-                           (FLG_FIXEDFORMALARRAY,
-                            message ("Function parameter %q declared as "
-                                     "manifest array (size constant is meaningless)",
-                                     uentry_getName (current)),
-                            uentry_whereDeclared (current));
+                         if (uentry_hasName (current))
+                           {
+                             voptgenerror 
+                               (FLG_FIXEDFORMALARRAY,
+                                message ("Function parameter %q declared as "
+                                         "manifest array (size constant is meaningless)",
+                                         uentry_getName (current)),
+                                uentry_whereDeclared (current));
+                           }
+                         else
+                           {
+                             voptgenerror 
+                               (FLG_FIXEDFORMALARRAY,
+                                message ("Unnamed function parameter %d declared as "
+                                         "manifest array (size constant is meaningless)",
+                                         paramno),
+                                uentry_whereDeclared (current));
+                           }
                        }
                    }
                  else 
                    {
                      if (ctype_isArray (ct))
                        {
-                         voptgenerror 
-                           (FLG_FORMALARRAY,
-                            message ("Function parameter %q declared as "
-                                     "array (treated as pointer)", 
-                                     uentry_getName (current)),
-                            uentry_whereDeclared (current));
+                         if (uentry_hasName (current))
+                           {
+                             voptgenerror 
+                               (FLG_FORMALARRAY,
+                                message ("Function parameter %q declared as "
+                                         "array (treated as pointer)", 
+                                         uentry_getName (current)),
+                                uentry_whereDeclared (current));
+                           }
+                         else
+                           {
+                             voptgenerror 
+                               (FLG_FORMALARRAY,
+                                message ("Unnamed function parameter %d declared as "
+                                         "array (treated as pointer)", 
+                                         paramno),
+                                uentry_whereDeclared (current));
+                           }
                        }
                    }
 
@@ -1042,7 +1068,9 @@ static void uentry_reflectClauses (uentry ue, functionClauseList clauses)
            }
          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))
@@ -1304,7 +1332,6 @@ uentry_makeVariableParamAux (cstring n, ctype t, /*@dependent@*/ sRef s,
   return (e);
 }
 
-# ifndef NOLCL
 void
 uentry_setRefCounted (uentry e)
 {
@@ -1314,7 +1341,6 @@ uentry_setRefCounted (uentry e)
       sRef_storeState (e->sref);
     }
 }
-# endif
 
 void
 uentry_setStatic (uentry c)
@@ -1443,13 +1469,14 @@ uentry_fixupSref (uentry ue)
   
   if (uentry_isVariable (ue))
     {
-      /*@i634    ue->sref = sRef_saveCopyShallow (ue->info->var->origsref); */
+      
+           /*@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);
     }
 }
 
-static void uentry_addStateClause (uentry ue, stateClause sc)
+static void uentry_addStateClause (/*@notnull@*/ uentry ue, stateClause sc)
 {
   /*
   ** Okay to allow multiple clauses of the same kind.
@@ -1594,6 +1621,7 @@ bool uentry_hasWarning (uentry ue)
 
 void uentry_addWarning (uentry ue, /*@only@*/ warnClause warn)
 {
+  llassert (uentry_isValid (ue));
   llassert (warnClause_isUndefined (ue->warn));
   ue->warn = warn;
 }
@@ -1641,7 +1669,7 @@ uentry_setPreconditions (uentry ue, /*@only@*/ functionConstraint preconditions)
     }
   else
     {
-      llfatalbug ( (message("uentry_setPreconditions called with invalid uentry") ));
+      llfatalbug ((message("uentry_setPreconditions called with invalid uentry") ));
     }
 }
 
@@ -1678,7 +1706,7 @@ uentry_setPostconditions (uentry ue, /*@only@*/ functionConstraint postcondition
     }
   else
     {
-      llfatalbug ( (message("uentry_setPostconditions called with invalid uentry") ));
+      llfatalbug ((message("uentry_setPostconditions called with invalid uentry") ));
     }
 }
 
@@ -2498,6 +2526,7 @@ uentry_reflectQualifiers (uentry ue, qualList q)
       else if (qual_isUnused (qel))
        {
          uentry_setUsed (ue, fileloc_undefined);         
+         DPRINTF (("Used: %s", uentry_unparseFull (ue)));
        }
       else if (qual_isExternal (qel))
        {
@@ -3083,7 +3112,7 @@ uentry_isSpecialFunction (uentry ue)
     {
       fileloc loc = setLocation ();
       uentry ue = uentry_makeVariable (idDecl_observeId (t), ct, loc, FALSE);
-      
+
       uentry_reflectQualifiers (ue, idDecl_getQuals (t));
 
       if (!uentry_isExtern (ue))
@@ -3095,12 +3124,10 @@ uentry_isSpecialFunction (uentry ue)
     }
 }
 
-# ifndef NOLCL
 /*@notnull@*/ uentry uentry_makeVariableParam (cstring n, ctype t, fileloc loc)
 {
   return (uentry_makeVariableParamAux (n, t, sRef_makeType (t), fileloc_copy (loc), SS_DEFINED));
 }
-# endif
 
 /*
 ** constants
@@ -3148,17 +3175,20 @@ uentry uentry_makeConstantAux (cstring n, ctype t,
 
 /*@notnull@*/ uentry uentry_makeConstant (cstring n, ctype t, fileloc f)
 {
-  return (uentry_makeConstantAux (n, t, f, FALSE, FALSE, multiVal_unknown ()));
+  uentry ue = uentry_makeConstantAux (n, t, f, FALSE, FALSE, multiVal_unknown ());
+  return ue;
 }
 
-
+/*@notnull@*/ uentry uentry_makeConstantValue (cstring n, ctype t, fileloc f, bool priv, multiVal val)
 {
-  return (uentry_makeConstantAux (n, t, f, priv, FALSE, val));
+  uentry ue = uentry_makeConstantAux (n, t, f, priv, FALSE, val);
+  return ue;
 }
 
 /*@notnull@*/ uentry uentry_makeMacroConstant (cstring n, ctype t, fileloc f)
 {
-  return (uentry_makeConstantAux (n, t, f, FALSE, TRUE, multiVal_unknown ()));
+  uentry ue = uentry_makeConstantAux (n, t, f, FALSE, TRUE, multiVal_unknown ());
+  return ue;
 }
 
 /*@notnull@*/ uentry uentry_makeIdConstant (idDecl t)
@@ -3260,14 +3290,14 @@ void uentry_setCheckedStrict (uentry ue)
 }
 
 static /*@only@*/ /*@notnull@*/ 
-  uentry uentry_makeVariableAux (cstring n, ctype t, 
-                                fileloc f,
-                                /*@exposed@*/ sRef s,
-                                bool priv, vkind kind)
+uentry uentry_makeVariableAux (cstring n, ctype t, 
+                              fileloc f,
+                              /*@exposed@*/ sRef s,
+                              bool priv, vkind kind)
 {
   uentry e = uentry_alloc ();
   ctype rt = t;
-
+  
   DPRINTF (("Make variable: %s %s %s", n, ctype_unparse (t), sRef_unparse (s)));
 
   e->ukind = KVAR;
@@ -3318,19 +3348,17 @@ static /*@only@*/ /*@notnull@*/
      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;
-     /*@access sRef@*/ /*i@222*/
-     /* It probably isn't necessary to violate the abstraction here
-      I'll fix this later
-     */
-     s->bufinfo.bufstate = BB_NOTNULLTERMINATED;
-     /*@noaccess sRef@*/
-  } else {
-     e->info->var->bufinfo = NULL;
-  }/* end else */
-/* end modification */
+  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;
+      sRef_setNotNullTerminatedState (s);
+    } 
+  else 
+    {
+      e->info->var->bufinfo = NULL;
+    }/* end else */
+  /* end modification */
 
   return (e);
 }
@@ -3583,36 +3611,24 @@ void uentry_makeConstantFunction (uentry ue)
 }
 
 void
-uentry_setGlobals (uentry ue, /*@owned@*/ globSet globs)
+uentry_setGlobals (uentry ue, /*@only@*/ globSet globs)
 {
   llassert (uentry_isValid (ue));
 
+  globSet_markImmutable (globs);
+
   if (uentry_isIter (ue))
     {
-      llassert (globSet_isUndefined (ue->info->iter->globs));
-      ue->info->iter->globs = globs;
+      ue->info->iter->globs = globSet_unionFree (ue->info->iter->globs, globs);
     }
   else
     {
       uentry_convertVarFunction (ue);
-      
       llassert (uentry_isFunction (ue));
-      llassert (!ue->info->fcn->hasGlobs 
-               && globSet_isUndefined (ue->info->fcn->globs));
-      
-      ue->info->fcn->hasGlobs = TRUE;
-      globSet_markImmutable (globs);
-      /*@-mustfree@*/ ue->info->fcn->globs = globs;
-      /*@=mustfree@*/
-    }
 
-  /*@i23*/
-  /* ???  - evans 2001-09-09 not sure what's going on here...?
-  if (globSet_hasStatic (globs))
-    {
-      context_recordFileGlobals (globs);
+      ue->info->fcn->hasGlobs = TRUE;
+      ue->info->fcn->globs = globSet_unionFree (ue->info->fcn->globs, globs);
     }
-  */
 
   if (context_getFlag (FLG_GLOBALSIMPMODIFIESNOTHING))
     {
@@ -3660,7 +3676,6 @@ void uentry_addAccessType (uentry ue, typeId tid)
                                  FALSE, FALSE));
 }
 
-# ifndef NOLCL
 /*@notnull@*/ uentry 
   uentry_makePrivFunction2 (cstring n, ctype t, 
                            typeIdSet access, 
@@ -3689,7 +3704,6 @@ void uentry_addAccessType (uentry ue, typeId tid)
   reflectImplicitFunctionQualifiers (ue, TRUE);
   return (ue);
 }
-# endif
 
 uentry uentry_makeExpandedMacro (cstring s, fileloc f)
 {
@@ -3728,7 +3742,6 @@ bool uentry_isForward (uentry e)
   return FALSE;
 }
 
-# ifndef NOLCL
 /*@notnull@*/ uentry 
 uentry_makeTypeListFunction (cstring n, typeIdSet access, fileloc f)
 {
@@ -3749,7 +3762,6 @@ uentry_makeUnspecFunction (cstring n, ctype t,
   reflectImplicitFunctionQualifiers (ue, TRUE);
   return ue;
 }
-# endif
 
 /*
 ** datatypes
@@ -3976,7 +3988,6 @@ uentry_makeUnionTag (cstring n, ctype t, fileloc loc)
   return (ret);
 }
 
-# ifndef NOLCL
 uentry
 uentry_makeEnumTag (cstring n, ctype t, fileloc loc)
 {
@@ -3986,7 +3997,6 @@ uentry_makeEnumTag (cstring n, ctype t, fileloc loc)
   cstring_free (ename);
   return ret;
 }
-# endif
 
 uentry
 uentry_makeUnionTagLoc (cstring n, ctype t)
@@ -4171,7 +4181,7 @@ uentry_compare (uentry u1, uentry u2)
     {
     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;
@@ -4298,7 +4308,7 @@ static uentry
   e->info = (uinfo) dmalloc (sizeof (*e->info));
   e->info->uconst = (ucinfo) dmalloc (sizeof (*e->info->uconst));
   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);
 
@@ -4446,7 +4456,6 @@ uentry_makeDatatypeBase (/*@only@*/ cstring name, ctype ct, ynm abstract,
   return (e);
 }
 
-# ifndef NOLCL
 static void uentry_setHasGlobs (uentry ue)
 {
   llassert (uentry_isFunction (ue));
@@ -4460,7 +4469,6 @@ static void uentry_setHasMods (uentry ue)
 
   ue->info->fcn->hasMods = TRUE;
 }
-# endif
 
 bool uentry_hasGlobs (uentry ue)
 {
@@ -5371,8 +5379,9 @@ uentry_unparseFull (uentry v)
        }
       else if (uentry_isConstant (v))
        {
-         res = message ("%q = %q",
-                        res, multiVal_unparse (uentry_getConstantValue (v)));
+         res = message ("%q = %q / %q",
+                        res, multiVal_unparse (uentry_getConstantValue (v)),
+                        sRef_unparseFull (v->sref));
        }
       else
        {
@@ -5717,27 +5726,35 @@ uentry_getGlobs (uentry l)
       return globSet_undefined;
     }
 
-  if (l->ukind != KFCN)
+  if (uentry_isFunction (l))
+    {
+      return l->info->fcn->globs;
+    }
+  else if (uentry_isIter (l))
+    {
+      return l->info->iter->globs;
+    }
+  else if (uentry_isEndIter (l))
+    {
+      return globSet_undefined;
+    }
+  else
     {
-      if (l->ukind != KITER && l->ukind != KENDITER)
+      if (l->ukind == KVAR)
        {
-         if (l->ukind == KVAR)
-           {
-             llbug (message ("Bad call to uentry_getGlobs (var): %q (%s)", 
+         llcontbug (message ("Bad call to uentry_getGlobs (var): %q (%s)", 
                              uentry_unparse (l), 
                              ekind_unparse (l->ukind)));
-           }
-         else
-           {
-             llbug (message ("Bad call to uentry_getGlobs: %q (%s)", 
+       }
+      else
+       {
+         llcontbug (message ("Bad call to uentry_getGlobs: %q (%s)", 
                              uentry_unparse (l), 
                              ekind_unparse (l->ukind)));
-           }
        }
+
       return globSet_undefined;
     }
-
-  return l->info->fcn->globs;
 }
 
 /*@observer@*/ sRefSet
@@ -5751,7 +5768,22 @@ uentry_getMods (uentry l)
       return sRefSet_undefined; 
     }
 
-  return l->info->fcn->mods;
+  if (uentry_isFunction (l))
+    {
+      return l->info->fcn->mods;
+    }
+  else if (uentry_isIter (l))
+    {
+      return l->info->iter->mods;
+    }
+  else if (uentry_isEndIter (l))
+    {
+      return sRefSet_undefined;
+    }
+  else
+    {
+      BADBRANCH;
+    }
 }
 
 ekind
@@ -6615,6 +6647,7 @@ ucinfo_copy (ucinfo u)
 {
   ucinfo ret = (ucinfo) dmalloc (sizeof (*ret));
   ret->access = u->access;
+  ret->macro = u->macro;
   return ret;
 }
 
@@ -6771,7 +6804,7 @@ uentry_reallyFree (/*@notnull@*/ /*@only@*/ uentry e)
 
   nuentries--;
   sfree (e);
-  }
+}
 
 extern void uentry_markOwned (/*@owned@*/ uentry u)
 {
@@ -6813,7 +6846,7 @@ KindConformanceError (/*@unique@*/ uentry old, uentry unew, bool mustConform)
   llassert (uentry_isValid (old));
   llassert (uentry_isValid (unew));
 
-  if (uentry_isEitherConstant (unew)
+  if ((uentry_isEitherConstant (unew) || uentry_isDatatype (unew))
       && (fileloc_isPreproc (uentry_whereDeclared (old))
          || ctype_isUnknown (old->utype))
       && !uentry_isSpecified (old))
@@ -7285,9 +7318,10 @@ checkEnumConformance (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew)
       if (optgenerror 
          (FLG_MATCHFIELDS,
           message ("Enum %q declared with members { %q } but "
-                   "specified with members { %q }",
+                   "%s with members { %q }",
                    uentry_getName (old), 
                    enumNameList_unparse (enew),
+                   uentry_specOrDefName (old),
                    enumNameList_unparse (eold)),
           uentry_whereDeclared (unew)))
        {
@@ -8536,7 +8570,7 @@ checkFunctionConformance (/*@unique@*/ /*@notnull@*/ uentry old,
 
              paramno++;  
              /*
-              ** Forgot this!  detected by lclint:
+              ** Forgot this!  detected by splint:
               ** uentry.c:1257,15: Suspected infinite loop
               */
            }
@@ -9815,12 +9849,12 @@ uentry_sameKind (uentry u1, uentry u2)
    
 static void uentry_updateInto (/*@unique@*/ uentry unew, uentry old)
 {
-  ekind okind = unew->ukind;
+  ekind okind;
   llassert (uentry_isValid (unew));
   llassert (uentry_isValid (old));
 
   DPRINTF (("Update into: %s / %s", uentry_unparseFull (unew), uentry_unparseFull (old)));
-
+  okind = unew->ukind;
   unew->ukind = old->ukind;
   llassert (cstring_equal (unew->uname, old->uname));
   unew->utype = old->utype;
@@ -9873,10 +9907,10 @@ static void uentry_updateInto (/*@unique@*/ uentry unew, uentry old)
   unew->info = uinfo_copy (old->info, old->ukind);
 }
 
-
-uentry
-uentry_copy (uentry e)
+static uentry
+uentry_copyAux (uentry e, bool saveCopy)
 {
+  
   if (uentry_isValid (e))
     {
       uentry enew = uentry_alloc ();
@@ -9889,7 +9923,15 @@ uentry_copy (uentry e)
       enew->whereDefined = fileloc_copy (e->whereDefined);
       enew->whereDeclared = fileloc_copy (e->whereDeclared);
       
-      enew->sref = sRef_saveCopy (e->sref); /* Memory leak! */
+      if (saveCopy)
+       {
+         enew->sref = sRef_saveCopy (e->sref); /* Memory leak! */
+       }
+      else
+       {
+         enew->sref = sRef_copy (e->sref);
+       }
+      
       enew->used = e->used;
       enew->lset = FALSE;
       enew->isPrivate = e->isPrivate;
@@ -9912,6 +9954,18 @@ uentry_copy (uentry e)
     }
 }
 
+uentry
+uentry_copy (uentry e)
+{
+  return uentry_copyAux (e, TRUE);
+}
+
+uentry
+uentry_copyNoSave (uentry e)
+{
+  return uentry_copyAux (e, FALSE);
+}
+
 void
 uentry_setState (uentry res, uentry other)
 {
@@ -9963,8 +10017,8 @@ uentry_mergeUses (uentry res, uentry other)
 */
 
 static void
-  branchStateError (/*@notnull@*/ uentry res, /*@notnull@*/ uentry other, 
-                   bool flip, clause cl, fileloc loc)
+branchStateError (/*@notnull@*/ uentry res, /*@notnull@*/ uentry other, 
+                 bool flip, clause cl, fileloc loc)
 {
   if (optgenerror 
       (FLG_BRANCHSTATE,
@@ -9977,10 +10031,12 @@ static void
       if (sRef_isDead (res->sref))
        {
          sRef_showStateInfo (res->sref);
+         sRef_showStateInfo (other->sref);
        }
       else if (sRef_isKept (res->sref))
        {
          sRef_showAliasInfo (res->sref);
+         sRef_showAliasInfo (other->sref);
        }
       else /* dependent */
        {
@@ -10067,8 +10123,8 @@ static bool uentry_relevantReference (sRef sr, bool flip)
 }
 
 static void
-uentry_mergeAliasStates (uentry res, uentry other, fileloc loc,
-                        bool mustReturn, bool flip, bool opt,
+uentry_mergeAliasStates (/*@notnull@*/ uentry res, /*@notnull@*/ uentry other, 
+                        fileloc loc, bool mustReturn, bool flip, bool opt,
                         clause cl)    
 {
   sRef rs = res->sref;
@@ -10224,7 +10280,8 @@ uentry_mergeAliasStates (uentry res, uentry other, fileloc loc,
 }
 
 static void
-uentry_mergeValueStates (uentry res, uentry other, fileloc loc, bool mustReturn, /*@unused@*/ bool flip)
+uentry_mergeValueStates (/*@notnull@*/ uentry res, /*@notnull@*/ uentry other,
+                        fileloc loc, bool mustReturn, /*@unused@*/ bool flip)
 {
   valueTable rvalues;
   valueTable ovalues;
@@ -10403,7 +10460,8 @@ uentry_mergeValueStates (uentry res, uentry other, fileloc loc, bool mustReturn,
 
 
 static void
-uentry_mergeSetStates (uentry res, uentry other, /*@unused@*/ fileloc loc,
+uentry_mergeSetStates (/*@notnull@*/ uentry res,
+                      /*@notnull@*/ uentry other, /*@unused@*/ fileloc loc,
                       bool flip, clause cl)
 {
   if (cl == DOWHILECLAUSE)
@@ -10483,6 +10541,8 @@ uentry_mergeState (uentry res, uentry other, fileloc loc,
   uentry_mergeAliasStates (res, other, loc, mustReturn, flip, opt, cl);
   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)
@@ -10606,6 +10666,8 @@ bool uentry_isReturned (uentry u)
              || u->info->var->kind == VKSEFRETPARAM));
 }
 
+/*@i52323@*/
+# if 0
 /*@exposed@*/ sRef uentry_returnedRef (uentry u, exprNodeList args)
 {
   llassert (uentry_isRealFunction (u));
@@ -10660,10 +10722,16 @@ bool uentry_isReturned (uentry u)
       alkind ak;
       sRefSet prefs = sRefSet_new ();
       sRef res = sRef_undefined;
+      sRef tcref = sRef_undefined;
+      sRef tref = sRef_undefined;
       int paramno = 0;
       
       params = uentry_getParams (u);
-      
+
+      /*
+      ** Setting up aliases has to happen *after* setting null state!
+      */
+
       uentryList_elements (params, current)
        {
          if (uentry_isReturned (current))
@@ -10671,16 +10739,14 @@ bool uentry_isReturned (uentry u)
              if (exprNodeList_size (args) >= paramno)
                {
                  exprNode ecur = exprNodeList_nth (args, paramno);
-                 sRef tref = exprNode_getSref (ecur);
+                 tref = exprNode_getSref (ecur);
                  
                  DPRINTF (("Returned reference: %s", sRef_unparseFull (tref)));
 
                  if (sRef_isValid (tref))
                    {
-                     sRef tcref = sRef_copy (tref);
+                     tcref = sRef_copy (tref);
                      
-                     usymtab_addForceMustAlias (tcref, tref); /* evans 2001-05-27 */
-
                      if (sRef_isDead (tcref))
                        {
                          sRef_setDefined (tcref, g_currentloc);
@@ -10701,14 +10767,17 @@ bool uentry_isReturned (uentry u)
          
          paramno++;
        } end_uentryList_elements ;
-      
+
       if (sRefSet_size (prefs) > 0)
        {
          nstate n = sRef_getNullState (u->sref);
-         
+
          if (sRefSet_size (prefs) == 1)
            {
-             res = sRefSet_choose (prefs);
+             sRef rref = sRefSet_choose (prefs);
+             tref = rref;
+             res = sRef_makeType (sRef_getType (rref));
+             sRef_copyState (res, tref);
            }
          else
            {
@@ -10719,6 +10788,7 @@ bool uentry_isReturned (uentry u)
          if (nstate_isKnown (n))
            {
              sRef_setNullState (res, n, g_currentloc);
+             DPRINTF (("Setting null: %s", sRef_unparseFull (res)));
            }
        }
       else
@@ -10730,6 +10800,7 @@ bool uentry_isReturned (uentry u)
            }
          else
            {
+             DPRINTF (("Making new from %s  -->", uentry_unparseFull (u)));
              res = sRef_makeNew (ctype_unknown, u->sref, u->uname);
            }
          
@@ -10739,7 +10810,6 @@ bool uentry_isReturned (uentry u)
            }
        }
       
-
       if (sRef_getNullState (res) == NS_ABSNULL)
        {
          ctype ct = ctype_realType (u->utype);
@@ -10776,15 +10846,219 @@ bool uentry_isReturned (uentry u)
       
       ak = sRef_getAliasKind (res);
       
+      if (alkind_isImplicit (ak))
+       {
+         sRef_setAliasKind (res, alkind_fixImplicit (ak), g_currentloc);
+       }
+
+# if 0
+      DPRINTF (("Aliasing: %s / %s", sRef_unparseFull (res), sRef_unparseFull (tref)));
+      usymtab_addReallyForceMustAlias (tref, res); /* evans 2001-05-27 */
+
+      /* evans 2002-03-03 - need to be symettric explicitly, since its not a local now */
+      usymtab_addReallyForceMustAlias (res, tref);
+# endif
+
+      sRefSet_free (prefs);
+      
+      DPRINTF (("Returns ref: %s", sRef_unparseFull (res)));
+      return res;
+    }
+}
+# endif
+
+/*@exposed@*/ sRef uentry_returnedRef (uentry u, exprNodeList args, fileloc loc)
+{
+  llassert (uentry_isRealFunction (u));
+
+  if (ctype_isFunction (u->utype) && sRef_isStateSpecial (uentry_getSref (u)))
+    {
+      stateClauseList clauses = uentry_getStateClauseList (u);
+      sRef res = sRef_makeNew (ctype_getReturnType (u->utype), u->sref, u->uname);
+
+      DPRINTF (("Returned: %s", sRef_unparseFull (res)));
+      sRef_setAllocated (res, loc);
+
+      DPRINTF (("ensures clause: %s / %s", uentry_unparse (u), 
+               stateClauseList_unparse (clauses)));
+
+      /*
+      ** This should be in exprNode_reflectEnsuresClause
+      */
+
+      stateClauseList_postElements (clauses, cl)
+       {
+         if (!stateClause_isGlobal (cl))
+           {
+             sRefSet refs = stateClause_getRefs (cl);
+             sRefMod modf = stateClause_getEffectFunction (cl);
+             
+             sRefSet_elements (refs, el)
+               {
+                 sRef base = sRef_getRootBase (el);
+                 
+                 if (sRef_isResult (base))
+                   {
+                     if (modf != NULL)
+                       {
+                         sRef sr = sRef_fixBase (el, res);
+                         modf (sr, loc);
+                       }
+                   }
+                 else
+                   {
+                     ;
+                   }
+               } end_sRefSet_elements ;
+           }
+       } end_stateClauseList_postElements ;
+       
+      return res;
+    }
+  else
+    {
+      uentryList params;
+      alkind ak;
+      sRefSet prefs = sRefSet_new ();
+      sRef res = sRef_undefined;
+      int paramno = 0;
+      
+      params = uentry_getParams (u);
+      
+      uentryList_elements (params, current)
+       {
+         if (uentry_isReturned (current))
+           {
+             if (exprNodeList_size (args) >= paramno)
+               {
+                 exprNode ecur = exprNodeList_nth (args, paramno);
+                 sRef tref = exprNode_getSref (ecur);
+                 
+                 DPRINTF (("Returned reference: %s", sRef_unparseFull (tref)));
+
+                 if (sRef_isValid (tref))
+                   {
+                     sRef tcref = sRef_copy (tref);
+                     
+                     usymtab_addForceMustAlias (tcref, tref); /* evans 2001-05-27 */
+
+                     if (sRef_isNew (tcref))
+                       {
+                         /* tcref->kind = SK_OBJECT; */ /*!! Not new anymore */
+                       }
+
+                     if (sRef_isDead (tcref))
+                       {
+                         sRef_setDefined (tcref, loc);
+                         sRef_setOnly (tcref, loc);
+                       }
+                     
+                     if (sRef_isRefCounted (tcref))
+                       {
+                         /* could be a new ref now (but only if its returned) */
+                         sRef_setAliasKindComplete (tcref, AK_ERROR, loc);
+                       }
+                     
+                     sRef_makeSafe (tcref);
+                     DPRINTF (("Returns tcref / %s", sRef_unparseFull (tcref)));
+                     prefs = sRefSet_insert (prefs, tcref);
+                   }
+               }
+           }
+         
+         paramno++;
+       } end_uentryList_elements ;
+      
+      if (sRefSet_size (prefs) > 0)
+       {
+         nstate n = sRef_getNullState (u->sref);
+         
+         if (sRefSet_size (prefs) == 1)
+           {
+             res = sRefSet_choose (prefs);
+           }
+         else
+           {
+             /* should this ever happen? */ /*@i534 evans 2001-05-27 */
+             res = sRefSet_mergeIntoOne (prefs);
+           }
+         
+         if (nstate_isKnown (n))
+           {
+             sRef_setNullState (res, n, loc);
+           }
+       }
+      else
+       {
+         if (ctype_isFunction (u->utype))
+           {
+             DPRINTF (("Making new from %s  -->", uentry_unparseFull (u)));
+             res = sRef_makeNew (ctype_getReturnType (u->utype), u->sref, u->uname);
+           }
+         else
+           {
+             res = sRef_makeNew (ctype_unknown, u->sref, u->uname);
+           }
+         
+         if (sRef_isRefCounted (res))
+           {
+             sRef_setAliasKind (res, AK_NEWREF, loc);
+           }
+       }
+      
+
+      if (sRef_getNullState (res) == NS_ABSNULL)
+       {
+         ctype ct = ctype_realType (u->utype);
+         
+         if (ctype_isAbstract (ct))
+           {
+             sRef_setNotNull (res, loc);
+           }
+         else
+           {
+             if (ctype_isUser (ct))
+               {
+                 sRef_setStateFromUentry (res, usymtab_getTypeEntry (ctype_typeId (ct)));
+               }
+             else
+               {
+                 sRef_setNotNull (res, loc);
+               }
+           }
+       }
+      
+      if (sRef_isRefCounted (res))
+       {
+         sRef_setAliasKind (res, AK_NEWREF, loc);
+       }
+      else if (sRef_isKillRef (res))
+       {
+         sRef_setAliasKind (res, AK_REFCOUNTED, loc);
+       }
+      else
+       {
+         ;
+       }
+      
+      ak = sRef_getAliasKind (res);
+      
       if (alkind_isImplicit (ak))
        {
          sRef_setAliasKind (res, 
                             alkind_fixImplicit (ak),
-                            g_currentloc);
+                            loc);
        }
       
       sRefSet_free (prefs);
-      
+
+      /*
+      if (sRef_isOnly (res))
+       {
+         sRef_setFresh (res, loc);
+       }
+      */
+
       DPRINTF (("Returns ref: %s", sRef_unparseFull (res)));
       return res;
     }
@@ -11056,7 +11330,7 @@ void uentry_checkName (uentry ue)
   fileloc_free (tloc);
   uentry_setHasNameError (ue);
   
-  if (context_getFlag (FLG_REPEATUNRECOG))
+  if (context_getFlag (FLG_REPEATUNRECOG) || (context_inOldSytleScope() ) )
     {
       uentry_markOwned (ue);
     }
@@ -11111,20 +11385,19 @@ effects: sets the state of the 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;
-      }
-    }
-  }
-  /*@noaccess sRef@*/
+void uentry_setPossiblyNullTerminatedState (uentry p_e)  
+{
+  llassert (uentry_isValid (p_e));
 
-  fprintf(stderr, "uentry:Error in setPossiblyNullTerminatedState\n");
+  if (p_e->info != NULL)
+    {
+      if (p_e->info->var != NULL) 
+       {
+         llassert (p_e->info->var->bufinfo != NULL);
+         p_e->info->var->bufinfo->bufstate = BB_POSSIBLYNULLTERMINATED;
+         sRef_setPossiblyNullTerminatedState (p_e->sref);
+       }
+    }
 }
 
 /*
@@ -11134,19 +11407,17 @@ effects: sets the size of the buffer
 */
 
 void uentry_setNullTerminatedState (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_NULLTERMINATED;
-       /*@access sRef@*/ /*@i523 bad!*/
-        p_e->sref->bufinfo.bufstate = BB_NULLTERMINATED;
-       /*@noaccess sRef@*/ 
-        return;
-      }
-    }
-  }
+  llassert (uentry_isValid (p_e));
 
-  fprintf(stderr, "uentry:Error in setNullTerminatedState\n");
+  if (p_e->info != NULL)
+    {
+      if (p_e->info->var != NULL)
+       {
+         llassert (p_e->info->var->bufinfo != NULL);
+         p_e->info->var->bufinfo->bufstate = BB_NULLTERMINATED;
+         sRef_setNullTerminatedState (p_e->sref);
+       }
+    }
 }
 
 /*
@@ -11155,43 +11426,40 @@ modifies: p_e
 effects: sets the size of the buffer
 */
 
-void uentry_setSize (uentry p_e, int size)  {
-  if( uentry_isValid(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;
-      }
+void uentry_setSize (uentry p_e, int size)  
+{
+  if (uentry_isValid (p_e))
+    {
+      if (p_e->info != NULL) 
+       {
+         if (p_e->info->var != NULL) 
+           {
+             llassert (p_e->info->var->bufinfo != NULL);
+             p_e->info->var->bufinfo->size = size;
+             sRef_setSize (p_e->sref, size);
+           }
+       }
     }
-  }
-
-  fprintf(stderr, "uentry:Error in setSize\n");
 }
 
-
 /*
 requires: p_e is defined, is a ptr/array variable 
 modifies: p_e
 effects: sets the length of the buffer
 */
 
-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;
-      }
+void uentry_setLen (uentry p_e, int len)  
+{
+  if (uentry_isValid (p_e)) 
+    {
+      if (p_e->info != NULL
+         && p_e->info->var != NULL) 
+       {
+         llassert (p_e->info->var->bufinfo != NULL);
+         p_e->info->var->bufinfo->len = len;
+         sRef_setLen (p_e->sref, len);
+       }
     }
-  }
-  
-  fprintf(stderr, "uentry:Error in setLen\n");
 }
 
 /*@=type*/
@@ -11213,3 +11481,19 @@ metaStateConstraintList uentry_getMetaStateEnsures (uentry e)
   llassert (uentry_isValid (e) && uentry_isFunction (e));
   return functionConstraint_getMetaStateConstraints (e->info->fcn->postconditions);
 }
+
+# ifdef DEBUGSPLINT
+
+/*
+** For debugging only
+*/
+
+void uentry_checkValid (uentry ue)
+{
+  if (uentry_isValid (ue))
+    {
+      sRef_checkCompletelyReasonable (ue->sref);
+    }
+}
+
+# endif
This page took 0.591214 seconds and 4 git commands to generate.