8 # include <ctype.h> /* for isdigit */
9 # include "lclintMacros.nf"
11 # include "cgrammar.h"
12 # include "cgrammar_tokens.h"
14 # include "exprChecks.h"
15 # include "aliasChecks.h"
16 # include "exprNodeSList.h"
17 //# include "exprData.i"
20 /*@access constraint, exprNode @*/
22 static bool rangeCheck (arithType ar1, /*@observer@*/ constraintExpr expr1, arithType ar2, /*@observer@*/ constraintExpr expr2);
24 static constraint inequalitySubstituteUnsound (/*@returned@*/ constraint c, constraintList p);
26 static constraint constraint_searchandreplace (/*@returned@*/ constraint c, constraintExpr old, constraintExpr new);
29 static constraint constraint_addOr (/*@returned@*/ constraint orig, /*@observer@*/ constraint or);
31 static bool resolveOr (/*@observer@*/ constraint c, /*@observer@*/ constraintList list);
33 static /*@only@*/ constraintList reflectChangesEnsuresFree1 (/*@only@*/ constraintList pre2, constraintList post1);
35 /*********************************************/
40 /*@only@*/ constraintList constraintList_mergeEnsuresFreeFirst (constraintList list1, constraintList list2)
44 ret = constraintList_mergeEnsures (list1, list2);
46 constraintList_free(list1);
50 /*@only@*/ constraintList constraintList_mergeEnsures (constraintList list1, constraintList list2)
55 //ret = constraintList_makeNew();
57 llassert(constraintList_isDefined(list1) );
58 llassert(constraintList_isDefined(list2) );
60 DPRINTF(( message ("constraintList_mergeEnsures: list1 %s list2 %s",
61 constraintList_print(list1), constraintList_print(list2)
64 ret = constraintList_fixConflicts (list1, list2);
65 ret = reflectChangesEnsuresFree1 (ret, list2);
66 temp = constraintList_subsumeEnsures (ret, list2);
67 constraintList_free(ret);
70 temp = constraintList_subsumeEnsures (list2, ret);
72 temp = constraintList_addList (temp, ret);
74 DPRINTF(( message ("constraintList_mergeEnsures: returning %s ",
75 constraintList_print(temp) )
80 //ret = constraintList_addList (ret, list2);
85 /*@only@*/ constraintList constraintList_mergeRequiresFreeFirst (/*@only@*/ constraintList list1, constraintList list2)
89 ret = constraintList_mergeRequires(list1, list2);
91 constraintList_free(list1);
96 /*@only@*/ constraintList constraintList_mergeRequires (constraintList list1, constraintList list2)
101 DPRINTF((message ("constraintList_mergeRequires: merging %s and %s ", constraintList_print (list1), constraintList_print(list2) ) ) );
103 /* get constraints in list1 not satified by list2 */
104 temp = reflectChanges (list1, list2);
105 DPRINTF((message ("constraintList_mergeRequires: temp = %s", constraintList_print(temp) ) ) );
107 /*get constraints in list2 not satified by temp*/
108 ret = reflectChanges (list2, temp);
110 DPRINTF((message ("constraintList_mergeRequires: ret = %s", constraintList_print(ret) ) ) );
112 ret = constraintList_addList (ret, temp);
114 DPRINTF((message ("constraintList_mergeRequires: returning %s", constraintList_print(ret) ) ) );
119 void checkArgumentList (/*@out@*/ exprNode temp, exprNodeList arglist, fileloc sequencePoint)
121 temp->requiresConstraints = constraintList_makeNew();
122 temp->ensuresConstraints = constraintList_makeNew();
123 temp->trueEnsuresConstraints = constraintList_makeNew();
124 temp->falseEnsuresConstraints = constraintList_makeNew();
126 exprNodeList_elements (arglist, el)
128 constraintList temp2;
129 exprNode_exprTraverse (el, FALSE, FALSE, sequencePoint);
130 temp2 = el->requiresConstraints;
131 el->requiresConstraints = exprNode_traversRequiresConstraints(el);
132 constraintList_free(temp2);
134 temp2 = el->ensuresConstraints;
135 el->ensuresConstraints = exprNode_traversEnsuresConstraints(el);
136 constraintList_free(temp2);
138 temp->requiresConstraints = constraintList_addList(temp->requiresConstraints,
139 el->requiresConstraints);
141 temp->ensuresConstraints = constraintList_addList(temp->ensuresConstraints,
142 el->ensuresConstraints);
144 end_exprNodeList_elements;
148 constraintList checkCall (exprNode fcn, exprNodeList arglist)
150 constraintList preconditions;
152 DPRINTF ( (message ("Got call that %s ( %s) ", exprNode_unparse(fcn), exprNodeList_unparse (arglist ) ) ) );
154 temp = exprNode_getUentry (fcn);
156 preconditions = uentry_getFcnPreconditions (temp);
158 if (preconditions != constraintList_undefined)
160 preconditions= constraintList_togglePost (preconditions);
161 preconditions = constraintList_doSRefFixConstraintParam (preconditions, arglist);
165 if (preconditions == NULL)
166 preconditions = constraintList_makeNew();
169 return preconditions;
172 constraintList getPostConditions (exprNode fcn, exprNodeList arglist, exprNode fcnCall)
174 constraintList postconditions;
176 DPRINTF ( (message ("Got call that %s ( %s) ", exprNode_unparse(fcn), exprNodeList_unparse (arglist ) ) ) );
178 temp = exprNode_getUentry (fcn);
180 postconditions = uentry_getFcnPostconditions (temp);
182 if (postconditions != constraintList_undefined)
184 postconditions = constraintList_doFixResult (postconditions, fcnCall);
185 postconditions = constraintList_doSRefFixConstraintParam (postconditions, arglist);
189 postconditions = constraintList_makeNew();
192 return postconditions;
195 void mergeResolve (exprNode parent, exprNode child1, exprNode child2)
197 constraintList temp, temp2;
199 DPRINTF( (message ("magically merging constraint into parent:%s for", exprNode_unparse (parent) )) );
201 DPRINTF( (message (" children: %s and %s", exprNode_unparse (child1), exprNode_unparse(child2) ) ) );
203 if (exprNode_isError (child1) || exprNode_isError(child2) )
205 if (exprNode_isError (child1) && !exprNode_isError(child2) )
207 constraintList_free(parent->requiresConstraints);
209 parent->requiresConstraints = constraintList_copy (child2->requiresConstraints);
210 constraintList_free(parent->ensuresConstraints);
212 parent->ensuresConstraints = constraintList_copy (child2->ensuresConstraints);
213 DPRINTF((message ("Copied child constraints: pre: %s and post: %s",
214 constraintList_print( child2->requiresConstraints),
215 constraintList_print (child2->ensuresConstraints)
222 llassert(exprNode_isError(child2) );
223 //parent->requiresConstraints = constraintList_makeNew();
224 //parent->ensuresConstraints = constraintList_makeNew();
229 llassert(!exprNode_isError (child1) && ! exprNode_isError(child2) );
231 DPRINTF( (message ("Child constraints are %s %s and %s %s",
232 constraintList_print (child1->requiresConstraints),
233 constraintList_print (child1->ensuresConstraints),
234 constraintList_print (child2->requiresConstraints),
235 constraintList_print (child2->ensuresConstraints)
239 constraintList_free(parent->requiresConstraints);
241 parent->requiresConstraints = constraintList_copy (child1->requiresConstraints);
243 if ( context_getFlag (FLG_ORCONSTRAINT) )
244 temp = reflectChangesOr (child2->requiresConstraints, child1->ensuresConstraints);
246 temp = reflectChanges (child2->requiresConstraints, child1->ensuresConstraints);
248 temp2 = constraintList_mergeRequires (parent->requiresConstraints, temp);
249 constraintList_free(parent->requiresConstraints);
250 constraintList_free(temp);
252 parent->requiresConstraints = temp2;
254 DPRINTF( (message ("Parent requires constraints are %s ",
255 constraintList_print (parent->requiresConstraints)
258 constraintList_free(parent->ensuresConstraints);
260 parent->ensuresConstraints = constraintList_mergeEnsures(child1->ensuresConstraints,
261 child2->ensuresConstraints);
264 DPRINTF( (message ("Parent constraints are %s and %s ",
265 constraintList_print (parent->requiresConstraints),
266 constraintList_print (parent->ensuresConstraints)
274 /*@only@*/ constraintList constraintList_subsumeEnsures (constraintList list1, constraintList list2)
277 ret = constraintList_makeNew();
278 constraintList_elements (list1, el)
281 DPRINTF ((message ("Examining %s", constraint_print (el) ) ) );
282 if (!resolve (el, list2) )
285 temp = constraint_copy(el);
286 ret = constraintList_add (ret, temp);
290 DPRINTF ( (message ("Subsuming %s", constraint_print (el) ) ) );
292 } end_constraintList_elements;
299 /* tries to resolve constraints in list pre2 using post1 */
300 /*@only@*/ constraintList reflectChangesFreePre (/*@only@*/ constraintList pre2, /*@observer@*/ constraintList post1)
304 ret = reflectChanges (pre2, post1);
306 constraintList_free (pre2);
312 /* tries to resolve constraints in list pre2 using post1 */
313 /*@only@*/ constraintList reflectChanges (/*@observer@*/ constraintList pre2, /*@observer@*/ constraintList post1)
320 ret = constraintList_makeNew();
321 DPRINTF((message ("reflectChanges: lists %s and %s", constraintList_print(pre2), constraintList_print(post1) )));
323 constraintList_elements (pre2, el)
325 if (!resolve (el, post1) )
327 temp = substitute (el, post1);
328 if (!resolve (temp, post1) )
330 // try inequality substitution
333 // the inequality substitution may cause us to lose information
334 //so we don't want to store the result but we do it anyway
335 temp2 = constraint_copy (temp);
336 // if (context_getFlag (FLG_ORCONSTRAINT) )
337 temp2 = inequalitySubstitute (temp2, post1);
338 if (!resolve (temp2, post1) )
340 temp2 = inequalitySubstituteUnsound (temp2, post1);
341 if (!resolve (temp2, post1) )
342 ret = constraintList_add (ret, temp2);
345 constraint_free(temp);
347 } end_constraintList_elements;
349 DPRINTF((message ("reflectChanges: returning %s", constraintList_print(ret) ) ) );
354 static constraint constraint_addOr (/*@returned@*/ constraint orig, /*@observer@*/ constraint or)
359 DPRINTF((message("constraint_addor: oring %s onto %s", constraint_printOr(or), constraint_printOr(orig) ) ));
361 while (c->or != NULL)
365 c->or = constraint_copy(or);
367 DPRINTF((message("constraint_addor: returning %s",constraint_printOr(orig) ) ));
373 static bool resolveOr (/*@observer@*/ constraint c, /*@observer@*/ constraintList list)
377 DPRINTF(( message("resolveOr: constraint %s and list %s", constraint_printOr(c), constraintList_print(list) ) ));
382 if (resolve (temp, list) )
386 while (constraint_isDefined(temp));
391 /*This is a "helper" function for doResolveOr */
393 static /*@only@*/ constraint doResolve (/*@only@*/ constraint c, constraintList post1, bool * resolved)
397 if (!resolveOr (c, post1) )
400 temp = substitute (c, post1);
402 if (!resolveOr (temp, post1) )
404 // try inequality substitution
407 // the inequality substitution may cause us to lose information
408 //so we don't want to store the result but we do it anyway
409 temp2 = constraint_copy (c);
410 // if (context_getFlag (FLG_ORCONSTRAINT) )
411 temp2 = inequalitySubstitute (temp2, post1);
412 if (!resolveOr (temp2, post1) )
414 temp2 = inequalitySubstituteUnsound (temp2, post1);
415 if (!resolveOr (temp2, post1) )
417 if (!constraint_same (temp, temp2) )
418 temp = constraint_addOr (temp, temp2);
421 constraint_free(temp2);
428 constraint_free(temp2);
430 constraint_free(temp);
442 static /*@only@*/ constraint doResolveOr (constraint c, constraintList post1, /*@out@*/bool * resolved)
449 ret = constraint_copy(c);
453 ret = doResolve (ret, post1, resolved);
457 constraint_free(next);
458 constraint_free(ret);
468 curr = doResolve (curr, post1, resolved);
471 constraint_free(curr);
472 constraint_free(next);
473 constraint_free(ret);
476 ret = constraint_addOr (ret, curr);
478 constraint_free(curr);
486 /* tries to resolve constraints in list pr2 using post1 */
487 /*@only@*/ constraintList reflectChangesOr (constraintList pre2, constraintList post1)
492 ret = constraintList_makeNew();
493 DPRINTF((message ("reflectChangesOr: lists %s and %s", constraintList_print(pre2), constraintList_print(post1) )));
495 constraintList_elements (pre2, el)
497 temp = doResolveOr (el, post1, &resolved);
501 ret = constraintList_add(ret, temp);
503 } end_constraintList_elements;
505 DPRINTF((message ("reflectChangesOr: returning %s", constraintList_print(ret) ) ) );
508 static /*@only@*/ constraintList reflectChangesEnsures (/*@observer@*/ constraintList pre2, constraintList post1)
512 ret = constraintList_makeNew();
513 constraintList_elements (pre2, el)
515 if (!resolve (el, post1) )
517 temp = substitute (el, post1);
518 llassert (temp != NULL);
520 if (!resolve (temp, post1) )
521 ret = constraintList_add (ret, temp);
525 DPRINTF ( (message ("Resolved away %s ", constraint_print(el) ) ) );
527 } end_constraintList_elements;
533 static /*@only@*/ constraintList reflectChangesEnsuresFree1 (/*@only@*/ constraintList pre2, constraintList post1)
537 ret = reflectChangesEnsures (pre2, post1);
539 constraintList_free(pre2);
545 static bool constraint_conflict (constraint c1, constraint c2)
548 if (constraintExpr_similar(c1->lexpr, c2->lexpr) )
551 if (c1->ar == c2->ar)
553 DPRINTF ( (message ("%s conflicts with %s ", constraint_print (c1), constraint_print(c2) ) ) );
558 DPRINTF ( (message ("%s doesn't conflict with %s ", constraint_print (c1), constraint_print(c2) ) ) );
564 static void constraint_fixConflict ( constraint good, /*@observer@*/ constraint conflicting) /*@modifies good@*/
566 if (conflicting->ar ==EQ )
568 good->expr = constraintExpr_searchandreplace (good->expr, conflicting->lexpr, conflicting->expr);
569 good = constraint_simplify (good);
575 static bool conflict (constraint c, constraintList list)
578 constraintList_elements (list, el)
580 if ( constraint_conflict(el, c) )
582 constraint_fixConflict (el, c);
585 } end_constraintList_elements;
591 //check if constraint in list1 conflicts with constraints in List2. If so we
592 //remove form list1 and change list2.
593 constraintList constraintList_fixConflicts (constraintList list1, constraintList list2)
596 ret = constraintList_makeNew();
597 llassert(constraintList_isDefined(list1) );
598 constraintList_elements (list1, el)
600 if (! conflict (el, list2) )
603 temp = constraint_copy(el);
604 ret = constraintList_add (ret, temp);
606 } end_constraintList_elements;
611 /*returns true if constraint post satifies cosntriant pre */
612 static bool satifies (constraint pre, constraint post)
614 if (constraint_isAlwaysTrue (pre) )
617 if (!constraintExpr_similar (pre->lexpr, post->lexpr) )
621 if (post->expr == NULL)
627 return rangeCheck (pre->ar, pre->expr, post->ar, post->expr);
631 bool resolve (/*@observer@*/ constraint c, /*@observer@*/ constraintList p)
633 constraintList_elements (p, el)
635 if ( satifies (c, el) )
637 DPRINTF ( (message ("\n%s Satifies %s\n ", constraint_print(el), constraint_print(c) ) ) );
640 DPRINTF ( (message ("\n%s does not satify %s\n ", constraint_print(el), constraint_print(c) ) ) );
642 end_constraintList_elements;
643 DPRINTF ( (message ("no constraints satify %s", constraint_print(c) ) ));
647 static bool arithType_canResolve (arithType ar1, arithType ar2)
653 if ( (ar2 == GT) || (ar2 == GTE) || (ar2 == EQ) )
667 if ( (ar2 == LT) || (ar2 == LTE) || (ar2 == EQ) )
676 /* We look for constraint which are tautologies */
678 bool constraint_isAlwaysTrue (/*@observer@*/ constraint c)
681 bool /*@unused@*/ lHasConstant, rHasConstant;
682 int /*@unused@*/ lConstant, rConstant;
687 DPRINTF(( message("constraint_IsAlwaysTrue:examining %s", constraint_print(c) ) ));
689 if (constraintExpr_canGetValue(l) && constraintExpr_canGetValue(r) )
692 cmp = constraintExpr_compare (l, r);
713 if (constraintExpr_similar (l,r) )
732 l = constraintExpr_copy (c->lexpr);
733 r = constraintExpr_copy (c->expr);
735 // l = constraintExpr_propagateConstants (l, &lHasConstant, &lConstant);
736 r = constraintExpr_propagateConstants (r, &rHasConstant, &rConstant);
738 if (constraintExpr_similar (l,r) && (rHasConstant ) )
740 DPRINTF(( message("constraint_IsAlwaysTrue: after removing constants %s and %s are similar", constraintExpr_unparse(l), constraintExpr_unparse(r) ) ));
741 DPRINTF(( message("constraint_IsAlwaysTrue: rconstant is %d", rConstant ) ));
743 constraintExpr_free(l);
744 constraintExpr_free(r);
749 return (rConstant == 0);
751 return (rConstant > 0);
753 return (rConstant >= 0);
755 return (rConstant <= 0);
757 return (rConstant < 0);
767 constraintExpr_free(l);
768 constraintExpr_free(r);
769 DPRINTF(( message("Constraint %s is not always true", constraint_print(c) ) ));
776 static bool rangeCheck (arithType ar1, /*@observer@*/ constraintExpr expr1, arithType ar2, /*@observer@*/ constraintExpr expr2)
779 DPRINTF ((message ("Doing Range CHECK %s and %s", constraintExpr_unparse(expr1), constraintExpr_unparse(expr2) ) ));
781 if (! arithType_canResolve (ar1, ar2) )
787 if (constraintExpr_similar (expr1, expr2) )
791 if (! (constraintExpr_canGetValue (expr1) &&
792 constraintExpr_canGetValue (expr2) ) )
794 constraintExpr e1, e2;
798 e1 = constraintExpr_copy(expr1);
799 e2 = constraintExpr_copy(expr2);
801 e1 = constraintExpr_propagateConstants (e1, &p1, &const1);
803 e2 = constraintExpr_propagateConstants (e2, &p2, &const2);
806 if (const1 <= const2)
807 if (constraintExpr_similar (e1, e2) )
809 constraintExpr_free(e1);
810 constraintExpr_free(e2);
814 DPRINTF( ("Can't Get value"));
816 constraintExpr_free(e1);
817 constraintExpr_free(e2);
821 if (constraintExpr_compare (expr2, expr1) >= 0)
826 if (constraintExpr_similar (expr1, expr2) )
831 if (constraintExpr_similar (expr1, expr2) )
835 if (! (constraintExpr_canGetValue (expr1) &&
836 constraintExpr_canGetValue (expr2) ) )
838 constraintExpr e1, e2;
842 e1 = constraintExpr_copy(expr1);
843 e2 = constraintExpr_copy(expr2);
845 e1 = constraintExpr_propagateConstants (e1, &p1, &const1);
847 e2 = constraintExpr_propagateConstants (e2, &p2, &const2);
850 if (const1 >= const2)
851 if (constraintExpr_similar (e1, e2) )
853 constraintExpr_free(e1);
854 constraintExpr_free(e2);
857 constraintExpr_free(e1);
858 constraintExpr_free(e2);
860 DPRINTF( ("Can't Get value"));
864 if (constraintExpr_compare (expr2, expr1) <= 0)
870 llcontbug((message("Unhandled case in switch: %q", arithType_print(ar1) ) ) );
876 static constraint constraint_searchandreplace (/*@returned@*/ constraint c, constraintExpr old, constraintExpr new)
878 DPRINTF (("Doing replace for lexpr") );
879 c->lexpr = constraintExpr_searchandreplace (c->lexpr, old, new);
880 DPRINTF (("Doing replace for expr") );
881 c->expr = constraintExpr_searchandreplace (c->expr, old, new);
885 bool constraint_search (constraint c, constraintExpr old) /*@*/
890 ret = constraintExpr_search (c->lexpr, old);
891 ret = ret || constraintExpr_search (c->expr, old);
895 //adjust file locs and stuff
896 static constraint constraint_adjust (/*@returned@*/ constraint substitute, /*@observer@*/ constraint old)
898 fileloc loc1, loc2, loc3;
900 DPRINTF ( (message("Start adjust on %s and %s", constraint_print(substitute),
901 constraint_print(old))
904 loc1 = constraint_getFileloc (old);
906 loc2 = constraintExpr_getFileloc (substitute->lexpr);
908 loc3 = constraintExpr_getFileloc (substitute->expr);
911 // special case of an equality that "contains itself"
912 if (constraintExpr_search (substitute->expr, substitute->lexpr) )
913 if (fileloc_closer (loc1, loc3, loc2))
916 DPRINTF ( (message("Doing adjust on %s", constraint_print(substitute) )
918 temp = substitute->lexpr;
919 substitute->lexpr = substitute->expr;
920 substitute->expr = temp;
921 substitute = constraint_simplify(substitute);
932 /* If function preforms substitutes based on inequality
934 It uses the rule x >= y && b < y ===> x >= b + 1
936 Warning this is sound but throws out information
938 constraint inequalitySubstitute (/*@returned@*/ constraint c, constraintList p)
943 constraintList_elements (p, el)
946 // if (!constraint_conflict (c, el) )
949 constraintExpr temp2;
953 //temp = constraint_copy(el);
955 // temp = constraint_adjust(temp, c);
957 if (constraintExpr_same (el->expr, c->expr) )
959 DPRINTF((message ("inequalitySubstitute Replacing %s in %s with %s",
960 constraintExpr_print (c->expr),
961 constraint_print (c),
962 constraintExpr_print (el->expr) )
964 temp2 = constraintExpr_copy (el->lexpr);
965 constraintExpr_free(c->expr);
966 c->expr = constraintExpr_makeIncConstraintExpr (temp2);
971 end_constraintList_elements;
973 c = constraint_simplify(c);
977 /* This function performs substitutions based on the rule:
978 for a constraint of the form expr1 >= expr2; a < b =>
979 a = b -1 for all a in expr1. This will work in most cases.
981 Like inequalitySubstitute we're throwing away some information
984 static constraint inequalitySubstituteUnsound (/*@returned@*/ constraint c, constraintList p)
986 DPRINTF (( message ("Doing inequalitySubstituteUnsound " ) ));
991 constraintList_elements (p, el)
993 DPRINTF (( message ("inequalitySubstituteUnsound examining substituting %s on %s", constraint_print(el), constraint_print(c) ) ));
994 if ( ( el->ar == LTE) || (el->ar == LT) )
995 // if (!constraint_conflict (c, el) )
998 constraintExpr temp2;
1000 //temp = constraint_copy(el);
1002 // temp = constraint_adjust(temp, c);
1003 temp2 = constraintExpr_copy (el->expr);
1006 temp2 = constraintExpr_makeDecConstraintExpr (temp2);
1008 DPRINTF((message ("Replacing %s in %s with %s",
1009 constraintExpr_print (el->lexpr),
1010 constraintExpr_print (c->lexpr),
1011 constraintExpr_print (temp2) ) ));
1013 c->lexpr = constraintExpr_searchandreplace (c->lexpr, el->lexpr, temp2);
1014 constraintExpr_free(temp2);
1017 end_constraintList_elements;
1019 c = constraint_simplify(c);
1023 /*@only@*/ constraint substitute (/*@observer@*/ constraint c, constraintList p)
1027 ret = constraint_copy(c);
1028 constraintList_elements (p, el)
1031 if (!constraint_conflict (ret, el) )
1036 temp = constraint_copy(el);
1038 temp = constraint_adjust(temp, ret);
1040 DPRINTF((message ("Substituting %s in the constraint %s",
1041 constraint_print (temp), constraint_print (ret)
1045 ret = constraint_searchandreplace (ret, temp->lexpr, temp->expr);
1046 DPRINTF(( message ("The new constraint is %s", constraint_print (ret) ) ));
1047 constraint_free(temp);
1050 end_constraintList_elements;
1051 DPRINTF(( message ("The finial new constraint is %s", constraint_print (ret) ) ));
1053 ret = constraint_simplify(ret);
1058 /*@only@*/ constraintList constraintList_substituteFreeTarget (/*@only@*/ constraintList target, /*@observer@*/ constraintList subList)
1062 ret = constraintList_substitute (target, subList);
1064 constraintList_free(target);
1069 /* we try to do substitutions on each constraint in target using the constraint in sublist*/
1071 /*@only@*/ constraintList constraintList_substitute (constraintList target,/*2observer@*/ constraintList subList)
1076 ret = constraintList_makeNew();
1078 constraintList_elements(target, el)
1081 #warning make sure this side effect is the right things
1082 #warning make sure that a side effect is not expected
1084 temp = substitute(el, subList);
1085 ret = constraintList_add (ret, temp);
1087 end_constraintList_elements;
1092 constraint constraint_solve (constraint c)
1094 DPRINTF( (message ("Solving %s\n", constraint_print(c) ) ) );
1095 c->expr = constraintExpr_solveBinaryExpr (c->lexpr, c->expr);
1096 DPRINTF( (message ("Solved and got %s\n", constraint_print(c) ) ) );
1101 static arithType flipAr (arithType ar)
1116 llcontbug (message("unexpected value: case not handled"));
1121 static constraint constraint_swapLeftRight (/*@returned@*/ constraint c)
1123 constraintExpr temp;
1124 c->ar = flipAr (c->ar);
1128 DPRINTF(("Swaped left and right sides of constraint"));
1134 constraint constraint_simplify ( /*@returned@*/ constraint c)
1136 c->lexpr = constraintExpr_simplify (c->lexpr);
1137 c->expr = constraintExpr_simplify (c->expr);
1139 if (constraintExpr_isBinaryExpr (c->lexpr) )
1141 c = constraint_solve (c);
1143 c->lexpr = constraintExpr_simplify (c->lexpr);
1144 c->expr = constraintExpr_simplify (c->expr);
1147 if (constraintExpr_isLit(c->lexpr) && (!constraintExpr_isLit(c->expr) ) )
1149 c = constraint_swapLeftRight(c);
1150 /*I don't think this will be an infinate loop*/
1151 c = constraint_simplify(c);
1159 /* returns true if fileloc for term1 is closer to file for term2 than term3*/
1161 bool fileloc_closer (fileloc loc1, fileloc loc2, fileloc loc3)
1164 if (!fileloc_isDefined (loc1) )
1167 if (!fileloc_isDefined (loc2) )
1170 if (!fileloc_isDefined (loc3) )
1176 if (fileloc_equal (loc2, loc3) )
1179 if (fileloc_equal (loc1, loc2) )
1182 if (fileloc_equal (loc1, loc3) )
1185 if ( fileloc_lessthan (loc1, loc2) )
1187 if (fileloc_lessthan (loc2, loc3) )
1189 llassert (fileloc_lessthan (loc1, loc3) );
1198 if ( !fileloc_lessthan (loc1, loc2) )
1200 if (!fileloc_lessthan (loc2, loc3) )
1202 llassert (!fileloc_lessthan (loc1, loc3) );