]> andersk Git - splint.git/blobdiff - src/constraint.c
Added support for or constraints.
[splint.git] / src / constraint.c
index ec5eb02d513dba3fd74a7fa7a2fa02060bc6b261..f313f7ff402419b07ae2790a144daf510c91a225 100644 (file)
@@ -19,7 +19,7 @@
 /*@-fcnuse*/
 /*@-assignexpose*/
 
-constraint constraint_makeNew (void);
+/*@notnull@*/ constraint constraint_makeNew (void);
 
 
 constraint makeConstraintParse (sRef x, lltok relOp, exprNode cconstant)
@@ -44,7 +44,7 @@ constraint makeConstraintParse (sRef x, lltok relOp, exprNode cconstant)
   else if (relOp.tok == EQ_OP)
     ret->ar = EQ;
   else
-  llfatalbug("Unsupported relational operator");
+    llfatalbug(message ("Unsupported relational operator") );
 
 
   t =  cstring_toCharsSafe (exprNode_unparse(cconstant));
@@ -65,7 +65,7 @@ constraint makeConstraintParse2 (constraintExpr l, lltok relOp, exprNode cconsta
   int c;
   constraint ret;
   ret = constraint_makeNew();
-  llassert (l);
+  llassert (l!=NULL);
   if (!l)
     return ret;
  
@@ -80,7 +80,7 @@ constraint makeConstraintParse2 (constraintExpr l, lltok relOp, exprNode cconsta
   else if (relOp.tok == EQ_OP)
     ret->ar = EQ;
   else
-  llfatalbug("Unsupported relational operator");
+  llfatalbug(message("Unsupported relational operator") );
 
 
   t =  cstring_toCharsSafe (exprNode_unparse(cconstant));
@@ -94,12 +94,26 @@ constraint makeConstraintParse2 (constraintExpr l, lltok relOp, exprNode cconsta
   return ret;
 }
 
+constraint constraint_same (constraint c1, constraint c2)
+{
+  
+  if (c1->ar != c2->ar)
+    return FALSE;
+
+  if (!constraintExpr_similar (c1->lexpr, c2->lexpr) )
+    return FALSE;
+
+  if (!constraintExpr_similar (c1->expr, c2->expr) )
+    return FALSE;
+
+  return TRUE;
+}
 
 constraint makeConstraintParse3 (constraintExpr l, lltok relOp, constraintExpr r)     
 {
   constraint ret;
   ret = constraint_makeNew();
-  llassert (l);
+  llassert (l !=NULL);
   if (!l)
     return ret;
  
@@ -114,11 +128,16 @@ constraint makeConstraintParse3 (constraintExpr l, lltok relOp, constraintExpr r
   else if (relOp.tok == EQ_OP)
     ret->ar = EQ;
   else
-  llfatalbug("Unsupported relational operator");
+  llfatalbug( message("Unsupported relational operator") );
 
   ret->expr = constraintExpr_copy (r);
 
   ret->post = TRUE;
+
+  ret->orig = constraint_copy(ret);
+
+  ret = constraint_simplify (ret);
+  
   //  ret->orig = ret;
   DPRINTF(("GENERATED CONSTRAINT:"));
   DPRINTF( (message ("%s", constraint_print(ret) ) ) );
@@ -128,16 +147,27 @@ constraint makeConstraintParse3 (constraintExpr l, lltok relOp, constraintExpr r
 constraint constraint_copy (constraint c)
 {
   constraint ret;
+
+  llassert (c);
+  
   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);
+  
   /*@i33 fix this*/
   if (c->orig != NULL)
     ret->orig = constraint_copy (c->orig);
   else
     ret->orig = NULL;
+
+  if (c->or != NULL)
+    ret->or = constraint_copy (c->or);
+  else
+    ret->or = NULL;
+  
   return ret;
 }
 
@@ -155,6 +185,12 @@ void constraint_overWrite (constraint c1, constraint c2)
   else
     c1->orig = NULL;
 
+  if (c2->or != NULL)
+    c1->or = constraint_copy (c2->or);
+  else
+    c1->or = NULL;
+  
+  c1->generatingExpr = exprNode_fakeCopy (c2->generatingExpr );
 }
 
 bool constraint_resolve (/*@unused@*/ constraint c)
@@ -164,7 +200,7 @@ bool constraint_resolve (/*@unused@*/ constraint c)
 
 
 
-constraint constraint_makeNew (void)
+/*@notnull@*/ constraint constraint_makeNew (void)
 {
   constraint ret;
   ret = dmalloc(sizeof (*ret) );
@@ -173,16 +209,55 @@ constraint constraint_makeNew (void)
   ret->ar = LT;
   ret->post = FALSE;
   ret->orig = NULL;
-  /*@i23*/return ret;
+  ret->or = NULL;
+  ret->generatingExpr = NULL;
+  return ret;
+}
+
+constraint constraint_addGeneratingExpr (/*@returned@*/ constraint c, exprNode e)
+{
+    
+  if (c->generatingExpr == NULL)
+    {
+      c->generatingExpr = exprNode_fakeCopy(e);
+      DPRINTF ((message ("setting generatingExpr for %s to %s", constraint_print(c), exprNode_unparse(e) )  ));
+    }
+  else
+    {
+      DPRINTF ((message ("Not setting generatingExpr for %s to %s", constraint_print(c), exprNode_unparse(e) )  ));
+    }
+  return c;
 }
 
 fileloc constraint_getFileloc (constraint c)
 {
+  if (c->generatingExpr)
+    return (exprNode_getfileloc (c->generatingExpr) );
+           
   return (constraintExpr_getFileloc (c->lexpr) );
 
 
 }
 
+static bool checkForMaxSet (constraint c)
+{
+  if (constraintExpr_hasMaxSet(c->lexpr) || constraintExpr_hasMaxSet(c->expr) )
+    return TRUE;
+
+  return FALSE;
+}
+
+bool constraint_hasMaxSet(constraint c)
+{
+  if (c->orig != NULL)
+    {
+      if (checkForMaxSet(c->orig) )
+       return TRUE;
+    }
+
+  return (checkForMaxSet(c) );
+}
+
 constraint constraint_makeReadSafeExprNode ( exprNode po, exprNode ind)
 {
   constraint ret = constraint_makeNew();
@@ -267,6 +342,18 @@ constraint constraint_makeReadSafeInt ( exprNode po, int ind)
   return ret;
 }
 
+constraint constraint_makeSRefReadSafeInt (sRef s, int ind)
+{
+  constraint ret = constraint_makeNew();
+
+  ret->lexpr = constraintExpr_makeSRefMaxRead (s);
+  ret->ar = GTE;
+  ret->expr =  constraintExpr_makeValueInt (ind);
+  ret->post = TRUE;
+  /*@i1*/return ret;
+}
+
 constraint constraint_makeEnsureMaxReadAtLeast (exprNode e1, exprNode t2, fileloc sequencePoint)
 {
   constraint ret = constraint_makeNew();
@@ -285,27 +372,47 @@ constraint constraint_makeEnsureMaxReadAtLeast (exprNode e1, exprNode t2, filelo
   return ret;
 }
 
+static constraint constraint_makeEnsuresOpConstraintExpr (constraintExpr c1, constraintExpr c2, fileloc sequencePoint,  arithType  ar)
+{
+
+  constraint ret;
+  
+  llassert(c1 && c2);
+  //  llassert(sequencePoint);
+
+  ret = constraint_makeNew();
+  
+  ret->lexpr = c1;
+  ret->ar = ar;
+  ret->post = TRUE;
+  ret->expr =  c2;
+  ret->lexpr = constraintExpr_setFileloc (ret->lexpr, sequencePoint);
+  return ret;
+}
 
 static constraint constraint_makeEnsuresOp (exprNode e1, exprNode e2, fileloc sequencePoint,  arithType  ar)
 {
-  constraint ret = constraint_makeNew();
+  constraintExpr c1, c2;
+  constraint ret;
   exprNode e;
-  
-  e = exprNode_fakeCopy(e1);
+
   if (! (e1 && e2) )
     {
       llcontbug((message("null exprNode, Exprnodes are %s and %s",
                       exprNode_unparse(e1), exprNode_unparse(e2) )
               ));
     }
-                      
-  ret->lexpr = constraintExpr_makeValueExpr (e);
-  ret->ar = ar;
-  ret->post = TRUE;
-  e = exprNode_fakeCopy(e2);
-  ret->expr =  constraintExpr_makeValueExpr (e);
+
+  //  llassert (sequencePoint);
+  
+  e  =  exprNode_fakeCopy(e1);
+  c1 =  constraintExpr_makeValueExpr (e);
+  
+  e  =  exprNode_fakeCopy(e2);
+  c2 =  constraintExpr_makeValueExpr (e);
+
+  ret = constraint_makeEnsuresOpConstraintExpr (c1, c2, sequencePoint, ar);
   
-  ret->lexpr = constraintExpr_setFileloc (ret->lexpr, sequencePoint);
   return ret;
 }
 
@@ -320,7 +427,16 @@ constraint constraint_makeEnsureEqual (exprNode e1, exprNode e2, fileloc sequenc
 /*make constraint ensures e1 < e2 */
 constraint constraint_makeEnsureLessThan (exprNode e1, exprNode e2, fileloc sequencePoint)
 {
- return ( constraint_makeEnsuresOp (e1, e2, sequencePoint, LT) );
+  constraintExpr t1, t2;
+
+  t1 = constraintExpr_makeValueExpr (e1);
+  t2 = constraintExpr_makeValueExpr (e2);
+
+  /*change this to e1 <= (e2 -1) */
+
+  t2 = constraintExpr_makeDecConstraintExpr (t2);
+  
+ return ( constraint_makeEnsuresOpConstraintExpr (t1, t2, sequencePoint, LTE) );
 }
 
 constraint constraint_makeEnsureLessThanEqual (exprNode e1, exprNode e2, fileloc sequencePoint)
@@ -330,7 +446,17 @@ constraint constraint_makeEnsureLessThanEqual (exprNode e1, exprNode e2, fileloc
 
 constraint constraint_makeEnsureGreaterThan (exprNode e1, exprNode e2, fileloc sequencePoint)
 {
- return ( constraint_makeEnsuresOp (e1, e2, sequencePoint, GT) );
+  constraintExpr t1, t2;
+
+  t1 = constraintExpr_makeValueExpr (e1);
+  t2 = constraintExpr_makeValueExpr (e2);
+
+
+  /* change this to e1 >= (e2 + 1) */
+  t2 = constraintExpr_makeIncConstraintExpr (t2);
+  
+  
+ return ( constraint_makeEnsuresOpConstraintExpr (t1, t2, sequencePoint, GTE) );
 }
 
 constraint constraint_makeEnsureGreaterThanEqual (exprNode e1, exprNode e2, fileloc sequencePoint)
@@ -400,7 +526,7 @@ constraint constraint_makeMaxSetSideEffectPostIncrement (exprNode e, fileloc seq
 // }
 
 
-cstring arithType_print (arithType ar)
+cstring arithType_print (arithType ar) /*@*/
 {
   cstring st = cstring_undefined;
   switch (ar)
@@ -436,16 +562,24 @@ cstring arithType_print (arithType ar)
 void constraint_printError (constraint c, fileloc loc)
 {
   cstring string;
-
+  fileloc errorLoc;
+  
   string = constraint_printDetailed (c);
+
+  errorLoc = loc;
+
+  if (constraint_getFileloc(c) )
+    /*@-branchstate@*/
+      errorLoc = constraint_getFileloc(c);
+  /*@=branchstate@*/
   
   if (c->post)
     {
-       voptgenerror (FLG_FUNCTIONPOST, string, loc);
+       voptgenerror (FLG_FUNCTIONPOST, string, errorLoc);
     }
   else
     {
-      voptgenerror (FLG_FUNCTIONCONSTRAINT, string, loc);
+      voptgenerror (FLG_FUNCTIONCONSTRAINT, string, errorLoc);
     }
       
 }
@@ -457,7 +591,7 @@ cstring  constraint_printDetailed (constraint c)
 
   if (!c->post)
     {
-    if (c->orig)  
+    if (c->orig != NULL)  
       st = message ("Unresolved constraint:\nLclint is unable to resolve %s needed to satisfy %s", constraint_print (c), constraint_print(c->orig) );
     else
       st = message ("Unresolved constraint:\nLclint is unable to resolve %s", constraint_print (c));
@@ -465,11 +599,27 @@ cstring  constraint_printDetailed (constraint c)
     }
   else
     {
-      if (c->orig)
+      if (c->orig != NULL)
        st = message ("Block Post condition:\nThis function block has the post condition %s\n based on %s", constraint_print (c), constraint_print(c->orig) );
       else
        st = message ("Block Post condition:\nThis function block has the post condition %s", constraint_print (c));    
     }
+
+  if (context_getFlag (FLG_CONSTRAINTLOCATION) )
+    {
+      cstring temp;
+      // llassert (c->generatingExpr);
+      temp = message ("\nOriginal Generating expression %s: %s\n", fileloc_unparse( exprNode_getfileloc (c->generatingExpr) ),
+                     exprNode_unparse(c->generatingExpr) );
+      st = cstring_concat (st, temp);
+
+      if (constraint_hasMaxSet(c) )
+       {
+         cstring temp2;
+         temp2 = message ("\nHas MaxSet\n");
+         st = cstring_concat (st, temp2);
+       }
+    }
   return st;
 }
 
@@ -477,7 +627,7 @@ cstring  constraint_print (constraint c) /*@*/
 {
   cstring st = cstring_undefined;
   cstring type = cstring_undefined;
-  llassert (c);
+  llassert (c !=NULL);
   if (c->post)
     {
       type = cstring_makeLiteral ("Ensures: ");
@@ -495,7 +645,30 @@ cstring  constraint_print (constraint c) /*@*/
   return st;
 }
 
-constraint constraint_doSRefFixBaseParam (constraint precondition,
+cstring  constraint_printOr (constraint c) /*@*/
+{
+  cstring ret;
+  constraint temp;
+
+  ret = cstring_undefined;
+  temp = c;
+
+  ret = cstring_concat (ret, constraint_print(temp) );
+
+  temp = temp->or;
+  
+  while (temp)
+    {
+      ret = cstring_concat (ret, cstring_makeLiteral (" OR ") );
+      ret = cstring_concat (ret, constraint_print(temp) );
+      temp = temp->or;
+    }
+
+  return ret;
+
+}
+
+/*@only@*/ constraint constraint_doSRefFixBaseParam (/*@returned@*/ /*@only@*/ constraint precondition,
                                                   exprNodeList arglist)
 {
   precondition->lexpr = constraintExpr_doSRefFixBaseParam (precondition->lexpr,
@@ -540,7 +713,7 @@ constraint constraint_doSRefFixConstraintParam (constraint precondition,
 //   return FALSE;
 // }
 
-constraint constraint_preserveOrig (constraint c)
+/*@only@*/ constraint constraint_preserveOrig (/*@returned@*/ /*@only@*/ constraint c) /*@modifies c @*/
 {
   c->orig = constraint_copy (c);
   return c;
This page took 0.048504 seconds and 4 git commands to generate.