+/*
+** 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"
constraintList ret;
constraintList temp;
- //ret = constraintList_makeNew();
-
llassert(constraintList_isDefined(list1) );
llassert(constraintList_isDefined(list2) );
return temp;
- //ret = constraintList_addList (ret, list2);
- //return ret;
}
else
{
llassert(exprNode_isError(child2) );
- //parent->requiresConstraints = constraintList_makeNew();
- //parent->ensuresConstraints = constraintList_makeNew();
return;
}
}
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) )
{
{
c = c->or;
}
+
c->or = constraint_copy(orConstr);
DPRINTF((message("constraint_addor: returning %s",constraint_printOr(orig) ) ));
{
constraint temp;
+ int numberOr;
+
+ numberOr = 0;
DPRINTF(( message("resolveOr: constraint %s and list %s", constraint_printOr(c), constraintList_print(list) ) ));
temp = c;
if (constraintList_resolve (temp, list) )
return TRUE;
temp = temp->or;
+ numberOr++;
+ llassert(numberOr <= 10);
}
while (constraint_isDefined(temp));
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;
{
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;
curr->or = NULL;
curr = doResolve (curr, post1, resolved);
+
if (*resolved)
{
/* curr is null so we don't try to free it*/
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)
{
}
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;
}
}
+ /* 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;
}
-//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;
case LT:
case LTE:
- // llassert(FALSE);
if ( (ar2 == LT) || (ar2 == LTE) || (ar2 == EQ) )
return TRUE;
break;
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;
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 ) )
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;
));
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))
{
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",
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",
{
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)
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);
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);
/*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;
}