2 ** Splint - annotation-assisted static program checker
3 ** Copyright (C) 1994-2003 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 /*drl We need to access the internal representation of exprNode
41 because these functions walk down the parse tree and need a richer
42 information than is accessible through the exprNode interface.*/
46 static /*@nullwhentrue@*/ bool exprNode_handleError (/*@temp@*/ exprNode p_e);
48 static void exprNode_stmt (/*@temp@*/ /*@temp@*/ exprNode p_e);
49 static void exprNode_multiStatement (/*@temp@*/ exprNode p_e);
51 static constraintList exprNode_traverseTrueEnsuresConstraints (/*@temp@*/ exprNode p_e);
52 static constraintList exprNode_traverseFalseEnsuresConstraints (/*@temp@*/ exprNode p_e);
54 static void checkArgumentList (/*@out@*/ exprNode p_temp, exprNodeList p_arglist, fileloc p_sequencePoint) /*@modifies p_temp @*/;
56 static constraintList checkCall (/*@temp@*/ exprNode p_fcn, exprNodeList p_arglist);
58 static bool exprNode_isUnhandled (/*@temp@*/ /*@observer@*/ exprNode e)
60 llassert(exprNode_isDefined(e));
86 DPRINTF((message ("Warning current constraint generation does not handle expression %s", exprNode_unparse(e))));
98 /*@nullwhentrue@*/ bool exprNode_handleError (exprNode e)
100 if (exprNode_isError (e) || exprNode_isUnhandled (e))
108 /* evans 2002-03-2 - parameter was dependent */
109 bool /*@alt void@*/ exprNode_generateConstraints (/*@temp@*/ exprNode e)
111 if (exprNode_isError (e))
114 if (exprNode_isUnhandled (e))
116 DPRINTF((message("Warning ignoring %s", exprNode_unparse (e))));
120 DPRINTF ((message ("exprNode_generateConstraints Analyzing %s at %s", exprNode_unparse(e),
121 fileloc_unparse(exprNode_loc (e)))));
123 if (exprNode_isMultiStatement (e))
125 exprNode_multiStatement(e);
131 /* loc = exprNode_getNextSequencePoint(e); */
132 /* exprNode_exprTraverse(e, FALSE, FALSE, loc); */
134 /* fileloc_free(loc); */
144 c = constraintList_makeFixedArrayConstraints (e->uses);
145 e->requiresConstraints = constraintList_reflectChangesFreePre (e->requiresConstraints, c);
146 constraintList_free(c);
149 DPRINTF ((message ("e->requiresConstraints %s",
150 constraintList_unparseDetailed (e->requiresConstraints))));
154 static void exprNode_stmt (/*@temp@*/ exprNode e)
159 DPRINTF (("Generating constraint for: %s", exprNode_unparse (e)));
161 if (exprNode_isError(e))
166 /*e->requiresConstraints = constraintList_makeNew();
167 e->ensuresConstraints = constraintList_makeNew(); */
169 /*!! s = exprNode_unparse (e); */
171 if (e->kind == XPR_INIT)
173 constraintList tempList;
174 DPRINTF (("Init: %s ", exprNode_unparse (e)));
175 loc = exprNode_getNextSequencePoint (e); /* reduces to an expression */
176 DPRINTF (("Location: %s", fileloc_unparse (loc)));
177 DPRINTF (("Ensures before: %s", constraintList_unparse (e->ensuresConstraints)));
178 exprNode_exprTraverse (e, FALSE, FALSE, loc);
179 DPRINTF (("Ensures after: %s", constraintList_unparse (e->ensuresConstraints)));
180 DPRINTF (("After traversing..."));
183 tempList = e->requiresConstraints;
184 DPRINTF (("Requires before: %s", constraintList_unparse (e->requiresConstraints)));
185 e->requiresConstraints = exprNode_traverseRequiresConstraints (e);
186 DPRINTF (("Requires after: %s", constraintList_unparse (e->requiresConstraints)));
187 constraintList_free(tempList);
189 tempList = e->ensuresConstraints;
190 DPRINTF (("Ensures before: %s", constraintList_unparse (e->ensuresConstraints)));
191 e->ensuresConstraints = exprNode_traverseEnsuresConstraints(e);
192 DPRINTF (("Ensures before: %s", constraintList_unparse (e->ensuresConstraints)));
193 constraintList_free(tempList);
197 /*drl 2/13/002 patched bug so return statement will be checked*/
198 /*return is a stmt not not expression ...*/
199 if (e->kind == XPR_RETURN)
201 constraintList tempList;
203 loc = exprNode_getNextSequencePoint(e); /* reduces to an expression */
205 exprNode_exprTraverse (exprData_getSingle (e->edata), FALSE, TRUE, loc);
208 tempList = e->requiresConstraints;
209 e->requiresConstraints = exprNode_traverseRequiresConstraints(e);
210 constraintList_free(tempList);
213 if (e->kind != XPR_STMT)
215 DPRINTF (("Not Stmt"));
216 DPRINTF ((message ("%s ", exprNode_unparse (e))));
218 if (exprNode_isMultiStatement (e))
220 exprNode_multiStatement (e); /* evans 2001-08-21: spurious return removed */
224 loc = exprNode_getNextSequencePoint(e); /* reduces to an expression */
226 exprNode_exprTraverse (e, FALSE, TRUE, loc);
234 DPRINTF ((message ("%s ", exprNode_unparse (e))));
236 snode = exprData_getUopNode (e->edata);
238 /* could be stmt involving multiple statements:
239 i.e. if, while for ect.
242 if (exprNode_isMultiStatement (snode))
244 exprNode_multiStatement (snode);
245 (void) exprNode_copyConstraints (e, snode);
249 loc = exprNode_getNextSequencePoint(e); /* reduces to an expression */
250 exprNode_exprTraverse (snode, FALSE, FALSE, loc);
254 constraintList_free (e->requiresConstraints);
255 e->requiresConstraints = exprNode_traverseRequiresConstraints(snode);
257 constraintList_free (e->ensuresConstraints);
258 e->ensuresConstraints = exprNode_traverseEnsuresConstraints(snode);
260 DPRINTF ((message ("smtlist constraints are: pre: %s \n and \t post %s\n",
261 constraintList_unparse(e->requiresConstraints),
262 constraintList_unparse(e->ensuresConstraints))));
267 static void exprNode_stmtList (/*@dependent@*/ exprNode e)
269 exprNode stmt1, stmt2;
270 if (exprNode_isError (e))
276 Handle case of stmtList with only one statement:
277 The parse tree stores this as stmt instead of stmtList
280 if (e->kind != XPR_STMTLIST)
285 llassert (e->kind == XPR_STMTLIST);
286 DPRINTF(("exprNode_stmtList STMTLIST:"));
287 DPRINTF ((cstring_toCharsSafe (exprNode_unparse(e))));
288 stmt1 = exprData_getPairA (e->edata);
289 stmt2 = exprData_getPairB (e->edata);
292 DPRINTF(("exprNode_stmtlist "));
293 DPRINTF ((message("XW%s | %s", exprNode_unparse(stmt1), exprNode_unparse(stmt2))));
295 exprNode_stmt (stmt1);
296 DPRINTF(("\nstmt after stmtList call "));
298 exprNode_stmt (stmt2);
299 exprNode_mergeResolve (e, stmt1, stmt2);
301 DPRINTF ((message ("smtlist constraints are: pre: %s \n and \t post %s\n",
302 constraintList_unparse(e->requiresConstraints),
303 constraintList_unparse(e->ensuresConstraints))));
307 static exprNode doIf (/*@returned@*/ exprNode e, /*@dependent@*/ exprNode test, /*@dependent@*/ exprNode body)
311 DPRINTF ((message ("doIf: %s ", exprNode_unparse(e))));
313 llassert (exprNode_isDefined(test));
314 llassert (exprNode_isDefined (e));
315 llassert (exprNode_isDefined (body));
317 DPRINTF((message ("ensures constraints for %s are %s", exprNode_unparse(e), constraintList_unparseDetailed(e->ensuresConstraints))));
319 DPRINTF((message ("Requires constraints for %s are %s", exprNode_unparse(e), constraintList_unparseDetailed(e->ensuresConstraints))));
321 DPRINTF((message ("trueEnsures constraints for %s are %s", exprNode_unparse(e), constraintList_unparseDetailed(e->trueEnsuresConstraints))));
323 DPRINTF((message ("falseEnsures constraints for %s are %s", exprNode_unparse(e), constraintList_unparseDetailed(e->falseEnsuresConstraints))));
327 DPRINTF((message ("ensures constraints for %s are %s", exprNode_unparse(test), constraintList_unparseDetailed(test->ensuresConstraints))));
329 DPRINTF((message ("Requires constraints for %s are %s", exprNode_unparse(test), constraintList_unparseDetailed(test->ensuresConstraints))));
331 DPRINTF((message ("trueEnsures constraints for %s are %s", exprNode_unparse(test), constraintList_unparseDetailed(test->trueEnsuresConstraints))));
333 DPRINTF((message ("falseEnsures constraints for %s are %s", exprNode_unparse(test), constraintList_unparseDetailed(test->falseEnsuresConstraints))));
337 temp = test->trueEnsuresConstraints;
338 test->trueEnsuresConstraints = exprNode_traverseTrueEnsuresConstraints(test);
339 constraintList_free(temp);
341 temp = test->ensuresConstraints;
342 test->ensuresConstraints = exprNode_traverseEnsuresConstraints (test);
343 constraintList_free(temp);
345 temp = test->requiresConstraints;
346 test->requiresConstraints = exprNode_traverseRequiresConstraints (test);
347 constraintList_free(temp);
350 test->trueEnsuresConstraints = constraintList_substituteFreeTarget(test->trueEnsuresConstraints, test->ensuresConstraints);
352 DPRINTF ((message ("doIf: test ensures %s ", constraintList_unparse(test->ensuresConstraints))));
354 DPRINTF ((message ("doIf: test true ensures %s ", constraintList_unparse(test->trueEnsuresConstraints))));
356 constraintList_free(e->requiresConstraints);
359 e->requiresConstraints = constraintList_reflectChanges(body->requiresConstraints, test->trueEnsuresConstraints);
361 e->requiresConstraints = constraintList_reflectChangesFreePre (e->requiresConstraints,
362 test->ensuresConstraints);
363 temp = e->requiresConstraints;
364 e->requiresConstraints = constraintList_mergeRequires (e->requiresConstraints, test->requiresConstraints);
365 constraintList_free(temp);
368 /* drl possible problem : warning bad */
369 constraintList_free(e->ensuresConstraints);
370 e->ensuresConstraints = constraintList_copy (test->ensuresConstraints);
372 if (exprNode_mayEscape (body))
374 DPRINTF ((message("doIf: the if statement body %s returns or exits", exprNode_unparse(body))));
375 e->ensuresConstraints = constraintList_mergeEnsuresFreeFirst (e->ensuresConstraints,
376 test->falseEnsuresConstraints);
379 DPRINTF ((message ("doIf: if requiers %s ", constraintList_unparse(e->requiresConstraints))));
385 Also used for condition i.e. ?: operation
388 This function assumes that p, trueBranch, falseBranch have have all been traversed
389 for constraints i.e. we assume that exprNode_traverseEnsuresConstraints,
390 exprNode_traverseRequiresConstraints, exprNode_traverseTrueEnsuresConstraints,
391 exprNode_traverseFalseEnsuresConstraints have all been run
394 static exprNode doIfElse (/*@returned@*/ exprNode e, /*@dependent@*/ exprNode p, /*@dependent@*/ exprNode trueBranch, /*@dependent@*/ exprNode falseBranch)
396 constraintList c1, cons, t, t2, f, f2;
398 llassert (exprNode_isDefined (e));
399 llassert (exprNode_isDefined (p));
400 llassert (exprNode_isDefined (trueBranch));
401 llassert (exprNode_isDefined (falseBranch));
402 DPRINTF ((message ("doIfElse: %s ", exprNode_unparse(e))));
404 /* do requires clauses */
405 c1 = constraintList_copy (p->ensuresConstraints);
407 t = constraintList_reflectChanges(trueBranch->requiresConstraints, p->trueEnsuresConstraints);
408 t = constraintList_reflectChangesFreePre (t, p->ensuresConstraints);
410 cons = constraintList_reflectChanges(falseBranch->requiresConstraints, p->falseEnsuresConstraints);
411 cons = constraintList_reflectChangesFreePre (cons, c1);
413 constraintList_free (e->requiresConstraints);
414 e->requiresConstraints = constraintList_mergeRequiresFreeFirst (t, cons);
415 e->requiresConstraints = constraintList_mergeRequiresFreeFirst (e->requiresConstraints, p->requiresConstraints);
417 /* do ensures clauses
418 find the the ensures lists for each subbranch
421 t = constraintList_mergeEnsures (p->trueEnsuresConstraints, trueBranch->ensuresConstraints);
423 t = constraintList_mergeEnsures (p->ensuresConstraints, t);
424 constraintList_free(t2);
426 f = constraintList_mergeEnsures (p->falseEnsuresConstraints, falseBranch->ensuresConstraints);
428 f = constraintList_mergeEnsures (p->ensuresConstraints, f);
429 constraintList_free(f2);
431 /* find ensures for whole if/else statement */
433 constraintList_free(e->ensuresConstraints);
435 e->ensuresConstraints = constraintList_logicalOr (t, f);
437 constraintList_free(t);
438 constraintList_free(f);
439 constraintList_free(cons);
440 constraintList_free(c1);
442 DPRINTF ((message ("doIfElse: if requires %q ", constraintList_unparse(e->requiresConstraints))));
443 DPRINTF ((message ("doIfElse: if ensures %q ", constraintList_unparse(e->ensuresConstraints))));
448 static exprNode doWhile (/*@returned@*/ exprNode e, /*@dependent@*/ exprNode test, /*@dependent@*/ exprNode body)
450 DPRINTF ((message ("doWhile: %s ", exprNode_unparse(e))));
451 return doIf (e, test, body);
454 /*@only@*/ constraintList constraintList_makeFixedArrayConstraints (/*@observer@*/ sRefSet s)
458 ret = constraintList_makeNew();
460 sRefSet_elements (s, el)
462 if (sRef_isFixedArray(el))
465 DPRINTF((message("%s is a fixed array",
467 size = sRef_getArraySize(el);
468 DPRINTF((message("%s is a fixed array with size %d",
469 sRef_unparse(el), (int)size)));
470 con = constraint_makeSRefSetBufferSize (el, size_toLong (size - 1));
471 ret = constraintList_add(ret, con);
475 DPRINTF((message("%s is not a fixed array",
479 if (sRef_isExternallyVisible (el))
482 DPRINTF((message("%s is externally visible",
484 con = constraint_makeSRefWriteSafeInt(el, 0);
485 ret = constraintList_add(ret, con);
487 con = constraint_makeSRefReadSafeInt(el, 0);
489 ret = constraintList_add(ret, con);
494 end_sRefSet_elements ;
496 DPRINTF((message("constraintList_makeFixedArrayConstraints returning %s",
497 constraintList_unparse(ret))));
502 exprNode makeDataTypeConstraints (/*@returned@*/ exprNode e)
505 DPRINTF(("makeDataTypeConstraints"));
507 c = constraintList_makeFixedArrayConstraints (e->uses);
509 e->ensuresConstraints = constraintList_addListFree (e->ensuresConstraints, c);
515 static void doFor (/*@dependent@*/ exprNode e, /*@dependent@*/ exprNode forPred, /*@dependent@*/ exprNode forBody)
517 exprNode init, test, inc;
518 /* merge the constraints: modle as if statement */
525 llassert (exprNode_isDefined (e));
526 llassert (exprNode_isDefined (forPred));
527 llassert (exprNode_isDefined (forBody));
529 init = exprData_getTripleInit (forPred->edata);
530 test = exprData_getTripleTest (forPred->edata);
531 inc = exprData_getTripleInc (forPred->edata);
533 if (((exprNode_isError (test) /*|| (exprNode_isError(init))*/) || (exprNode_isError (inc))))
535 DPRINTF ((message ("strange for statement:%s, ignoring it", exprNode_unparse(e))));
539 exprNode_forLoopHeuristics(e, forPred, forBody);
541 constraintList_free(e->requiresConstraints);
542 e->requiresConstraints = constraintList_reflectChanges(forBody->requiresConstraints, test->ensuresConstraints);
543 e->requiresConstraints = constraintList_reflectChangesFreePre (e->requiresConstraints, test->trueEnsuresConstraints);
544 e->requiresConstraints = constraintList_reflectChangesFreePre (e->requiresConstraints, forPred->ensuresConstraints);
546 if (!forBody->canBreak)
548 e->ensuresConstraints = constraintList_addListFree(e->ensuresConstraints, constraintList_copy(forPred->ensuresConstraints));
549 e->ensuresConstraints = constraintList_addListFree(e->ensuresConstraints,constraintList_copy(test->falseEnsuresConstraints));
553 DPRINTF(("Can break"));
557 static /*@dependent@*/ exprNode exprNode_makeDependent(/*@returned@*/ exprNode e)
559 /* !!! DRL - this is ridiculous! Read the manual on memory annotations please! */
564 exprNode_doGenerateConstraintSwitch
565 (/*@dependent@*/ exprNode switchExpr,
566 /*@dependent@*/ exprNode body,
567 /*@special@*/ constraintList *currentRequires,
568 /*@special@*/ constraintList *currentEnsures,
569 /*@special@*/ constraintList *savedRequires,
570 /*@special@*/ constraintList *savedEnsures)
571 /*@post:only *currentRequires, *currentEnsures, *savedRequires, *savedEnsures @*/
572 /*@sets *currentRequires, *currentEnsures, *savedRequires, *savedEnsures @*/
574 exprNode stmt, stmtList;
576 DPRINTF((message("exprNode_doGenerateConstraintSwitch: (switch %s) %s",
577 exprNode_unparse(switchExpr), exprNode_unparse(body)
580 if (exprNode_isError(body))
582 *currentRequires = constraintList_makeNew ();
583 *currentEnsures = constraintList_makeNew ();
585 *savedRequires = constraintList_makeNew ();
586 *savedEnsures = constraintList_makeNew ();
592 if (body->kind != XPR_STMTLIST)
594 DPRINTF((message("exprNode_doGenerateConstraintSwitch: non stmtlist: %s",
595 exprNode_unparse(body))));
597 stmtList = exprNode_undefined;
598 stmt = exprNode_makeDependent(stmt);
599 stmtList = exprNode_makeDependent(stmtList);
603 stmt = exprData_getPairB(body->edata);
604 stmtList = exprData_getPairA(body->edata);
605 stmt = exprNode_makeDependent(stmt);
606 stmtList = exprNode_makeDependent(stmtList);
609 DPRINTF((message("exprNode_doGenerateConstraintSwitch: stmtlist: %s stmt: %s",
610 exprNode_unparse(stmtList), exprNode_unparse(stmt))
614 exprNode_doGenerateConstraintSwitch (switchExpr, stmtList, currentRequires, currentEnsures,
615 savedRequires, savedEnsures);
617 if (exprNode_isError(stmt))
624 switchExpr = exprNode_makeDependent (switchExpr);
626 if (! exprNode_isCaseMarker(stmt))
631 DPRINTF ((message("Got normal statement %s (requires %s ensures %s)", exprNode_unparse(stmt),
632 constraintList_unparse(stmt->requiresConstraints), constraintList_unparse(stmt->ensuresConstraints))));
634 temp = constraintList_reflectChanges (stmt->requiresConstraints,
637 *currentRequires = constraintList_mergeRequiresFreeFirst(
641 constraintList_free(temp);
643 *currentEnsures = constraintList_mergeEnsuresFreeFirst
645 stmt->ensuresConstraints);
646 DPRINTF((message("returning from exprNode_doGenerateConstraintSwitch: (switch %s) %s currentRequires:"
647 "%s currentEnsures:%s",
648 exprNode_unparse(switchExpr), exprNode_unparse(body),
649 constraintList_unparse(*currentRequires), constraintList_unparse(*currentEnsures)
657 if (exprNode_isCaseMarker(stmt) && exprNode_mustEscape(stmtList))
660 ** merge current and saved constraint with Logical Or...
661 ** make a constraint for ensures
667 DPRINTF ((message("Got case marker")));
669 if (constraintList_isUndefined(*savedEnsures) &&
670 constraintList_isUndefined(*savedRequires))
672 llassert(constraintList_isUndefined(*savedEnsures));
673 llassert(constraintList_isUndefined(*savedRequires));
674 *savedEnsures = constraintList_copy(*currentEnsures);
675 *savedRequires = constraintList_copy(*currentRequires);
679 DPRINTF ((message("Doing logical or")));
680 temp = constraintList_logicalOr (*savedEnsures, *currentEnsures);
681 constraintList_free (*savedEnsures);
682 *savedEnsures = temp;
684 *savedRequires = constraintList_mergeRequiresFreeFirst (*savedRequires, *currentRequires);
687 con = constraint_makeEnsureEqual (switchExpr, exprData_getSingle (stmt->edata), exprNode_loc (stmt));
689 constraintList_free (*currentEnsures);
690 *currentEnsures = constraintList_makeNew();
691 *currentEnsures = constraintList_add(*currentEnsures, con);
693 constraintList_free(*currentRequires);
694 *currentRequires = constraintList_makeNew();
695 DPRINTF (("exprNode_doGenerateConstraintSwitch: (switch %s) %s savedRequires:"
696 "%s savedEnsures:%s",
697 exprNode_unparse(switchExpr), exprNode_unparse(body),
698 constraintList_unparse(*savedRequires), constraintList_unparse(*savedEnsures)
701 else if (exprNode_isCaseMarker(stmt)) /* prior case has no break. */
704 We don't do anything to the sved constraints because the case hasn't ended
705 The new ensures constraints for the case will be:
706 the constraint for the case statement (CASE_LABEL == SWITCH_EXPR) logicalOr currentEnsures
711 constraintList ensuresTemp;
713 con = constraint_makeEnsureEqual (switchExpr, exprData_getSingle (stmt->edata), exprNode_loc (stmt));
715 ensuresTemp = constraintList_makeNew ();
716 ensuresTemp = constraintList_add (ensuresTemp, con);
718 if (exprNode_isError (stmtList))
720 constraintList_free (*currentEnsures);
721 *currentEnsures = constraintList_copy (ensuresTemp);
722 constraintList_free (ensuresTemp);
726 temp = constraintList_logicalOr (*currentEnsures, ensuresTemp);
727 constraintList_free (*currentEnsures);
728 constraintList_free (ensuresTemp);
729 *currentEnsures = temp;
732 constraintList_free (*currentRequires);
733 *currentRequires = constraintList_makeNew();
738 we handle the case of ! exprNode_isCaseMarker above
739 the else if clause should always be true.
744 DPRINTF (("returning from exprNode_doGenerateConstraintSwitch: (switch %s) %s currentRequires:"
745 "%s currentEnsures:%s",
746 exprNode_unparse(switchExpr), exprNode_unparse(body),
747 constraintList_unparse(*currentRequires), constraintList_unparse(*currentEnsures)
756 static void exprNode_generateConstraintSwitch (/*@notnull@*/ exprNode switchStmt)
758 constraintList constraintsRequires;
759 constraintList constraintsEnsures;
760 constraintList lastRequires;
761 constraintList lastEnsures;
766 switchExpr = exprData_getPairA (switchStmt->edata);
767 body = exprData_getPairB (switchStmt->edata);
769 if (!exprNode_isDefined (body))
774 DPRINTF((message("")));
776 if (body->kind == XPR_BLOCK)
777 body = exprData_getSingle(body->edata);
780 constraintsRequires = constraintList_undefined;
781 constraintsEnsures = constraintList_undefined;
783 lastRequires = constraintList_makeNew();
784 lastEnsures = constraintList_makeNew();
788 /* evans 2002-01-01: spurious warnings for these becuase of stack allocated storage */
789 exprNode_doGenerateConstraintSwitch (switchExpr, body, &lastRequires,
790 &lastEnsures, &constraintsRequires, &constraintsEnsures);
794 merge current and saved constraint with Logical Or...
795 make a constraint for ensures
798 constraintList_free(switchStmt->requiresConstraints);
799 constraintList_free(switchStmt->ensuresConstraints);
801 if (constraintList_isDefined(constraintsEnsures) && constraintList_isDefined(constraintsRequires))
803 switchStmt->ensuresConstraints = constraintList_logicalOr(constraintsEnsures, lastEnsures);
804 switchStmt->requiresConstraints = constraintList_mergeRequires(constraintsRequires, lastRequires);
805 constraintList_free (constraintsRequires);
806 constraintList_free (constraintsEnsures);
810 switchStmt->ensuresConstraints = constraintList_copy(lastEnsures);
811 switchStmt->requiresConstraints = constraintList_copy(lastRequires);
814 constraintList_free (lastRequires);
815 constraintList_free (lastEnsures);
817 DPRINTF(((message(" exprNode_generateConstraintSwitch returning requires: %s and ensures %s",
818 constraintList_unparse(switchStmt->requiresConstraints),
819 constraintList_unparse(switchStmt->ensuresConstraints)
824 static exprNode doSwitch (/*@returned@*/ /*@notnull@*/ exprNode e)
830 DPRINTF ((message ("doSwitch for: switch (%s) %s",
831 exprNode_unparse (exprData_getPairA (data)),
832 exprNode_unparse (exprData_getPairB (data)))));
834 body = exprData_getPairB (data);
835 exprNode_generateConstraintSwitch (e);
839 void exprNode_multiStatement (/*@dependent@*/ exprNode e)
845 exprNode p, trueBranch, falseBranch;
846 exprNode forPred, forBody;
851 DPRINTF((message ("exprNode_multistatement Analysising %s %s at", exprNode_unparse(e),
852 fileloc_unparse(exprNode_getNextSequencePoint(e)))));
854 if (exprNode_handleError (e))
867 forPred = exprData_getPairA (data);
868 forBody = exprData_getPairB (data);
870 /* First generate the constraints */
871 exprNode_generateConstraints (forPred);
872 exprNode_generateConstraints (forBody);
875 doFor (e, forPred, forBody);
880 exprNode_generateConstraints (exprData_getTripleInit (data));
881 test = exprData_getTripleTest (data);
882 exprNode_exprTraverse (test,FALSE, FALSE, exprNode_loc(e));
883 exprNode_generateConstraints (exprData_getTripleInc (data));
885 if (!exprNode_isError(test))
887 constraintList temp2;
888 temp2 = test->trueEnsuresConstraints;
889 test->trueEnsuresConstraints = exprNode_traverseTrueEnsuresConstraints(test);
890 constraintList_free(temp2);
893 exprNode_generateConstraints (exprData_getTripleInc (data));
897 e1 = exprData_getPairA (data);
898 e2 = exprData_getPairB (data);
900 exprNode_exprTraverse (e1,
901 FALSE, FALSE, exprNode_loc(e1));
903 exprNode_generateConstraints (e2);
905 e = doWhile (e, e1, e2);
911 DPRINTF ((exprNode_unparse(e)));
912 e1 = exprData_getPairA (data);
913 e2 = exprData_getPairB (data);
915 exprNode_exprTraverse (e1, FALSE, FALSE, exprNode_loc(e1));
917 exprNode_generateConstraints (e2);
918 e = doIf (e, e1, e2);
922 DPRINTF(("Starting IFELSE"));
923 p = exprData_getTriplePred (data);
925 trueBranch = exprData_getTripleTrue (data);
926 falseBranch = exprData_getTripleFalse (data);
928 exprNode_exprTraverse (p,
929 FALSE, FALSE, exprNode_loc(p));
930 exprNode_generateConstraints (trueBranch);
931 exprNode_generateConstraints (falseBranch);
933 llassert (exprNode_isDefined (p));
934 temp = p->ensuresConstraints;
935 p->ensuresConstraints = exprNode_traverseEnsuresConstraints (p);
936 constraintList_free(temp);
938 temp = p->requiresConstraints;
939 p->requiresConstraints = exprNode_traverseRequiresConstraints (p);
940 constraintList_free(temp);
942 temp = p->trueEnsuresConstraints;
943 p->trueEnsuresConstraints = exprNode_traverseTrueEnsuresConstraints(p);
944 constraintList_free(temp);
948 DPRINTF((message("p->trueEnsuresConstraints before substitue %s", constraintList_unparse(p->trueEnsuresConstraints) )
951 /*drl 10/10/2002 this is a bit of a hack but the reason why we do this is so that any function post conditions or similar things get applied correctly to each branch. e.g. in strlen(s) < 5 we want the trueEnsures to be maxRead(s) < 5*/
953 p->trueEnsuresConstraints = constraintList_substituteFreeTarget (p->trueEnsuresConstraints,
954 p->ensuresConstraints);
956 DPRINTF(( message ("p->trueEnsuresConstraints after substitue %s", constraintList_unparse(p->trueEnsuresConstraints) )
959 temp = p->falseEnsuresConstraints;
960 p->falseEnsuresConstraints = exprNode_traverseFalseEnsuresConstraints(p);
961 constraintList_free(temp);
963 /*See comment on trueEnsures*/
964 p->falseEnsuresConstraints = constraintList_substituteFreeTarget (p->falseEnsuresConstraints,
965 p->ensuresConstraints);
967 e = doIfElse (e, p, trueBranch, falseBranch);
968 DPRINTF(("Done IFELSE"));
973 e2 = (exprData_getPairB (data));
974 e1 = (exprData_getPairA (data));
976 DPRINTF((message ("do { %s } while (%s)", exprNode_unparse(e2), exprNode_unparse(e1))));
977 exprNode_generateConstraints (e2);
978 exprNode_generateConstraints (e1);
979 e = exprNode_copyConstraints (e, e2);
980 DPRINTF ((message ("e = %s ", constraintList_unparse(e->requiresConstraints))));
988 tempExpr = exprData_getSingle (data);
990 exprNode_generateConstraints (tempExpr);
992 if (exprNode_isDefined(tempExpr) )
994 constraintList_free(e->requiresConstraints);
995 e->requiresConstraints = constraintList_copy (tempExpr->requiresConstraints);
996 constraintList_free(e->ensuresConstraints);
997 e->ensuresConstraints = constraintList_copy (tempExpr->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_isEqOp (tok))
1031 if (lltok_isAndOp (tok))
1037 if (lltok_isOrOp (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;
1074 if (exprNode_isUndefined(e) )
1076 llassert (exprNode_isDefined(e) );
1082 tok = exprData_getOpTok (data);
1083 t1 = exprData_getOpA (data);
1084 t2 = exprData_getOpB (data);
1086 /* drl 3/2/2003 we know this because of the type of expression*/
1087 llassert( exprNode_isDefined(t1) && exprNode_isDefined(t2) );
1090 tempList = constraintList_undefined;
1092 /* arithmetic tests */
1094 if (lltok_isEqOp (tok))
1096 cons = constraint_makeEnsureEqual (t1, t2, sequencePoint);
1097 e->trueEnsuresConstraints = constraintList_add(e->trueEnsuresConstraints, cons);
1101 if (lltok_isLt_Op (tok))
1103 cons = constraint_makeEnsureLessThan (t1, t2, sequencePoint);
1104 e->trueEnsuresConstraints = constraintList_add(e->trueEnsuresConstraints, cons);
1105 cons = constraint_makeEnsureGreaterThanEqual (t1, t2, sequencePoint);
1106 e->falseEnsuresConstraints = constraintList_add(e->falseEnsuresConstraints, cons);
1109 if (lltok_isGe_Op (tok))
1111 cons = constraint_makeEnsureGreaterThanEqual (t1, t2, sequencePoint);
1112 e->trueEnsuresConstraints = constraintList_add(e->trueEnsuresConstraints, cons);
1114 cons = constraint_makeEnsureLessThan (t1, t2, sequencePoint);
1115 e->falseEnsuresConstraints = constraintList_add(e->falseEnsuresConstraints, cons);
1118 if (lltok_isGt_Op (tok))
1120 cons = constraint_makeEnsureGreaterThan (t1, t2, sequencePoint);
1121 e->trueEnsuresConstraints = constraintList_add(e->trueEnsuresConstraints, cons);
1122 cons = constraint_makeEnsureLessThanEqual (t1, t2, sequencePoint);
1123 e->falseEnsuresConstraints = constraintList_add(e->falseEnsuresConstraints, cons);
1126 if (lltok_isLe_Op (tok))
1128 cons = constraint_makeEnsureLessThanEqual (t1, t2, sequencePoint);
1129 e->trueEnsuresConstraints = constraintList_add(e->trueEnsuresConstraints, cons);
1131 cons = constraint_makeEnsureGreaterThan (t1, t2, sequencePoint);
1132 e->falseEnsuresConstraints = constraintList_add(e->falseEnsuresConstraints, cons);
1135 /* Logical operations */
1137 if (lltok_isAndOp (tok))
1140 tempList = constraintList_copy (t1->trueEnsuresConstraints);
1141 tempList = constraintList_addList (tempList, t2->trueEnsuresConstraints);
1142 e->trueEnsuresConstraints = constraintList_addListFree(e->trueEnsuresConstraints, tempList);
1144 /* false ensures: fens t1 or tens t1 and fens t2 */
1145 tempList = constraintList_copy (t1->trueEnsuresConstraints);
1146 tempList = constraintList_addList (tempList, t2->falseEnsuresConstraints);
1148 tempList = constraintList_logicalOr (tempList, t1->falseEnsuresConstraints);
1149 constraintList_free (temp);
1151 /* evans - was constraintList_addList - memory leak detected by splint */
1152 e->falseEnsuresConstraints = constraintList_addListFree (e->falseEnsuresConstraints, tempList);
1154 else if (lltok_isOrOp (tok))
1157 tempList = constraintList_copy (t1->falseEnsuresConstraints);
1158 tempList = constraintList_addList (tempList, t2->falseEnsuresConstraints);
1159 e->falseEnsuresConstraints = constraintList_addListFree(e->falseEnsuresConstraints, tempList);
1161 /* true ensures: tens t1 or fens t1 and tens t2 */
1162 tempList = constraintList_copy (t1->falseEnsuresConstraints);
1163 tempList = constraintList_addList (tempList, t2->trueEnsuresConstraints);
1166 tempList = constraintList_logicalOr (tempList, t1->trueEnsuresConstraints);
1167 constraintList_free(temp);
1169 e->trueEnsuresConstraints = constraintList_addListFree(e->trueEnsuresConstraints, tempList);
1170 tempList = constraintList_undefined;
1174 DPRINTF((message("%s is not a boolean operation", lltok_unparse(tok))));
1178 void exprNode_exprTraverse (/*@dependent@*/ exprNode e,
1179 bool definatelv, bool definaterv,
1180 /*@observer@*/ /*@temp@*/ fileloc sequencePoint)
1182 exprNode t1, t2, fcn;
1186 constraintList temp;
1188 if (exprNode_isError(e))
1193 DPRINTF (("exprNode_exprTraverse analyzing %s at %s",
1194 exprNode_unparse (e),
1195 fileloc_unparse (exprNode_loc (e))));
1197 if (exprNode_isUnhandled (e))
1207 t1 = exprData_getSingle (data);
1208 exprNode_exprTraverse (t1, definatelv, definaterv, sequencePoint);
1209 e = exprNode_copyConstraints (e, t1);
1216 t1 = (exprData_getPairA (data));
1217 t2 = (exprData_getPairB (data));
1218 cons = constraint_makeWriteSafeExprNode (t1, t2);
1222 t1 = (exprData_getPairA (data));
1223 t2 = (exprData_getPairB (data));
1224 cons = constraint_makeReadSafeExprNode (t1, t2);
1227 e->requiresConstraints = constraintList_add(e->requiresConstraints, cons);
1228 cons = constraint_makeEnsureMaxReadAtLeast (t1, t2, sequencePoint);
1229 e->ensuresConstraints = constraintList_add(e->ensuresConstraints, cons);
1231 cons = constraint_makeEnsureLteMaxRead (t2, t1);
1232 e->trueEnsuresConstraints = constraintList_add(e->trueEnsuresConstraints, cons);
1234 exprNode_exprTraverse (exprData_getPairA (data), FALSE, TRUE, sequencePoint);
1235 exprNode_exprTraverse (exprData_getPairB (data), FALSE, TRUE, sequencePoint);
1240 exprNode_exprTraverse (exprData_getUopNode (e->edata), definatelv, definaterv, sequencePoint);
1244 t2 = exprData_getInitNode (data);
1246 DPRINTF (("initialization ==> %s",exprNode_unparse (t2)));
1248 exprNode_exprTraverse (t2, definatelv, TRUE, sequencePoint);
1250 /* This test is nessecary because some expressions generate a null expression node.
1251 function pointer do that -- drl */
1253 if (!exprNode_isError (e) && !exprNode_isError (t2))
1255 cons = constraint_makeEnsureEqual (e, t2, sequencePoint);
1256 e->ensuresConstraints = constraintList_add(e->ensuresConstraints, cons);
1262 t1 = exprData_getOpA (data);
1263 t2 = exprData_getOpB (data);
1264 DPRINTF (("Assignment constraints t1: %s", constraintList_unparse (t1->ensuresConstraints)));
1265 DPRINTF (("Assignment constraints t2: %s", constraintList_unparse (t2->ensuresConstraints)));
1266 exprNode_exprTraverse (t1, TRUE, definaterv, sequencePoint);
1267 DPRINTF (("Assignment constraints t1: %s", constraintList_unparse (t1->ensuresConstraints)));
1268 DPRINTF (("Assignment constraints t2: %s", constraintList_unparse (t2->ensuresConstraints)));
1269 exprNode_exprTraverse (t2, definatelv, TRUE, sequencePoint);
1270 DPRINTF (("Assignment constraints t1: %s", constraintList_unparse (t1->ensuresConstraints)));
1271 DPRINTF (("Assignment constraints t2: %s", constraintList_unparse (t2->ensuresConstraints)));
1273 /* this test is nessecary because some expressions generate a null expression node.
1274 function pointer do that -- drl */
1276 if ((!exprNode_isError (t1)) && (!exprNode_isError(t2)))
1278 cons = constraint_makeEnsureEqual (t1, t2, sequencePoint);
1279 DPRINTF (("Ensure equal constraint: %s", constraint_unparse (cons)));
1280 e->ensuresConstraints = constraintList_add (e->ensuresConstraints, cons);
1281 DPRINTF (("Assignment constraints: %s", constraintList_unparse (e->ensuresConstraints)));
1285 t1 = exprData_getOpA (data);
1286 t2 = exprData_getOpB (data);
1287 tok = exprData_getOpTok (data);
1289 if (lltok_getTok (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 (lltok_getTok (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 /*drl 4-11-03 I think this is the same as the next case...*/
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 (("Got call that %s (%s)",
1333 exprNode_unparse(fcn), exprNodeList_unparse (exprData_getArgs (data))));
1335 llassert( exprNode_isDefined(fcn) );
1337 fcn->requiresConstraints =
1338 constraintList_addListFree (fcn->requiresConstraints,
1339 checkCall (fcn, exprData_getArgs (data)));
1341 fcn->ensuresConstraints =
1342 constraintList_addListFree (fcn->ensuresConstraints,
1343 exprNode_getPostConditions(fcn, exprData_getArgs (data),e ));
1345 t1 = exprNode_createNew (exprNode_getType (e));
1346 checkArgumentList (t1, exprData_getArgs(data), sequencePoint);
1347 exprNode_mergeResolve (e, t1, fcn);
1352 exprNode_exprTraverse (exprData_getSingle (data), definatelv, definaterv, sequencePoint);
1355 case XPR_NULLRETURN:
1361 exprNode_exprTraverse (exprData_getFieldNode (data), definatelv, definaterv, sequencePoint);
1365 exprNode_exprTraverse (exprData_getFieldNode (data), definatelv, definaterv, sequencePoint);
1368 case XPR_STRINGLITERAL:
1377 t1 = exprData_getUopNode(data);
1380 /* drl 3/2/2003 we know this because of the type of expression*/
1381 llassert( exprNode_isDefined(t1) );
1384 tok = (exprData_getUopTok (data));
1385 exprNode_exprTraverse (t1, definatelv, definaterv, sequencePoint);
1386 /*handle * pointer access */
1387 if (lltok_isIncOp (tok))
1389 DPRINTF(("doing ++(var)"));
1390 t1 = exprData_getUopNode (data);
1391 cons = constraint_makeMaxSetSideEffectPostIncrement (t1, sequencePoint);
1392 e->ensuresConstraints = constraintList_add (e->ensuresConstraints, cons);
1394 else if (lltok_isDecOp (tok))
1396 DPRINTF(("doing --(var)"));
1397 t1 = exprData_getUopNode (data);
1398 cons = constraint_makeMaxSetSideEffectPostDecrement (t1, sequencePoint);
1399 e->ensuresConstraints = constraintList_add (e->ensuresConstraints, cons);
1401 else if (lltok_isMult(tok ))
1405 cons = constraint_makeWriteSafeInt (t1, 0);
1409 cons = constraint_makeReadSafeInt (t1, 0);
1411 e->requiresConstraints = constraintList_add(e->requiresConstraints, cons);
1413 else if (lltok_isNotOp (tok))
1416 constraintList_free(e->trueEnsuresConstraints);
1418 e->trueEnsuresConstraints = constraintList_copy (t1->falseEnsuresConstraints);
1419 constraintList_free(e->falseEnsuresConstraints);
1420 e->falseEnsuresConstraints = constraintList_copy (t1->trueEnsuresConstraints);
1423 else if (lltok_isAmpersand_Op (tok))
1427 else if (lltok_isMinus_Op (tok))
1431 else if (lltok_isPlus_Op (tok))
1435 else if (lltok_isExcl_Op (tok))
1439 else if (lltok_isTilde_Op (tok))
1445 llcontbug (message("Unsupported preop in %s", exprNode_unparse(e)));
1451 exprNode_exprTraverse (exprData_getUopNode (data), TRUE,
1452 definaterv, sequencePoint);
1454 if (lltok_isIncOp (exprData_getUopTok (data)))
1456 DPRINTF(("doing ++"));
1457 t1 = exprData_getUopNode (data);
1458 cons = constraint_makeMaxSetSideEffectPostIncrement (t1, sequencePoint);
1459 e->ensuresConstraints = constraintList_add (e->ensuresConstraints, cons);
1461 if (lltok_isDecOp (exprData_getUopTok (data)))
1463 DPRINTF(("doing --"));
1464 t1 = exprData_getUopNode (data);
1465 cons = constraint_makeMaxSetSideEffectPostDecrement (t1, sequencePoint);
1466 e->ensuresConstraints = constraintList_add (e->ensuresConstraints, cons);
1471 t2 = exprData_getCastNode (data);
1472 DPRINTF ((message ("Examining cast (%q)%s",
1473 qtype_unparse (exprData_getCastType (data)),
1474 exprNode_unparse (t2))
1476 exprNode_exprTraverse (t2, definatelv, definaterv, sequencePoint);
1482 exprNode pred, trueBranch, falseBranch;
1484 pred = exprData_getTriplePred (data);
1485 trueBranch = exprData_getTripleTrue (data);
1486 falseBranch = exprData_getTripleFalse (data);
1488 llassert (exprNode_isDefined (pred));
1489 llassert (exprNode_isDefined (trueBranch));
1490 llassert (exprNode_isDefined (falseBranch));
1492 exprNode_exprTraverse (pred, FALSE, TRUE, sequencePoint);
1494 temp = pred->ensuresConstraints;
1495 pred->ensuresConstraints = exprNode_traverseEnsuresConstraints(pred);
1496 constraintList_free(temp);
1498 temp = pred->requiresConstraints;
1499 pred->requiresConstraints = exprNode_traverseRequiresConstraints(pred);
1500 constraintList_free(temp);
1502 temp = pred->trueEnsuresConstraints;
1503 pred->trueEnsuresConstraints = exprNode_traverseTrueEnsuresConstraints(pred);
1504 constraintList_free(temp);
1506 temp = pred->falseEnsuresConstraints;
1507 pred->falseEnsuresConstraints = exprNode_traverseFalseEnsuresConstraints(pred);
1508 constraintList_free(temp);
1510 exprNode_exprTraverse (trueBranch, FALSE, TRUE, sequencePoint);
1512 temp = trueBranch->ensuresConstraints;
1513 trueBranch->ensuresConstraints = exprNode_traverseEnsuresConstraints(trueBranch);
1514 constraintList_free(temp);
1516 temp = trueBranch->requiresConstraints;
1517 trueBranch->requiresConstraints = exprNode_traverseRequiresConstraints(trueBranch);
1518 constraintList_free(temp);
1520 temp = trueBranch->trueEnsuresConstraints;
1521 trueBranch->trueEnsuresConstraints = exprNode_traverseTrueEnsuresConstraints(trueBranch);
1522 constraintList_free(temp);
1524 temp = trueBranch->falseEnsuresConstraints;
1525 trueBranch->falseEnsuresConstraints = exprNode_traverseFalseEnsuresConstraints(trueBranch);
1526 constraintList_free(temp);
1528 exprNode_exprTraverse (falseBranch, FALSE, TRUE, sequencePoint);
1530 temp = falseBranch->ensuresConstraints;
1531 falseBranch->ensuresConstraints = exprNode_traverseEnsuresConstraints(falseBranch);
1532 constraintList_free(temp);
1535 temp = falseBranch->requiresConstraints;
1536 falseBranch->requiresConstraints = exprNode_traverseRequiresConstraints(falseBranch);
1537 constraintList_free(temp);
1539 temp = falseBranch->trueEnsuresConstraints;
1540 falseBranch->trueEnsuresConstraints = exprNode_traverseTrueEnsuresConstraints(falseBranch);
1541 constraintList_free(temp);
1543 temp = falseBranch->falseEnsuresConstraints;
1544 falseBranch->falseEnsuresConstraints = exprNode_traverseFalseEnsuresConstraints(falseBranch);
1545 constraintList_free(temp);
1547 /* if pred is true e equals true otherwise pred equals false */
1549 cons = constraint_makeEnsureEqual (e, trueBranch, sequencePoint);
1550 trueBranch->ensuresConstraints = constraintList_add(trueBranch->ensuresConstraints, cons);
1552 cons = constraint_makeEnsureEqual (e, trueBranch, sequencePoint);
1553 falseBranch->ensuresConstraints = constraintList_add(falseBranch->ensuresConstraints, cons);
1555 e = doIfElse (e, pred, trueBranch, falseBranch);
1560 t1 = exprData_getPairA (data);
1561 t2 = exprData_getPairB (data);
1562 /* we essiantially treat this like expr1; expr2
1563 of course sequencePoint isn't adjusted so this isn't completely accurate
1566 exprNode_exprTraverse (t1, FALSE, FALSE, sequencePoint);
1567 exprNode_exprTraverse (t2, definatelv, definaterv, sequencePoint);
1568 exprNode_mergeResolve (e, t1, t2);
1575 e->requiresConstraints = constraintList_preserveOrig (e->requiresConstraints);
1576 e->ensuresConstraints = constraintList_preserveOrig (e->ensuresConstraints);
1577 e->requiresConstraints = constraintList_addGeneratingExpr (e->requiresConstraints, e);
1578 e->ensuresConstraints = constraintList_addGeneratingExpr (e->ensuresConstraints, e);
1579 e->requiresConstraints = constraintList_removeSurpressed (e->requiresConstraints);
1581 DPRINTF (("ensures constraints for %s are %s",
1582 exprNode_unparse(e), constraintList_unparseDetailed (e->ensuresConstraints)));
1584 DPRINTF (("Requires constraints for %s are %s", exprNode_unparse(e),
1585 constraintList_unparseDetailed(e->ensuresConstraints)));
1587 DPRINTF (("trueEnsures constraints for %s are %s", exprNode_unparse(e),
1588 constraintList_unparseDetailed(e->trueEnsuresConstraints)));
1590 DPRINTF (("falseEnsures constraints for %s are %s", exprNode_unparse(e),
1591 constraintList_unparseDetailed(e->falseEnsuresConstraints)));
1596 constraintList exprNode_traverseTrueEnsuresConstraints (exprNode e)
1600 bool handledExprNode;
1604 if (exprNode_handleError (e))
1606 ret = constraintList_makeNew();
1610 ret = constraintList_copy (e->trueEnsuresConstraints);
1612 handledExprNode = TRUE;
1619 t1 = exprData_getSingle (data);
1620 ret = constraintList_addListFree (ret, exprNode_traverseTrueEnsuresConstraints (t1));
1625 ret = constraintList_addListFree (ret,
1626 exprNode_traverseTrueEnsuresConstraints
1627 (exprData_getPairA (data)));
1629 ret = constraintList_addListFree (ret,
1630 exprNode_traverseTrueEnsuresConstraints
1631 (exprData_getPairB (data)));
1635 ret = constraintList_addListFree (ret,
1636 exprNode_traverseTrueEnsuresConstraints
1637 (exprData_getUopNode (data)));
1641 ret = constraintList_addListFree (ret, exprNode_traverseTrueEnsuresConstraints
1642 (exprData_getUopNode (data)));
1646 ret = constraintList_addListFree (ret,
1647 exprNode_traverseTrueEnsuresConstraints
1648 (exprData_getInitNode (data)));
1653 ret = constraintList_addListFree (ret,
1654 exprNode_traverseTrueEnsuresConstraints
1655 (exprData_getOpA (data)));
1657 ret = constraintList_addListFree (ret,
1658 exprNode_traverseTrueEnsuresConstraints
1659 (exprData_getOpB (data)));
1662 ret = constraintList_addListFree (ret,
1663 exprNode_traverseTrueEnsuresConstraints
1664 (exprData_getOpA (data)));
1666 ret = constraintList_addListFree (ret,
1667 exprNode_traverseTrueEnsuresConstraints
1668 (exprData_getOpB (data)));
1675 ret = constraintList_addListFree (ret,
1676 exprNode_traverseTrueEnsuresConstraints
1677 (exprData_getSingle (data)));
1681 ret = constraintList_addListFree (ret,
1682 exprNode_traverseTrueEnsuresConstraints
1683 (exprData_getFcn (data)));
1687 ret = constraintList_addListFree (ret,
1688 exprNode_traverseTrueEnsuresConstraints
1689 (exprData_getSingle (data)));
1692 case XPR_NULLRETURN:
1696 ret = constraintList_addListFree (ret,
1697 exprNode_traverseTrueEnsuresConstraints
1698 (exprData_getFieldNode (data)));
1702 ret = constraintList_addListFree (ret,
1703 exprNode_traverseTrueEnsuresConstraints
1704 (exprData_getFieldNode (data)));
1707 case XPR_STRINGLITERAL:
1714 ret = constraintList_addListFree (ret,
1715 exprNode_traverseTrueEnsuresConstraints
1716 (exprData_getUopNode (data)));
1721 ret = constraintList_addListFree (ret,
1722 exprNode_traverseTrueEnsuresConstraints
1723 (exprData_getCastNode (data)));
1733 constraintList exprNode_traverseFalseEnsuresConstraints (exprNode e)
1736 bool handledExprNode;
1740 if (exprNode_handleError (e))
1742 ret = constraintList_makeNew();
1746 ret = constraintList_copy (e->falseEnsuresConstraints);
1747 handledExprNode = TRUE;
1753 t1 = exprData_getSingle (data);
1754 ret = constraintList_addListFree (ret,exprNode_traverseFalseEnsuresConstraints (t1));
1759 ret = constraintList_addListFree (ret,
1760 exprNode_traverseFalseEnsuresConstraints
1761 (exprData_getPairA (data)));
1763 ret = constraintList_addListFree (ret,
1764 exprNode_traverseFalseEnsuresConstraints
1765 (exprData_getPairB (data)));
1769 ret = constraintList_addListFree (ret,
1770 exprNode_traverseFalseEnsuresConstraints
1771 (exprData_getUopNode (data)));
1775 ret = constraintList_addListFree (ret, exprNode_traverseFalseEnsuresConstraints
1776 (exprData_getUopNode (data)));
1779 ret = constraintList_addListFree (ret,
1780 exprNode_traverseFalseEnsuresConstraints
1781 ( exprData_getInitNode (data)));
1785 ret = constraintList_addListFree (ret,
1786 exprNode_traverseFalseEnsuresConstraints
1787 (exprData_getOpA (data)));
1789 ret = constraintList_addListFree (ret,
1790 exprNode_traverseFalseEnsuresConstraints
1791 (exprData_getOpB (data)));
1794 ret = constraintList_addListFree (ret,
1795 exprNode_traverseFalseEnsuresConstraints
1796 (exprData_getOpA (data)));
1798 ret = constraintList_addListFree (ret,
1799 exprNode_traverseFalseEnsuresConstraints
1800 (exprData_getOpB (data)));
1807 ret = constraintList_addListFree (ret,
1808 exprNode_traverseFalseEnsuresConstraints
1809 (exprData_getSingle (data)));
1813 ret = constraintList_addListFree (ret,
1814 exprNode_traverseFalseEnsuresConstraints
1815 (exprData_getFcn (data)));
1819 ret = constraintList_addListFree (ret,
1820 exprNode_traverseFalseEnsuresConstraints
1821 (exprData_getSingle (data)));
1824 case XPR_NULLRETURN:
1828 ret = constraintList_addListFree (ret,
1829 exprNode_traverseFalseEnsuresConstraints
1830 (exprData_getFieldNode (data)));
1834 ret = constraintList_addListFree (ret,
1835 exprNode_traverseFalseEnsuresConstraints
1836 (exprData_getFieldNode (data)));
1839 case XPR_STRINGLITERAL:
1846 ret = constraintList_addListFree (ret,
1847 exprNode_traverseFalseEnsuresConstraints
1848 (exprData_getUopNode (data)));
1853 ret = constraintList_addListFree (ret,
1854 exprNode_traverseFalseEnsuresConstraints
1855 (exprData_getCastNode (data)));
1866 /* walk down the tree and get all requires Constraints in each subexpression*/
1867 /*@only@*/ constraintList exprNode_traverseRequiresConstraints (exprNode e)
1871 bool handledExprNode;
1875 if (exprNode_handleError (e))
1877 ret = constraintList_makeNew();
1881 ret = constraintList_copy (e->requiresConstraints);
1882 handledExprNode = TRUE;
1888 t1 = exprData_getSingle (data);
1889 ret = constraintList_addListFree (ret, exprNode_traverseRequiresConstraints (t1));
1894 ret = constraintList_addListFree (ret,
1895 exprNode_traverseRequiresConstraints
1896 (exprData_getPairA (data)));
1898 ret = constraintList_addListFree (ret,
1899 exprNode_traverseRequiresConstraints
1900 (exprData_getPairB (data)));
1904 ret = constraintList_addListFree (ret,
1905 exprNode_traverseRequiresConstraints
1906 (exprData_getUopNode (data)));
1910 ret = constraintList_addListFree (ret, exprNode_traverseRequiresConstraints
1911 (exprData_getUopNode (data)));
1914 ret = constraintList_addListFree (ret,
1915 exprNode_traverseRequiresConstraints
1916 (exprData_getInitNode (data)));
1920 ret = constraintList_addListFree (ret,
1921 exprNode_traverseRequiresConstraints
1922 (exprData_getOpA (data)));
1924 ret = constraintList_addListFree (ret,
1925 exprNode_traverseRequiresConstraints
1926 (exprData_getOpB (data)));
1929 ret = constraintList_addListFree (ret,
1930 exprNode_traverseRequiresConstraints
1931 (exprData_getOpA (data)));
1933 ret = constraintList_addListFree (ret,
1934 exprNode_traverseRequiresConstraints
1935 (exprData_getOpB (data)));
1942 ret = constraintList_addListFree (ret,
1943 exprNode_traverseRequiresConstraints
1944 (exprData_getSingle (data)));
1948 ret = constraintList_addListFree (ret,
1949 exprNode_traverseRequiresConstraints
1950 (exprData_getFcn (data)));
1954 ret = constraintList_addListFree (ret,
1955 exprNode_traverseRequiresConstraints
1956 (exprData_getSingle (data)));
1959 case XPR_NULLRETURN:
1963 ret = constraintList_addListFree (ret,
1964 exprNode_traverseRequiresConstraints
1965 (exprData_getFieldNode (data)));
1969 ret = constraintList_addListFree (ret,
1970 exprNode_traverseRequiresConstraints
1971 (exprData_getFieldNode (data)));
1974 case XPR_STRINGLITERAL:
1981 ret = constraintList_addListFree (ret,
1982 exprNode_traverseRequiresConstraints
1983 (exprData_getUopNode (data)));
1988 ret = constraintList_addListFree (ret,
1989 exprNode_traverseRequiresConstraints
1990 (exprData_getCastNode (data)));
2001 /* walk down the tree and get all Ensures Constraints in each subexpression*/
2002 /*@only@*/ constraintList exprNode_traverseEnsuresConstraints (exprNode e)
2006 bool handledExprNode;
2010 if (exprNode_handleError (e))
2012 ret = constraintList_makeNew();
2016 ret = constraintList_copy (e->ensuresConstraints);
2017 handledExprNode = TRUE;
2021 DPRINTF ((message ("exprnode_traversEnsuresConstraints call for %s with "
2022 "constraintList of %s",
2023 exprNode_unparse (e),
2024 constraintList_unparse(e->ensuresConstraints)
2032 t1 = exprData_getSingle (data);
2033 ret = constraintList_addListFree (ret,exprNode_traverseEnsuresConstraints (t1));
2037 ret = constraintList_addListFree (ret,
2038 exprNode_traverseEnsuresConstraints
2039 (exprData_getPairA (data)));
2041 ret = constraintList_addListFree (ret,
2042 exprNode_traverseEnsuresConstraints
2043 (exprData_getPairB (data)));
2046 ret = constraintList_addListFree (ret,
2047 exprNode_traverseEnsuresConstraints
2048 (exprData_getUopNode (data)));
2052 ret = constraintList_addListFree (ret, exprNode_traverseEnsuresConstraints
2053 (exprData_getUopNode (data)));
2057 ret = constraintList_addListFree (ret,
2058 exprNode_traverseEnsuresConstraints
2059 (exprData_getInitNode (data)));
2064 ret = constraintList_addListFree (ret,
2065 exprNode_traverseEnsuresConstraints
2066 (exprData_getOpA (data)));
2068 ret = constraintList_addListFree (ret,
2069 exprNode_traverseEnsuresConstraints
2070 (exprData_getOpB (data)));
2073 ret = constraintList_addListFree (ret,
2074 exprNode_traverseEnsuresConstraints
2075 (exprData_getOpA (data)));
2077 ret = constraintList_addListFree (ret,
2078 exprNode_traverseEnsuresConstraints
2079 (exprData_getOpB (data)));
2085 ret = constraintList_addListFree (ret,
2086 exprNode_traverseEnsuresConstraints
2087 (exprData_getSingle (data)));
2090 ret = constraintList_addListFree (ret,
2091 exprNode_traverseEnsuresConstraints
2092 (exprData_getFcn (data)));
2095 ret = constraintList_addListFree (ret,
2096 exprNode_traverseEnsuresConstraints
2097 (exprData_getSingle (data)));
2099 case XPR_NULLRETURN:
2102 ret = constraintList_addListFree (ret,
2103 exprNode_traverseEnsuresConstraints
2104 (exprData_getFieldNode (data)));
2107 ret = constraintList_addListFree (ret,
2108 exprNode_traverseEnsuresConstraints
2109 (exprData_getFieldNode (data)));
2111 case XPR_STRINGLITERAL:
2116 ret = constraintList_addListFree (ret,
2117 exprNode_traverseEnsuresConstraints
2118 (exprData_getUopNode (data)));
2121 ret = constraintList_addListFree (ret,
2122 exprNode_traverseEnsuresConstraints
2123 (exprData_getCastNode (data)));
2129 DPRINTF((message ("exprnode_traversEnsuresConstraints call for %s with "
2130 "constraintList of is returning %s",
2131 exprNode_unparse (e),
2132 constraintList_unparse(ret))));
2137 /*drl moved out of constraintResolve.c 07-02-001 */
2138 void checkArgumentList (/*@out@*/ exprNode temp, exprNodeList arglist,
2139 fileloc sequencePoint)
2142 llassert(temp != NULL );
2144 temp->requiresConstraints = constraintList_makeNew();
2145 temp->ensuresConstraints = constraintList_makeNew();
2146 temp->trueEnsuresConstraints = constraintList_makeNew();
2147 temp->falseEnsuresConstraints = constraintList_makeNew();
2149 exprNodeList_elements (arglist, el)
2151 constraintList temp2;
2153 llassert(exprNode_isDefined(el) );
2155 exprNode_exprTraverse (el, FALSE, FALSE, sequencePoint);
2156 temp2 = el->requiresConstraints;
2157 el->requiresConstraints = exprNode_traverseRequiresConstraints(el);
2158 constraintList_free(temp2);
2160 temp2 = el->ensuresConstraints;
2161 el->ensuresConstraints = exprNode_traverseEnsuresConstraints(el);
2162 constraintList_free(temp2);
2164 temp->requiresConstraints = constraintList_addList(temp->requiresConstraints,
2165 el->requiresConstraints);
2167 temp->ensuresConstraints = constraintList_addList(temp->ensuresConstraints,
2168 el->ensuresConstraints);
2170 end_exprNodeList_elements;
2174 /*drl moved out of constraintResolve.c 07-03-001 */
2175 constraintList exprNode_getPostConditions (exprNode fcn, exprNodeList arglist, exprNode fcnCall)
2177 constraintList postconditions;
2179 DPRINTF((message ("Got call that %s (%s) ", exprNode_unparse(fcn), exprNodeList_unparse (arglist))));
2181 temp = exprNode_getUentry (fcn);
2183 postconditions = uentry_getFcnPostconditions (temp);
2185 if (constraintList_isDefined (postconditions))
2187 postconditions = constraintList_doSRefFixConstraintParam (postconditions, arglist);
2188 postconditions = constraintList_doFixResult (postconditions, fcnCall);
2192 postconditions = constraintList_makeNew();
2195 return postconditions;
2199 comment this out for now
2200 we'll include it in a production release when its stable...
2202 void findStructs (exprNodeList arglist)
2208 message("doing findStructs: %s", exprNodeList_unparse(arglist))
2212 exprNodeList_elements(arglist, expr)
2214 ct = exprNode_getType(expr);
2216 rt = ctype_realType (ct);
2218 if (ctype_isStruct (rt))
2219 DPRINTF((message("Found structure %s", exprNode_unparse(expr))
2221 if (hasInvariants(ct))
2223 constraintList invars;
2225 invars = getInvariants(ct);
2228 DPRINTF((message ("findStructs has invariants %s ", constraintList_unparse (invars))
2231 invars = constraintList_doSRefFixStructConstraint(invars, exprNode_getSref(expr), ct);
2234 DPRINTF((message ("findStructs finded invariants to be %s ", constraintList_unparse (invars))
2238 end_exprNodeList_elements;
2243 /*drl moved out of constraintResolve.c 07-02-001 */
2244 constraintList checkCall (/*@dependent@*/ exprNode fcn, exprNodeList arglist)
2246 constraintList preconditions;
2248 DPRINTF((message ("Got call that %s (%s) ", exprNode_unparse(fcn), exprNodeList_unparse (arglist))));
2250 temp = exprNode_getUentry (fcn);
2252 preconditions = uentry_getFcnPreconditions (temp);
2254 if (constraintList_isDefined(preconditions))
2256 preconditions = constraintList_togglePost (preconditions);
2257 preconditions = constraintList_preserveCallInfo(preconditions, fcn);
2258 preconditions = constraintList_doSRefFixConstraintParam (preconditions, arglist);
2262 if (constraintList_isUndefined(preconditions))
2263 preconditions = constraintList_makeNew();
2266 if (context_getFlag (FLG_IMPBOUNDSCONSTRAINTS))
2270 uentryList_elements (arglist, el)
2273 DPRINTF((message("setImplicitfcnConstraints doing: %s", uentry_unparse(el) ) ));
2275 s = uentry_getSref(el);
2276 if (sRef_isReference (s) )
2278 DPRINTF((message ("%s is a pointer", sRef_unparse(s) ) ));
2282 DPRINTF((message ("%s is NOT a pointer", sRef_unparse(s) ) ));
2285 //chagned this from MaxSet(s) == 0 to MaxSet(s) >= 0
2286 c = constraint_makeSRefWriteSafeInt (s, 0);
2288 implicitFcnConstraints = constraintList_add(implicitFcnConstraints , c);
2290 //drl 10/23/2002 added support for out
2291 if (!uentry_isOut(el) )
2293 c = constraint_makeSRefReadSafeInt (s, 0);
2294 implicitFcnConstraints = constraintList_add(implicitFcnConstraints , c);
2302 DPRINTF ((message("Done checkCall\n")));
2303 DPRINTF ((message("Returning list %q ", constraintList_unparseDetailed(preconditions))));
2306 drl we're going to comment this out for now
2307 we'll include it if we're sure it's working
2309 findStructs(arglist);
2312 return preconditions;
2315 /*drl added this function 10.29.001
2316 takes an exprNode of the form const + const
2320 I'm a bit nervous about modifying the exprNode
2321 but this is the easy way to do this
2322 If I have time I'd like to cause the exprNode to get created correctly in the first place */
2323 void exprNode_findValue(exprNode e)
2330 llassert(exprNode_isDefined(e) );
2334 if (exprNode_hasValue(e))
2337 if (e->kind == XPR_OP)
2339 t1 = exprData_getOpA (data);
2340 t2 = exprData_getOpB (data);
2341 tok = exprData_getOpTok (data);
2343 exprNode_findValue(t1);
2344 exprNode_findValue(t2);
2346 if (!(exprNode_knownIntValue(t1) && (exprNode_knownIntValue(t2))))
2349 if (lltok_isPlus_Op (tok))
2353 v1 = exprNode_getLongValue(t1);
2354 v2 = exprNode_getLongValue(t2);
2356 if (multiVal_isDefined(e->val))
2357 multiVal_free (e->val);
2359 e->val = multiVal_makeInt (v1 + v2);
2362 if (lltok_isMinus_Op (tok))
2366 v1 = exprNode_getLongValue(t1);
2367 v2 = exprNode_getLongValue(t2);
2369 if (multiVal_isDefined(e->val))
2371 multiVal_free (e->val);
2374 e->val = multiVal_makeInt (v1 - v2);
2377 /*drl I should really do * and / at some point */