]> andersk Git - splint.git/blobdiff - src/constraint.c
*** empty log message ***
[splint.git] / src / constraint.c
index 92a1e16bdfac18d0a7fadfae906c033f0492540f..6a8c98979cda2aef8c91ca200ed2f1788a971305 100644 (file)
 # include "cgrammar_tokens.h"
 
 # include "exprChecks.h"
-# include "aliasChecks.h"
 # include "exprNodeSList.h"
-//# include "exprData.i"
 
 /*@i33*/
-/*@-fcnuse*/
-/*@-assignexpose*/
 
 /*@access exprNode @*/
 
 
-static /*@notnull@*/  /*@special@*/ constraint constraint_makeNew (void)
-     /*@post:isnull result->or, result->orig,  result->generatingExpr, result->fcnPre @*/ /*@defines result->or, result->generatingExpr, result->orig, result->fcnPre @*/;
+static /*@only@*/ cstring  constraint_printDetailedPostCondition (/*@observer@*/ /*@temp@*/ constraint p_c);
+
+
+static /*@notnull@*/ /*@special@*/ constraint constraint_makeNew (void)
+     /*@post:isnull result->or, result->orig,  result->generatingExpr, result->fcnPre @*/
+     /*@defines result->or, result->generatingExpr, result->orig, result->fcnPre @*/;
      
 /*  constraint makeConstraintParse (sRef x, lltok relOp, exprNode cconstant) */
      
@@ -61,16 +61,25 @@ static /*@notnull@*/  /*@special@*/ constraint constraint_makeNew (void)
 /*    return ret; */
 /*  } */
 
-constraint makeConstraintParse2 (constraintExpr l, lltok relOp, exprNode cconstant)    
+
+static void
+advanceField (char **s)
+{
+  reader_checkChar (s, '@');
+}
+
+
+
+static constraint makeConstraintParse2 (constraintExpr l, lltok relOp, exprNode cconstant)    
 {
   char *t;
   int c;
   constraint ret;
-  ret = constraint_makeNew();
-  llassert (l!=NULL);
+  ret = constraint_makeNew ();
+  llassert (constraintExpr_isDefined(l) );
       
   ret->lexpr = constraintExpr_copy (l);
-  #warning fix abstraction
+
 
   if (relOp.tok == GE_OP)
       ret->ar = GTE;
@@ -112,10 +121,9 @@ constraint makeConstraintParse3 (constraintExpr l, lltok relOp, constraintExpr r
 {
   constraint ret;
   ret = constraint_makeNew();
-  llassert (l !=NULL);
+  llassert (constraintExpr_isDefined(l) );
     
   ret->lexpr = constraintExpr_copy (l);
-  #warning fix abstraction
 
   if (relOp.tok == GE_OP)
       ret->ar = GTE;
@@ -140,19 +148,21 @@ constraint makeConstraintParse3 (constraintExpr l, lltok relOp, constraintExpr r
   return ret;
 }
 
-constraint constraint_copy (constraint c)
+constraint constraint_copy (/*@temp@*/ /*@observer@*/ constraint c)
 {
   constraint ret;
 
   llassert (constraint_isDefined(c) );
-  // TPRINTF((message("Copying constraint %q", constraint_print) ));
+  // DPRINTF((message("Copying constraint %q", constraint_print) ));
   
   ret = constraint_makeNew();
   ret->lexpr = constraintExpr_copy (c->lexpr);
   ret->ar = c->ar;
   ret->expr =  constraintExpr_copy (c->expr);
   ret->post = c->post;
-  ret->generatingExpr = exprNode_fakeCopy(c->generatingExpr);
+  /*@-assignexpose@*/
+  ret->generatingExpr = c->generatingExpr;
+  /*@=assignexpose@*/
   
   /*@i33 fix this*/
   if (c->orig != NULL)
@@ -207,14 +217,17 @@ void constraint_overWrite (constraint c1, constraint c2)
     c1->or = NULL;
 
   c1->fcnPre = c2->fcnPre;
-  
+
+  /*@-assignexpose@*/
   c1->generatingExpr = c2->generatingExpr;
+  /*@=assignexpose@*/
 }
 
 
 
 static /*@notnull@*/  /*@special@*/ constraint constraint_makeNew (void)
-     /*@post:isnull result->or, result->orig,  result->generatingExpr, result->fcnPre @*/ /*@defines result->or, result->generatingExpr, result->orig, result->fcnPre @*/
+     /*@post:isnull result->or, result->orig,  result->generatingExpr, result->fcnPre @*/ 
+     /*@defines result->or, result->generatingExpr, result->orig, result->fcnPre @*/
 {
   constraint ret;
   ret = dmalloc(sizeof (*ret) );
@@ -229,12 +242,12 @@ static /*@notnull@*/  /*@special@*/ constraint constraint_makeNew (void)
   return ret;
 }
 
-constraint constraint_addGeneratingExpr (/*@returned@*/ constraint c, exprNode e)
+constraint constraint_addGeneratingExpr (/*@returned@*/ constraint c, /*@exposed@*/ exprNode e)
 {
     
   if (c->generatingExpr == NULL)
     {
-      c->generatingExpr = exprNode_fakeCopy(e);
+      c->generatingExpr = e;
       DPRINTF ((message ("setting generatingExpr for %s to %s", constraint_print(c), exprNode_unparse(e) )  ));
     }
   else
@@ -258,8 +271,6 @@ constraint constraint_origAddGeneratingExpr (/*@returned@*/ constraint c, exprNo
   return c;
 }
 
-
-
 constraint constraint_setFcnPre (/*@returned@*/ constraint c )
 {
 
@@ -270,7 +281,7 @@ constraint constraint_setFcnPre (/*@returned@*/ constraint c )
   else
     {
       c->fcnPre = TRUE;
-      TPRINTF(( message("Warning Setting fcnPre directly") ));
+      //      DPRINTF(( message("Warning Setting fcnPre directly") ));
     }
   return c;
 }
@@ -298,21 +309,24 @@ static bool checkForMaxSet (constraint c)
 
 bool constraint_hasMaxSet(constraint c)
 {
+  if (checkForMaxSet(c) )
+    return TRUE;
+  
   if (c->orig != NULL)
     {
       if (checkForMaxSet(c->orig) )
        return TRUE;
     }
 
-  return (checkForMaxSet(c) );
+  return FALSE;
 }
 
-constraint constraint_makeReadSafeExprNode ( exprNode po, exprNode ind)
+constraint constraint_makeReadSafeExprNode (  exprNode po, exprNode ind)
 {
   constraint ret = constraint_makeNew();
   //  constraintTerm term;
-  po = exprNode_fakeCopy(po);
-  ind = exprNode_fakeCopy(ind);
+  po = po;
+  ind = ind;
   ret->lexpr = constraintExpr_makeMaxReadExpr(po);
   ret->ar    = GTE;
   ret->expr  = constraintExpr_makeValueExpr (ind);
@@ -320,7 +334,7 @@ constraint constraint_makeReadSafeExprNode ( exprNode po, exprNode ind)
   return ret;
 }
 
-constraint constraint_makeWriteSafeInt (exprNode po, int ind)
+constraint constraint_makeWriteSafeInt (   exprNode po, int ind)
 {
   constraint ret = constraint_makeNew();
 
@@ -380,15 +394,13 @@ constraint constraint_makeWriteSafeExprNode (exprNode po, exprNode ind)
 }
 
 
-constraint constraint_makeReadSafeInt ( exprNode po, int ind)
+constraint constraint_makeReadSafeInt ( exprNode t1, int index)
 {
   constraint ret = constraint_makeNew();
 
-  po = exprNode_fakeCopy(po);
-  
-  ret->lexpr = constraintExpr_makeMaxReadExpr(po);
+  ret->lexpr = constraintExpr_makeMaxReadExpr(t1);
   ret->ar    = GTE;
-  ret->expr  = constraintExpr_makeIntLiteral (ind);
+  ret->expr  = constraintExpr_makeIntLiteral (index);
   ret->post = FALSE;
   return ret;
 }
@@ -405,14 +417,11 @@ constraint constraint_makeSRefReadSafeInt (sRef s, int ind)
   /*@i1*/return ret;
 }
 
-constraint constraint_makeEnsureMaxReadAtLeast (exprNode e1, exprNode t2, fileloc sequencePoint)
+constraint constraint_makeEnsureMaxReadAtLeast (exprNode t1, exprNode t2, fileloc sequencePoint)
 {
   constraint ret;
-
-  e1 = exprNode_fakeCopy (e1);
-  t2 = exprNode_fakeCopy (t2);
   
-  ret = constraint_makeReadSafeExprNode(e1, t2);
+  ret = constraint_makeReadSafeExprNode(t1, t2);
 
   ret->lexpr = constraintExpr_setFileloc (ret->lexpr, sequencePoint);
   
@@ -427,7 +436,7 @@ static constraint constraint_makeEnsuresOpConstraintExpr (/*@only@*/ constraintE
 
   constraint ret;
   
-  llassert(c1 && c2);
+  llassert(constraintExpr_isDefined(c1) && constraintExpr_isDefined(c2) );
   //  llassert(sequencePoint);
 
   ret = constraint_makeNew();
@@ -440,13 +449,13 @@ static constraint constraint_makeEnsuresOpConstraintExpr (/*@only@*/ constraintE
   return ret;
 }
 
-static constraint constraint_makeEnsuresOp (exprNode e1, exprNode e2, fileloc sequencePoint,  arithType  ar)
+static constraint constraint_makeEnsuresOp (/*@dependent@*/ exprNode e1, /*@dependent@*/ exprNode e2, fileloc sequencePoint,  arithType  ar)
 {
   constraintExpr c1, c2;
   constraint ret;
   exprNode e;
 
-  if (! (e1 && e2) )
+  if (! (exprNode_isDefined(e1) && exprNode_isDefined(e2) ) )
     {
       llcontbug((message("null exprNode, Exprnodes are %s and %s",
                       exprNode_unparse(e1), exprNode_unparse(e2) )
@@ -455,10 +464,10 @@ static constraint constraint_makeEnsuresOp (exprNode e1, exprNode e2, fileloc se
 
   //  llassert (sequencePoint);
   
-  e  =  exprNode_fakeCopy(e1);
+  e  =  e1;
   c1 =  constraintExpr_makeValueExpr (e);
   
-  e  =  exprNode_fakeCopy(e2);
+  e  =  e2;
   c2 =  constraintExpr_makeValueExpr (e);
 
   ret = constraint_makeEnsuresOpConstraintExpr (c1, c2, sequencePoint, ar);
@@ -529,12 +538,57 @@ exprNode exprNode_copyConstraints (/*@returned@*/ exprNode dst, exprNode src)
   return dst;
 }
 
+/* Makes the constraint e = e + f */
+constraint constraint_makeAddAssign (exprNode e, exprNode f, fileloc sequencePoint)
+{
+  constraintExpr x1, x2, y;
+  constraint ret;
+
+  ret = constraint_makeNew();
+
+  x1 =  constraintExpr_makeValueExpr (e);
+  x2 =  constraintExpr_copy(x1);
+  y  =  constraintExpr_makeValueExpr (f);
+
+  ret->lexpr = x1;
+  ret->ar = EQ;
+  ret->post = TRUE;
+  ret->expr = constraintExpr_makeAddExpr (x2, y);
+  
+  ret->lexpr = constraintExpr_setFileloc (ret->lexpr, sequencePoint);
+
+  return ret;
+}
+
+
+/* Makes the constraint e = e - f */
+constraint constraint_makeSubtractAssign (exprNode e, exprNode f, fileloc sequencePoint)
+{
+  constraintExpr x1, x2, y;
+  constraint ret;
+
+  ret = constraint_makeNew();
+
+  x1 =  constraintExpr_makeValueExpr (e);
+  x2 =  constraintExpr_copy(x1);
+  y  =  constraintExpr_makeValueExpr (f);
+
+  ret->lexpr = x1;
+  ret->ar = EQ;
+  ret->post = TRUE;
+  ret->expr = constraintExpr_makeSubtractExpr (x2, y);
+  
+  ret->lexpr = constraintExpr_setFileloc (ret->lexpr, sequencePoint);
+
+  return ret;
+}
+
 constraint constraint_makeMaxSetSideEffectPostDecrement (exprNode e, fileloc sequencePoint)
 {
   constraint ret = constraint_makeNew();
   //constraintTerm term;
 
-  e = exprNode_fakeCopy(e);
+  //  e = exprNode_fakeCopy(e);
   ret->lexpr = constraintExpr_makeValueExpr (e);
   ret->ar = EQ;
   ret->post = TRUE;
@@ -551,7 +605,7 @@ constraint constraint_makeMaxSetSideEffectPostIncrement (exprNode e, fileloc seq
   constraint ret = constraint_makeNew();
   //constraintTerm term;
 
-  e = exprNode_fakeCopy(e);
+  //  e = exprNode_fakeCopy(e);
   ret->lexpr = constraintExpr_makeValueExpr (e);
   ret->ar = EQ;
   ret->post = TRUE;
@@ -565,7 +619,7 @@ constraint constraint_makeMaxSetSideEffectPostIncrement (exprNode e, fileloc seq
 }
 
 
-void constraint_free (/*@only@*/ /*@notnull@*/ constraint c)
+void constraint_free (/*@only@*/ constraint c)
 {
   llassert(constraint_isDefined (c) );
 
@@ -637,6 +691,34 @@ cstring arithType_print (arithType ar) /*@*/
   return st;
 }
 
+void constraint_printErrorPostCondition (constraint c, fileloc loc)
+{
+  cstring string;
+  fileloc errorLoc, temp;
+  
+  string = constraint_printDetailedPostCondition (c);
+
+  errorLoc = loc;
+
+  loc = NULL;
+
+  temp = constraint_getFileloc(c);
+
+  if (fileloc_isDefined(temp) )
+    {
+      errorLoc = temp;
+      voptgenerror (  FLG_CHECKPOST, string, errorLoc);
+      fileloc_free(temp);
+    }
+  else
+    {
+      voptgenerror (  FLG_CHECKPOST, string, errorLoc);
+    }
+}
+
+
+
+
 void constraint_printError (constraint c, fileloc loc)
 {
   cstring string;
@@ -660,9 +742,13 @@ void constraint_printError (constraint c, fileloc loc)
        }
       else
        {
-         voptgenerror (FLG_FUNCTIONCONSTRAINT, string, errorLoc);
+         if (constraint_hasMaxSet (c) )
+           voptgenerror (FLG_ARRAYBOUNDS, string, errorLoc);
+         else
+           voptgenerror (FLG_ARRAYBOUNDSREAD, string, errorLoc);
        }
       fileloc_free(temp);
+      errorLoc = NULL;
     }
   else
     {
@@ -674,25 +760,30 @@ void constraint_printError (constraint c, fileloc loc)
        {
          voptgenerror (FLG_FUNCTIONCONSTRAINT, string, errorLoc);
        }
+      errorLoc = NULL;
     }
 }
 
 
-cstring constraint_printDeep (constraint c)
+static cstring constraint_printDeep (constraint c)
 {
+  cstring genExpr;
   cstring st = cstring_undefined;
 
   st = constraint_print(c);
 
+  
   if (c->orig != constraint_undefined)
     {
+      st = cstring_appendChar(st, '\n');
+      genExpr =  exprNode_unparse(c->orig->generatingExpr);
       if (!c->post)
        {
          if (c->orig->fcnPre)
-           st = cstring_concatFree(st, (message(" derived from %s precondition: %q", exprNode_unparse(c->orig->generatingExpr), constraint_printDeep(c->orig) )
+           st = cstring_concatFree(st, (message(" derived from %s precondition: %q", genExpr, constraint_printDeep(c->orig) )
                                         ) );
          else
-           st = cstring_concatFree(st,(message(" needed to satisfy %q",
+           st = cstring_concatFree(st,(message(" needed to satisfy precondition:\n%q",
                                                constraint_printDeep(c->orig) )
                                        ) );
          
@@ -709,36 +800,72 @@ cstring constraint_printDeep (constraint c)
 
 }
 
-cstring  constraint_printDetailed (constraint c)
+
+static /*@only@*/ cstring  constraint_printDetailedPostCondition (/*@observer@*/ /*@temp@*/ constraint c)
 {
   cstring st = cstring_undefined;
+  cstring genExpr;
+  
+  st = message ("Unsatisfied ensures constraint condition:\nLCLint is unable to verify the constraint %q", constraint_printDeep (c) );
 
-  if (!c->post)
-    {
-      st = message ("Unresolved constraint:\nLclint is unable to resolve %q", constraint_printDeep (c) );
-    }
-  else
-    {
-      st = message ("Block Post condition:\nThis function block has the post condition %q", constraint_printDeep (c) );
-    }
-
+  genExpr = exprNode_unparse (c->generatingExpr);
+    
   if (context_getFlag (FLG_CONSTRAINTLOCATION) )
     {
       cstring temp;
       // llassert (c->generatingExpr);
       temp = message ("\nOriginal Generating expression %q: %s\n", fileloc_unparse( exprNode_getfileloc (c->generatingExpr) ),
-                     exprNode_unparse(c->generatingExpr) );
+                     genExpr );
       st = cstring_concatFree (st, temp);
 
       if (constraint_hasMaxSet(c) )
        {
-         temp = message ("\nHas MaxSet\n");
+         temp = message ("Has MaxSet\n");
          st = cstring_concatFree (st, temp);
        }
     }
   return st;
 }
 
+cstring  constraint_printDetailed (constraint c)
+{
+  cstring st = cstring_undefined;
+  cstring temp = cstring_undefined;
+    cstring genExpr;
+  
+  if (!c->post)
+    {
+      st = message ("Unable to resolve constraint:\n%q", constraint_printDeep (c) );
+    }
+  else
+    {
+      st = message ("Block Post condition:\nThis function block has the post condition %q", constraint_printDeep (c) );
+    }
+
+  if (constraint_hasMaxSet(c) )
+    {
+      temp = cstring_makeLiteral("Possible out-of-bounds store.  ");
+    }
+  else
+    {
+      temp = cstring_makeLiteral("Possible out-of-bounds read.  ");
+    }
+
+  st  = cstring_concatFree(temp,st);
+  
+  genExpr = exprNode_unparse (c->generatingExpr);
+
+  if (context_getFlag (FLG_CONSTRAINTLOCATION) )
+    {
+      temp = message ("\nConstraint generated from expression: %s at %q\n",
+                     genExpr,
+                     fileloc_unparse( exprNode_getfileloc (c->generatingExpr) )
+                     );
+      st = cstring_concatFree (st, temp);
+    }
+  return st;
+}
+
 /*@only@*/ cstring  constraint_print (constraint c) /*@*/
 {
   cstring st = cstring_undefined;
@@ -746,11 +873,11 @@ cstring  constraint_printDetailed (constraint c)
   llassert (c !=NULL);
   if (c->post)
     {
-      type = cstring_makeLiteral ("Ensures: ");
+      type = cstring_makeLiteral ("ensures: ");
     }
   else
     {
-      type = cstring_makeLiteral ("Requires: ");
+      type = cstring_makeLiteral ("requires: ");
     }
   st = message ("%q: %q %q %q",
                type,
@@ -796,7 +923,7 @@ cstring  constraint_printOr (constraint c) /*@*/
 }
 
 
-constraint constraint_doFixResult (constraint postcondition, exprNode fcnCall)
+constraint constraint_doFixResult (constraint postcondition, /*@dependent@*/ exprNode fcnCall)
 {
   postcondition = constraint_copy (postcondition);
   postcondition->lexpr = constraintExpr_doFixResult (postcondition->lexpr, fcnCall);
@@ -848,9 +975,17 @@ constraint constraint_preserveOrig (/*@returned@*/ constraint c) /*@modifies c @
       c->orig = NULL;
       c->orig = constraint_copy (c);
       if (c->orig->orig == NULL)
-       c->orig->orig = temp;
+       {
+         c->orig->orig = temp;
+         temp = NULL;
+       }
       else
-       llcontbug((message("Expected c->orig->orig to be null" ) ));
+       {
+         llcontbug((message("Expected c->orig->orig to be null" ) ));
+         constraint_free(c->orig->orig);
+         c->orig->orig = temp;
+         temp = NULL;
+       }
     }
   else
     {
@@ -865,8 +1000,139 @@ constraint constraint_preserveOrig (/*@returned@*/ constraint c) /*@modifies c @
 /*@=assignexpose*/
 /*@=czechfcns@*/
 
+
 constraint constraint_togglePost (/*@returned@*/ constraint c)
 {
   c->post = !c->post;
   return c;
 }
+
+constraint constraint_togglePostOrig (/*@returned@*/ constraint c)
+{
+  if (c->orig != NULL)
+    c->orig = constraint_togglePost(c->orig);
+  return c;
+}
+
+bool constraint_hasOrig( /*@observer@*/ /*@temp@*/ constraint c)
+{
+  if (c->orig == NULL)
+    return FALSE;
+  else
+    return TRUE;
+}
+
+
+constraint constraint_undump (FILE *f)
+{
+  constraint c;
+  bool           fcnPre;
+  bool post;
+  arithType       ar;
+  
+  constraintExpr lexpr;
+  constraintExpr  expr;
+
+
+  char * s;
+
+  char *os;
+
+  s = mstring_create (MAX_DUMP_LINE_LENGTH);
+
+  os = s;
+  
+  s = fgets(os, MAX_DUMP_LINE_LENGTH, f);
+
+  /*@i33*/ /*this should probably be wrappered...*/
+  
+  fcnPre = (bool) reader_getInt (&s);
+  advanceField(&s);
+  post = (bool) reader_getInt (&s);
+  advanceField(&s);
+  ar = (arithType) reader_getInt (&s);
+
+  s = fgets(os, MAX_DUMP_LINE_LENGTH, f);
+
+  reader_checkChar (&s, 'l');
+
+  lexpr = constraintExpr_undump (f);
+
+  s = fgets(os, MAX_DUMP_LINE_LENGTH, f);
+
+  reader_checkChar (&s, 'r');
+  expr = constraintExpr_undump (f);
+
+  c = constraint_makeNew();
+  
+  c->fcnPre = fcnPre; 
+  c->post = post;
+  c->ar = ar;
+
+  c->lexpr = lexpr;
+  c->expr =  expr;
+
+  free(os);
+  c = constraint_preserveOrig(c);
+  return c;
+}
+
+
+void constraint_dump (/*@observer@*/ constraint c,  FILE *f)
+{
+  bool           fcnPre;
+  bool post;
+  arithType       ar;
+  
+  constraintExpr lexpr;
+  constraintExpr  expr;
+
+
+  fcnPre = c->fcnPre;
+  post   = c->post;
+  ar     = c->ar;
+  lexpr = c->lexpr;
+  expr = c->expr;
+  
+  fprintf(f, "%d@%d@%d\n", (int) fcnPre, (int) post, (int) ar);
+  fprintf(f,"l\n");
+  constraintExpr_dump (lexpr, f);
+  fprintf(f,"r\n");
+  constraintExpr_dump (expr, f);
+}
+
+
+int constraint_compare (/*@observer@*/ /*@temp@*/ constraint * c1, /*@observer@*/ /*@temp@*/ constraint * c2) /*@*/
+{
+  fileloc loc1, loc2;
+
+  int ret;
+  
+  llassert(constraint_isDefined(*c1) );
+  llassert(constraint_isDefined(*c2) );
+
+  if (constraint_isUndefined(*c1) )
+    {
+        if (constraint_isUndefined(*c2) )
+         return 0;
+       else
+         return 1;
+    }
+
+  if (constraint_isUndefined(*c2) )
+    {
+      return -1;
+    }
+    
+  loc1 = constraint_getFileloc(*c1);
+  loc2 = constraint_getFileloc(*c2);
+
+  ret = fileloc_compare(loc1, loc2);
+
+  fileloc_free(loc1);
+  fileloc_free(loc2);
+    
+  return ret;
+}
+
+
This page took 0.150614 seconds and 4 git commands to generate.