]> andersk Git - splint.git/blobdiff - src/sRef.c
Fixed line numbering when multi-line macro parameters are used.
[splint.git] / src / sRef.c
index 395a00e280ab145901d442d9a3abda0c87590653..ed43a689062d4329db77d57e92e1e07b8f1460e7 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
@@ -17,9 +17,9 @@
 ** 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
 */
 /*
 ** storeRef.c
@@ -34,7 +34,7 @@
 **
 */
 
-# include "lclintMacros.nf"
+# include "splintMacros.nf"
 # include "basic.h"
 # include "exprChecks.h"
 # include "transferChecks.h"
@@ -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@*/
@@ -366,6 +369,8 @@ static /*@dependent@*/ /*@notnull@*/ /*@special@*/ sRef
 
   /* start modifications */
   s->bufinfo.bufstate = BB_NOTNULLTERMINATED;
+  s->bufinfo.size = -1; /*@i24 unknown@*/
+  s->bufinfo.len = -1; /*@i24 unknown@*/
   /* end modifications */
 
   s->aliaskind = AK_UNKNOWN;
@@ -585,20 +590,21 @@ static bool
          && (fileloc_isDefined (s->aliasinfo->loc)));
 }
 
-static /*@falsenull@*/ bool
+static /*@falsewhennull@*/ bool
 sRef_hasStateInfoLoc (sRef s)
 {
   return (sRef_isValid (s) && (s->definfo != NULL) 
          && (fileloc_isDefined (s->definfo->loc)));
 }
 
-static /*@falsenull@*/ bool
+static /*@falsewhennull@*/ bool
 sRef_hasExpInfoLoc (sRef s)
 {
   return (sRef_isValid (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 +622,7 @@ static /*@observer@*/ /*@unused@*/ stateInfo sRef_getInfo (sRef s, cstring key)
   
   return stateInfo_undefined;
 }
-
+# endif
 
 static bool
 sRef_hasNullInfoLoc (sRef s)
@@ -726,6 +732,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;
@@ -1016,10 +1030,8 @@ void sRef_setModified (sRef s)
        {
          sRef base = sRef_getBase (s);
          
-         
          llassert (s->kind == SK_FIELD);
          
-         
          if (sRef_isPointer (base))
            {
              base = sRef_getBase (base);
@@ -1054,7 +1066,6 @@ sRef_canModifyVal (sRef s, sRefSet sl)
 bool
 sRef_canModify (sRef s, sRefSet sl)
 {
-  
   if (context_getFlag (FLG_MUSTMOD))
     {
       return (sRef_doModify (s, sl));
@@ -2168,7 +2179,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 +2196,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;
       }
@@ -2230,9 +2241,6 @@ sRef_closeEnough (sRef s1, sRef s2)
       return ce;
       }
     }
-
-  
-
 }
 
 /*@exposed@*/ sRef
@@ -2277,9 +2285,14 @@ sRef_fixBaseParam (/*@returned@*/ sRef s, exprNodeList args)
                  (sRef_fixBaseParam (s->info->arrayfetch->arr, args)));
        }
     case SK_FIELD:
-      return (sRef_makeField (sRef_fixBaseParam (s->info->field->rec, args),
-                             s->info->field->field));
-
+      {
+       sRef res;
+       DPRINTF (("Fix field: %s", sRef_unparseFull (s)));
+       res = sRef_makeField (sRef_fixBaseParam (s->info->field->rec, args),
+                             s->info->field->field);
+       DPRINTF (("Returns: %s", sRef_unparseFull (res)));
+       return res;
+      }
     case SK_PTR:
       return (sRef_makePointer (sRef_fixBaseParam (s->info->ref, args)));
 
@@ -2798,9 +2811,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 +3397,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 +3727,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);
 
@@ -4327,7 +4342,7 @@ sRef_makeUnknown ()
   return s;
 }
 
-static /*@owned@*/ sRef
+static /*@owned@*/ /*@notnull@*/ sRef
 sRef_makeSpecial (speckind sk) /*@*/
 {
   sRef s = sRef_new ();
@@ -4583,10 +4598,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 +4618,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 +4628,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 +4652,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 +4671,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 +4887,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)
@@ -5128,6 +5150,7 @@ static void sRef_setDefinedAux (sRef s, fileloc loc, bool clear)
       /* evans 2001-07-12: need to define the derived references */
       sRefSet_elements (s->deriv, el)
        {
+         llassert (sRef_isValid (el));
          el->defstate = SS_DEFINED;
        } end_sRefSet_elements ;
     }
@@ -5152,7 +5175,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);
 }
 
@@ -5230,6 +5275,7 @@ void sRef_setPdefined (sRef s, fileloc loc)
            { 
              sRef nb;
              
+             DPRINTF (("set pdefined: %s", sRef_unparseFull (base)));
              base->defstate = SS_PDEFINED; 
              nb = sRef_getBaseSafe (base); 
              base = nb;
@@ -5267,9 +5313,9 @@ static void sRef_setStateAux (sRef s, sstate ss, fileloc loc)
              if (base->defstate == SS_DEFINED) 
                { 
                  sRef nb;
-                 
+
+                 DPRINTF (("set pdefined: %s", sRef_unparseFull (s)));           
                  base->defstate = SS_PDEFINED; 
-                 
                  nb = sRef_getBaseSafe (base); 
                  base = nb;
                }
@@ -5279,8 +5325,7 @@ static void sRef_setStateAux (sRef s, sstate ss, fileloc loc)
                }
            }
        }
-
-          }
+    }
 }
 
 void sRef_setAllocatedComplete (sRef s, fileloc loc)
@@ -5356,7 +5401,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);
@@ -5373,8 +5419,12 @@ void sRef_setNotNull (sRef s, fileloc loc)
 
 void sRef_setNullStateN (sRef s, nstate n)
 {
-  sRef_checkMutable (s);
-  s->nullstate = n;
+  if (sRef_isValid (s))
+    {
+      sRef_checkMutable (s);
+      s->nullstate = n;
+      sRef_resetAliasKind (s);
+    }
 }
 
 void sRef_setNullState (sRef s, nstate n, fileloc loc)
@@ -5385,22 +5435,23 @@ 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);
-          sRef_setLen (s, b.len);
-          break;
-     case BB_POSSIBLYNULLTERMINATED:
-          sRef_setPossiblyNullTerminatedState(s);
-          break;
-     case BB_NOTNULLTERMINATED:
-          sRef_setNotNullTerminatedState (s);
-          break;
+  case BB_NULLTERMINATED:
+    sRef_setNullTerminatedState (s);
+    sRef_setLen (s, b.len);
+    break;
+  case BB_POSSIBLYNULLTERMINATED:
+    sRef_setPossiblyNullTerminatedState(s);
+    break;
+  case BB_NOTNULLTERMINATED:
+    sRef_setNotNullTerminatedState (s);
+    break;
   }
-  sRef_setSize (s, b.size);
 
+  sRef_setSize (s, b.size);
+  
   /* PL: TO BE DONE : Aliases are not modified right now, have to be similar to
    * setNullStateInnerComplete.
    */
@@ -5528,13 +5579,12 @@ void sRef_setKept (sRef s, fileloc loc)
          if (base->defstate == SS_DEFINED) 
            {
              base->defstate = SS_PDEFINED; 
-                     base = sRef_getBaseSafe (base); 
+             base = sRef_getBaseSafe (base); 
            }
          else 
            {
              break; 
            }
-
        }
 
       s->aliaskind = AK_KEPT;
@@ -6132,7 +6182,7 @@ sRef_buildNCField (/*@exposed@*/ sRef rec, /*@exposed@*/ cstring f)
   else
     {
       ctype ct = ctype_realType (rec->type);
-
+      
       DPRINTF (("Field of: %s", sRef_unparse (rec)));
       
       s = sRef_newRef ();      
@@ -6176,7 +6226,7 @@ sRef_buildNCField (/*@exposed@*/ sRef rec, /*@exposed@*/ cstring f)
              
              s->oaliaskind = s->aliaskind;
              s->oexpkind = s->expkind;
-
+             
              DPRINTF (("sref: %s", sRef_unparseFull (s)));
            }
          else
@@ -6268,6 +6318,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 +6524,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 +6570,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 +6605,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 +8028,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 +8225,6 @@ sRef_aliasCheckPred (bool (predf) (sRef, exprNode, sRef, exprNode),
   else
     {
       sRefSet aliases = usymtab_allAliases (s);
-
       
       sRefSet_realElements (aliases, current)
        {
@@ -8254,7 +8311,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 +8334,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 +8405,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 +8458,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 +8490,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 +8535,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 +8551,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 +8832,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 +8846,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 +9042,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;
 }
 
@@ -9311,11 +9408,12 @@ static speckind speckind_fromInt (int i)
 }
 
 
-static void sRef_updateNullState (sRef res, sRef other)
+static void sRef_updateNullState (/*@notnull@*/ sRef res, /*@notnull@*/ sRef other)
      /*@modifies res@*/
 {
   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 +9473,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.358676 seconds and 4 git commands to generate.