]> andersk Git - splint.git/blobdiff - src/constraintResolve.c
Added a comment with standard header giving copyright information.
[splint.git] / src / constraintResolve.c
index 5a70dacae4220f8b5ea9cb1e860bcdcc3d621f4d..5eb743abee1dcd75929828e5f57b4760f0b4e10b 100644 (file)
@@ -1,9 +1,33 @@
+/*
+** LCLint - annotation-assisted static program checker
+** Copyright (C) 1994-2001 University of Virginia,
+**         Massachusetts Institute of Technology
+**
+** This program is free software; you can redistribute it and/or modify it
+** under the terms of the GNU General Public License as published by the
+** Free Software Foundation; either version 2 of the License, or (at your
+** option) any later version.
+** 
+** This program is distributed in the hope that it will be useful, but
+** WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+** General Public License for more details.
+** 
+** The GNU General Public License is available from http://www.gnu.org/ or
+** 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
+*/
+
 /*
 *
 ** constraintResolve.c
 */
 
-//#define DEBUGPRINT 1
+/* #define DEBUGPRINT 1 */
 
 # include <ctype.h> /* for isdigit */
 # include "lclintMacros.nf"
@@ -56,8 +80,6 @@ static /*@only@*/ constraintList reflectChangesEnsuresFree1 (/*@only@*/ constrai
   constraintList ret;
   constraintList temp;
 
-  //ret = constraintList_makeNew();
-
   llassert(constraintList_isDefined(list1) );
   llassert(constraintList_isDefined(list2) );
 
@@ -82,8 +104,6 @@ static /*@only@*/ constraintList reflectChangesEnsuresFree1 (/*@only@*/ constrai
   
 
   return temp;
-  //ret = constraintList_addList (ret, list2);
-  //return ret;
 }
 
 
@@ -150,8 +170,6 @@ void exprNode_mergeResolve (exprNode parent, exprNode child1, exprNode child2)
        else
         {
           llassert(exprNode_isError(child2) );
-          //parent->requiresConstraints = constraintList_makeNew();
-          //parent->ensuresConstraints = constraintList_makeNew();
           return;
         }
      }
@@ -262,13 +280,11 @@ static /*@only@*/ constraintList reflectChangesNoOr (/*@observer@*/ /*@temp@*/ c
          temp = constraint_substitute (el, post1);
          if (!constraintList_resolve (temp, post1) )
            {
-             // try inequality substitution
-             //constraint temp2;
-             
-             // the inequality substitution may cause us to lose information
-             //so we don't want to store the result but we do it anyway
+             /* try inequality substitution
+                the inequality substitution may cause us to lose information
+                so we don't want to store the result but we do it anyway
+             */
              temp2 = constraint_copy (temp);
-             //                  if (context_getFlag (FLG_ORCONSTRAINT) )
              temp2 = inequalitySubstitute (temp2, post1); 
              if (!constraintList_resolve (temp2, post1) )
                {
@@ -316,6 +332,7 @@ static constraint constraint_addOr (/*@returned@*/ constraint orig, /*@observer@
     {
       c = c->or;
     }
+  
   c->or = constraint_copy(orConstr);
 
   DPRINTF((message("constraint_addor: returning %s",constraint_printOr(orig) ) ));
@@ -328,6 +345,9 @@ static bool resolveOr ( /*@temp@*/ constraint c, /*@observer@*/ /*@temp@*/ const
 {
   constraint temp;
 
+  int numberOr;
+
+  numberOr = 0;
   DPRINTF(( message("resolveOr: constraint %s and list %s", constraint_printOr(c), constraintList_print(list) ) ));
   temp = c;
 
@@ -336,6 +356,8 @@ static bool resolveOr ( /*@temp@*/ constraint c, /*@observer@*/ /*@temp@*/ const
       if (constraintList_resolve (temp, list) )
        return TRUE;
       temp = temp->or;
+      numberOr++;
+      llassert(numberOr <= 10);
     }
   while (constraint_isDefined(temp));
 
@@ -347,79 +369,94 @@ static bool resolveOr ( /*@temp@*/ constraint c, /*@observer@*/ /*@temp@*/ const
 static /*@only@*/ constraint doResolve (/*@only@*/ constraint c, constraintList post1, bool * resolved)
 {
   constraint temp;
+
+  llassert(constraint_isUndefined (c->or ) );
   
- if (!resolveOr (c, post1) )
+  if (!resolveOr (c, post1) )
+    {
+      
+      temp = constraint_substitute (c, post1);
+      
+      if (!resolveOr (temp, post1) )
        {
-
-         temp = constraint_substitute (c, post1);
+         /* try inequality substitution */
+         constraint temp2;
          
-         if (!resolveOr (temp, post1) )
+         /* the inequality substitution may cause us to lose information
+            so we don't want to store the result but we do  anyway
+         */
+         temp2 = constraint_copy (c);
+         temp2 = inequalitySubstitute (temp2, post1);
+
+         if (!resolveOr (temp2, post1) )
            {
-             // try inequality substitution
-             constraint temp2;
+             constraint temp3;
+             temp3 = constraint_copy(temp2);
              
-             // the inequality substitution may cause us to lose information
-             //so we don't want to store the result but we do  anyway
-             temp2 = constraint_copy (c);
-             //                  if (context_getFlag (FLG_ORCONSTRAINT) )
-             temp2 = inequalitySubstitute (temp2, post1);
-             if (!resolveOr (temp2, post1) )
+             temp3 = inequalitySubstituteStrong (temp3, post1);
+             if (!resolveOr (temp3, post1) )
                {
-                 constraint temp3;
-                 temp3 = constraint_copy(temp2);
-                 
-                 temp3 = inequalitySubstituteStrong (temp3, post1);
-                 if (!resolveOr (temp3, post1) )
-                   {
-                     temp2 = inequalitySubstituteUnsound (temp2, post1); 
-                     if (!resolveOr (temp2, post1) )
-                       {
-                         if (!constraint_same (temp, temp2) )
-                           temp = constraint_addOr (temp, temp2);
-
-                         if (!constraint_same (temp, temp3) && !constraint_same (temp3, temp2) )
-                           temp = constraint_addOr (temp, temp3);
-                         
-                         *resolved = FALSE;
-                         
-                         constraint_free(temp2);
-                         constraint_free(temp3);
-                         constraint_free(c);
-                         
-                         return temp;
-                       }
-                     constraint_free(temp2);
-                     constraint_free(temp3);
-                   }
-                 else
+                 temp2 = inequalitySubstituteUnsound (temp2, post1); 
+                 if (!resolveOr (temp2, post1) )
                    {
+                     if (!constraint_same (temp, temp2) )
+                       temp = constraint_addOr (temp, temp2);
+                     
+                     if (!constraint_same (temp, temp3) && !constraint_same (temp3, temp2) )
+                       temp = constraint_addOr (temp, temp3);
+                     
+                     *resolved = FALSE;
+                     
                      constraint_free(temp2);
                      constraint_free(temp3);
+                     constraint_free(c);
+                     
+                     return temp;
                    }
+                 constraint_free(temp2);
+                 constraint_free(temp3);
                }
              else
                {
                  constraint_free(temp2);
-               }                 
-
+                 constraint_free(temp3);
+               }
            }
-         constraint_free(temp);
+         else
+           {
+             constraint_free(temp2);
+           }             
+         
        }
- constraint_free(c);
- *resolved = TRUE;
- return NULL;
-
+      constraint_free(temp);
+    }
+  constraint_free(c);
+  
+  *resolved = TRUE;
+  return NULL;
 }
 
-static /*@only@*/ constraint doResolveOr (constraint c, constraintList post1, /*@out@*/bool * resolved)
+static /*@only@*/ constraint doResolveOr (/*@observer@*/ /*@temp@*/ constraint c, constraintList post1, /*@out@*/bool * resolved)
 {
   constraint ret;
   constraint next;
   constraint curr;
+
+  
+  DPRINTF(( message("doResolveOr: constraint %s and list %s", constraint_printOr(c), constraintList_print(post1) ) ));
+
+
   
   *resolved = FALSE;
+
+
   ret = constraint_copy(c);
+
+  if (constraintList_isEmpty(post1) )
+    {
+      return ret;
+    }
+  
   next = ret->or;
   ret->or = NULL;
 
@@ -429,13 +466,13 @@ static /*@only@*/ constraint doResolveOr (constraint c, constraintList post1, /*
     {
       if (next != NULL)
        constraint_free(next);
-
+      
       /*we don't need to free ret when resolved is false because ret is null*/
       llassert(ret == NULL);
       
-       return NULL;
+      return NULL;
     }
-
+  
   while (next != NULL)
     {
       curr = next;
@@ -443,6 +480,7 @@ static /*@only@*/ constraint doResolveOr (constraint c, constraintList post1, /*
       curr->or = NULL;
 
       curr = doResolve (curr, post1, resolved);
+      
       if (*resolved)
        {
          /* curr is null so we don't try to free it*/
@@ -457,14 +495,9 @@ static /*@only@*/ constraint doResolveOr (constraint c, constraintList post1, /*
       ret = constraint_addOr (ret, curr);
       constraint_free(curr);
     }
-
   return ret;
 }
 
-
-
-
-
 /* tries to resolve constraints in list pr2 using post1 */
 /*@only@*/ constraintList constraintList_reflectChangesOr (constraintList pre2, constraintList post1)
 {
@@ -484,15 +517,17 @@ static /*@only@*/ constraint doResolveOr (constraint c, constraintList post1, /*
        }
       else
        {
-     /*we don't need to free ret when resolved is false because ret is null*/
+     /* we don't need to free temp when
+       resolved is false because temp is null */
          llassert(temp == NULL);
        }
       
     } end_constraintList_elements;
 
-    DPRINTF((message ("constraintList_reflectChangesOr: returning %s", constraintList_print(ret) ) ) );
+  DPRINTF((message ("constraintList_reflectChangesOr: returning %s", constraintList_print(ret) ) ) );
     return ret;
 }
+
 static /*@only@*/ constraintList reflectChangesEnsures (/*@observer@*/ constraintList pre2, constraintList post1)
 {  
   constraintList ret;
@@ -545,6 +580,36 @@ static bool constraint_conflict (constraint c1, constraint c2)
          }
     }  
 
+  /* This is a slight kludg to prevent circular constraints like
+     strlen(str) == maxRead(s) + strlen(str);
+  */
+
+  /*@i324234*/ /* clean this up */
+  
+  if (c1->ar == EQ)
+    if (c1->ar == c2->ar)
+      {
+       if (constraintExpr_search (c1->lexpr, c2->expr) )
+         if (constraintExpr_isTerm(c1->lexpr) )
+           {
+             constraintTerm term;
+             
+             term = constraintExpr_getTerm(c1->lexpr);
+
+             if (constraintTerm_isExprNode(term) )
+               {
+                 DPRINTF ( (message ("%s conflicts with %s ", constraint_print (c1), constraint_print(c2) ) ) );
+                 return TRUE;
+               }
+           }
+      }
+
+  if (constraint_tooDeep(c1) || constraint_tooDeep(c2) )
+       {
+         DPRINTF ( (message ("%s conflicts with %s (constraint is too deep", constraint_print (c1), constraint_print(c2) ) ) );
+         return TRUE;
+       }
+  
   DPRINTF ( (message ("%s doesn't conflict with %s ", constraint_print (c1), constraint_print(c2) ) ) );
 
   return FALSE; 
@@ -578,8 +643,11 @@ static bool conflict (constraint c, constraintList list)
 
 }
 
-//check if constraint in list1 conflicts with constraints in List2.  If so we
-//remove form list1 and change list2.
+/*
+  check if constraint in list1 conflicts with constraints in List2.  If so we
+  remove form list1 and change list2.
+*/
+
 constraintList constraintList_fixConflicts (constraintList list1, constraintList list2)
 {
   constraintList ret;
@@ -653,7 +721,6 @@ static bool arithType_canResolve (arithType ar1, arithType ar2)
 
     case LT:
     case LTE:
-      //      llassert(FALSE); 
       if ( (ar2 == LT) || (ar2 == LTE) || (ar2 == EQ) )
        return TRUE;
       break;
@@ -668,8 +735,8 @@ static bool arithType_canResolve (arithType ar1, arithType ar2)
 bool constraint_isAlwaysTrue (/*@observer@*/ /*@temp@*/ constraint c)
 {
   constraintExpr l, r;
-  bool /*@unused@*/ lHasConstant, rHasConstant;
-  int /*@unused@*/ lConstant, rConstant;
+  bool rHasConstant;
+  int rConstant;
   
   l = c->lexpr;
   r = c->expr;
@@ -722,7 +789,6 @@ bool constraint_isAlwaysTrue (/*@observer@*/ /*@temp@*/ constraint c)
   l = constraintExpr_copy (c->lexpr);
   r = constraintExpr_copy (c->expr);
 
-  //  l = constraintExpr_propagateConstants (l, &lHasConstant, &lConstant);
   r = constraintExpr_propagateConstants (r, &rHasConstant, &rConstant);
 
   if (constraintExpr_similar (l,r) && (rHasConstant ) )
@@ -896,7 +962,7 @@ bool constraint_search (constraint c, constraintExpr old) /*@*/
   return ret;
 }
 
-//adjust file locs and stuff
+/* adjust file locs and stuff */
 static constraint constraint_adjust (/*@returned@*/ constraint substitute, /*@observer@*/ constraint old)
 {
   fileloc loc1, loc2, loc3;
@@ -906,13 +972,10 @@ static constraint constraint_adjust (/*@returned@*/ constraint substitute, /*@ob
                   ));
 
   loc1 = constraint_getFileloc (old);
-
   loc2 = constraintExpr_getFileloc (substitute->lexpr);
-
   loc3 = constraintExpr_getFileloc (substitute->expr);
-
   
-  // special case of an equality that "contains itself"
+  /* special case of an equality that "contains itself" */
   if (constraintExpr_search (substitute->expr, substitute->lexpr) )
       if (fileloc_closer (loc1, loc3, loc2))
       {
@@ -948,17 +1011,12 @@ constraint  inequalitySubstitute  (/*@returned@*/ constraint c, constraintList p
   constraintList_elements (p, el)
     {
       if ( (el->ar == LT )  )
-        //      if (!constraint_conflict (c, el) )
+       /* if (!constraint_conflict (c, el) ) */ /*@i523 explain this! */
           {
-            //constraint temp;
             constraintExpr  temp2;
             
             /*@i22*/
 
-            //temp = constraint_copy(el);
-            
-            //      temp = constraint_adjust(temp, c);
-
             if (constraintExpr_same (el->expr, c->expr) )
               {
                 DPRINTF((message ("inequalitySubstitute Replacing %q in %q with  %q",
@@ -1005,17 +1063,12 @@ static constraint  inequalitySubstituteStrong  (/*@returned@*/ constraint c, con
       DPRINTF (( message ("inequalitySubstituteStrong examining substituting %s on %s", constraint_print(el), constraint_print(c) ) ));      
 
       if ( (el->ar == LT ) ||  (el->ar == LTE )  )
-        //      if (!constraint_conflict (c, el) )
+       /* if (!constraint_conflict (c, el) ) */ /*@i523@*/
           {
-            //constraint temp;
             constraintExpr  temp2;
             
             /*@i22*/
 
-            //temp = constraint_copy(el);
-            
-            //      temp = constraint_adjust(temp, c);
-
             if (constraintExpr_same (el->lexpr, c->expr) )
               {
                 DPRINTF((message ("inequalitySubstitute Replacing %s in %s with  %s",
@@ -1062,14 +1115,10 @@ static constraint  inequalitySubstituteUnsound  (/*@returned@*/ constraint c, co
     {
   DPRINTF (( message ("inequalitySubstituteUnsound examining substituting %s on %s", constraint_print(el), constraint_print(c) ) ));      
        if ( ( el->ar == LTE) || (el->ar == LT) )
-        //      if (!constraint_conflict (c, el) )
+        /* if (!constraint_conflict (c, el) ) */ /*@i532@*/
           {
-            // constraint temp;
             constraintExpr  temp2;
-            
-            //temp = constraint_copy(el);
-            
-            //      temp = constraint_adjust(temp, c);
+
             temp2   = constraintExpr_copy (el->expr);
             
             if (el->ar == LT)
@@ -1148,7 +1197,7 @@ return ret;
   constraintList_elements(target, el)
   { 
     constraint temp;
-    //drl possible problem : warning make sure that a side effect is not expected
+    /* drl possible problem : warning make sure that a side effect is not expected */
 
     temp = constraint_substitute(el, subList);
     ret = constraintList_add (ret, temp);
@@ -1202,6 +1251,16 @@ static constraint  constraint_swapLeftRight (/*@returned@*/ constraint c)
 
 constraint constraint_simplify ( /*@returned@*/ constraint c)
 {
+
+  DPRINTF(( message("constraint_simplify on %q ", constraint_print(c) ) ));
+
+  if (constraint_tooDeep(c))
+    {
+        DPRINTF(( message("constraint_simplify: constraint to complex aborting %q ", constraint_print(c) ) ));
+      return c;
+
+    }
+  
   c->lexpr = constraintExpr_simplify (c->lexpr);
   c->expr  = constraintExpr_simplify (c->expr);
 
@@ -1219,6 +1278,9 @@ constraint constraint_simplify ( /*@returned@*/ constraint c)
       /*I don't think this will be an infinate loop*/
       c = constraint_simplify(c);
     }
+
+  DPRINTF(( message("constraint_simplify returning  %q ", constraint_print(c) ) ));
+
   return c;
 }
 
This page took 0.08201 seconds and 4 git commands to generate.