]> andersk Git - splint.git/blobdiff - src/sRef.c
Changed checking of complete descruction so +strictdestroy is no
[splint.git] / src / sRef.c
index 395a00e280ab145901d442d9a3abda0c87590653..83f370530166341bb33fba79a5aca1db5048a285 100644 (file)
@@ -1,6 +1,6 @@
 /*
-** 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
@@ -19,7 +19,7 @@
 **
 ** 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
 */
 /*
 ** storeRef.c
@@ -63,10 +63,6 @@ static void sRef_updateNullState (sRef p_res, sRef p_other) /*@modifies p_res@*/
 static bool sRef_isAllocatedStorage (sRef p_s) /*@*/ ;
 static void sRef_setNullErrorLoc (sRef p_s, fileloc) /*@*/ ;
 
-static void
-  sRef_aliasSetComplete (void (p_predf) (sRef, fileloc), sRef p_s, fileloc p_loc)
-  /*@modifies p_s@*/ ;
-
 static int sRef_depth (sRef p_s) /*@*/ ;
 
 static void
@@ -78,17 +74,24 @@ static void
 sRef_innerAliasSetCompleteParam (void (p_predf) (sRef, sRef), sRef p_s, sRef p_t)
      /*@modifies p_s@*/ ;
      
-static void
-  sRef_aliasSetCompleteParam (void (p_predf) (sRef, alkind, fileloc), sRef p_s, 
-                             alkind p_kind, fileloc p_loc)
-  /*@modifies p_s@*/ ;
-
 static speckind speckind_fromInt (int p_i);
 static bool sRef_equivalent (sRef p_s1, sRef p_s2);
 static bool sRef_isDeepUnionField (sRef p_s);
 static void sRef_addDeriv (/*@notnull@*/ sRef p_s, /*@notnull@*/ /*@exposed@*/ sRef p_t);
 static bool sRef_checkModify (sRef p_s, sRefSet p_sl) /*@*/ ;
 
+/*
+** If s is definitely null, it has no memory state.
+*/
+
+static void sRef_resetAliasKind (/*@notnull@*/ sRef s) /*@modifies s->aliaskind@*/
+{
+  if (s->nullstate == NS_DEFNULL)
+    {
+      /* s->aliaskind = AK_ERROR; */
+    }
+}
+
 static void sRef_checkMutable (/*@unused@*/ sRef s)
 {
   /*@i235@*/
@@ -599,6 +602,7 @@ sRef_hasExpInfoLoc (sRef s)
          && (s->expinfo != NULL) && (fileloc_isDefined (s->expinfo->loc)));
 }
 
+# if 0
 static /*@observer@*/ /*@unused@*/ stateInfo sRef_getInfo (sRef s, cstring key)
 {
   stateValue sv;
@@ -616,7 +620,7 @@ static /*@observer@*/ /*@unused@*/ stateInfo sRef_getInfo (sRef s, cstring key)
   
   return stateInfo_undefined;
 }
-
+# endif
 
 static bool
 sRef_hasNullInfoLoc (sRef s)
@@ -726,6 +730,14 @@ void sRef_clearGlobalScopeSafe ()
 
 void sRef_enterFunctionScope ()
 {
+  /* evans 2001-09-09 - cleanup if we are in a macro! */
+  if (context_inMacro ())
+    {
+      if (inFunction) {
+       sRef_exitFunctionScope ();
+      }
+    }
+
   llassert (!inFunction);
   llassert (sRefTable_isEmpty (allRefs));
   inFunction = TRUE;
@@ -2168,7 +2180,7 @@ sRef_closeEnough (sRef s1, sRef s2)
     {
     case SK_RESULT:
       {
-       //      s = sRef_saveCopy(s);
+       /* s = sRef_saveCopy(s); */ /*@i523@*/
        ce = constraintExpr_makeTermsRef (s);
        return ce;
       }
@@ -2185,7 +2197,7 @@ sRef_closeEnough (sRef s1, sRef s2)
       {
        sRef temp;
        temp = (sRef_makePointer (sRef_fixBaseParam (s->info->ref, args)));
-       //temp = sRef_saveCopy(temp);
+       /* temp = sRef_saveCopy(temp); */ /*@i523@*/
        ce = constraintExpr_makeTermsRef (temp);
        return ce;
       }
@@ -2798,9 +2810,7 @@ sRef_unparseWithArgs (sRef s, uentryList args)
              return uentry_getName (ue);
          }
 
-       return (message ("<bad param: %q / args %q",
-                        sRef_unparseDebug (s),
-                        uentryList_unparse (args)));
+       return (message ("parameter %d", s->info->paramno + 1));
       }
     case SK_ARRAYFETCH:
       if (s->info->arrayfetch->indknown)
@@ -3386,7 +3396,7 @@ sRef_getRootBaseAux (sRef s, int depth)
                ("Warning: reference base limit exceeded for %q. "
                 "This either means there is a variable with at least "
                 "%d indirections from this reference, or "
-                "there is a bug in LCLint.",
+                "there is a bug in Splint.",
                 sRef_unparse (s),
                 MAXBASEDEPTH),
                g_currentloc);
@@ -3716,6 +3726,10 @@ sRef_mergeStateAux (/*@notnull@*/ sRef res, /*@notnull@*/ sRef other,
   llassertfatal (sRef_isValid (res));
   llassertfatal (sRef_isValid (other));
   
+  DPRINTF (("Merge aux: %s / %s",
+           bool_unparse (sRef_isDefinitelyNull (res)),
+           bool_unparse (sRef_isDefinitelyNull (other))));
+
   sRef_checkMutable (res);
   sRef_checkMutable (other);
 
@@ -4583,10 +4597,17 @@ bool sRef_hasNoStorage (sRef s)
 
 bool sRef_isStrictReadable (sRef s)
 {
-  return (ynm_toBoolStrict (sRef_isReadable (s)));
+  return (ynm_toBoolStrict (sRef_isValidLvalue (s)));
 }
 
-ynm sRef_isReadable (sRef s)
+/*
+** Is this what is does?
+** Returns YES if s can be used as an rvalue,
+**         MAYBE if its not clear
+**         NO if s cannot be safely used as an rvalue.
+*/
+
+ynm sRef_isValidLvalue (sRef s)
 {
   sstate ss;
 
@@ -4596,9 +4617,9 @@ ynm sRef_isReadable (sRef s)
   
   if (sRef_isConj (s) && s->defstate == SS_UNKNOWN)
     {
-      if (ynm_toBoolStrict (sRef_isReadable (sRef_getConjA (s))))
+      if (ynm_toBoolStrict (sRef_isValidLvalue (sRef_getConjA (s))))
        {
-         if (ynm_toBoolStrict (sRef_isReadable (sRef_getConjB (s))))
+         if (ynm_toBoolStrict (sRef_isValidLvalue (sRef_getConjB (s))))
            {
              return YES;
            }
@@ -4606,7 +4627,7 @@ ynm sRef_isReadable (sRef s)
        }
       else
        {
-         if (ynm_toBoolStrict (sRef_isReadable (sRef_getConjB (s))))
+         if (ynm_toBoolStrict (sRef_isValidLvalue (sRef_getConjB (s))))
            {
              return MAYBE;
            }
@@ -4630,9 +4651,9 @@ ynm sRef_isReadable (sRef s)
                            || ss == SS_FIXED 
                            || ss == SS_RELDEF 
                            || ss == SS_PDEFINED 
-                           || ss == SS_PARTIAL
+                           || ss == SS_PARTIAL 
                            || ss == SS_SPECIAL
-                           || ss == SS_ALLOCATED
+                           || ss == SS_ALLOCATED 
                            || ss == SS_KILLED /* evans 2001-05-26: added this for killed globals */
                            || ss == SS_UNKNOWN));
     }
@@ -4649,7 +4670,7 @@ static /*@exposed@*/ sRef whatUndefined (/*@exposed@*/ sRef fref, int depth)
                ("Warning: 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),
                g_currentloc);
@@ -4865,7 +4886,7 @@ void sRef_clearAliasState (sRef s, fileloc loc)
 void sRef_setAliasKindComplete (sRef s, alkind kind, fileloc loc)
 {
   sRef_checkMutable (s);  
-  sRef_aliasSetCompleteParam (sRef_setAliasKind, s, kind, loc);
+  sRef_aliasSetCompleteAlkParam (sRef_setAliasKind, s, kind, loc); 
 }
 
 void sRef_setAliasKind (sRef s, alkind kind, fileloc loc)
@@ -5152,7 +5173,29 @@ void sRef_setPartialDefinedComplete (sRef s, fileloc loc)
 
 void sRef_setDefinedComplete (sRef s, fileloc loc)
 {
+  sRef_innerAliasSetComplete (sRef_setDefined, s, loc);
+}
+
+void sRef_setDefinedCompleteDirect (sRef s, fileloc loc)
+{
+  sRefSet aliases;
+  
+  aliases = usymtab_allAliases (s);
   DPRINTF (("Set defined complete: %s", sRef_unparseFull (s)));
+  DPRINTF (("All aliases: %s", sRefSet_unparseFull (aliases)));
+  
+  sRef_setDefined (s, loc);
+
+  sRefSet_realElements (aliases, current)
+    {
+      if (sRef_isValid (current))
+       {
+         current = sRef_updateSref (current);
+         sRef_setDefined (current, loc);
+       }
+    } end_sRefSet_realElements;
+  
+  sRefSet_free (aliases);
   sRef_innerAliasSetComplete (sRef_setDefined, s, loc);
 }
 
@@ -5356,7 +5399,8 @@ void sRef_setNullStateAux (/*@notnull@*/ sRef s, nstate ns, fileloc loc)
   DPRINTF (("Set null state: %s / %s", sRef_unparse (s), nstate_unparse (ns)));
   sRef_checkMutable (s);
   s->nullstate = ns;
-  
+  sRef_resetAliasKind (s);
+
   if (fileloc_isDefined (loc))
     {
       s->nullinfo = stateInfo_updateLoc (s->nullinfo, loc);
@@ -5375,6 +5419,7 @@ void sRef_setNullStateN (sRef s, nstate n)
 {
   sRef_checkMutable (s);
   s->nullstate = n;
+  sRef_resetAliasKind (s);
 }
 
 void sRef_setNullState (sRef s, nstate n, fileloc loc)
@@ -5385,8 +5430,8 @@ void sRef_setNullState (sRef s, nstate n, fileloc loc)
     }
 }
 
-void sRef_setNullTerminatedStateInnerComplete (sRef s, struct s_bbufinfo b, /*@unused@*/ fileloc loc) {
-   
+void sRef_setNullTerminatedStateInnerComplete (sRef s, struct s_bbufinfo b, /*@unused@*/ fileloc loc) 
+{
   switch (b.bufstate) {
      case BB_NULLTERMINATED:
          sRef_setNullTerminatedState (s);
@@ -6268,6 +6313,10 @@ void sRef_setArrayFetchState (/*@notnull@*/ /*@exposed@*/ sRef s,
     }
 
   /* a hack, methinks... makeArrayFetch (&a[0]) ==> a[] */
+  /* evans - 2001-08-27: not sure where this was necessary - it
+  ** causes an assertion in in aliasCheckPred to fail.
+  */
+
   if (sRef_isAddress (arr)) 
     {
       sRef t = arr->info->ref;
@@ -6470,6 +6519,7 @@ void sRef_setArrayFetchState (/*@notnull@*/ /*@exposed@*/ sRef s,
          check (sRefSet_delete (arr->deriv, s));
          res = sRef_buildArrayFetch (arr);
          sRef_copyState (res, s);
+         llassert (res->info->arrayfetch->arr == arr); 
          return res;
        }
 
@@ -6515,25 +6565,28 @@ void sRef_setArrayFetchState (/*@notnull@*/ /*@exposed@*/ sRef s,
 
   if (ctype_isRealPointer (arr->type))
     {
-       (void) sRef_buildPointer (arr); /* do this to define arr! */
+      (void) sRef_buildPointer (arr); /* do this to define arr! */
     }
 
   s = sRef_findDerivedArrayFetch (arr, TRUE, i, FALSE);
-      
+
   if (sRef_isValid (s))
     {
       /* evans 2001-07-12: this is bogus, clean-up hack */
       if (s->info->arrayfetch->arr != arr)
        {
          sRef res;
+
          check (sRefSet_delete (arr->deriv, s));
          res = sRef_buildArrayFetchKnown (arr, i);
+
+         llassert (res->info->arrayfetch->arr == arr);
          sRef_copyState (res, s);
+         llassert (res->info->arrayfetch->arr == arr);
          return res;
        }
 
       sRef_setExKind (s, sRef_getExKind (arr), g_currentloc);      
-
       llassert (s->info->arrayfetch->arr == arr);
       return s;
     }
@@ -6547,16 +6600,16 @@ void sRef_setArrayFetchState (/*@notnull@*/ /*@exposed@*/ sRef s,
       s->info->arrayfetch->arr = arr; /* sRef_copy (arr); */ /*@i32@*/
       s->info->arrayfetch->indknown = TRUE;
       s->info->arrayfetch->ind = i;
-      
+
       sRef_setArrayFetchState (s, arr);
-      
+      /* evans 2001-08-27 no: can change this - llassert (s->info->arrayfetch->arr == arr); */
+
       s->oaliaskind = s->aliaskind;
       s->oexpkind = s->expkind;
       sRef_addDeriv (arr, s);
 
       llassert (valueTable_isUndefined (s->state));
       s->state = context_createValueTable (s, stateInfo_makeLoc (g_currentloc));
-
       return (s);
     }
 }
@@ -7970,7 +8023,7 @@ bool sRef_isJustAllocated (sRef s)
 static bool
 sRef_isAllocatedStorage (sRef s)
 {
-  if (sRef_isValid (s) && ynm_toBoolStrict (sRef_isReadable (s)))
+  if (sRef_isValid (s) && ynm_toBoolStrict (sRef_isValidLvalue (s)))
     {
       return (ctype_isVisiblySharable (sRef_getType (s)));
     }
@@ -8167,7 +8220,6 @@ sRef_aliasCheckPred (bool (predf) (sRef, exprNode, sRef, exprNode),
   else
     {
       sRefSet aliases = usymtab_allAliases (s);
-
       
       sRefSet_realElements (aliases, current)
        {
@@ -8254,7 +8306,7 @@ sRef_aliasCompleteSimplePred (bool (predf) (sRef), sRef s)
   return result;
 }
 
-static void
+void
 sRef_aliasSetComplete (void (predf) (sRef, fileloc), sRef s, fileloc loc)
 {
   sRefSet aliases;
@@ -8277,12 +8329,44 @@ sRef_aliasSetComplete (void (predf) (sRef, fileloc), sRef s, fileloc loc)
   sRefSet_free (aliases);
 }
 
-static void
-sRef_aliasSetCompleteParam (void (predf) (sRef, alkind, fileloc), sRef s, 
-                           alkind kind, fileloc loc)
+void
+sRef_aliasSetCompleteParam (void (predf) (sRef, int, fileloc), sRef s, 
+                           int kind, fileloc loc)
 {
   sRefSet aliases;
+  
+  if (sRef_isDeep (s))
+    {
+      aliases = usymtab_allAliases (s);
+    }
+  else
+    {
+      aliases = usymtab_aliasedBy (s);
+    }
+
+  (*predf)(s, kind, loc);
+
+  sRefSet_realElements (aliases, current)
+    {
+      if (sRef_isValid (current))
+       {
+         current = sRef_updateSref (current);
+         ((*predf)(current, kind, loc));
+       }
+    } end_sRefSet_realElements;
+
+  sRefSet_free (aliases);
+}
 
+/*
+** Version of aliasSetCompleteParam for alkind parameters
+*/
+
+void
+sRef_aliasSetCompleteAlkParam (void (predf) (sRef, alkind, fileloc), sRef s, 
+                              alkind kind, fileloc loc)
+{
+  sRefSet aliases;
   
   if (sRef_isDeep (s))
     {
@@ -8316,7 +8400,6 @@ sRef_innerAliasSetComplete (void (predf) (sRef, fileloc), sRef s, fileloc loc)
 
   if (!sRef_isValid (s)) return;
 
-  
   /*
   ** Type equivalence checking is necessary --- there might be casting.
   */
@@ -8370,13 +8453,19 @@ sRef_innerAliasSetComplete (void (predf) (sRef, fileloc), sRef s, fileloc loc)
                    {
                      sRef af = sRef_makeArrayFetchKnown (current, s->info->arrayfetch->ind);
                      DPRINTF (("Defining: %s", sRef_unparseFull (af)));
-                     llassert (af->info->arrayfetch->arr == current);
+                     /* evans 2001-08-27 This isn't true:
+                          llassert (af->info->arrayfetch->arr == current);
+                        see comments in buildArrayFetchKnown
+                     */
                      ((*predf)(af, loc));
                    }
                  else
                    {
                      sRef af = sRef_makeArrayFetch (current);
-                     llassert (af->info->arrayfetch->arr == current);
+                     /* evans 2001-08-27 This isn't true:
+                        llassert (af->info->arrayfetch->arr == current);
+                        see comments in buildArrayFetch
+                     */ 
                      DPRINTF (("Defining: %s", sRef_unparseFull (af)));
                      ((*predf)(af, loc));
                    }
@@ -8396,7 +8485,6 @@ sRef_innerAliasSetComplete (void (predf) (sRef, fileloc), sRef s, fileloc loc)
       inner = s->info->field->rec;
       aliases = usymtab_allAliases (inner);
       ct = sRef_getType (inner);
-
       
       sRefSet_realElements (aliases, current)
        {
@@ -8442,7 +8530,6 @@ sRef_innerAliasSetCompleteParam (void (predf) (sRef, sRef), sRef s, sRef t)
 
   if (!sRef_isValid (s)) return;
 
-  
   /*
   ** Type equivalence checking is necessary --- there might be casting.
   */
@@ -8459,8 +8546,7 @@ sRef_innerAliasSetCompleteParam (void (predf) (sRef, sRef), sRef s, sRef t)
       inner = s->info->ref;
       aliases = usymtab_allAliases (inner);
       ct = sRef_getType (inner);
-      
-      
+            
       sRefSet_realElements (aliases, current)
        {
          if (sRef_isValid (current))
@@ -8741,6 +8827,8 @@ static void
 
   sRef_checkMutable (res);
 
+  DPRINTF (("Combine alias kinds: \n\t%s / \n\t%s",
+           sRef_unparseFull (res), sRef_unparseFull (other)));
   if (alkind_equal (ares, aother)
       || aother == AK_UNKNOWN
       || aother == AK_ERROR)
@@ -8753,12 +8841,14 @@ static void
       res ->aliaskind = AK_ERROR; 
     }
   else if (ares == AK_UNKNOWN || ares == AK_ERROR
-          || sRef_isStateUndefined (res))
+          || sRef_isStateUndefined (res)
+          || sRef_isDefinitelyNull (res))
     { 
       res->aliasinfo = stateInfo_update (res->aliasinfo, other->aliasinfo);
       res->aliaskind = aother;  
     }
-  else if (sRef_isStateUndefined (other))
+  else if (sRef_isStateUndefined (other)
+          || sRef_isDefinitelyNull (other))
     {
       ;
     }
@@ -8947,6 +9037,8 @@ extern /*@exposed@*/ sRef sRef_makeArrow (sRef s, /*@dependent@*/ cstring f)
   
   p = sRef_makePointer (s);
   ret = sRef_makeField (p, f);
+  DPRINTF (("Arrow: %s => %s",
+           sRef_unparseFull (s), sRef_unparseFull (ret)));
   return ret;
 }
 
@@ -9316,6 +9408,7 @@ static void sRef_updateNullState (sRef res, sRef other)
 {
   res->nullstate = other->nullstate;
   res->nullinfo = stateInfo_update (res->nullinfo, other->nullinfo);
+  sRef_resetAliasKind (res);
 }
 
 void sRef_combineNullState (/*@notnull@*/ sRef res, /*@notnull@*/ sRef other)
@@ -9375,6 +9468,7 @@ void sRef_combineNullState (/*@notnull@*/ sRef res, /*@notnull@*/ sRef other)
     }
 
   res->nullstate = nn;
+  sRef_resetAliasKind (res);
 }
 
 cstring sRef_nullMessage (sRef s)
This page took 0.066668 seconds and 4 git commands to generate.