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"
19 #include "constraintExpr.h"
23 constraintList reflectChanges (constraintList pre2, constraintList post1);
24 constraint substitute (constraint c, constraintList p);
25 constraint constraint_searchandreplace (constraint c, constraintExpr old, constraintExpr new);
26 bool rangeCheck (arithType ar1, constraintExpr expr1, arithType ar2, constraintExpr expr2);
27 bool satifies (constraint pre, constraint post);
28 bool resolve (constraint c, constraintList p);
29 constraintList reflectChangesEnsures (constraintList pre2, constraintList post1);
30 constraint constraint_simplify (constraint c);
32 constraintList constraintList_fixConflicts (constraintList list1, constraintList list2);
34 constraintList constraintList_subsumeEnsures (constraintList list1, constraintList list2);
36 constraintList constraintList_mergeEnsures (constraintList list1, constraintList list2);
37 constraint inequalitySubstitute (constraint c, constraintList p);
39 /*********************************************/
42 constraintList constraintList_mergeEnsures (constraintList list1, constraintList list2)
46 ret = constraintList_new();
48 ret = reflectChangesEnsures (list1, list2);
49 ret = constraintList_fixConflicts (ret, list2);
50 ret = constraintList_subsumeEnsures (ret, list2);
51 list2 = constraintList_subsumeEnsures (list2, ret);
52 temp = constraintList_copy(list2);
54 temp = constraintList_addList (temp, ret);
56 //ret = constraintList_addList (ret, list2);
61 /* constraintList constraintList_resolveRequires (constraintList requires, constraintList ensures) */
64 /* constraintList ret; */
65 /* constraintList temp; */
66 /* ret = constraintList_new(); */
68 /* ret = reflectChangesEnsures (list1, list2); */
69 /* ret = constraintList_fixConflicts (ret, list2); */
70 /* ret = constraintList_subsumeEnsures (ret, list2); */
71 /* list2 = constraintList_subsumeEnsures (list2, ret); */
72 /* temp = constraintList_copy(list2); */
74 /* temp = constraintList_addList (temp, ret); */
76 /* //ret = constraintList_addList (ret, list2); */
81 constraintList checkCall (exprNode fcn, exprNodeList arglist)
83 constraintList preconditions;
85 DPRINTF ( (message ("Got call that %s ( %s) ", exprNode_unparse(fcn), exprNodeList_unparse (arglist ) ) ) );
87 temp = exprNode_getUentry (fcn);
89 preconditions = uentry_getFcnPreconditions (temp);
93 preconditions = constraintList_copy(preconditions);
94 preconditions = constraintList_doSRefFixBaseParam (preconditions, arglist);
98 preconditions = constraintList_new();
101 return preconditions;
104 void mergeResolve (exprNode parent, exprNode child1, exprNode child2)
108 DPRINTF( (message ("magically merging constraint into parent:%s for", exprNode_unparse (parent) )));
110 DPRINTF( (message (" children: %s and %s", exprNode_unparse (child1), exprNode_unparse(child2) ) ) );
112 if (exprNode_isError (child1) || exprNode_isError(child2) )
114 if (exprNode_isError (child1) && !exprNode_isError(child2) )
116 parent->requiresConstraints = constraintList_copy (child2->requiresConstraints);
117 parent->ensuresConstraints = constraintList_copy (child2->ensuresConstraints);
118 DPRINTF((message ("Copied child constraints: pre: %s and post: %s",
119 constraintList_print( child2->requiresConstraints),
120 constraintList_print (child2->ensuresConstraints)
127 llassert(exprNode_isError(child2) );
128 parent->requiresConstraints = constraintList_new();
129 parent->ensuresConstraints = constraintList_new();
134 llassert(!exprNode_isError (child1) && ! exprNode_isError(child2) );
136 DPRINTF( (message ("Child constraints are %s %s and %s %s",
137 constraintList_print (child1->requiresConstraints),
138 constraintList_print (child1->ensuresConstraints),
139 constraintList_print (child2->requiresConstraints),
140 constraintList_print (child2->ensuresConstraints)
143 parent->requiresConstraints = constraintList_new();
144 parent->ensuresConstraints = constraintList_new();
146 parent->requiresConstraints = constraintList_copy (child1->requiresConstraints);
148 temp = reflectChanges (child2->requiresConstraints, child1->ensuresConstraints);
149 parent->requiresConstraints = constraintList_addList (parent->requiresConstraints, temp);
151 parent->ensuresConstraints = constraintList_mergeEnsures(child1->ensuresConstraints,
152 child2->ensuresConstraints);
154 DPRINTF( (message ("Parent constraints are %s and %s ",
155 constraintList_print (parent->requiresConstraints),
156 constraintList_print (parent->ensuresConstraints)
164 constraintList constraintList_subsumeEnsures (constraintList list1, constraintList list2)
167 ret = constraintList_new();
168 constraintList_elements (list1, el)
171 DPRINTF ((message ("Examining %s", constraint_print (el) ) ) );
172 if (!resolve (el, list2) )
174 ret = constraintList_add (ret, el);
178 DPRINTF ( (message ("Subsuming %s", constraint_print (el) ) ) );
180 } end_constraintList_elements;
186 constraintList reflectChanges (constraintList pre2, constraintList post1)
191 ret = constraintList_new();
192 constraintList_elements (pre2, el)
194 if (!resolve (el, post1) )
196 temp = substitute (el, post1);
197 if (!resolve (temp, post1) )
199 // try inequality substitution
202 // the inequality substitution may cause us to lose information
203 //so we don't want to store the result but we do it anyway
204 temp2 = constraint_copy (temp);
205 temp2 = inequalitySubstitute (temp, post1);
206 if (!resolve (temp2, post1) )
207 ret = constraintList_add (ret, temp2);
210 } end_constraintList_elements;
217 constraintList reflectChangesEnsures (constraintList pre2, constraintList post1)
221 ret = constraintList_new();
222 constraintList_elements (pre2, el)
224 if (!resolve (el, post1) )
226 temp = substitute (el, post1);
227 llassert (temp != NULL);
229 if (!resolve (temp, post1) )
230 ret = constraintList_add (ret, temp);
234 DPRINTF ( (message ("Resolved away %s ", constraint_print(el) ) ) );
236 } end_constraintList_elements;
242 bool constraint_conflict (constraint c1, constraint c2)
245 if (constraintExpr_similar(c1->lexpr, c2->lexpr) )
248 if (c1->ar == c2->ar)
250 DPRINTF ( (message ("%s conflicts with %s ", constraint_print (c1), constraint_print(c2) ) ) );
255 DPRINTF ( (message ("%s doesn't conflict with %s ", constraint_print (c1), constraint_print(c2) ) ) );
261 void constraint_fixConflict (constraint good, constraint conflicting)
264 if (conflicting->ar ==EQ )
266 good->expr = constraintExpr_searchandreplace (good->expr, conflicting->lexpr, conflicting->expr);
267 temp = constraint_simplify (good);
268 constraint_overWrite (good, temp);
274 bool conflict (constraint c, constraintList list)
277 constraintList_elements (list, el)
279 if ( constraint_conflict(el, c) )
281 constraint_fixConflict (el, c);
284 } end_constraintList_elements;
291 //check if constraint in list1 and conflict with constraints in List2. If so we
292 //remove form list1 and (optionally) change list2.
293 constraintList constraintList_fixConflicts (constraintList list1, constraintList list2)
296 ret = constraintList_new();
297 constraintList_elements (list1, el)
299 if (! conflict (el, list2) )
301 ret = constraintList_add (ret, el);
303 } end_constraintList_elements;
310 bool resolve (constraint c, constraintList p)
312 constraintList_elements (p, el)
314 if ( satifies (c, el) )
316 DPRINTF ( (message ("\n%s Satifies %s\n ", constraint_print(el), constraint_print(c) ) ) );
320 end_constraintList_elements;
321 DPRINTF ( (message ("no constraints satify %s", constraint_print(c) ) ));
326 /*returns true if cosntraint post satifies cosntriant pre */
327 bool satifies (constraint pre, constraint post)
329 if (!constraintExpr_similar (pre->lexpr, post->lexpr) )
333 if (post->expr == NULL)
339 return rangeCheck (pre->ar, pre->expr, post->ar, post->expr);
342 bool arithType_canResolve (arithType ar1, arithType ar2)
348 if ( (ar2 == GT) || (ar2 == GTE) || (ar2 == EQ) )
362 if ( (ar2 == LT) || (ar2 == LTE) || (ar2 == EQ) )
368 bool rangeCheck (arithType ar1, constraintExpr expr1, arithType ar2, constraintExpr expr2)
371 DPRINTF ((message ("Doing Range CHECK %s and %s", constraintExpr_unparse(expr1), constraintExpr_unparse(expr2) ) ));
373 if (! arithType_canResolve (ar1, ar2) )
380 if (! (constraintExpr_canGetValue (expr1) &&
381 constraintExpr_canGetValue (expr2) ) )
383 DPRINTF( ("Can't Get value"));
387 if (constraintExpr_compare (expr2, expr1) >= 0)
392 if (constraintExpr_similar (expr1, expr2) )
398 DPRINTF(("case not handled"));
404 constraint constraint_searchandreplace (constraint c, constraintExpr old, constraintExpr new)
406 DPRINTF (("Doing replace for lexpr") );
407 c->lexpr = constraintExpr_searchandreplace (c->lexpr, old, new);
408 DPRINTF (("Doing replace for expr") );
409 c->expr = constraintExpr_searchandreplace (c->expr, old, new);
413 bool constraint_search (constraint c, constraintExpr old)
418 ret = constraintExpr_search (c->lexpr, old);
419 ret = ret || constraintExpr_search (c->expr, old);
423 //adjust file locs and stuff
424 constraint constraint_adjust (constraint substitute, constraint old)
426 fileloc loc1, loc2, loc3;
428 DPRINTF ( (message("Start adjust on %s and %s", constraint_print(substitute),
429 constraint_print(old))
432 loc1 = constraint_getFileloc (old);
434 loc2 = constraintExpr_getFileloc (substitute->lexpr);
436 loc3 = constraintExpr_getFileloc (substitute->expr);
439 // special case of an equality that "contains itself"
440 if (constraintExpr_search (substitute->expr, substitute->lexpr) )
441 if (fileloc_closer (loc1, loc3, loc2))
444 DPRINTF ( (message("Doing adjust on %s", constraint_print(substitute) )
446 temp = substitute->lexpr;
447 substitute->lexpr = substitute->expr;
448 substitute->expr = temp;
449 substitute = constraint_simplify(substitute);
456 constraint inequalitySubstitute (constraint c, constraintList p)
461 constraintList_elements (p, el)
464 // if (!constraint_conflict (c, el) )
467 temp = constraint_copy(el);
469 // temp = constraint_adjust(temp, c);
471 if (constraintExpr_same (el->lexpr, c->expr) )
473 DPRINTF((message ("Replacing %s in %s with %s",
474 constraintExpr_print (c->expr),
475 constraint_print (c),
476 constraintExpr_print (el->expr) )
478 c->expr = constraintExpr_copy (el->expr);
483 end_constraintList_elements;
485 c = constraint_simplify(c);
489 constraint substitute (constraint c, constraintList p)
491 constraintList_elements (p, el)
494 if (!constraint_conflict (c, el) )
498 temp = constraint_copy(el);
500 temp = constraint_adjust(temp, c);
502 DPRINTF((message ("Substituting %s for %s",
503 constraint_print (temp), constraint_print (c)
507 c = constraint_searchandreplace (c, temp->lexpr, temp->expr);
510 end_constraintList_elements;
512 c = constraint_simplify(c);
517 constraint constraint_solve (constraint c)
519 DPRINTF( (message ("Solving %s\n", constraint_print(c) ) ) );
520 c->expr = constraintExpr_solveBinaryExpr (c->lexpr, c->expr);
521 DPRINTF( (message ("Solved and got %s\n", constraint_print(c) ) ) );
527 constraint constraint_simplify (constraint c)
529 c->lexpr = constraintExpr_simplify (c->lexpr);
530 c->expr = constraintExpr_simplify (c->expr);
532 c = constraint_solve (c);
534 c->lexpr = constraintExpr_simplify (c->lexpr);
535 c->expr = constraintExpr_simplify (c->expr);
543 /* returns true if fileloc for term1 is closer to file for term2 than term3*/
545 bool fileloc_closer (fileloc loc1, fileloc loc2, fileloc loc3)
547 if ( fileloc_lessthan (loc1, loc2) )
549 if (fileloc_lessthan (loc2, loc3) )
551 llassert (fileloc_lessthan (loc1, loc3) );
560 if ( !fileloc_lessthan (loc1, loc2) )
562 if (!fileloc_lessthan (loc2, loc3) )
564 llassert (!fileloc_lessthan (loc1, loc3) );