3 ** constraintGeneration.c
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"
18 # include "exprData.i"
19 # include "exprDataQuite.i"
21 extern void forLoopHeuristics( exprNode e, exprNode forPred, exprNode forBody);
23 bool /*@alt void@*/ exprNode_generateConstraints (/*@temp@*/ exprNode e);
24 static bool exprNode_handleError( exprNode p_e);
26 //static cstring exprNode_findConstraints ( exprNode p_e);
27 static bool exprNode_isMultiStatement(exprNode p_e);
28 static bool exprNode_multiStatement (exprNode p_e);
29 bool exprNode_exprTraverse (exprNode e, bool definatelv, bool definaterv, fileloc sequencePoint);
30 //static void exprNode_constraintPropagateUp (exprNode p_e);
31 constraintList exprNode_traversRequiresConstraints (exprNode e);
32 constraintList exprNode_traversEnsuresConstraints (exprNode e);
34 constraintList exprNode_traversTrueEnsuresConstraints (exprNode e);
35 constraintList exprNode_traversFalseEnsuresConstraints (exprNode e);
37 extern constraintList reflectChanges (constraintList pre2, constraintList post1);
39 void mergeResolve (exprNode parent, exprNode child1, exprNode child2);
40 exprNode makeDataTypeConstraints (exprNode e);
41 constraintList constraintList_makeFixedArrayConstraints (sRefSet s);
42 constraintList checkCall (exprNode fcn, exprNodeList arglist);
44 void checkArgumentList (exprNode temp, exprNodeList arglist, fileloc sequencePoint);
46 //bool exprNode_testd()
48 /* if ( ( (exprNode_isError ) ) )
57 bool exprNode_isUnhandled (exprNode e)
59 llassert( exprNode_isDefined(e) );
88 DPRINTF((message ("Warning current constraint generation does not handle expression %s", exprNode_unparse(e)) ) );
100 bool exprNode_handleError( exprNode e)
102 if (exprNode_isError (e) || exprNode_isUnhandled(e) )
104 static /*@only@*/ cstring error = cstring_undefined;
106 if (!cstring_isDefined (error))
108 error = cstring_makeLiteral ("<error>");
111 /*@-unqualifiedtrans*/ return TRUE; /*@=unqualifiedtrans*/
116 bool /*@alt void@*/ exprNode_generateConstraints (/*@temp@*/ exprNode e)
118 if (exprNode_isError (e) )
121 e->requiresConstraints = constraintList_makeNew();
122 e->ensuresConstraints = constraintList_makeNew();
123 e->trueEnsuresConstraints = constraintList_makeNew();
124 e->falseEnsuresConstraints = constraintList_makeNew();
126 if (exprNode_isUnhandled (e) )
128 DPRINTF( (message("Warning ignoring %s", exprNode_unparse (e) ) ) );
133 // e = makeDataTypeConstraints (e);
135 DPRINTF((message ("exprNode_generateConstraints Analysising %s at %s", exprNode_unparse( e),
136 fileloc_unparse(exprNode_getfileloc(e) ) ) ) );
138 if (exprNode_isMultiStatement ( e) )
140 exprNode_multiStatement(e);
146 loc = exprNode_getNextSequencePoint(e);
147 exprNode_exprTraverse(e, FALSE, FALSE, loc);
156 c = constraintList_makeFixedArrayConstraints (e->uses);
157 e->requiresConstraints = reflectChanges (e->requiresConstraints, c);
159 // e->ensuresConstraints = constraintList_mergeEnsures(c, e->ensuresConstraints);
163 /* printf ("%s", (message ("%s", constraintList_printDetailed (e->requiresConstraints) ) ) );
164 printf ("%s", (message ("%s", constraintList_printDetailed (e->ensuresConstraints) ) ) ); */
169 /* handles multiple statements */
171 bool exprNode_isMultiStatement(exprNode e)
173 if (exprNode_handleError (e) != NULL)
195 bool exprNode_stmt (exprNode e)
202 if (exprNode_isError(e) )
206 e->requiresConstraints = constraintList_makeNew();
207 e->ensuresConstraints = constraintList_makeNew();
208 // e = makeDataTypeConstraints(e);
211 DPRINTF(( "STMT:") );
212 s = exprNode_unparse(e);
213 // DPRINTF ( ( message("STMT: %s ") ) );
215 if (e->kind == XPR_INIT)
218 DPRINTF ( (message ("%s ", exprNode_unparse (e)) ) );
219 loc = exprNode_getNextSequencePoint(e); /* reduces to an expression */
220 notError = exprNode_exprTraverse (e, FALSE, FALSE, loc);
221 e->requiresConstraints = exprNode_traversRequiresConstraints(e);
222 e->ensuresConstraints = exprNode_traversEnsuresConstraints(e);
226 if (e->kind != XPR_STMT)
229 DPRINTF (("Not Stmt") );
230 DPRINTF ( (message ("%s ", exprNode_unparse (e)) ) );
231 if (exprNode_isMultiStatement (e) )
233 return exprNode_multiStatement (e );
235 BPRINTF( (message ("Ignoring non-statement %s", exprNode_unparse(e) ) ) );
241 DPRINTF ( (message ("%s ", exprNode_unparse (e)) ) );
243 snode = exprData_getUopNode (e->edata);
245 /* could be stmt involving multiple statements:
246 i.e. if, while for ect.
249 if (exprNode_isMultiStatement (snode))
253 temp = exprNode_multiStatement (snode);
254 exprNode_copyConstraints (e, snode);
258 loc = exprNode_getNextSequencePoint(e); /* reduces to an expression */
259 notError = exprNode_exprTraverse (snode, FALSE, FALSE, loc);
260 e->requiresConstraints = exprNode_traversRequiresConstraints(snode);
261 // printf ("For: %s \n", exprNode_unparse (e) );
262 // printf ("%s\n", constraintList_print(e->requiresConstraints) );
263 e->ensuresConstraints = exprNode_traversEnsuresConstraints(snode);
264 // printf ("Ensures that:\n %s\n", constraintList_print(e->ensuresConstraints) );
265 // llassert(notError);
271 bool exprNode_stmtList (exprNode e)
273 exprNode stmt1, stmt2;
274 if (exprNode_isError (e) )
279 e->requiresConstraints = constraintList_makeNew();
280 e->ensuresConstraints = constraintList_makeNew();
281 // e = makeDataTypeConstraints(e);
283 /*Handle case of stmtList with only one statement:
284 The parse tree stores this as stmt instead of stmtList*/
285 if (e->kind != XPR_STMTLIST)
287 return exprNode_stmt(e);
289 llassert (e->kind == XPR_STMTLIST);
290 DPRINTF(( "STMTLIST:") );
291 DPRINTF ((cstring_toCharsSafe (exprNode_unparse(e)) ) );
292 stmt1 = exprData_getPairA (e->edata);
293 stmt2 = exprData_getPairB (e->edata);
296 DPRINTF((" stmtlist ") );
297 DPRINTF ((message("XW%s | %s", exprNode_unparse(stmt1), exprNode_unparse(stmt2) ) ) );
299 exprNode_stmt (stmt1);
300 DPRINTF(("\nstmt after stmtList call " ));
302 exprNode_stmt (stmt2);
303 mergeResolve (e, stmt1, stmt2 );
305 DPRINTF ( (message ("smtlist constraints are: pre: %s \n and \t post %s\n",
306 constraintList_print(e->requiresConstraints),
307 constraintList_print(e->ensuresConstraints) ) ) );
311 exprNode doIf (exprNode e, exprNode test, exprNode body)
313 DPRINTF ((message ("doIf: %s ", exprNode_unparse(e) ) ) );
319 test->ensuresConstraints = exprNode_traversEnsuresConstraints (test);
320 test->requiresConstraints = exprNode_traversRequiresConstraints (test);
322 test->trueEnsuresConstraints = exprNode_traversTrueEnsuresConstraints(test);
324 test->trueEnsuresConstraints = constraintList_substitute(test->trueEnsuresConstraints, test->ensuresConstraints);
326 DPRINTF ((message ("doIf: test ensures %s ", constraintList_print(test->ensuresConstraints) ) ) );
328 DPRINTF ((message ("doIf: test true ensures %s ", constraintList_print(test->trueEnsuresConstraints) ) ) );
330 e->requiresConstraints = reflectChanges (body->requiresConstraints, test->trueEnsuresConstraints);
331 e->requiresConstraints = reflectChanges (e->requiresConstraints,
332 test->ensuresConstraints);
333 e->requiresConstraints = constraintList_mergeRequires (e->requiresConstraints, test->requiresConstraints);
336 e->ensuresConstraints = constraintList_copy (test->ensuresConstraints);
338 if (exprNode_mayEscape (body) )
340 DPRINTF (( message("doIf: the if statement body %s returns or exits", exprNode_unparse(body) ) ));
341 e->ensuresConstraints = constraintList_mergeEnsures (e->ensuresConstraints,
342 test->falseEnsuresConstraints);
345 DPRINTF ((message ("doIf: if requiers %s ", constraintList_print(e->requiresConstraints) ) ) );
351 Also used for condition i.e. ?: operation
354 This function assumes that p, trueBranch, falseBranch have have all been traversed
355 for constraints i.e. we assume that exprNode_traversEnsuresConstraints,
356 exprNode_traversRequiresConstraints, exprNode_traversTrueEnsuresConstraints,
357 exprNode_traversFalseEnsuresConstraints have all been run
361 exprNode doIfElse (/*@returned@*/ exprNode e, exprNode p, exprNode trueBranch, exprNode falseBranch)
364 constraintList c1, cons, t, f;
366 // do requires clauses
367 c1 = constraintList_copy (p->ensuresConstraints);
369 t = reflectChanges (trueBranch->requiresConstraints, p->trueEnsuresConstraints);
370 t = reflectChanges (t, p->ensuresConstraints);
372 // e->requiresConstraints = constraintList_copy (cons);
374 cons = reflectChanges (falseBranch->requiresConstraints, p->falseEnsuresConstraints);
375 cons = reflectChanges (cons, c1);
377 e->requiresConstraints = constraintList_mergeRequires (t, cons);
378 e->requiresConstraints = constraintList_mergeRequires (e->requiresConstraints, p->requiresConstraints);
380 // do ensures clauses
381 // find the the ensures lists for each subbranch
382 t = constraintList_mergeEnsures (p->trueEnsuresConstraints, trueBranch->ensuresConstraints);
383 t = constraintList_mergeEnsures (p->ensuresConstraints, t);
385 f = constraintList_mergeEnsures (p->falseEnsuresConstraints, falseBranch->ensuresConstraints);
386 f = constraintList_mergeEnsures (p->ensuresConstraints, f);
388 // find ensures for whole if/else statement
390 e->ensuresConstraints = constraintList_logicalOr (t, f);
395 exprNode doWhile (exprNode e, exprNode test, exprNode body)
397 DPRINTF ((message ("doWhile: %s ", exprNode_unparse(e) ) ) );
398 return doIf (e, test, body);
401 constraintList constraintList_makeFixedArrayConstraints (sRefSet s)
405 ret = constraintList_makeNew();
407 sRefSet_elements (s, el)
410 if (sRef_isFixedArray(el) )
413 DPRINTF( (message("%s is a fixed array",
414 sRef_unparse(el)) ) );
415 //if (el->kind == SK_DERIVED)
416 // break; //hack until I find the real problem
417 s = sRef_getArraySize(el);
418 DPRINTF( (message("%s is a fixed array with size %d",
419 sRef_unparse(el), s) ) );
420 con = constraint_makeSRefSetBufferSize (el, (s - 1));
421 //con = constraint_makeSRefWriteSafeInt (el, (s - 1));
422 ret = constraintList_add(ret, con);
426 DPRINTF( (message("%s is not a fixed array",
427 sRef_unparse(el)) ) );
430 if (sRef_isExternallyVisible (el) )
432 /*DPRINTF( (message("%s is externally visible",
433 sRef_unparse(el) ) ));
434 con = constraint_makeSRefWriteSafeInt(el, 0);
435 ret = constraintList_add(ret, con);
437 con = constraint_makeSRefReadSafeInt(el, 0);
439 ret = constraintList_add(ret, con);*/
445 DPRINTF(( message("constraintList_makeFixedArrayConstraints returning %s",
446 constraintList_print(ret) ) ));
450 exprNode makeDataTypeConstraints (exprNode e)
453 DPRINTF(("makeDataTypeConstraints"));
455 c = constraintList_makeFixedArrayConstraints (e->uses);
457 e->ensuresConstraints = constraintList_addList (e->ensuresConstraints, c);
462 void doFor (exprNode e, exprNode forPred, exprNode forBody)
464 exprNode init, test, inc;
465 //merge the constraints: modle as if statement
470 init = exprData_getTripleInit (forPred->edata);
471 test = exprData_getTripleTest (forPred->edata);
472 inc = exprData_getTripleInc (forPred->edata);
474 if ( ( (exprNode_isError (test) /*|| (exprNode_isError(init) )*/ ) || (exprNode_isError (inc) ) ) )
476 DPRINTF ((message ("strange for statement:%s, ignoring it", exprNode_unparse(e) ) ) );
480 forLoopHeuristics(e, forPred, forBody);
482 e->requiresConstraints = reflectChanges (forBody->requiresConstraints, test->ensuresConstraints);
483 e->requiresConstraints = reflectChanges (e->requiresConstraints, test->trueEnsuresConstraints);
484 e->requiresConstraints = reflectChanges (e->requiresConstraints, forPred->ensuresConstraints);
486 if (!forBody->canBreak)
488 e->ensuresConstraints = constraintList_addList(e->ensuresConstraints, forPred->ensuresConstraints);
489 e->ensuresConstraints = constraintList_addList(e->ensuresConstraints, test->falseEnsuresConstraints);
493 DPRINTF(("Can break") );
498 exprNode doSwitch (/*@returned@*/ exprNode e)
505 //DPRINTF (( message ("doSwitch for: switch (%s) %s",
506 // exprNode_unparse (exprData_getPairA (data)),
507 // exprNode_unparse (exprData_getPairB (data))) ));
509 body = exprData_getPairB (data);
511 // exprNode_generateConstraints(body);
513 // e->requiresConstraints = constraintList_copy ( body->requiresConstraints );
514 //e->ensuresConstraints = constraintList_copy ( body->ensuresConstraints );
520 bool exprNode_multiStatement (exprNode e)
526 exprNode p, trueBranch, falseBranch;
527 exprNode forPred, forBody;
529 // constraintList t, f;
530 e->requiresConstraints = constraintList_makeNew();
531 e->ensuresConstraints = constraintList_makeNew();
532 e->trueEnsuresConstraints = constraintList_makeNew();
533 e->falseEnsuresConstraints = constraintList_makeNew();
535 // e = makeDataTypeConstraints(e);
537 DPRINTF((message ("exprNode_multistatement Analysising %s %s at", exprNode_unparse( e),
538 fileloc_unparse(exprNode_getfileloc(e) ) ) ) );
540 if (exprNode_handleError (e))
553 // ret = message ("%s %s",
554 forPred = exprData_getPairA (data);
555 forBody = exprData_getPairB (data);
557 //first generate the constraints
558 exprNode_generateConstraints (forPred);
559 exprNode_generateConstraints (forBody);
562 doFor (e, forPred, forBody);
567 // ret = message ("for (%s; %s; %s)",
568 exprNode_generateConstraints (exprData_getTripleInit (data) );
569 test = exprData_getTripleTest (data);
570 exprNode_exprTraverse (test,FALSE, FALSE, exprNode_loc(e));
571 exprNode_generateConstraints (exprData_getTripleInc (data) );
573 if (!exprNode_isError(test) )
574 test->trueEnsuresConstraints = exprNode_traversTrueEnsuresConstraints(test);
576 exprNode_generateConstraints (exprData_getTripleInc (data));
580 e1 = exprData_getPairA (data);
581 e2 = exprData_getPairB (data);
583 exprNode_exprTraverse (e1,
584 FALSE, FALSE, exprNode_loc(e1));
586 exprNode_generateConstraints (e2);
588 e = doWhile (e, e1, e2);
594 DPRINTF ((exprNode_unparse(e) ) );
595 // ret = message ("if (%s) %s",
596 e1 = exprData_getPairA (data);
597 e2 = exprData_getPairB (data);
599 exprNode_exprTraverse (e1,
600 FALSE, FALSE, exprNode_loc(e1));
602 exprNode_generateConstraints (e2);
604 e = doIf (e, e1, e2);
607 // e->constraints = constraintList_exprNodemerge (exprData_getPairA (data),exprData_getPairB(data));
612 DPRINTF(("Starting IFELSE"));
613 // ret = message ("if (%s) %s else %s",
614 p = exprData_getTriplePred (data);
615 trueBranch = exprData_getTripleTrue (data);
616 falseBranch = exprData_getTripleFalse (data);
618 exprNode_exprTraverse (p,
619 FALSE, FALSE, exprNode_loc(p));
620 exprNode_generateConstraints (trueBranch);
621 exprNode_generateConstraints (falseBranch);
623 p->ensuresConstraints = exprNode_traversEnsuresConstraints (p);
624 p->requiresConstraints = exprNode_traversRequiresConstraints (p);
626 p->trueEnsuresConstraints = exprNode_traversTrueEnsuresConstraints(p);
627 p->falseEnsuresConstraints = exprNode_traversFalseEnsuresConstraints(p);
629 e = doIfElse (e, p, trueBranch, falseBranch);
630 DPRINTF( ("Done IFELSE") );
635 e2 = (exprData_getPairB (data));
636 e1 = (exprData_getPairA (data));
638 DPRINTF((message ("do { %s } while (%s)", exprNode_unparse(e2), exprNode_unparse(e1) ) ));
639 exprNode_generateConstraints (e2);
640 exprNode_generateConstraints (e1);
641 e = exprNode_copyConstraints (e, e2);
642 DPRINTF ((message ("e = %s ", constraintList_print(e->requiresConstraints) ) ));
647 // ret = message ("{ %s }",
648 exprNode_generateConstraints (exprData_getSingle (data));
649 e->requiresConstraints = constraintList_copy ( (exprData_getSingle (data))->requiresConstraints );
650 e->ensuresConstraints = constraintList_copy ( (exprData_getSingle (data))->ensuresConstraints );
651 // e->constraints = (exprData_getSingle (data))->constraints;
659 return exprNode_stmtList (e);
668 bool lltok_isBoolean_Op (lltok tok)
670 /*this should really be a switch statement but
671 I don't want to violate the abstraction
672 maybe this should go in lltok.c */
674 if (lltok_isEq_Op (tok) )
678 if (lltok_isAnd_Op (tok) )
684 if (lltok_isOr_Op (tok) )
689 if (lltok_isGt_Op (tok) )
693 if (lltok_isLt_Op (tok) )
698 if (lltok_isLe_Op (tok) )
703 if (lltok_isGe_Op (tok) )
713 void exprNode_booleanTraverse (exprNode e, bool definatelv, bool definaterv, fileloc sequencePoint)
719 constraintList tempList;
722 tok = exprData_getOpTok (data);
725 t1 = exprData_getOpA (data);
726 t2 = exprData_getOpB (data);
729 /* arithmetic tests */
731 if (lltok_isEq_Op (tok) )
733 cons = constraint_makeEnsureEqual (t1, t2, sequencePoint);
734 e->trueEnsuresConstraints = constraintList_add(e->trueEnsuresConstraints, cons);
738 if (lltok_isLt_Op (tok) )
740 cons = constraint_makeEnsureLessThan (t1, t2, sequencePoint);
741 e->trueEnsuresConstraints = constraintList_add(e->trueEnsuresConstraints, cons);
742 cons = constraint_makeEnsureGreaterThanEqual (t1, t2, sequencePoint);
743 e->falseEnsuresConstraints = constraintList_add(e->falseEnsuresConstraints, cons);
747 if (lltok_isGe_Op (tok) )
750 cons = constraint_makeEnsureGreaterThanEqual (t1, t2, sequencePoint);
751 e->trueEnsuresConstraints = constraintList_add(e->trueEnsuresConstraints, cons);
753 cons = constraint_makeEnsureLessThan (t1, t2, sequencePoint);
754 e->falseEnsuresConstraints = constraintList_add(e->falseEnsuresConstraints, cons);
759 if (lltok_isGt_Op (tok) )
761 cons = constraint_makeEnsureGreaterThan (t1, t2, sequencePoint);
762 e->trueEnsuresConstraints = constraintList_add(e->trueEnsuresConstraints, cons);
763 cons = constraint_makeEnsureLessThanEqual (t1, t2, sequencePoint);
764 e->falseEnsuresConstraints = constraintList_add(e->falseEnsuresConstraints, cons);
767 if (lltok_isLe_Op (tok) )
769 cons = constraint_makeEnsureLessThanEqual (t1, t2, sequencePoint);
770 e->trueEnsuresConstraints = constraintList_add(e->trueEnsuresConstraints, cons);
772 cons = constraint_makeEnsureGreaterThan (t1, t2, sequencePoint);
773 e->falseEnsuresConstraints = constraintList_add(e->falseEnsuresConstraints, cons);
778 /*Logical operations */
780 if (lltok_isAnd_Op (tok) )
784 tempList = constraintList_copy (t1->trueEnsuresConstraints);
785 tempList = constraintList_addList (tempList, t2->trueEnsuresConstraints);
786 e->trueEnsuresConstraints = constraintList_addList(e->trueEnsuresConstraints, tempList);
788 //false ensures: fens t1 or tens t1 and fens t2
789 tempList = constraintList_copy (t1->trueEnsuresConstraints);
790 tempList = constraintList_addList (tempList, t2->falseEnsuresConstraints);
791 tempList = constraintList_logicalOr (tempList, t1->falseEnsuresConstraints);
792 e->falseEnsuresConstraints =constraintList_addList(e->falseEnsuresConstraints, tempList);
796 if (lltok_isOr_Op (tok) )
799 tempList = constraintList_copy (t1->falseEnsuresConstraints);
800 tempList = constraintList_addList (tempList, t2->falseEnsuresConstraints);
801 e->falseEnsuresConstraints = constraintList_addList(e->falseEnsuresConstraints, tempList);
803 //true ensures: tens t1 or fens t1 and tens t2
804 tempList = constraintList_copy (t1->falseEnsuresConstraints);
805 tempList = constraintList_addList (tempList, t2->trueEnsuresConstraints);
806 tempList = constraintList_logicalOr (tempList, t1->trueEnsuresConstraints);
807 e->trueEnsuresConstraints =constraintList_addList(e->trueEnsuresConstraints, tempList);
813 bool exprNode_exprTraverse (exprNode e, bool definatelv, bool definaterv, fileloc sequencePoint)
815 exprNode t1, t2, fcn;
817 bool handledExprNode;
821 if (exprNode_isError(e) )
826 DPRINTF((message ("exprNode_exprTraverset Analysising %s %s at", exprNode_unparse( e),
827 fileloc_unparse(exprNode_getfileloc(e) ) ) ) );
829 e->requiresConstraints = constraintList_makeNew();
830 e->ensuresConstraints = constraintList_makeNew();
831 e->trueEnsuresConstraints = constraintList_makeNew();;
832 e->falseEnsuresConstraints = constraintList_makeNew();;
834 if (exprNode_isUnhandled (e) )
838 // e = makeDataTypeConstraints (e);
840 handledExprNode = TRUE;
849 t1 = exprData_getSingle (data);
850 exprNode_exprTraverse (t1, definatelv, definaterv, sequencePoint);
851 e = exprNode_copyConstraints (e, t1);
858 t1 = (exprData_getPairA (data) );
859 t2 = (exprData_getPairB (data) );
860 cons = constraint_makeWriteSafeExprNode (t1, t2);
864 t1 = (exprData_getPairA (data) );
865 t2 = (exprData_getPairB (data) );
866 cons = constraint_makeReadSafeExprNode (t1, t2 );
869 e->requiresConstraints = constraintList_add(e->requiresConstraints, cons);
870 cons = constraint_makeEnsureMaxReadAtLeast (t1, t2, sequencePoint);
871 e->ensuresConstraints = constraintList_add(e->ensuresConstraints, cons);
873 cons = constraint_makeEnsureLteMaxRead (t2, t1);
874 e->trueEnsuresConstraints = constraintList_add(e->trueEnsuresConstraints, cons);
876 // cons = constraint_makeEnsureMinReadAtMost (t1, t2, sequencePoint);
877 // e->ensuresConstraints = constraintList_add(e->ensuresConstraints, cons);
879 exprNode_exprTraverse (exprData_getPairA (data), FALSE, TRUE, sequencePoint);
880 exprNode_exprTraverse (exprData_getPairB (data), FALSE, TRUE, sequencePoint);
882 /*@i325 Should check which is array/index. */
886 exprNode_exprTraverse (exprData_getUopNode (e->edata), definatelv, definaterv, sequencePoint);
887 // e->constraints = constraintList_exprNodemerge (exprData_getUopNode (e->edata), exprNode_undefined);
890 /* //t1 = exprData_getInitId (data); */
891 t2 = exprData_getInitNode (data);
892 //exprNode_exprTraverse (t1, TRUE, FALSE, sequencePoint );
894 exprNode_exprTraverse (t2, definatelv, TRUE, sequencePoint );
896 /* this test is nessecary because some expressions generate a null expression node. function pointer do that -- drl */
897 if ( (!exprNode_isError (e)) && (!exprNode_isError(t2)) )
899 cons = constraint_makeEnsureEqual (e, t2, sequencePoint);
900 e->ensuresConstraints = constraintList_add(e->ensuresConstraints, cons);
905 t1 = exprData_getOpA (data);
906 t2 = exprData_getOpB (data);
907 exprNode_exprTraverse (t1, TRUE, definaterv, sequencePoint );
908 lltok_unparse (exprData_getOpTok (data));
909 exprNode_exprTraverse (t2, definatelv, TRUE, sequencePoint );
911 /* this test is nessecary because some expressions generate a null expression node. function pointer do that -- drl */
912 if ( (!exprNode_isError (t1)) && (!exprNode_isError(t2)) )
914 cons = constraint_makeEnsureEqual (t1, t2, sequencePoint);
915 e->ensuresConstraints = constraintList_add(e->ensuresConstraints, cons);
919 t1 = exprData_getOpA (data);
920 t2 = exprData_getOpB (data);
922 exprNode_exprTraverse (t1, definatelv, definaterv, sequencePoint );
923 tok = exprData_getOpTok (data);
924 exprNode_exprTraverse (t2, definatelv, definaterv, sequencePoint );
926 if (lltok_isBoolean_Op (tok) )
927 exprNode_booleanTraverse (e, definatelv, definaterv, sequencePoint);
929 // e->constraints = constraintList_exprNodemerge (exprData_getOpA (data), exprData_getOpB (data));
932 ctype_unparse (qtype_getType (exprData_getType (data) ) );
937 exprNode_exprTraverse (exprData_getSingle (data), definatelv, definaterv, sequencePoint );
938 // e->constraints = constraintList_exprNodemerge (exprData_getSingle (e->edata), exprNode_undefined);
942 fcn = exprData_getFcn(data);
944 exprNode_exprTraverse (fcn, definatelv, definaterv, sequencePoint );
945 exprNodeList_unparse (exprData_getArgs (data) );
946 DPRINTF ( (message ("Got call that %s ( %s) ", exprNode_unparse(fcn), exprNodeList_unparse (exprData_getArgs (data) ) ) ) );
948 fcn->requiresConstraints = constraintList_addList (fcn->requiresConstraints,
949 checkCall (fcn, exprData_getArgs (data) ) );
951 fcn->ensuresConstraints = constraintList_addList (fcn->ensuresConstraints,
952 getPostConditions(fcn, exprData_getArgs (data),e ) );
954 t1 = exprNode_createNew (exprNode_getType (e) );
956 checkArgumentList (t1, exprData_getArgs(data), sequencePoint);
959 mergeResolve (e, t1, fcn);
961 // e->constraints = constraintList_add (e->constraints, constraint_create (e,exprNode_undefined, GT, CALLSAFE ) );
965 exprNode_exprTraverse (exprData_getSingle (data), definatelv, definaterv, sequencePoint );
969 cstring_makeLiteral ("return");;
974 exprNode_exprTraverse (exprData_getFieldNode (data), definatelv, definaterv, sequencePoint );
975 exprData_getFieldName (data) ;
979 exprNode_exprTraverse (exprData_getFieldNode (data), definatelv, definaterv, sequencePoint );
980 exprData_getFieldName (data);
983 case XPR_STRINGLITERAL:
984 cstring_copy (exprData_getLiteral (data));
988 cstring_copy (exprData_getLiteral (data));
992 t1 = exprData_getUopNode(data);
993 tok = (exprData_getUopTok (data));
994 //lltok_unparse (exprData_getUopTok (data));
995 exprNode_exprTraverse (t1, definatelv, definaterv, sequencePoint );
996 /*handle * pointer access */
997 if (lltok_isInc_Op (tok) )
999 DPRINTF(("doing ++(var)"));
1000 t1 = exprData_getUopNode (data);
1001 cons = constraint_makeMaxSetSideEffectPostIncrement (t1, sequencePoint );
1002 e->ensuresConstraints = constraintList_add (e->ensuresConstraints, cons);
1004 else if (lltok_isDec_Op (tok) )
1006 DPRINTF(("doing --(var)"));
1007 t1 = exprData_getUopNode (data);
1008 cons = constraint_makeMaxSetSideEffectPostDecrement (t1, sequencePoint );
1009 e->ensuresConstraints = constraintList_add (e->ensuresConstraints, cons);
1012 if (lltok_isMult( exprData_getUopTok (data) ) )
1016 cons = constraint_makeWriteSafeInt (t1, 0);
1020 cons = constraint_makeReadSafeInt (t1, 0);
1022 e->requiresConstraints = constraintList_add(e->requiresConstraints, cons);
1026 if (lltok_isNot_Op (exprData_getUopTok (data) ) )
1028 e->trueEnsuresConstraints = constraintList_copy (t1->falseEnsuresConstraints);
1029 e->falseEnsuresConstraints = constraintList_copy (t1->trueEnsuresConstraints);
1035 exprNode_exprTraverse (exprData_getUopNode (data), TRUE, definaterv, sequencePoint );
1036 lltok_unparse (exprData_getUopTok (data));
1037 if (lltok_isInc_Op (exprData_getUopTok (data) ) )
1039 DPRINTF(("doing ++"));
1040 t1 = exprData_getUopNode (data);
1041 cons = constraint_makeMaxSetSideEffectPostIncrement (t1, sequencePoint );
1042 e->ensuresConstraints = constraintList_add (e->ensuresConstraints, cons);
1044 if (lltok_isDec_Op (exprData_getUopTok (data) ) )
1046 DPRINTF(("doing --"));
1047 t1 = exprData_getUopNode (data);
1048 cons = constraint_makeMaxSetSideEffectPostDecrement (t1, sequencePoint );
1049 e->ensuresConstraints = constraintList_add (e->ensuresConstraints, cons);
1054 exprNode_exprTraverse (exprData_getCastNode (data), definatelv, definaterv, sequencePoint );
1058 exprNode pred, true, false;
1060 pred = exprData_getTriplePred (data);
1061 true = exprData_getTripleTrue (data);
1062 false = exprData_getTripleFalse (data);
1064 exprNode_exprTraverse (pred, FALSE, TRUE, sequencePoint );
1065 pred->ensuresConstraints = exprNode_traversEnsuresConstraints(pred);
1066 pred->requiresConstraints = exprNode_traversRequiresConstraints(pred);
1068 pred->trueEnsuresConstraints = exprNode_traversTrueEnsuresConstraints(pred);
1069 pred->falseEnsuresConstraints = exprNode_traversFalseEnsuresConstraints(pred);
1071 exprNode_exprTraverse (true, FALSE, TRUE, sequencePoint );
1072 true->ensuresConstraints = exprNode_traversEnsuresConstraints(true);
1073 true->requiresConstraints = exprNode_traversRequiresConstraints(true);
1075 true->trueEnsuresConstraints = exprNode_traversTrueEnsuresConstraints(true);
1076 true->falseEnsuresConstraints = exprNode_traversFalseEnsuresConstraints(true);
1078 exprNode_exprTraverse (false, FALSE, TRUE, sequencePoint );
1079 false->ensuresConstraints = exprNode_traversEnsuresConstraints(false);
1080 false->requiresConstraints = exprNode_traversRequiresConstraints(false);
1082 false->trueEnsuresConstraints = exprNode_traversTrueEnsuresConstraints(false);
1083 false->falseEnsuresConstraints = exprNode_traversFalseEnsuresConstraints(false);
1086 /* if pred is true e equals true otherwise pred equals false */
1088 cons = constraint_makeEnsureEqual (e, true, sequencePoint);
1089 true->ensuresConstraints = constraintList_add(true->ensuresConstraints, cons);
1091 cons = constraint_makeEnsureEqual (e, true, sequencePoint);
1092 false->ensuresConstraints = constraintList_add(false->ensuresConstraints, cons);
1094 e = doIfElse (e, pred, true, false);
1100 t1 = exprData_getPairA (data);
1101 t2 = exprData_getPairB (data);
1102 /* we essiantially treat this like expr1; expr2
1103 of course sequencePoint isn't adjusted so this isn't completely accurate
1105 exprNode_exprTraverse (t1, FALSE, FALSE, sequencePoint );
1106 exprNode_exprTraverse (t2, definatelv, definaterv, sequencePoint );
1107 mergeResolve (e, t1, t2);
1111 handledExprNode = FALSE;
1114 e->requiresConstraints = constraintList_preserveOrig ( e->requiresConstraints);
1115 e->ensuresConstraints = constraintList_preserveOrig ( e->ensuresConstraints);
1116 e->requiresConstraints = constraintList_addGeneratingExpr ( e->requiresConstraints, e);
1118 e->ensuresConstraints = constraintList_addGeneratingExpr ( e->ensuresConstraints, e);
1120 DPRINTF((message ("ensures constraint for %s are %s", exprNode_unparse(e), constraintList_printDetailed(e->ensuresConstraints) ) ));
1122 return handledExprNode;
1126 constraintList exprNode_traversTrueEnsuresConstraints (exprNode e)
1130 bool handledExprNode;
1135 if (exprNode_handleError (e))
1137 ret = constraintList_makeNew();
1140 ret = constraintList_copy (e->trueEnsuresConstraints );
1142 handledExprNode = TRUE;
1149 t1 = exprData_getSingle (data);
1150 ret = constraintList_addList ( ret,exprNode_traversTrueEnsuresConstraints (t1) );
1155 ret = constraintList_addList (ret,
1156 exprNode_traversTrueEnsuresConstraints
1157 (exprData_getPairA (data) ) );
1159 ret = constraintList_addList (ret,
1160 exprNode_traversTrueEnsuresConstraints
1161 (exprData_getPairB (data) ) );
1165 ret = constraintList_addList (ret,
1166 exprNode_traversTrueEnsuresConstraints
1167 (exprData_getUopNode (data) ) );
1171 ret = constraintList_addList (ret, exprNode_traversTrueEnsuresConstraints
1172 (exprData_getUopNode (data) ) );
1175 ret = constraintList_addList (ret,
1176 exprNode_traversTrueEnsuresConstraints
1177 (exprData_getOpA (data) ) );
1179 ret = constraintList_addList (ret,
1180 exprNode_traversTrueEnsuresConstraints
1181 (exprData_getOpB (data) ) );
1184 ret = constraintList_addList (ret,
1185 exprNode_traversTrueEnsuresConstraints
1186 (exprData_getOpA (data) ) );
1188 ret = constraintList_addList (ret,
1189 exprNode_traversTrueEnsuresConstraints
1190 (exprData_getOpB (data) ) );
1194 // ctype_unparse (qtype_getType (exprData_getType (data) ) );
1200 ret = constraintList_addList (ret,
1201 exprNode_traversTrueEnsuresConstraints
1202 (exprData_getSingle (data) ) );
1206 ret = constraintList_addList (ret,
1207 exprNode_traversTrueEnsuresConstraints
1208 (exprData_getFcn (data) ) );
1209 /*@i11*/ // exprNodeList_unparse (exprData_getArgs (data) );
1213 ret = constraintList_addList (ret,
1214 exprNode_traversTrueEnsuresConstraints
1215 (exprData_getSingle (data) ) );
1218 case XPR_NULLRETURN:
1219 // cstring_makeLiteral ("return");;
1223 ret = constraintList_addList (ret,
1224 exprNode_traversTrueEnsuresConstraints
1225 (exprData_getFieldNode (data) ) );
1226 //exprData_getFieldName (data) ;
1230 ret = constraintList_addList (ret,
1231 exprNode_traversTrueEnsuresConstraints
1232 (exprData_getFieldNode (data) ) );
1233 // exprData_getFieldName (data);
1236 case XPR_STRINGLITERAL:
1237 // cstring_copy (exprData_getLiteral (data));
1241 // cstring_copy (exprData_getLiteral (data));
1245 ret = constraintList_addList (ret,
1246 exprNode_traversTrueEnsuresConstraints
1247 (exprData_getUopNode (data) ) );
1252 ret = constraintList_addList (ret,
1253 exprNode_traversTrueEnsuresConstraints
1254 (exprData_getCastNode (data) ) );
1265 constraintList exprNode_traversFalseEnsuresConstraints (exprNode e)
1269 bool handledExprNode;
1274 if (exprNode_handleError (e))
1276 ret = constraintList_makeNew();
1279 ret = constraintList_copy (e->falseEnsuresConstraints );
1281 handledExprNode = TRUE;
1288 t1 = exprData_getSingle (data);
1289 ret = constraintList_addList ( ret,exprNode_traversFalseEnsuresConstraints (t1) );
1294 ret = constraintList_addList (ret,
1295 exprNode_traversFalseEnsuresConstraints
1296 (exprData_getPairA (data) ) );
1298 ret = constraintList_addList (ret,
1299 exprNode_traversFalseEnsuresConstraints
1300 (exprData_getPairB (data) ) );
1304 ret = constraintList_addList (ret,
1305 exprNode_traversFalseEnsuresConstraints
1306 (exprData_getUopNode (data) ) );
1310 ret = constraintList_addList (ret, exprNode_traversFalseEnsuresConstraints
1311 (exprData_getUopNode (data) ) );
1314 ret = constraintList_addList (ret,
1315 exprNode_traversFalseEnsuresConstraints
1316 (exprData_getOpA (data) ) );
1318 ret = constraintList_addList (ret,
1319 exprNode_traversFalseEnsuresConstraints
1320 (exprData_getOpB (data) ) );
1323 ret = constraintList_addList (ret,
1324 exprNode_traversFalseEnsuresConstraints
1325 (exprData_getOpA (data) ) );
1327 ret = constraintList_addList (ret,
1328 exprNode_traversFalseEnsuresConstraints
1329 (exprData_getOpB (data) ) );
1333 // ctype_unparse (qtype_getType (exprData_getType (data) ) );
1339 ret = constraintList_addList (ret,
1340 exprNode_traversFalseEnsuresConstraints
1341 (exprData_getSingle (data) ) );
1345 ret = constraintList_addList (ret,
1346 exprNode_traversFalseEnsuresConstraints
1347 (exprData_getFcn (data) ) );
1348 /*@i11*/ // exprNodeList_unparse (exprData_getArgs (data) );
1352 ret = constraintList_addList (ret,
1353 exprNode_traversFalseEnsuresConstraints
1354 (exprData_getSingle (data) ) );
1357 case XPR_NULLRETURN:
1358 // cstring_makeLiteral ("return");;
1362 ret = constraintList_addList (ret,
1363 exprNode_traversFalseEnsuresConstraints
1364 (exprData_getFieldNode (data) ) );
1365 //exprData_getFieldName (data) ;
1369 ret = constraintList_addList (ret,
1370 exprNode_traversFalseEnsuresConstraints
1371 (exprData_getFieldNode (data) ) );
1372 // exprData_getFieldName (data);
1375 case XPR_STRINGLITERAL:
1376 // cstring_copy (exprData_getLiteral (data));
1380 // cstring_copy (exprData_getLiteral (data));
1384 ret = constraintList_addList (ret,
1385 exprNode_traversFalseEnsuresConstraints
1386 (exprData_getUopNode (data) ) );
1391 ret = constraintList_addList (ret,
1392 exprNode_traversFalseEnsuresConstraints
1393 (exprData_getCastNode (data) ) );
1404 /* walk down the tree and get all requires Constraints in each subexpression*/
1405 constraintList exprNode_traversRequiresConstraints (exprNode e)
1409 bool handledExprNode;
1414 if (exprNode_handleError (e))
1416 ret = constraintList_makeNew();
1419 ret = constraintList_copy (e->requiresConstraints );
1421 handledExprNode = TRUE;
1428 t1 = exprData_getSingle (data);
1429 ret = constraintList_addList ( ret,exprNode_traversRequiresConstraints (t1) );
1434 ret = constraintList_addList (ret,
1435 exprNode_traversRequiresConstraints
1436 (exprData_getPairA (data) ) );
1438 ret = constraintList_addList (ret,
1439 exprNode_traversRequiresConstraints
1440 (exprData_getPairB (data) ) );
1444 ret = constraintList_addList (ret,
1445 exprNode_traversRequiresConstraints
1446 (exprData_getUopNode (data) ) );
1450 ret = constraintList_addList (ret, exprNode_traversRequiresConstraints
1451 (exprData_getUopNode (data) ) );
1454 ret = constraintList_addList (ret,
1455 exprNode_traversRequiresConstraints
1456 (exprData_getOpA (data) ) );
1458 ret = constraintList_addList (ret,
1459 exprNode_traversRequiresConstraints
1460 (exprData_getOpB (data) ) );
1463 ret = constraintList_addList (ret,
1464 exprNode_traversRequiresConstraints
1465 (exprData_getOpA (data) ) );
1467 ret = constraintList_addList (ret,
1468 exprNode_traversRequiresConstraints
1469 (exprData_getOpB (data) ) );
1473 // ctype_unparse (qtype_getType (exprData_getType (data) ) );
1479 ret = constraintList_addList (ret,
1480 exprNode_traversRequiresConstraints
1481 (exprData_getSingle (data) ) );
1485 ret = constraintList_addList (ret,
1486 exprNode_traversRequiresConstraints
1487 (exprData_getFcn (data) ) );
1488 /*@i11*/ // exprNodeList_unparse (exprData_getArgs (data) );
1492 ret = constraintList_addList (ret,
1493 exprNode_traversRequiresConstraints
1494 (exprData_getSingle (data) ) );
1497 case XPR_NULLRETURN:
1498 // cstring_makeLiteral ("return");;
1502 ret = constraintList_addList (ret,
1503 exprNode_traversRequiresConstraints
1504 (exprData_getFieldNode (data) ) );
1505 //exprData_getFieldName (data) ;
1509 ret = constraintList_addList (ret,
1510 exprNode_traversRequiresConstraints
1511 (exprData_getFieldNode (data) ) );
1512 // exprData_getFieldName (data);
1515 case XPR_STRINGLITERAL:
1516 // cstring_copy (exprData_getLiteral (data));
1520 // cstring_copy (exprData_getLiteral (data));
1524 ret = constraintList_addList (ret,
1525 exprNode_traversRequiresConstraints
1526 (exprData_getUopNode (data) ) );
1531 ret = constraintList_addList (ret,
1532 exprNode_traversRequiresConstraints
1533 (exprData_getCastNode (data) ) );
1544 /* walk down the tree and get all Ensures Constraints in each subexpression*/
1545 constraintList exprNode_traversEnsuresConstraints (exprNode e)
1549 bool handledExprNode;
1552 // constraintExpr tmp;
1557 if (exprNode_handleError (e))
1559 ret = constraintList_makeNew();
1563 ret = constraintList_copy (e->ensuresConstraints );
1564 handledExprNode = TRUE;
1569 "exprnode_traversEnsuresConstraints call for %s with constraintList of %s",
1570 exprNode_unparse (e),
1571 constraintList_print(e->ensuresConstraints)
1579 t1 = exprData_getSingle (data);
1580 ret = constraintList_addList ( ret,exprNode_traversEnsuresConstraints (t1) );
1585 ret = constraintList_addList (ret,
1586 exprNode_traversEnsuresConstraints
1587 (exprData_getPairA (data) ) );
1589 ret = constraintList_addList (ret,
1590 exprNode_traversEnsuresConstraints
1591 (exprData_getPairB (data) ) );
1595 ret = constraintList_addList (ret,
1596 exprNode_traversEnsuresConstraints
1597 (exprData_getUopNode (data) ) );
1601 ret = constraintList_addList (ret, exprNode_traversEnsuresConstraints
1602 (exprData_getUopNode (data) ) );
1605 ret = constraintList_addList (ret,
1606 exprNode_traversEnsuresConstraints
1607 (exprData_getOpA (data) ) );
1609 ret = constraintList_addList (ret,
1610 exprNode_traversEnsuresConstraints
1611 (exprData_getOpB (data) ) );
1614 ret = constraintList_addList (ret,
1615 exprNode_traversEnsuresConstraints
1616 (exprData_getOpA (data) ) );
1618 ret = constraintList_addList (ret,
1619 exprNode_traversEnsuresConstraints
1620 (exprData_getOpB (data) ) );
1624 // ctype_unparse (qtype_getType (exprData_getType (data) ) );
1630 ret = constraintList_addList (ret,
1631 exprNode_traversEnsuresConstraints
1632 (exprData_getSingle (data) ) );
1636 ret = constraintList_addList (ret,
1637 exprNode_traversEnsuresConstraints
1638 (exprData_getFcn (data) ) );
1639 /*@i11*/ // exprNodeList_unparse (exprData_getArgs (data) );
1643 ret = constraintList_addList (ret,
1644 exprNode_traversEnsuresConstraints
1645 (exprData_getSingle (data) ) );
1648 case XPR_NULLRETURN:
1649 // cstring_makeLiteral ("return");;
1653 ret = constraintList_addList (ret,
1654 exprNode_traversEnsuresConstraints
1655 (exprData_getFieldNode (data) ) );
1656 //exprData_getFieldName (data) ;
1660 ret = constraintList_addList (ret,
1661 exprNode_traversEnsuresConstraints
1662 (exprData_getFieldNode (data) ) );
1663 // exprData_getFieldName (data);
1666 case XPR_STRINGLITERAL:
1667 // cstring_copy (exprData_getLiteral (data));
1671 // cstring_copy (exprData_getLiteral (data));
1675 ret = constraintList_addList (ret,
1676 exprNode_traversEnsuresConstraints
1677 (exprData_getUopNode (data) ) );
1681 ret = constraintList_addList (ret,
1682 exprNode_traversEnsuresConstraints
1683 (exprData_getCastNode (data) ) );
1690 "exprnode_traversEnsuresConstraints call for %s with constraintList of is returning %s",
1691 exprNode_unparse (e),
1692 // constraintList_print(e->ensuresConstraints),
1693 constraintList_print(ret)