2 ** Splint - annotation-assisted static program checker
3 ** Copyright (C) 1994-2002 University of Virginia,
4 ** Massachusetts Institute of Technology
6 ** This program is free software; you can redistribute it and/or modify it
7 ** under the terms of the GNU General Public License as published by the
8 ** Free Software Foundation; either version 2 of the License, or (at your
9 ** option) any later version.
11 ** This program is distributed in the hope that it will be useful, but
12 ** WITHOUT ANY WARRANTY; without even the implied warranty of
13 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 ** General Public License for more details.
16 ** The GNU General Public License is available from http://www.gnu.org/ or
17 ** the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
18 ** MA 02111-1307, USA.
20 ** For information on splint: info@splint.org
21 ** To report a bug: splint-bug@splint.org
22 ** For more information: http://www.splint.org
26 ** constraintGeneration.c
29 /* #define DEBUGPRINT 1 */
31 # include <ctype.h> /* for isdigit */
32 # include "splintMacros.nf"
35 # include "cgrammar_tokens.h"
37 # include "exprChecks.h"
38 # include "exprNodeSList.h"
40 /*@access exprNode @*/
43 static bool exprNode_handleError(/*@dependent@*/ exprNode p_e);
45 static void exprNode_stmt ( /*@dependent@*/ /*@temp@*/ exprNode p_e);
47 static bool exprNode_isMultiStatement(/*@dependent@*/ exprNode p_e);
48 static void exprNode_multiStatement (/*@dependent@*/ exprNode p_e);
50 static constraintList exprNode_traversTrueEnsuresConstraints (/*@dependent@*/ exprNode p_e);
51 static constraintList exprNode_traversFalseEnsuresConstraints (/*@dependent@*/ exprNode p_e);
53 static void checkArgumentList (/*@out@*/ exprNode p_temp, exprNodeList p_arglist, fileloc p_sequencePoint) /*@modifies p_temp @*/;
55 static constraintList checkCall (/*@dependent@*/ exprNode p_fcn, exprNodeList p_arglist);
57 static bool exprNode_isUnhandled (/*@dependent@*/ /*@observer@*/ exprNode e)
59 llassert( exprNode_isDefined(e) );
85 DPRINTF((message ("Warning current constraint generation does not handle expression %s", exprNode_unparse(e)) ) );
97 bool exprNode_handleError( exprNode e)
99 if (exprNode_isError (e) || exprNode_isUnhandled(e) )
101 static /*@only@*/ cstring error = cstring_undefined;
103 if (!cstring_isDefined (error))
105 error = cstring_makeLiteral ("<error>");
108 /*@-unqualifiedtrans*/ return TRUE; /*@=unqualifiedtrans*/
113 bool /*@alt void@*/ exprNode_generateConstraints (/*@dependent@*/ exprNode e)
115 if (exprNode_isError (e) )
118 if (exprNode_isUnhandled (e) )
120 DPRINTF((message("Warning ignoring %s", exprNode_unparse (e) ) ) );
124 DPRINTF((message ("exprNode_generateConstraints Analysising %s at %s", exprNode_unparse( e),
125 fileloc_unparse(exprNode_getfileloc(e) ) ) ) );
127 if (exprNode_isMultiStatement ( e) )
129 exprNode_multiStatement(e);
135 /* loc = exprNode_getNextSequencePoint(e); */
136 /* exprNode_exprTraverse(e, FALSE, FALSE, loc); */
138 /* fileloc_free(loc); */
148 c = constraintList_makeFixedArrayConstraints (e->uses);
149 e->requiresConstraints = constraintList_reflectChangesFreePre (e->requiresConstraints, c);
150 constraintList_free(c);
153 DPRINTF ((message ("e->requiresConstraints %s", constraintList_printDetailed (e->requiresConstraints) ) ) );
158 /* handles multiple statements */
160 bool exprNode_isMultiStatement(exprNode e)
162 if (exprNode_handleError (e) != NULL)
185 static void exprNode_stmt ( /*@dependent@*/ /*@temp@*/ exprNode e)
191 if (exprNode_isError(e) )
196 /*e->requiresConstraints = constraintList_makeNew();
197 e->ensuresConstraints = constraintList_makeNew(); */
199 DPRINTF(( "expNode_stmt: STMT:") );
200 s = exprNode_unparse(e);
201 DPRINTF (( message("exprNode_stmt: STMT: %s ", s) ) );
203 if (e->kind == XPR_INIT)
205 constraintList tempList;
207 DPRINTF ((message ("%s ", exprNode_unparse (e)) ) );
208 loc = exprNode_getNextSequencePoint(e); /* reduces to an expression */
209 exprNode_exprTraverse (e, FALSE, FALSE, loc);
212 tempList = e->requiresConstraints;
213 e->requiresConstraints = exprNode_traversRequiresConstraints(e);
214 constraintList_free(tempList);
216 tempList = e->ensuresConstraints;
217 e->ensuresConstraints = exprNode_traversEnsuresConstraints(e);
218 constraintList_free(tempList);
222 /*drl 2/13/002 patched bug so return statement will be checked*/
223 /*return is a stmt not not expression ...*/
224 if (e->kind == XPR_RETURN)
226 constraintList tempList;
228 loc = exprNode_getNextSequencePoint(e); /* reduces to an expression */
230 exprNode_exprTraverse (exprData_getSingle (e->edata), FALSE, TRUE, loc);
233 tempList = e->requiresConstraints;
234 e->requiresConstraints = exprNode_traversRequiresConstraints(e);
235 constraintList_free(tempList);
238 if (e->kind != XPR_STMT)
241 DPRINTF (("Not Stmt") );
242 DPRINTF ((message ("%s ", exprNode_unparse (e)) ) );
244 if (exprNode_isMultiStatement (e))
246 exprNode_multiStatement (e); /* evans 2001-08-21: spurious return removed */
250 loc = exprNode_getNextSequencePoint(e); /* reduces to an expression */
252 exprNode_exprTraverse (e, FALSE, TRUE, loc);
260 DPRINTF ((message ("%s ", exprNode_unparse (e)) ) );
262 snode = exprData_getUopNode (e->edata);
264 /* could be stmt involving multiple statements:
265 i.e. if, while for ect.
268 if (exprNode_isMultiStatement (snode))
270 exprNode_multiStatement (snode);
271 (void) exprNode_copyConstraints (e, snode);
275 loc = exprNode_getNextSequencePoint(e); /* reduces to an expression */
276 exprNode_exprTraverse (snode, FALSE, FALSE, loc);
280 constraintList_free (e->requiresConstraints);
281 e->requiresConstraints = exprNode_traversRequiresConstraints(snode);
283 constraintList_free (e->ensuresConstraints);
284 e->ensuresConstraints = exprNode_traversEnsuresConstraints(snode);
286 DPRINTF ((message ("smtlist constraints are: pre: %s \n and \t post %s\n",
287 constraintList_print(e->requiresConstraints),
288 constraintList_print(e->ensuresConstraints) ) ) );
293 static void exprNode_stmtList (/*@dependent@*/ exprNode e)
295 exprNode stmt1, stmt2;
296 if (exprNode_isError (e) )
302 Handle case of stmtList with only one statement:
303 The parse tree stores this as stmt instead of stmtList
306 if (e->kind != XPR_STMTLIST)
311 llassert (e->kind == XPR_STMTLIST);
312 DPRINTF(( "exprNode_stmtList STMTLIST:") );
313 DPRINTF ((cstring_toCharsSafe (exprNode_unparse(e)) ) );
314 stmt1 = exprData_getPairA (e->edata);
315 stmt2 = exprData_getPairB (e->edata);
318 DPRINTF(("exprNode_stmtlist ") );
319 DPRINTF ((message("XW%s | %s", exprNode_unparse(stmt1), exprNode_unparse(stmt2) ) ) );
321 exprNode_stmt (stmt1);
322 DPRINTF(("\nstmt after stmtList call " ));
324 exprNode_stmt (stmt2);
325 exprNode_mergeResolve (e, stmt1, stmt2 );
327 DPRINTF ((message ("smtlist constraints are: pre: %s \n and \t post %s\n",
328 constraintList_print(e->requiresConstraints),
329 constraintList_print(e->ensuresConstraints) ) ) );
333 static exprNode doIf (/*@returned@*/ exprNode e, /*@dependent@*/ exprNode test, /*@dependent@*/ exprNode body)
337 DPRINTF ((message ("doIf: %s ", exprNode_unparse(e) ) ) );
339 llassert(exprNode_isDefined(test) );
340 llassert (exprNode_isDefined (e) );
341 llassert (exprNode_isDefined (body) );
344 DPRINTF((message ("ensures constraints for %s are %s", exprNode_unparse(e), constraintList_printDetailed(e->ensuresConstraints) ) ));
346 DPRINTF((message ("Requires constraints for %s are %s", exprNode_unparse(e), constraintList_printDetailed(e->ensuresConstraints) ) ));
348 DPRINTF((message ("trueEnsures constraints for %s are %s", exprNode_unparse(e), constraintList_printDetailed(e->trueEnsuresConstraints) ) ));
350 DPRINTF((message ("falseEnsures constraints for %s are %s", exprNode_unparse(e), constraintList_printDetailed(e->falseEnsuresConstraints) ) ));
354 DPRINTF((message ("ensures constraints for %s are %s", exprNode_unparse(test), constraintList_printDetailed(test->ensuresConstraints) ) ));
356 DPRINTF((message ("Requires constraints for %s are %s", exprNode_unparse(test), constraintList_printDetailed(test->ensuresConstraints) ) ));
358 DPRINTF((message ("trueEnsures constraints for %s are %s", exprNode_unparse(test), constraintList_printDetailed(test->trueEnsuresConstraints) ) ));
360 DPRINTF((message ("falseEnsures constraints for %s are %s", exprNode_unparse(test), constraintList_printDetailed(test->falseEnsuresConstraints) ) ));
364 temp = test->trueEnsuresConstraints;
365 test->trueEnsuresConstraints = exprNode_traversTrueEnsuresConstraints(test);
366 constraintList_free(temp);
368 temp = test->ensuresConstraints;
369 test->ensuresConstraints = exprNode_traversEnsuresConstraints (test);
370 constraintList_free(temp);
372 temp = test->requiresConstraints;
373 test->requiresConstraints = exprNode_traversRequiresConstraints (test);
374 constraintList_free(temp);
377 test->trueEnsuresConstraints = constraintList_substituteFreeTarget(test->trueEnsuresConstraints, test->ensuresConstraints);
379 DPRINTF ((message ("doIf: test ensures %s ", constraintList_print(test->ensuresConstraints) ) ) );
381 DPRINTF ((message ("doIf: test true ensures %s ", constraintList_print(test->trueEnsuresConstraints) ) ) );
383 constraintList_free(e->requiresConstraints);
386 e->requiresConstraints = constraintList_reflectChanges(body->requiresConstraints, test->trueEnsuresConstraints);
388 e->requiresConstraints = constraintList_reflectChangesFreePre (e->requiresConstraints,
389 test->ensuresConstraints);
390 temp = e->requiresConstraints;
391 e->requiresConstraints = constraintList_mergeRequires (e->requiresConstraints, test->requiresConstraints);
392 constraintList_free(temp);
395 /* drl possible problem : warning bad */
396 constraintList_free(e->ensuresConstraints);
397 e->ensuresConstraints = constraintList_copy (test->ensuresConstraints);
399 if (exprNode_mayEscape (body) )
401 DPRINTF (( message("doIf: the if statement body %s returns or exits", exprNode_unparse(body) ) ));
402 e->ensuresConstraints = constraintList_mergeEnsuresFreeFirst (e->ensuresConstraints,
403 test->falseEnsuresConstraints);
406 DPRINTF ((message ("doIf: if requiers %s ", constraintList_print(e->requiresConstraints) ) ) );
412 Also used for condition i.e. ?: operation
415 This function assumes that p, trueBranch, falseBranch have have all been traversed
416 for constraints i.e. we assume that exprNode_traversEnsuresConstraints,
417 exprNode_traversRequiresConstraints, exprNode_traversTrueEnsuresConstraints,
418 exprNode_traversFalseEnsuresConstraints have all been run
422 static exprNode doIfElse (/*@returned@*/ exprNode e, /*@dependent@*/ exprNode p, /*@dependent@*/ exprNode trueBranch, /*@dependent@*/ exprNode falseBranch)
424 constraintList c1, cons, t, t2, f, f2;
426 DPRINTF ((message ("doIfElse: %s ", exprNode_unparse(e) ) ) );
428 /* do requires clauses */
429 c1 = constraintList_copy (p->ensuresConstraints);
431 t = constraintList_reflectChanges(trueBranch->requiresConstraints, p->trueEnsuresConstraints);
432 t = constraintList_reflectChangesFreePre (t, p->ensuresConstraints);
434 cons = constraintList_reflectChanges(falseBranch->requiresConstraints, p->falseEnsuresConstraints);
435 cons = constraintList_reflectChangesFreePre (cons, c1);
437 constraintList_free(e->requiresConstraints);
438 e->requiresConstraints = constraintList_mergeRequiresFreeFirst (t, cons);
439 e->requiresConstraints = constraintList_mergeRequiresFreeFirst (e->requiresConstraints, p->requiresConstraints);
441 /* do ensures clauses
442 find the the ensures lists for each subbranch
445 t = constraintList_mergeEnsures (p->trueEnsuresConstraints, trueBranch->ensuresConstraints);
447 t = constraintList_mergeEnsures (p->ensuresConstraints, t);
448 constraintList_free(t2);
450 f = constraintList_mergeEnsures (p->falseEnsuresConstraints, falseBranch->ensuresConstraints);
452 f = constraintList_mergeEnsures (p->ensuresConstraints, f);
453 constraintList_free(f2);
455 /* find ensures for whole if/else statement */
457 constraintList_free(e->ensuresConstraints);
459 e->ensuresConstraints = constraintList_logicalOr (t, f);
461 constraintList_free(t);
462 constraintList_free(f);
463 constraintList_free(cons);
464 constraintList_free(c1);
466 DPRINTF ((message ("doIfElse: if requires %q ", constraintList_print(e->requiresConstraints) ) ) );
467 DPRINTF ((message ("doIfElse: if ensures %q ", constraintList_print(e->ensuresConstraints) ) ) );
472 static exprNode doWhile (/*@returned@*/ exprNode e, /*@dependent@*/ exprNode test, /*@dependent@*/ exprNode body)
474 DPRINTF ((message ("doWhile: %s ", exprNode_unparse(e) ) ) );
475 return doIf (e, test, body);
478 /*@only@*/ constraintList constraintList_makeFixedArrayConstraints (/*@observer@*/ sRefSet s)
482 ret = constraintList_makeNew();
484 sRefSet_elements (s, el)
486 if (sRef_isFixedArray(el) )
489 DPRINTF((message("%s is a fixed array",
490 sRef_unparse(el)) ) );
491 size = sRef_getArraySize(el);
492 DPRINTF((message("%s is a fixed array with size %d",
493 sRef_unparse(el), (int)size) ) );
494 con = constraint_makeSRefSetBufferSize (el, (size - 1));
495 ret = constraintList_add(ret, con);
499 DPRINTF((message("%s is not a fixed array",
500 sRef_unparse(el)) ) );
503 if (sRef_isExternallyVisible (el) )
506 DPRINTF((message("%s is externally visible",
507 sRef_unparse(el) ) ));
508 con = constraint_makeSRefWriteSafeInt(el, 0);
509 ret = constraintList_add(ret, con);
511 con = constraint_makeSRefReadSafeInt(el, 0);
513 ret = constraintList_add(ret, con);
518 end_sRefSet_elements ;
520 DPRINTF(( message("constraintList_makeFixedArrayConstraints returning %s",
521 constraintList_print(ret) ) ));
526 exprNode makeDataTypeConstraints (/*@returned@*/ exprNode e)
529 DPRINTF(("makeDataTypeConstraints"));
531 c = constraintList_makeFixedArrayConstraints (e->uses);
533 e->ensuresConstraints = constraintList_addListFree (e->ensuresConstraints, c);
539 static void doFor (/*@dependent@*/ exprNode e, /*@dependent@*/ exprNode forPred, /*@dependent@*/ exprNode forBody)
541 exprNode init, test, inc;
542 /* merge the constraints: modle as if statement */
548 init = exprData_getTripleInit (forPred->edata);
549 test = exprData_getTripleTest (forPred->edata);
550 inc = exprData_getTripleInc (forPred->edata);
552 if (( (exprNode_isError (test) /*|| (exprNode_isError(init) )*/ ) || (exprNode_isError (inc) ) ) )
554 DPRINTF ((message ("strange for statement:%s, ignoring it", exprNode_unparse(e) ) ) );
558 exprNode_forLoopHeuristics(e, forPred, forBody);
560 constraintList_free(e->requiresConstraints);
561 e->requiresConstraints = constraintList_reflectChanges(forBody->requiresConstraints, test->ensuresConstraints);
562 e->requiresConstraints = constraintList_reflectChangesFreePre (e->requiresConstraints, test->trueEnsuresConstraints);
563 e->requiresConstraints = constraintList_reflectChangesFreePre (e->requiresConstraints, forPred->ensuresConstraints);
565 if (!forBody->canBreak)
567 e->ensuresConstraints = constraintList_addListFree(e->ensuresConstraints, constraintList_copy(forPred->ensuresConstraints) );
568 e->ensuresConstraints = constraintList_addListFree(e->ensuresConstraints,constraintList_copy( test->falseEnsuresConstraints));
572 DPRINTF(("Can break") );
576 static /*@dependent@*/ exprNode exprNode_makeDependent(/*@returned@*/ exprNode e)
584 exprNode_doGenerateConstraintSwitch
585 (/*@dependent@*/ exprNode switchExpr,
586 /*@dependent@*/ exprNode body,
587 /*@special@*/ constraintList *currentRequires,
588 /*@special@*/ constraintList *currentEnsures,
589 /*@special@*/ constraintList *savedRequires,
590 /*@special@*/ constraintList *savedEnsures)
591 /*@post:only *currentRequires, *currentEnsures, *savedRequires, *savedEnsures @*/
592 /*@sets *currentRequires, *currentEnsures, *savedRequires, *savedEnsures @*/
594 exprNode stmt, stmtList;
596 DPRINTF(( message("exprNode_doGenerateConstraintSwitch: (switch %s) %s",
597 exprNode_unparse(switchExpr), exprNode_unparse(body)
600 if (exprNode_isError(body) )
602 *currentRequires = constraintList_makeNew ();
603 *currentEnsures = constraintList_makeNew ();
605 *savedRequires = constraintList_makeNew ();
606 *savedEnsures = constraintList_makeNew ();
612 if (body->kind != XPR_STMTLIST )
614 DPRINTF((message("exprNode_doGenerateConstraintSwitch: non stmtlist: %s",
615 exprNode_unparse(body) )));
617 stmtList = exprNode_undefined;
618 stmt = exprNode_makeDependent(stmt);
619 stmtList = exprNode_makeDependent(stmtList);
623 stmt = exprData_getPairB(body->edata);
624 stmtList = exprData_getPairA(body->edata);
625 stmt = exprNode_makeDependent(stmt);
626 stmtList = exprNode_makeDependent(stmtList);
629 DPRINTF((message("exprNode_doGenerateConstraintSwitch: stmtlist: %s stmt: %s",
630 exprNode_unparse(stmtList), exprNode_unparse(stmt) )
634 exprNode_doGenerateConstraintSwitch (switchExpr, stmtList, currentRequires, currentEnsures,
635 savedRequires, savedEnsures );
637 if (exprNode_isError(stmt) )
644 switchExpr = exprNode_makeDependent (switchExpr);
646 if (! exprNode_isCaseMarker(stmt) )
651 DPRINTF (( message("Got normal statement %s (requires %s ensures %s)", exprNode_unparse(stmt),
652 constraintList_unparse(stmt->requiresConstraints), constraintList_unparse(stmt->ensuresConstraints) ) ));
654 temp = constraintList_reflectChanges (stmt->requiresConstraints,
657 *currentRequires = constraintList_mergeRequiresFreeFirst(
661 constraintList_free(temp);
663 *currentEnsures = constraintList_mergeEnsuresFreeFirst
665 stmt->ensuresConstraints);
666 DPRINTF(( message("returning from exprNode_doGenerateConstraintSwitch: (switch %s) %s currentRequires:"
667 "%s currentEnsures:%s",
668 exprNode_unparse(switchExpr), exprNode_unparse(body),
669 constraintList_print(*currentRequires), constraintList_print(*currentEnsures)
677 if (exprNode_isCaseMarker(stmt) && exprNode_mustEscape(stmtList) )
680 ** merge current and saved constraint with Logical Or...
681 ** make a constraint for ensures
687 DPRINTF (( message("Got case marker") ));
689 if (constraintList_isUndefined(*savedEnsures) &&
690 constraintList_isUndefined(*savedRequires) )
692 llassert(constraintList_isUndefined(*savedEnsures) );
693 llassert(constraintList_isUndefined(*savedRequires) );
694 *savedEnsures = constraintList_copy(*currentEnsures);
695 *savedRequires = constraintList_copy(*currentRequires);
699 DPRINTF (( message("Doing logical or") ));
700 temp = constraintList_logicalOr (*savedEnsures, *currentEnsures);
701 constraintList_free (*savedEnsures);
702 *savedEnsures = temp;
704 *savedRequires = constraintList_mergeRequiresFreeFirst (*savedRequires, *currentRequires);
707 con = constraint_makeEnsureEqual (switchExpr, exprData_getSingle
708 (stmt->edata), exprNode_getfileloc(stmt) );
711 constraintList_free(*currentEnsures);
712 *currentEnsures = constraintList_makeNew();
713 *currentEnsures = constraintList_add(*currentEnsures, con);
715 constraintList_free(*currentRequires);
716 *currentRequires = constraintList_makeNew();
717 DPRINTF(( message("exprNode_doGenerateConstraintSwitch: (switch %s) %s savedRequires:"
718 "%s savedEnsures:%s",
719 exprNode_unparse(switchExpr), exprNode_unparse(body),
720 constraintList_print(*savedRequires), constraintList_print(*savedEnsures)
725 else if (exprNode_isCaseMarker(stmt) )
726 /* prior case has no break. */
729 We don't do anything to the sved constraints because the case hasn't ended
730 The new ensures constraints for the case will be:
731 the constraint for the case statement (CASE_LABEL == SWITCH_EXPR) logicalOr currentEnsures
737 constraintList ensuresTemp;
739 DPRINTF (( message("Got case marker with no prior break") ));
741 con = constraint_makeEnsureEqual (switchExpr, exprData_getSingle
742 (stmt->edata), exprNode_getfileloc(stmt) );
744 ensuresTemp = constraintList_makeNew();
746 ensuresTemp = constraintList_add (ensuresTemp, con);
748 if (exprNode_isError(stmtList) )
750 constraintList_free(*currentEnsures);
752 *currentEnsures = constraintList_copy(ensuresTemp);
753 constraintList_free(ensuresTemp);
759 temp = constraintList_logicalOr (*currentEnsures, ensuresTemp);
761 constraintList_free(*currentEnsures);
762 constraintList_free(ensuresTemp);
764 *currentEnsures = temp;
766 constraintList_free(*currentRequires);
768 *currentRequires = constraintList_makeNew();
773 we handle the case of ! exprNode_isCaseMarker above
774 the else if clause should always be true.
779 DPRINTF(( message("returning from exprNode_doGenerateConstraintSwitch: (switch %s) %s currentRequires:"
780 "%s currentEnsures:%s",
781 exprNode_unparse(switchExpr), exprNode_unparse(body),
782 constraintList_print(*currentRequires), constraintList_print(*currentEnsures)
791 static void exprNode_generateConstraintSwitch (exprNode switchStmt)
793 constraintList constraintsRequires;
794 constraintList constraintsEnsures;
795 constraintList lastRequires;
796 constraintList lastEnsures;
801 switchExpr = exprData_getPairA(switchStmt->edata);
802 body = exprData_getPairB(switchStmt->edata);
805 DPRINTF((message("") ));
807 if ( body->kind == XPR_BLOCK)
808 body = exprData_getSingle(body->edata);
811 constraintsRequires = constraintList_undefined;
812 constraintsEnsures = constraintList_undefined;
814 lastRequires = constraintList_makeNew();
815 lastEnsures = constraintList_makeNew();
819 /*@i6534 - evans 2002-01-01: spurious warnings for these becuase of stack allocated storage */
820 exprNode_doGenerateConstraintSwitch (switchExpr, body, &lastRequires,
821 &lastEnsures, &constraintsRequires, &constraintsEnsures);
825 merge current and saved constraint with Logical Or...
826 make a constraint for ensures
829 constraintList_free(switchStmt->requiresConstraints);
830 constraintList_free(switchStmt->ensuresConstraints);
832 if (constraintList_isDefined(constraintsEnsures) && constraintList_isDefined(constraintsRequires) )
834 switchStmt->ensuresConstraints = constraintList_logicalOr(constraintsEnsures, lastEnsures);
835 switchStmt->requiresConstraints = constraintList_mergeRequires(constraintsRequires, lastRequires);
836 constraintList_free (constraintsRequires);
837 constraintList_free (constraintsEnsures);
841 switchStmt->ensuresConstraints = constraintList_copy(lastEnsures);
842 switchStmt->requiresConstraints = constraintList_copy(lastRequires);
845 constraintList_free (lastRequires);
846 constraintList_free (lastEnsures);
848 DPRINTF(((message(" exprNode_generateConstraintSwitch returning requires: %s and ensures %s",
849 constraintList_print( switchStmt->requiresConstraints),
850 constraintList_print( switchStmt->ensuresConstraints)
855 static exprNode doSwitch (/*@returned@*/ exprNode e)
861 DPRINTF (( message ("doSwitch for: switch (%s) %s",
862 exprNode_unparse (exprData_getPairA (data)),
863 exprNode_unparse (exprData_getPairB (data))) ));
865 body = exprData_getPairB (data);
866 exprNode_generateConstraintSwitch (e);
870 void exprNode_multiStatement (/*@dependent@*/ exprNode e)
876 exprNode p, trueBranch, falseBranch;
877 exprNode forPred, forBody;
882 DPRINTF((message ("exprNode_multistatement Analysising %s %s at", exprNode_unparse( e),
883 fileloc_unparse(exprNode_getfileloc(e) ) ) ) );
885 if (exprNode_handleError (e))
898 forPred = exprData_getPairA (data);
899 forBody = exprData_getPairB (data);
901 /* First generate the constraints */
902 exprNode_generateConstraints (forPred);
903 exprNode_generateConstraints (forBody);
906 doFor (e, forPred, forBody);
911 exprNode_generateConstraints (exprData_getTripleInit (data) );
912 test = exprData_getTripleTest (data);
913 exprNode_exprTraverse (test,FALSE, FALSE, exprNode_loc(e));
914 exprNode_generateConstraints (exprData_getTripleInc (data) );
916 if (!exprNode_isError(test) )
918 constraintList temp2;
919 temp2 = test->trueEnsuresConstraints;
920 test->trueEnsuresConstraints = exprNode_traversTrueEnsuresConstraints(test);
921 constraintList_free(temp2);
924 exprNode_generateConstraints (exprData_getTripleInc (data));
928 e1 = exprData_getPairA (data);
929 e2 = exprData_getPairB (data);
931 exprNode_exprTraverse (e1,
932 FALSE, FALSE, exprNode_loc(e1));
934 exprNode_generateConstraints (e2);
936 e = doWhile (e, e1, e2);
942 DPRINTF ((exprNode_unparse(e) ) );
943 e1 = exprData_getPairA (data);
944 e2 = exprData_getPairB (data);
946 exprNode_exprTraverse (e1, FALSE, FALSE, exprNode_loc(e1));
948 exprNode_generateConstraints (e2);
949 e = doIf (e, e1, e2);
953 DPRINTF(("Starting IFELSE"));
954 p = exprData_getTriplePred (data);
955 trueBranch = exprData_getTripleTrue (data);
956 falseBranch = exprData_getTripleFalse (data);
958 exprNode_exprTraverse (p,
959 FALSE, FALSE, exprNode_loc(p));
960 exprNode_generateConstraints (trueBranch);
961 exprNode_generateConstraints (falseBranch);
963 temp = p->ensuresConstraints;
964 p->ensuresConstraints = exprNode_traversEnsuresConstraints (p);
965 constraintList_free(temp);
967 temp = p->requiresConstraints;
968 p->requiresConstraints = exprNode_traversRequiresConstraints (p);
969 constraintList_free(temp);
971 temp = p->trueEnsuresConstraints;
972 p->trueEnsuresConstraints = exprNode_traversTrueEnsuresConstraints(p);
973 constraintList_free(temp);
975 temp = p->falseEnsuresConstraints;
976 p->falseEnsuresConstraints = exprNode_traversFalseEnsuresConstraints(p);
977 constraintList_free(temp);
979 e = doIfElse (e, p, trueBranch, falseBranch);
980 DPRINTF(("Done IFELSE") );
985 e2 = (exprData_getPairB (data));
986 e1 = (exprData_getPairA (data));
988 DPRINTF((message ("do { %s } while (%s)", exprNode_unparse(e2), exprNode_unparse(e1) ) ));
989 exprNode_generateConstraints (e2);
990 exprNode_generateConstraints (e1);
991 e = exprNode_copyConstraints (e, e2);
992 DPRINTF ((message ("e = %s ", constraintList_print(e->requiresConstraints) ) ));
997 exprNode_generateConstraints (exprData_getSingle (data));
999 constraintList_free(e->requiresConstraints);
1000 e->requiresConstraints = constraintList_copy ((exprData_getSingle (data))->requiresConstraints );
1002 constraintList_free(e->ensuresConstraints);
1003 e->ensuresConstraints = constraintList_copy ((exprData_getSingle (data))->ensuresConstraints );
1011 exprNode_stmtList (e);
1021 static bool lltok_isBoolean_Op (lltok tok)
1023 /*this should really be a switch statement but
1024 I don't want to violate the abstraction
1025 maybe this should go in lltok.c */
1027 if (lltok_isEq_Op (tok) )
1031 if (lltok_isAnd_Op (tok) )
1037 if (lltok_isOr_Op (tok) )
1042 if (lltok_isGt_Op (tok) )
1046 if (lltok_isLt_Op (tok) )
1051 if (lltok_isLe_Op (tok) )
1056 if (lltok_isGe_Op (tok) )
1066 static void exprNode_booleanTraverse (/*@dependent@*/ exprNode e, /*@unused@*/ bool definatelv, /*@unused@*/ bool definaterv, fileloc sequencePoint)
1072 constraintList tempList, temp;
1075 tok = exprData_getOpTok (data);
1076 t1 = exprData_getOpA (data);
1077 t2 = exprData_getOpB (data);
1079 tempList = constraintList_undefined;
1081 /* arithmetic tests */
1083 if (lltok_isEq_Op (tok) )
1085 cons = constraint_makeEnsureEqual (t1, t2, sequencePoint);
1086 e->trueEnsuresConstraints = constraintList_add(e->trueEnsuresConstraints, cons);
1090 if (lltok_isLt_Op (tok) )
1092 cons = constraint_makeEnsureLessThan (t1, t2, sequencePoint);
1093 e->trueEnsuresConstraints = constraintList_add(e->trueEnsuresConstraints, cons);
1094 cons = constraint_makeEnsureGreaterThanEqual (t1, t2, sequencePoint);
1095 e->falseEnsuresConstraints = constraintList_add(e->falseEnsuresConstraints, cons);
1098 if (lltok_isGe_Op (tok) )
1100 cons = constraint_makeEnsureGreaterThanEqual (t1, t2, sequencePoint);
1101 e->trueEnsuresConstraints = constraintList_add(e->trueEnsuresConstraints, cons);
1103 cons = constraint_makeEnsureLessThan (t1, t2, sequencePoint);
1104 e->falseEnsuresConstraints = constraintList_add(e->falseEnsuresConstraints, cons);
1107 if (lltok_isGt_Op (tok) )
1109 cons = constraint_makeEnsureGreaterThan (t1, t2, sequencePoint);
1110 e->trueEnsuresConstraints = constraintList_add(e->trueEnsuresConstraints, cons);
1111 cons = constraint_makeEnsureLessThanEqual (t1, t2, sequencePoint);
1112 e->falseEnsuresConstraints = constraintList_add(e->falseEnsuresConstraints, cons);
1115 if (lltok_isLe_Op (tok) )
1117 cons = constraint_makeEnsureLessThanEqual (t1, t2, sequencePoint);
1118 e->trueEnsuresConstraints = constraintList_add(e->trueEnsuresConstraints, cons);
1120 cons = constraint_makeEnsureGreaterThan (t1, t2, sequencePoint);
1121 e->falseEnsuresConstraints = constraintList_add(e->falseEnsuresConstraints, cons);
1124 /* Logical operations */
1126 if (lltok_isAnd_Op (tok) )
1129 tempList = constraintList_copy (t1->trueEnsuresConstraints);
1130 tempList = constraintList_addList (tempList, t2->trueEnsuresConstraints);
1131 e->trueEnsuresConstraints = constraintList_addListFree(e->trueEnsuresConstraints, tempList);
1133 /* false ensures: fens t1 or tens t1 and fens t2 */
1134 tempList = constraintList_copy (t1->trueEnsuresConstraints);
1135 tempList = constraintList_addList (tempList, t2->falseEnsuresConstraints);
1137 tempList = constraintList_logicalOr (tempList, t1->falseEnsuresConstraints);
1138 constraintList_free (temp);
1140 /* evans - was constraintList_addList - memory leak detected by splint */
1141 e->falseEnsuresConstraints = constraintList_addListFree (e->falseEnsuresConstraints, tempList);
1143 else if (lltok_isOr_Op (tok) )
1146 tempList = constraintList_copy (t1->falseEnsuresConstraints);
1147 tempList = constraintList_addList (tempList, t2->falseEnsuresConstraints);
1148 e->falseEnsuresConstraints = constraintList_addListFree(e->falseEnsuresConstraints, tempList);
1150 /* true ensures: tens t1 or fens t1 and tens t2 */
1151 tempList = constraintList_copy (t1->falseEnsuresConstraints);
1152 tempList = constraintList_addList (tempList, t2->trueEnsuresConstraints);
1155 tempList = constraintList_logicalOr (tempList, t1->trueEnsuresConstraints);
1156 constraintList_free(temp);
1158 e->trueEnsuresConstraints = constraintList_addListFree(e->trueEnsuresConstraints, tempList);
1159 tempList = constraintList_undefined;
1163 DPRINTF((message("%s is not a boolean operation", lltok_unparse(tok) ) ));
1167 void exprNode_exprTraverse (exprNode e, bool definatelv, bool definaterv, /*@observer@*/ /*@temp@*/ fileloc sequencePoint)
1169 exprNode t1, t2, fcn;
1171 bool handledExprNode;
1175 constraintList temp;
1177 if (exprNode_isError(e) )
1182 DPRINTF((message ("exprNode_exprTraverset Analysising %s %s at", exprNode_unparse( e),
1183 fileloc_unparse(exprNode_getfileloc(e) ) ) ) );
1185 /*e->requiresConstraints = constraintList_makeNew();
1186 e->ensuresConstraints = constraintList_makeNew();
1187 e->trueEnsuresConstraints = constraintList_makeNew();;
1188 e->falseEnsuresConstraints = constraintList_makeNew();;
1191 if (exprNode_isUnhandled (e) )
1196 handledExprNode = TRUE;
1203 t1 = exprData_getSingle (data);
1204 exprNode_exprTraverse (t1, definatelv, definaterv, sequencePoint);
1205 e = exprNode_copyConstraints (e, t1);
1212 t1 = (exprData_getPairA (data) );
1213 t2 = (exprData_getPairB (data) );
1214 cons = constraint_makeWriteSafeExprNode (t1, t2);
1218 t1 = (exprData_getPairA (data) );
1219 t2 = (exprData_getPairB (data) );
1220 cons = constraint_makeReadSafeExprNode (t1, t2 );
1223 e->requiresConstraints = constraintList_add(e->requiresConstraints, cons);
1224 cons = constraint_makeEnsureMaxReadAtLeast (t1, t2, sequencePoint);
1225 e->ensuresConstraints = constraintList_add(e->ensuresConstraints, cons);
1227 cons = constraint_makeEnsureLteMaxRead (t2, t1);
1228 e->trueEnsuresConstraints = constraintList_add(e->trueEnsuresConstraints, cons);
1230 exprNode_exprTraverse (exprData_getPairA (data), FALSE, TRUE, sequencePoint);
1231 exprNode_exprTraverse (exprData_getPairB (data), FALSE, TRUE, sequencePoint);
1233 /*@i325 Should check which is array/index. */
1237 exprNode_exprTraverse (exprData_getUopNode (e->edata), definatelv, definaterv, sequencePoint);
1247 t = exprData_getInitId (data);
1248 ue = usymtab_lookup (idDecl_observeId (t));
1249 lhs = exprNode_createId (ue);
1251 t2 = exprData_getInitNode (data);
1253 /* DPRINTF(((message("initialization: %s = %s",
1254 exprNode_unparse(lhs),
1255 exprNode_unparse(t2)
1259 exprNode_exprTraverse (t2, definatelv, TRUE, sequencePoint );
1261 /* this test is nessecary because some expressions generate a null expression node. function pointer do that -- drl */
1262 if ((!exprNode_isError (e)) && (!exprNode_isError(t2)) )
1264 cons = constraint_makeEnsureEqual (e, t2, sequencePoint);
1265 e->ensuresConstraints = constraintList_add(e->ensuresConstraints, cons);
1271 t1 = exprData_getOpA (data);
1272 t2 = exprData_getOpB (data);
1273 exprNode_exprTraverse (t1, TRUE, definaterv, sequencePoint );
1274 exprNode_exprTraverse (t2, definatelv, TRUE, sequencePoint );
1276 /* this test is nessecary because some expressions generate a null expression node. function pointer do that -- drl */
1277 if ((!exprNode_isError (t1)) && (!exprNode_isError(t2)) )
1279 cons = constraint_makeEnsureEqual (t1, t2, sequencePoint);
1280 e->ensuresConstraints = constraintList_add(e->ensuresConstraints, cons);
1284 t1 = exprData_getOpA (data);
1285 t2 = exprData_getOpB (data);
1286 tok = exprData_getOpTok (data);
1289 if (tok.tok == ADD_ASSIGN)
1291 exprNode_exprTraverse (t1, TRUE, definaterv, sequencePoint );
1292 exprNode_exprTraverse (t2, definatelv, TRUE, sequencePoint );
1294 cons = constraint_makeAddAssign (t1, t2, sequencePoint );
1295 e->ensuresConstraints = constraintList_add(e->ensuresConstraints, cons);
1297 else if (tok.tok == SUB_ASSIGN)
1299 exprNode_exprTraverse (t1, TRUE, definaterv, sequencePoint );
1300 exprNode_exprTraverse (t2, definatelv, TRUE, sequencePoint );
1302 cons = constraint_makeSubtractAssign (t1, t2, sequencePoint );
1303 e->ensuresConstraints = constraintList_add(e->ensuresConstraints, cons);
1307 exprNode_exprTraverse (t1, definatelv, definaterv, sequencePoint );
1308 exprNode_exprTraverse (t2, definatelv, definaterv, sequencePoint );
1311 if (lltok_isBoolean_Op (tok) )
1312 exprNode_booleanTraverse (e, definatelv, definaterv, sequencePoint);
1316 /*@i43 drl possible problem : warning make sure the case can be ignored.. */
1322 C standard says operand to sizeof isn't evaluated unless
1323 its a variable length array. So we don't generate constraints.
1329 fcn = exprData_getFcn(data);
1331 exprNode_exprTraverse (fcn, definatelv, definaterv, sequencePoint );
1332 DPRINTF ((message ("Got call that %s ( %s) ", exprNode_unparse(fcn), exprNodeList_unparse (exprData_getArgs (data) ) ) ) );
1334 fcn->requiresConstraints = constraintList_addListFree (fcn->requiresConstraints,
1335 checkCall (fcn, exprData_getArgs (data) ) );
1337 fcn->ensuresConstraints = constraintList_addListFree (fcn->ensuresConstraints,
1338 exprNode_getPostConditions(fcn, exprData_getArgs (data),e ) );
1340 t1 = exprNode_createNew (exprNode_getType (e) );
1341 checkArgumentList (t1, exprData_getArgs(data), sequencePoint);
1342 exprNode_mergeResolve (e, t1, fcn);
1347 exprNode_exprTraverse (exprData_getSingle (data), definatelv, definaterv, sequencePoint );
1350 case XPR_NULLRETURN:
1356 exprNode_exprTraverse (exprData_getFieldNode (data), definatelv, definaterv, sequencePoint );
1360 exprNode_exprTraverse (exprData_getFieldNode (data), definatelv, definaterv, sequencePoint );
1363 case XPR_STRINGLITERAL:
1372 t1 = exprData_getUopNode(data);
1373 tok = (exprData_getUopTok (data));
1374 exprNode_exprTraverse (t1, definatelv, definaterv, sequencePoint );
1375 /*handle * pointer access */
1376 if (lltok_isInc_Op (tok) )
1378 DPRINTF(("doing ++(var)"));
1379 t1 = exprData_getUopNode (data);
1380 cons = constraint_makeMaxSetSideEffectPostIncrement (t1, sequencePoint );
1381 e->ensuresConstraints = constraintList_add (e->ensuresConstraints, cons);
1383 else if (lltok_isDec_Op (tok) )
1385 DPRINTF(("doing --(var)"));
1386 t1 = exprData_getUopNode (data);
1387 cons = constraint_makeMaxSetSideEffectPostDecrement (t1, sequencePoint );
1388 e->ensuresConstraints = constraintList_add (e->ensuresConstraints, cons);
1390 else if (lltok_isMult( tok ) )
1394 cons = constraint_makeWriteSafeInt (t1, 0);
1398 cons = constraint_makeReadSafeInt (t1, 0);
1400 e->requiresConstraints = constraintList_add(e->requiresConstraints, cons);
1402 else if (lltok_isNot_Op (tok) )
1405 constraintList_free(e->trueEnsuresConstraints);
1407 e->trueEnsuresConstraints = constraintList_copy (t1->falseEnsuresConstraints);
1408 constraintList_free(e->falseEnsuresConstraints);
1409 e->falseEnsuresConstraints = constraintList_copy (t1->trueEnsuresConstraints);
1412 else if (lltok_isAmpersand_Op (tok) )
1416 else if (lltok_isMinus_Op (tok) )
1420 else if ( lltok_isExcl_Op (tok) )
1424 else if (lltok_isTilde_Op (tok) )
1430 llcontbug((message("Unsupported preop in %s", exprNode_unparse(e) ) ));
1437 exprNode_exprTraverse (exprData_getUopNode (data), TRUE, definaterv, sequencePoint );
1439 if (lltok_isInc_Op (exprData_getUopTok (data) ) )
1441 DPRINTF(("doing ++"));
1442 t1 = exprData_getUopNode (data);
1443 cons = constraint_makeMaxSetSideEffectPostIncrement (t1, sequencePoint );
1444 e->ensuresConstraints = constraintList_add (e->ensuresConstraints, cons);
1446 if (lltok_isDec_Op (exprData_getUopTok (data) ) )
1448 DPRINTF(("doing --"));
1449 t1 = exprData_getUopNode (data);
1450 cons = constraint_makeMaxSetSideEffectPostDecrement (t1, sequencePoint );
1451 e->ensuresConstraints = constraintList_add (e->ensuresConstraints, cons);
1456 t2 = exprData_getCastNode (data);
1457 DPRINTF (( message ("Examining cast (%q)%s",
1458 qtype_unparse (exprData_getCastType (data)),
1459 exprNode_unparse (t2) )
1461 exprNode_exprTraverse (t2, definatelv, definaterv, sequencePoint );
1467 exprNode pred, trueBranch, falseBranch;
1469 pred = exprData_getTriplePred (data);
1470 trueBranch = exprData_getTripleTrue (data);
1471 falseBranch = exprData_getTripleFalse (data);
1473 exprNode_exprTraverse (pred, FALSE, TRUE, sequencePoint );
1475 temp = pred->ensuresConstraints;
1476 pred->ensuresConstraints = exprNode_traversEnsuresConstraints(pred);
1477 constraintList_free(temp);
1479 temp = pred->requiresConstraints;
1480 pred->requiresConstraints = exprNode_traversRequiresConstraints(pred);
1481 constraintList_free(temp);
1483 temp = pred->trueEnsuresConstraints;
1484 pred->trueEnsuresConstraints = exprNode_traversTrueEnsuresConstraints(pred);
1485 constraintList_free(temp);
1487 temp = pred->falseEnsuresConstraints;
1488 pred->falseEnsuresConstraints = exprNode_traversFalseEnsuresConstraints(pred);
1489 constraintList_free(temp);
1492 exprNode_exprTraverse (trueBranch, FALSE, TRUE, sequencePoint );
1494 temp = trueBranch->ensuresConstraints;
1495 trueBranch->ensuresConstraints = exprNode_traversEnsuresConstraints(trueBranch);
1496 constraintList_free(temp);
1499 temp = trueBranch->requiresConstraints;
1500 trueBranch->requiresConstraints = exprNode_traversRequiresConstraints(trueBranch);
1501 constraintList_free(temp);
1504 temp = trueBranch->trueEnsuresConstraints;
1505 trueBranch->trueEnsuresConstraints = exprNode_traversTrueEnsuresConstraints(trueBranch);
1506 constraintList_free(temp);
1508 temp = trueBranch->falseEnsuresConstraints;
1509 trueBranch->falseEnsuresConstraints = exprNode_traversFalseEnsuresConstraints(trueBranch);
1510 constraintList_free(temp);
1512 exprNode_exprTraverse (falseBranch, FALSE, TRUE, sequencePoint );
1514 temp = falseBranch->ensuresConstraints;
1515 falseBranch->ensuresConstraints = exprNode_traversEnsuresConstraints(falseBranch);
1516 constraintList_free(temp);
1519 temp = falseBranch->requiresConstraints;
1520 falseBranch->requiresConstraints = exprNode_traversRequiresConstraints(falseBranch);
1521 constraintList_free(temp);
1524 temp = falseBranch->trueEnsuresConstraints;
1525 falseBranch->trueEnsuresConstraints = exprNode_traversTrueEnsuresConstraints(falseBranch);
1526 constraintList_free(temp);
1528 temp = falseBranch->falseEnsuresConstraints;
1529 falseBranch->falseEnsuresConstraints = exprNode_traversFalseEnsuresConstraints(falseBranch);
1530 constraintList_free(temp);
1532 /* if pred is true e equals true otherwise pred equals false */
1534 cons = constraint_makeEnsureEqual (e, trueBranch, sequencePoint);
1535 trueBranch->ensuresConstraints = constraintList_add(trueBranch->ensuresConstraints, cons);
1537 cons = constraint_makeEnsureEqual (e, trueBranch, sequencePoint);
1538 falseBranch->ensuresConstraints = constraintList_add(falseBranch->ensuresConstraints, cons);
1540 e = doIfElse (e, pred, trueBranch, falseBranch);
1546 t1 = exprData_getPairA (data);
1547 t2 = exprData_getPairB (data);
1548 /* we essiantially treat this like expr1; expr2
1549 of course sequencePoint isn't adjusted so this isn't completely accurate
1551 exprNode_exprTraverse (t1, FALSE, FALSE, sequencePoint );
1552 exprNode_exprTraverse (t2, definatelv, definaterv, sequencePoint );
1553 exprNode_mergeResolve (e, t1, t2);
1557 handledExprNode = FALSE;
1560 e->requiresConstraints = constraintList_preserveOrig ( e->requiresConstraints);
1561 e->ensuresConstraints = constraintList_preserveOrig ( e->ensuresConstraints);
1562 e->requiresConstraints = constraintList_addGeneratingExpr ( e->requiresConstraints, e);
1564 e->ensuresConstraints = constraintList_addGeneratingExpr ( e->ensuresConstraints, e);
1567 e->requiresConstraints = constraintList_removeSurpressed( e->requiresConstraints);
1569 DPRINTF((message ("ensures constraints for %s are %s", exprNode_unparse(e), constraintList_printDetailed(e->ensuresConstraints) ) ));
1571 DPRINTF((message ("Requires constraints for %s are %s", exprNode_unparse(e), constraintList_printDetailed(e->ensuresConstraints) ) ));
1573 DPRINTF((message ("trueEnsures constraints for %s are %s", exprNode_unparse(e), constraintList_printDetailed(e->trueEnsuresConstraints) ) ));
1575 DPRINTF((message ("falseEnsures constraints for %s are %s", exprNode_unparse(e), constraintList_printDetailed(e->falseEnsuresConstraints) ) ));
1581 constraintList exprNode_traversTrueEnsuresConstraints (exprNode e)
1585 bool handledExprNode;
1589 if (exprNode_handleError (e))
1591 ret = constraintList_makeNew();
1594 ret = constraintList_copy (e->trueEnsuresConstraints );
1596 handledExprNode = TRUE;
1603 t1 = exprData_getSingle (data);
1604 ret = constraintList_addListFree ( ret, exprNode_traversTrueEnsuresConstraints (t1) );
1609 ret = constraintList_addListFree (ret,
1610 exprNode_traversTrueEnsuresConstraints
1611 (exprData_getPairA (data) ) );
1613 ret = constraintList_addListFree (ret,
1614 exprNode_traversTrueEnsuresConstraints
1615 (exprData_getPairB (data) ) );
1619 ret = constraintList_addListFree (ret,
1620 exprNode_traversTrueEnsuresConstraints
1621 (exprData_getUopNode (data) ) );
1625 ret = constraintList_addListFree (ret, exprNode_traversTrueEnsuresConstraints
1626 (exprData_getUopNode (data) ) );
1630 ret = constraintList_addListFree (ret,
1631 exprNode_traversTrueEnsuresConstraints
1632 (exprData_getInitNode (data) ) );
1637 ret = constraintList_addListFree (ret,
1638 exprNode_traversTrueEnsuresConstraints
1639 (exprData_getOpA (data) ) );
1641 ret = constraintList_addListFree (ret,
1642 exprNode_traversTrueEnsuresConstraints
1643 (exprData_getOpB (data) ) );
1646 ret = constraintList_addListFree (ret,
1647 exprNode_traversTrueEnsuresConstraints
1648 (exprData_getOpA (data) ) );
1650 ret = constraintList_addListFree (ret,
1651 exprNode_traversTrueEnsuresConstraints
1652 (exprData_getOpB (data) ) );
1659 ret = constraintList_addListFree (ret,
1660 exprNode_traversTrueEnsuresConstraints
1661 (exprData_getSingle (data) ) );
1665 ret = constraintList_addListFree (ret,
1666 exprNode_traversTrueEnsuresConstraints
1667 (exprData_getFcn (data) ) );
1668 /*@i11*/ /* exprNodeList_unparse (exprData_getArgs (data) ); */
1672 ret = constraintList_addListFree (ret,
1673 exprNode_traversTrueEnsuresConstraints
1674 (exprData_getSingle (data) ) );
1677 case XPR_NULLRETURN:
1681 ret = constraintList_addListFree (ret,
1682 exprNode_traversTrueEnsuresConstraints
1683 (exprData_getFieldNode (data) ) );
1687 ret = constraintList_addListFree (ret,
1688 exprNode_traversTrueEnsuresConstraints
1689 (exprData_getFieldNode (data) ) );
1692 case XPR_STRINGLITERAL:
1699 ret = constraintList_addListFree (ret,
1700 exprNode_traversTrueEnsuresConstraints
1701 (exprData_getUopNode (data) ) );
1706 ret = constraintList_addListFree (ret,
1707 exprNode_traversTrueEnsuresConstraints
1708 (exprData_getCastNode (data) ) );
1718 constraintList exprNode_traversFalseEnsuresConstraints (exprNode e)
1721 bool handledExprNode;
1725 if (exprNode_handleError (e))
1727 ret = constraintList_makeNew();
1731 ret = constraintList_copy (e->falseEnsuresConstraints );
1733 handledExprNode = TRUE;
1740 t1 = exprData_getSingle (data);
1741 ret = constraintList_addListFree ( ret,exprNode_traversFalseEnsuresConstraints (t1) );
1746 ret = constraintList_addListFree (ret,
1747 exprNode_traversFalseEnsuresConstraints
1748 (exprData_getPairA (data) ) );
1750 ret = constraintList_addListFree (ret,
1751 exprNode_traversFalseEnsuresConstraints
1752 (exprData_getPairB (data) ) );
1756 ret = constraintList_addListFree (ret,
1757 exprNode_traversFalseEnsuresConstraints
1758 (exprData_getUopNode (data) ) );
1762 ret = constraintList_addListFree (ret, exprNode_traversFalseEnsuresConstraints
1763 (exprData_getUopNode (data) ) );
1766 ret = constraintList_addListFree (ret,
1767 exprNode_traversFalseEnsuresConstraints
1768 ( exprData_getInitNode (data) ) );
1772 ret = constraintList_addListFree (ret,
1773 exprNode_traversFalseEnsuresConstraints
1774 (exprData_getOpA (data) ) );
1776 ret = constraintList_addListFree (ret,
1777 exprNode_traversFalseEnsuresConstraints
1778 (exprData_getOpB (data) ) );
1781 ret = constraintList_addListFree (ret,
1782 exprNode_traversFalseEnsuresConstraints
1783 (exprData_getOpA (data) ) );
1785 ret = constraintList_addListFree (ret,
1786 exprNode_traversFalseEnsuresConstraints
1787 (exprData_getOpB (data) ) );
1794 ret = constraintList_addListFree (ret,
1795 exprNode_traversFalseEnsuresConstraints
1796 (exprData_getSingle (data) ) );
1800 ret = constraintList_addListFree (ret,
1801 exprNode_traversFalseEnsuresConstraints
1802 (exprData_getFcn (data) ) );
1803 /*@i11*/ /* exprNodeList_unparse (exprData_getArgs (data) ); */
1807 ret = constraintList_addListFree (ret,
1808 exprNode_traversFalseEnsuresConstraints
1809 (exprData_getSingle (data) ) );
1812 case XPR_NULLRETURN:
1816 ret = constraintList_addListFree (ret,
1817 exprNode_traversFalseEnsuresConstraints
1818 (exprData_getFieldNode (data) ) );
1822 ret = constraintList_addListFree (ret,
1823 exprNode_traversFalseEnsuresConstraints
1824 (exprData_getFieldNode (data) ) );
1827 case XPR_STRINGLITERAL:
1834 ret = constraintList_addListFree (ret,
1835 exprNode_traversFalseEnsuresConstraints
1836 (exprData_getUopNode (data) ) );
1841 ret = constraintList_addListFree (ret,
1842 exprNode_traversFalseEnsuresConstraints
1843 (exprData_getCastNode (data) ) );
1854 /* walk down the tree and get all requires Constraints in each subexpression*/
1855 /*@only@*/ constraintList exprNode_traversRequiresConstraints (exprNode e)
1859 bool handledExprNode;
1863 if (exprNode_handleError (e))
1865 ret = constraintList_makeNew();
1868 ret = constraintList_copy (e->requiresConstraints );
1870 handledExprNode = TRUE;
1877 t1 = exprData_getSingle (data);
1878 ret = constraintList_addListFree ( ret, exprNode_traversRequiresConstraints (t1) );
1883 ret = constraintList_addListFree (ret,
1884 exprNode_traversRequiresConstraints
1885 (exprData_getPairA (data) ) );
1887 ret = constraintList_addListFree (ret,
1888 exprNode_traversRequiresConstraints
1889 (exprData_getPairB (data) ) );
1893 ret = constraintList_addListFree (ret,
1894 exprNode_traversRequiresConstraints
1895 (exprData_getUopNode (data) ) );
1899 ret = constraintList_addListFree (ret, exprNode_traversRequiresConstraints
1900 (exprData_getUopNode (data) ) );
1903 ret = constraintList_addListFree (ret,
1904 exprNode_traversRequiresConstraints
1905 (exprData_getInitNode (data) ) );
1909 ret = constraintList_addListFree (ret,
1910 exprNode_traversRequiresConstraints
1911 (exprData_getOpA (data) ) );
1913 ret = constraintList_addListFree (ret,
1914 exprNode_traversRequiresConstraints
1915 (exprData_getOpB (data) ) );
1918 ret = constraintList_addListFree (ret,
1919 exprNode_traversRequiresConstraints
1920 (exprData_getOpA (data) ) );
1922 ret = constraintList_addListFree (ret,
1923 exprNode_traversRequiresConstraints
1924 (exprData_getOpB (data) ) );
1931 ret = constraintList_addListFree (ret,
1932 exprNode_traversRequiresConstraints
1933 (exprData_getSingle (data) ) );
1937 ret = constraintList_addListFree (ret,
1938 exprNode_traversRequiresConstraints
1939 (exprData_getFcn (data) ) );
1940 /*@i11*/ /* exprNodeList_unparse (exprData_getArgs (data) ); */
1944 ret = constraintList_addListFree (ret,
1945 exprNode_traversRequiresConstraints
1946 (exprData_getSingle (data) ) );
1949 case XPR_NULLRETURN:
1953 ret = constraintList_addListFree (ret,
1954 exprNode_traversRequiresConstraints
1955 (exprData_getFieldNode (data) ) );
1959 ret = constraintList_addListFree (ret,
1960 exprNode_traversRequiresConstraints
1961 (exprData_getFieldNode (data) ) );
1964 case XPR_STRINGLITERAL:
1971 ret = constraintList_addListFree (ret,
1972 exprNode_traversRequiresConstraints
1973 (exprData_getUopNode (data) ) );
1978 ret = constraintList_addListFree (ret,
1979 exprNode_traversRequiresConstraints
1980 (exprData_getCastNode (data) ) );
1991 /* walk down the tree and get all Ensures Constraints in each subexpression*/
1992 /*@only@*/ constraintList exprNode_traversEnsuresConstraints (exprNode e)
1996 bool handledExprNode;
2001 if (exprNode_handleError (e))
2003 ret = constraintList_makeNew();
2007 ret = constraintList_copy (e->ensuresConstraints );
2008 handledExprNode = TRUE;
2013 "exprnode_traversEnsuresConstraints call for %s with constraintList of %s",
2014 exprNode_unparse (e),
2015 constraintList_print(e->ensuresConstraints)
2023 t1 = exprData_getSingle (data);
2024 ret = constraintList_addListFree ( ret,exprNode_traversEnsuresConstraints (t1) );
2029 ret = constraintList_addListFree (ret,
2030 exprNode_traversEnsuresConstraints
2031 (exprData_getPairA (data) ) );
2033 ret = constraintList_addListFree (ret,
2034 exprNode_traversEnsuresConstraints
2035 (exprData_getPairB (data) ) );
2039 ret = constraintList_addListFree (ret,
2040 exprNode_traversEnsuresConstraints
2041 (exprData_getUopNode (data) ) );
2045 ret = constraintList_addListFree (ret, exprNode_traversEnsuresConstraints
2046 (exprData_getUopNode (data) ) );
2050 ret = constraintList_addListFree (ret,
2051 exprNode_traversEnsuresConstraints
2052 (exprData_getInitNode (data) ) );
2057 ret = constraintList_addListFree (ret,
2058 exprNode_traversEnsuresConstraints
2059 (exprData_getOpA (data) ) );
2061 ret = constraintList_addListFree (ret,
2062 exprNode_traversEnsuresConstraints
2063 (exprData_getOpB (data) ) );
2066 ret = constraintList_addListFree (ret,
2067 exprNode_traversEnsuresConstraints
2068 (exprData_getOpA (data) ) );
2070 ret = constraintList_addListFree (ret,
2071 exprNode_traversEnsuresConstraints
2072 (exprData_getOpB (data) ) );
2079 ret = constraintList_addListFree (ret,
2080 exprNode_traversEnsuresConstraints
2081 (exprData_getSingle (data) ) );
2085 ret = constraintList_addListFree (ret,
2086 exprNode_traversEnsuresConstraints
2087 (exprData_getFcn (data) ) );
2088 /*@i11*/ /* exprNodeList_unparse (exprData_getArgs (data) ); */
2092 ret = constraintList_addListFree (ret,
2093 exprNode_traversEnsuresConstraints
2094 (exprData_getSingle (data) ) );
2097 case XPR_NULLRETURN:
2101 ret = constraintList_addListFree (ret,
2102 exprNode_traversEnsuresConstraints
2103 (exprData_getFieldNode (data) ) );
2107 ret = constraintList_addListFree (ret,
2108 exprNode_traversEnsuresConstraints
2109 (exprData_getFieldNode (data) ) );
2112 case XPR_STRINGLITERAL:
2119 ret = constraintList_addListFree (ret,
2120 exprNode_traversEnsuresConstraints
2121 (exprData_getUopNode (data) ) );
2125 ret = constraintList_addListFree (ret,
2126 exprNode_traversEnsuresConstraints
2127 (exprData_getCastNode (data) ) );
2135 "exprnode_traversEnsuresConstraints call for %s with constraintList of is returning %s",
2136 exprNode_unparse (e),
2137 constraintList_print(ret))));
2142 /*drl moved out of constraintResolve.c 07-02-001 */
2143 void checkArgumentList (/*@out@*/ exprNode temp, exprNodeList arglist, fileloc sequencePoint)
2145 temp->requiresConstraints = constraintList_makeNew();
2146 temp->ensuresConstraints = constraintList_makeNew();
2147 temp->trueEnsuresConstraints = constraintList_makeNew();
2148 temp->falseEnsuresConstraints = constraintList_makeNew();
2150 exprNodeList_elements (arglist, el)
2152 constraintList temp2;
2153 exprNode_exprTraverse (el, FALSE, FALSE, sequencePoint);
2154 temp2 = el->requiresConstraints;
2155 el->requiresConstraints = exprNode_traversRequiresConstraints(el);
2156 constraintList_free(temp2);
2158 temp2 = el->ensuresConstraints;
2159 el->ensuresConstraints = exprNode_traversEnsuresConstraints(el);
2160 constraintList_free(temp2);
2162 temp->requiresConstraints = constraintList_addList(temp->requiresConstraints,
2163 el->requiresConstraints);
2165 temp->ensuresConstraints = constraintList_addList(temp->ensuresConstraints,
2166 el->ensuresConstraints);
2168 end_exprNodeList_elements;
2172 /*drl moved out of constraintResolve.c 07-03-001 */
2173 constraintList exprNode_getPostConditions (exprNode fcn, exprNodeList arglist, exprNode fcnCall)
2175 constraintList postconditions;
2177 DPRINTF((message ("Got call that %s ( %s) ", exprNode_unparse(fcn), exprNodeList_unparse (arglist ) ) ) );
2179 temp = exprNode_getUentry (fcn);
2181 postconditions = uentry_getFcnPostconditions (temp);
2183 if (constraintList_isDefined (postconditions))
2185 postconditions = constraintList_doSRefFixConstraintParam (postconditions, arglist);
2186 postconditions = constraintList_doFixResult (postconditions, fcnCall);
2190 postconditions = constraintList_makeNew();
2193 return postconditions;
2197 comment this out for now
2198 we'll include it in a production release when its stable...
2200 void findStructs ( exprNodeList arglist)
2206 message("doing findStructs: %s", exprNodeList_unparse(arglist) )
2210 exprNodeList_elements(arglist, expr)
2212 ct = exprNode_getType(expr);
2214 rt = ctype_realType (ct);
2216 if ( ctype_isStruct (rt ) )
2217 TPRINTF(( message("Found structure %s", exprNode_unparse(expr) )
2219 if (hasInvariants(ct) )
2221 constraintList invars;
2223 invars = getInvariants(ct);
2226 TPRINTF(( message ("findStructs has invariants %s ", constraintList_print (invars) )
2229 invars = constraintList_doSRefFixStructConstraint(invars, exprNode_getSref(expr), ct );
2232 TPRINTF(( message ("findStructs finded invariants to be %s ", constraintList_print (invars) )
2236 end_exprNodeList_elements;
2241 /*drl moved out of constraintResolve.c 07-02-001 */
2242 constraintList checkCall (/*@dependent@*/ exprNode fcn, exprNodeList arglist)
2244 constraintList preconditions;
2246 DPRINTF((message ("Got call that %s ( %s) ", exprNode_unparse(fcn), exprNodeList_unparse (arglist ) ) ) );
2248 temp = exprNode_getUentry (fcn);
2250 preconditions = uentry_getFcnPreconditions (temp);
2252 if (constraintList_isDefined(preconditions) )
2254 preconditions = constraintList_togglePost (preconditions);
2255 preconditions = constraintList_preserveCallInfo(preconditions, fcn);
2256 preconditions = constraintList_doSRefFixConstraintParam (preconditions, arglist);
2260 if (constraintList_isUndefined(preconditions) )
2261 preconditions = constraintList_makeNew();
2263 DPRINTF (( message("Done checkCall\n") ));
2264 DPRINTF (( message("Returning list %q ", constraintList_printDetailed(preconditions) ) ));
2267 drl we're going to comment this out for now
2268 we'll include it if we're sure it's working
2270 findStructs(arglist);
2273 return preconditions;
2276 /*drl added this function 10.29.001
2277 takes an exprNode of the form const + const
2281 I'm a bit nervous about modifying the exprNode
2282 but this is the easy way to do this
2283 If I have time I'd like to cause the exprNode to get created correctly in the first place */
2285 void exprNode_findValue( exprNode e)
2294 if (exprNode_hasValue(e) )
2297 if (e->kind == XPR_OP)
2299 t1 = exprData_getOpA (data);
2300 t2 = exprData_getOpB (data);
2301 tok = exprData_getOpTok (data);
2303 exprNode_findValue(t1);
2304 exprNode_findValue(t2);
2306 if (!(exprNode_knownIntValue(t1) && (exprNode_knownIntValue(t2) ) ) )
2309 if (lltok_isPlus_Op (tok) )
2313 v1 = exprNode_getLongValue(t1);
2314 v2 = exprNode_getLongValue(t2);
2316 if (multiVal_isDefined(e->val) )
2317 multiVal_free (e->val);
2319 e->val = multiVal_makeInt (v1 + v2);
2322 if ( lltok_isMinus_Op (tok) )
2326 v1 = exprNode_getLongValue(t1);
2327 v2 = exprNode_getLongValue(t2);
2329 if (multiVal_isDefined(e->val) )
2330 multiVal_free (e->val);
2332 e->val = multiVal_makeInt (v1 - v2);
2335 /*drl I should really do * and / at some point */