]> andersk Git - splint.git/blobdiff - src/constraint.c
Fixed library dump support so that buffer constraint annotations are read and written...
[splint.git] / src / constraint.c
index f3e09a49757b1bc6fc115c9cd91f9750ff5a39d4..389124776f4b79d816c9f41ac35eefef43a434f0 100644 (file)
@@ -1,5 +1,5 @@
 /*
-** constraintList.c
+** constraint.c
 */
 
 //#define DEBUGPRINT 1
@@ -13,7 +13,6 @@
 # include "exprChecks.h"
 # include "aliasChecks.h"
 # include "exprNodeSList.h"
-//# include "exprData.i"
 
 /*@i33*/
 /*@-fcnuse*/
 
 /*@access exprNode @*/
 
-static /*@notnull@*/  /*@special@*/ constraint constraint_makeNew (void)
-     /*@post:isnull result->or, result->orig,  result->generatingExpr @*/ /*@defines result->or, result->generatingExpr, result->orig @*/;
 
+static /*@only@*/ cstring  constraint_printDetailedPostCondition (/*@observer@*/ /*@temp@*/ constraint 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) */
      
 /*  { */
@@ -60,6 +63,15 @@ static /*@notnull@*/  /*@special@*/ constraint constraint_makeNew (void)
 /*    return ret; */
 /*  } */
 
+
+static void
+advanceField (char **s)
+{
+  checkChar (s, '@');
+}
+
+
+
 constraint makeConstraintParse2 (constraintExpr l, lltok relOp, exprNode cconstant)    
 {
   char *t;
@@ -69,7 +81,7 @@ constraint makeConstraintParse2 (constraintExpr l, lltok relOp, exprNode cconsta
   llassert (l!=NULL);
       
   ret->lexpr = constraintExpr_copy (l);
-  #warning fix abstraction
+
 
   if (relOp.tok == GE_OP)
       ret->ar = GTE;
@@ -114,7 +126,6 @@ constraint makeConstraintParse3 (constraintExpr l, lltok relOp, constraintExpr r
   llassert (l !=NULL);
     
   ret->lexpr = constraintExpr_copy (l);
-  #warning fix abstraction
 
   if (relOp.tok == GE_OP)
       ret->ar = GTE;
@@ -163,6 +174,8 @@ constraint constraint_copy (constraint c)
     ret->or = constraint_copy (c->or);
   else
     ret->or = NULL;
+
+  ret->fcnPre = c->fcnPre;
   
   return ret;
 }
@@ -202,14 +215,16 @@ void constraint_overWrite (constraint c1, constraint c2)
     c1->or = constraint_copy (c2->or);
   else
     c1->or = NULL;
+
+  c1->fcnPre = c2->fcnPre;
   
-  c1->generatingExpr = exprNode_fakeCopy (c2->generatingExpr );
+  c1->generatingExpr = c2->generatingExpr;
 }
 
 
 
 static /*@notnull@*/  /*@special@*/ constraint constraint_makeNew (void)
-     /*@post:isnull result->or, result->orig,  result->generatingExpr @*/ /*@defines result->or, result->generatingExpr, result->orig @*/
+     /*@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) );
@@ -220,6 +235,7 @@ static /*@notnull@*/  /*@special@*/ constraint constraint_makeNew (void)
   ret->orig = NULL;
   ret->or = NULL;
   ret->generatingExpr = NULL;
+  ret->fcnPre = NULL;
   return ret;
 }
 
@@ -238,6 +254,38 @@ constraint constraint_addGeneratingExpr (/*@returned@*/ constraint c, exprNode e
   return c;
 }
 
+constraint constraint_origAddGeneratingExpr (/*@returned@*/ constraint c, exprNode e)
+{
+
+  if (c->orig != constraint_undefined)
+    {
+      c->orig = constraint_addGeneratingExpr(c->orig, e);
+    }
+  else
+    {
+      DPRINTF ((message ("constraint_origAddGeneratingExpr: Not setting generatingExpr for %s to %s", constraint_print(c), exprNode_unparse(e) )  ));
+    }
+  return c;
+}
+
+constraint constraint_setFcnPre (/*@returned@*/ constraint c )
+{
+
+  if (c->orig != constraint_undefined)
+    {
+      c->orig->fcnPre = TRUE;
+    }
+  else
+    {
+      c->fcnPre = TRUE;
+      //      TPRINTF(( message("Warning Setting fcnPre directly") ));
+    }
+  return c;
+}
+
+
+
+
 fileloc constraint_getFileloc (constraint c)
 {
   if (exprNode_isDefined(c->generatingExpr) )
@@ -294,7 +342,7 @@ constraint constraint_makeWriteSafeInt (exprNode po, int ind)
 constraint constraint_makeSRefSetBufferSize (sRef s, long int size)
 {
  constraint ret = constraint_makeNew();
- ret->lexpr = constraintExpr_makeSRefMaxset (sRef_saveCopy(s) );
+ ret->lexpr = constraintExpr_makeSRefMaxset (s);
  ret->ar = EQ;
  ret->expr =  constraintExpr_makeIntLiteral ((int)size);
  ret->post = TRUE;
@@ -306,7 +354,7 @@ constraint constraint_makeSRefWriteSafeInt (sRef s, int ind)
   constraint ret = constraint_makeNew();
 
  
-  ret->lexpr = constraintExpr_makeSRefMaxset ( sRef_saveCopy(s) );
+  ret->lexpr = constraintExpr_makeSRefMaxset ( s );
   ret->ar = GTE;
   ret->expr =  constraintExpr_makeIntLiteral (ind);
   ret->post = TRUE;
@@ -358,7 +406,7 @@ constraint constraint_makeSRefReadSafeInt (sRef s, int ind)
   constraint ret = constraint_makeNew();
 
  
-  ret->lexpr = constraintExpr_makeSRefMaxRead (sRef_saveCopy(s) );
+  ret->lexpr = constraintExpr_makeSRefMaxRead (s );
   ret->ar = GTE;
   ret->expr =  constraintExpr_makeIntLiteral (ind);
   ret->post = TRUE;
@@ -489,6 +537,51 @@ 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();
@@ -525,7 +618,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) );
 
@@ -597,48 +690,141 @@ 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;
-  fileloc errorLoc;
+  fileloc errorLoc, temp;
   
   string = constraint_printDetailed (c);
 
   errorLoc = loc;
 
-  if (constraint_getFileloc(c) )
-      errorLoc = constraint_getFileloc(c);
-  
-  if (c->post)
+  loc = NULL;
+
+  temp = constraint_getFileloc(c);
+
+  if (fileloc_isDefined(temp) )
     {
-       voptgenerror (FLG_FUNCTIONPOST, string, errorLoc);
+      errorLoc = temp;
+      
+      if (c->post)
+       {
+         voptgenerror (FLG_FUNCTIONPOST, string, errorLoc);
+       }
+      else
+       {
+         voptgenerror (FLG_FUNCTIONCONSTRAINT, string, errorLoc);
+       }
+      fileloc_free(temp);
     }
   else
     {
-      voptgenerror (FLG_FUNCTIONCONSTRAINT, string, errorLoc);
+      if (c->post)
+       {
+         voptgenerror (FLG_FUNCTIONPOST, string, errorLoc);
+       }
+      else
+       {
+         voptgenerror (FLG_FUNCTIONCONSTRAINT, string, errorLoc);
+       }
+    }
+}
+
+
+cstring constraint_printDeep (constraint c)
+{
+  cstring st = cstring_undefined;
+
+  st = constraint_print(c);
+
+  if (c->orig != constraint_undefined)
+    {
+      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) )
+                                        ) );
+         else
+           st = cstring_concatFree(st,(message(" needed to satisfy %q",
+                                               constraint_printDeep(c->orig) )
+                                       ) );
+         
+       }
+      else
+       {
+         st = cstring_concatFree(st,(message("derived from: %q",
+                                             constraint_printDeep(c->orig) )
+                                     ) );
+       }
     }
-      
+
+  return st;  
+
 }
 
-cstring  constraint_printDetailed (constraint c)
+
+static /*@only@*/ cstring  constraint_printDetailedPostCondition (/*@observer@*/ /*@temp@*/ constraint c)
 {
   cstring st = cstring_undefined;
 
+  st = message ("Unsatisfied ensures constraint condition:\nLCLint is unable to verify the constraint %q", constraint_printDeep (c) );
+  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) );
+      st = cstring_concatFree (st, temp);
+
+      if (constraint_hasMaxSet(c) )
+       {
+         temp = message ("Has MaxSet\n");
+         st = cstring_concatFree (st, temp);
+       }
+    }
+  return st;
+}
+
+cstring  constraint_printDetailed (constraint c)
+{
+  cstring st = cstring_undefined;
 
   if (!c->post)
     {
-    if (c->orig != NULL)  
-      st = message ("Unresolved constraint:\nLclint is unable to resolve %q needed to satisfy %q", constraint_print (c), constraint_print(c->orig) );
-    else
-      st = message ("Unresolved constraint:\nLclint is unable to resolve %q", constraint_print (c));
-      
+      st = message ("Unresolved constraint:\nLclint is unable to resolve %q", constraint_printDeep (c) );
     }
   else
     {
-      if (c->orig != NULL)
-       st = message ("Block Post condition:\nThis function block has the post condition %q\n based on %q", constraint_print (c), constraint_print(c->orig) );
-      else
-       st = message ("Block Post condition:\nThis function block has the post condition %q", constraint_print (c));    
+      st = message ("Block Post condition:\nThis function block has the post condition %q", constraint_printDeep (c) );
     }
 
   if (context_getFlag (FLG_CONSTRAINTLOCATION) )
@@ -651,7 +837,7 @@ cstring  constraint_printDetailed (constraint c)
 
       if (constraint_hasMaxSet(c) )
        {
-         temp = message ("\nHas MaxSet\n");
+         temp = message ("Has MaxSet\n");
          st = cstring_concatFree (st, temp);
        }
     }
@@ -732,6 +918,7 @@ constraint constraint_doFixResult (constraint postcondition, exprNode fcnCall)
   precondition->lexpr = constraintExpr_doSRefFixConstraintParam (precondition->lexpr, arglist);
   precondition->expr = constraintExpr_doSRefFixConstraintParam (precondition->expr, arglist);
 
+  precondition->fcnPre = FALSE;
   return precondition;
 }
 
@@ -750,17 +937,145 @@ constraint constraint_doFixResult (constraint postcondition, exprNode fcnCall)
 
 constraint constraint_preserveOrig (/*@returned@*/ constraint c) /*@modifies c @*/
 {
+
+  DPRINTF( (message("Doing constraint_preserverOrig for %q ", constraint_printDetailed(c) ) ));
+  
   if (c->orig == constraint_undefined)
     c->orig = constraint_copy (c);
+
+  else if (c->orig->fcnPre)
+    {
+      constraint temp;
+      
+      temp = c->orig;
+      
+      /* avoid infinite loop */
+      c->orig = NULL;
+      c->orig = constraint_copy (c);
+      if (c->orig->orig == NULL)
+       {
+         c->orig->orig = temp;
+         temp = NULL;
+       }
+      else
+       {
+         llcontbug((message("Expected c->orig->orig to be null" ) ));
+         constraint_free(c->orig->orig);
+         c->orig->orig = temp;
+         temp = NULL;
+       }
+    }
+  else
+    {
+      DPRINTF( (message("Not changing constraint") ));
+    }
   
+  DPRINTF( (message("After Doing constraint_preserverOrig for %q ", constraint_printDetailed(c) ) ));
+
   return c;
 }
 /*@=fcnuse*/
 /*@=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;
+  //  /*@kept@*/ exprNode generatingExpr;
+
+  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) getInt (&s);
+  advanceField(&s);
+  post = (bool) getInt (&s);
+  advanceField(&s);
+  ar = (arithType) getInt (&s);
+
+  s = fgets(os, MAX_DUMP_LINE_LENGTH, f);
+
+  checkChar (&s, 'l');
+
+  lexpr = constraintExpr_undump (f);
+
+  s = fgets(os, MAX_DUMP_LINE_LENGTH, f);
+
+  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);
+  return c;
+}
+
+
+void constraint_dump (/*@observer@*/ constraint c,  FILE *f)
+{
+  bool           fcnPre;
+  bool post;
+  arithType       ar;
+  
+  constraintExpr lexpr;
+  constraintExpr  expr;
+  //  /*@kept@*/ exprNode generatingExpr;
+
+  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);
+}
+
+
This page took 0.050305 seconds and 4 git commands to generate.