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 "splintMacros.nf"
34 # include "cgrammar.h"
36 /*drl We need to access the internal representation of exprNode
37 because these functions walk down the parse tree and need a richer
38 information than is accessible through the exprNode interface.*/
42 static /*@nullwhentrue@*/ bool exprNode_handleError (/*@temp@*/ exprNode p_e
);
44 static void exprNode_stmt (/*@temp@*/ /*@temp@*/ exprNode p_e
);
45 static void exprNode_multiStatement (/*@temp@*/ exprNode p_e
);
47 static constraintList
exprNode_traverseTrueEnsuresConstraints (/*@temp@*/ exprNode p_e
);
48 static constraintList
exprNode_traverseFalseEnsuresConstraints (/*@temp@*/ exprNode p_e
);
50 static void checkArgumentList (/*@out@*/ exprNode p_temp
, exprNodeList p_arglist
, fileloc p_sequencePoint
) /*@modifies p_temp @*/;
52 static constraintList
checkCall (/*@temp@*/ exprNode p_fcn
, exprNodeList p_arglist
);
54 static void exprNode_exprTraverse (exprNode p_e
, bool p_definatelv
, bool p_definaterv
,
55 /*@temp@*/ /*@observer@*/ fileloc p_sequencePoint
);
56 static /*@only@*/ constraintList
exprNode_traverseRequiresConstraints (exprNode p_e
);
57 static constraintList
exprNode_getPostConditions (
58 /*@dependent@*/ /*@observer@*/ exprNode p_fcn
, exprNodeList p_arglist
,
59 /*@dependent@*/ /*@observer@*/ exprNode p_fcnCall
) /*@*/;
60 static /*@only@*/ constraintList
exprNode_traverseEnsuresConstraints (exprNode p_e
);
63 static bool exprNode_isUnhandled (/*@temp@*/ /*@observer@*/ exprNode e
)
65 llassertfatal (exprNode_isDefined(e
));
91 DPRINTF((message ("Warning current constraint generation does not handle expression %s", exprNode_unparse(e
))));
98 /*@nullwhentrue@*/ bool exprNode_handleError (exprNode e
)
100 if (exprNode_isUndefined (e
) || exprNode_isUnhandled (e
))
105 /* evans 2002-03-2 - parameter was dependent */
106 void exprNode_generateConstraints (/*@temp@*/ exprNode e
)
108 if (exprNode_isUndefined (e
))
111 if (exprNode_isUnhandled (e
))
113 DPRINTF((message("Warning ignoring %s", exprNode_unparse (e
))));
117 DPRINTF ((message ("exprNode_generateConstraints Analyzing %s at %s", exprNode_unparse(e
),
118 fileloc_unparse(exprNode_loc (e
)))));
120 if (exprNode_isMultiStatement (e
))
122 exprNode_multiStatement(e
);
128 /* loc = exprNode_getNextSequencePoint(e); */
129 /* exprNode_exprTraverse(e, FALSE, FALSE, loc); */
131 /* fileloc_free(loc); */
141 c
= constraintList_makeFixedArrayConstraints (e
->uses
);
142 e
->requiresConstraints
= constraintList_reflectChangesFreePre (e
->requiresConstraints
, c
);
143 constraintList_free(c
);
146 DPRINTF ((message ("e->requiresConstraints %s",
147 constraintList_unparseDetailed (e
->requiresConstraints
))));
151 static void exprNode_stmt (/*@temp@*/ exprNode e
)
156 DPRINTF (("Generating constraint for: %s", exprNode_unparse (e
)));
158 if (exprNode_isUndefined(e
))
161 /*e->requiresConstraints = constraintList_makeNew();
162 e->ensuresConstraints = constraintList_makeNew(); */
164 /*!! s = exprNode_unparse (e); */
166 if (e
->kind
== XPR_INIT
)
168 constraintList tempList
;
169 DPRINTF (("Init: %s ", exprNode_unparse (e
)));
170 loc
= exprNode_getNextSequencePoint (e
); /* reduces to an expression */
171 DPRINTF (("Location: %s", fileloc_unparse (loc
)));
172 DPRINTF (("Ensures before: %s", constraintList_unparse (e
->ensuresConstraints
)));
173 exprNode_exprTraverse (e
, FALSE
, FALSE
, loc
);
174 DPRINTF (("Ensures after: %s", constraintList_unparse (e
->ensuresConstraints
)));
175 DPRINTF (("After traversing..."));
178 tempList
= e
->requiresConstraints
;
179 DPRINTF (("Requires before: %s", constraintList_unparse (e
->requiresConstraints
)));
180 e
->requiresConstraints
= exprNode_traverseRequiresConstraints (e
);
181 DPRINTF (("Requires after: %s", constraintList_unparse (e
->requiresConstraints
)));
182 constraintList_free(tempList
);
184 tempList
= e
->ensuresConstraints
;
185 DPRINTF (("Ensures before: %s", constraintList_unparse (e
->ensuresConstraints
)));
186 e
->ensuresConstraints
= exprNode_traverseEnsuresConstraints(e
);
187 DPRINTF (("Ensures before: %s", constraintList_unparse (e
->ensuresConstraints
)));
188 constraintList_free(tempList
);
192 /*drl 2/13/002 patched bug so return statement will be checked*/
193 /*return is a stmt not not expression ...*/
194 if (e
->kind
== XPR_RETURN
)
196 constraintList tempList
;
198 loc
= exprNode_getNextSequencePoint(e
); /* reduces to an expression */
200 exprNode_exprTraverse (exprData_getSingle (e
->edata
), FALSE
, TRUE
, loc
);
203 tempList
= e
->requiresConstraints
;
204 e
->requiresConstraints
= exprNode_traverseRequiresConstraints(e
);
205 constraintList_free(tempList
);
208 if (e
->kind
!= XPR_STMT
)
210 DPRINTF (("Not Stmt"));
211 DPRINTF ((message ("%s ", exprNode_unparse (e
))));
213 if (exprNode_isMultiStatement (e
))
215 exprNode_multiStatement (e
); /* evans 2001-08-21: spurious return removed */
219 loc
= exprNode_getNextSequencePoint(e
); /* reduces to an expression */
221 exprNode_exprTraverse (e
, FALSE
, TRUE
, loc
);
229 DPRINTF ((message ("%s ", exprNode_unparse (e
))));
231 snode
= exprData_getUopNode (e
->edata
);
232 if (exprNode_isUndefined (snode
))
235 /* could be stmt involving multiple statements:
236 i.e. if, while for ect. */
237 if (exprNode_isMultiStatement (snode
))
239 exprNode_multiStatement (snode
);
240 (void) exprNode_copyConstraints (e
, snode
);
244 loc
= exprNode_getNextSequencePoint(e
); /* reduces to an expression */
245 exprNode_exprTraverse (snode
, FALSE
, FALSE
, loc
);
249 constraintList_free (e
->requiresConstraints
);
250 e
->requiresConstraints
= exprNode_traverseRequiresConstraints(snode
);
252 constraintList_free (e
->ensuresConstraints
);
253 e
->ensuresConstraints
= exprNode_traverseEnsuresConstraints(snode
);
255 DPRINTF ((message ("smtlist constraints are: pre: %s \n and \t post %s\n",
256 constraintList_unparse(e
->requiresConstraints
),
257 constraintList_unparse(e
->ensuresConstraints
))));
262 static void exprNode_stmtList (/*@dependent@*/ exprNode e
)
264 exprNode stmt1
, stmt2
;
266 if (exprNode_isUndefined (e
))
269 /* Handle case of stmtList with only one statement:
270 The parse tree stores this as stmt instead of stmtList */
271 if (e
->kind
!= XPR_STMTLIST
)
277 DPRINTF(("exprNode_stmtList STMTLIST:"));
278 DPRINTF ((cstring_toCharsSafe (exprNode_unparse(e
))));
279 stmt1
= exprData_getPairA (e
->edata
);
280 stmt2
= exprData_getPairB (e
->edata
);
282 DPRINTF(("exprNode_stmtlist "));
283 DPRINTF ((message("XW%s | %s", exprNode_unparse(stmt1
), exprNode_unparse(stmt2
))));
285 exprNode_stmt (stmt1
);
286 DPRINTF(("\nstmt after stmtList call "));
288 exprNode_stmt (stmt2
);
289 exprNode_mergeResolve (e
, stmt1
, stmt2
);
291 DPRINTF ((message ("smtlist constraints are: pre: %s \n and \t post %s\n",
292 constraintList_unparse(e
->requiresConstraints
),
293 constraintList_unparse(e
->ensuresConstraints
))));
297 static void doIf (exprNode e
, /*@dependent@*/ exprNode test
, /*@dependent@*/ exprNode body
)
301 DPRINTF ((message ("doIf: %s ", exprNode_unparse(e
))));
303 llassertfatal (exprNode_isDefined (e
));
304 llassertfatal (exprNode_isDefined (test
));
305 llassertfatal (exprNode_isDefined (body
));
307 DPRINTF((message ("ensures constraints for %s are %s", exprNode_unparse(e
),
308 constraintList_unparseDetailed(e
->ensuresConstraints
))));
310 DPRINTF((message ("Requires constraints for %s are %s", exprNode_unparse(e
),
311 constraintList_unparseDetailed(e
->ensuresConstraints
))));
313 DPRINTF((message ("trueEnsures constraints for %s are %s", exprNode_unparse(e
),
314 constraintList_unparseDetailed(e
->trueEnsuresConstraints
))));
316 DPRINTF((message ("falseEnsures constraints for %s are %s", exprNode_unparse(e
),
317 constraintList_unparseDetailed(e
->falseEnsuresConstraints
))));
319 DPRINTF((message ("ensures constraints for %s are %s", exprNode_unparse(test
),
320 constraintList_unparseDetailed(test
->ensuresConstraints
))));
322 DPRINTF((message ("Requires constraints for %s are %s", exprNode_unparse(test
),
323 constraintList_unparseDetailed(test
->ensuresConstraints
))));
325 DPRINTF((message ("trueEnsures constraints for %s are %s", exprNode_unparse(test
),
326 constraintList_unparseDetailed(test
->trueEnsuresConstraints
))));
328 DPRINTF((message ("falseEnsures constraints for %s are %s", exprNode_unparse(test
),
329 constraintList_unparseDetailed(test
->falseEnsuresConstraints
))));
331 temp
= test
->trueEnsuresConstraints
;
332 test
->trueEnsuresConstraints
= exprNode_traverseTrueEnsuresConstraints(test
);
333 constraintList_free(temp
);
335 temp
= test
->ensuresConstraints
;
336 test
->ensuresConstraints
= exprNode_traverseEnsuresConstraints (test
);
337 constraintList_free(temp
);
339 temp
= test
->requiresConstraints
;
340 test
->requiresConstraints
= exprNode_traverseRequiresConstraints (test
);
341 constraintList_free(temp
);
343 test
->trueEnsuresConstraints
= constraintList_substituteFreeTarget(test
->trueEnsuresConstraints
, test
->ensuresConstraints
);
345 DPRINTF ((message ("doIf: test ensures %s ", constraintList_unparse(test
->ensuresConstraints
))));
347 DPRINTF ((message ("doIf: test true ensures %s ", constraintList_unparse(test
->trueEnsuresConstraints
))));
349 constraintList_free(e
->requiresConstraints
);
351 e
->requiresConstraints
= constraintList_reflectChanges(body
->requiresConstraints
, test
->trueEnsuresConstraints
);
353 e
->requiresConstraints
= constraintList_reflectChangesFreePre (e
->requiresConstraints
,
354 test
->ensuresConstraints
);
355 temp
= e
->requiresConstraints
;
356 e
->requiresConstraints
= constraintList_mergeRequires (e
->requiresConstraints
, test
->requiresConstraints
);
357 constraintList_free(temp
);
359 /* drl possible problem : warning bad */
360 constraintList_free(e
->ensuresConstraints
);
361 e
->ensuresConstraints
= constraintList_copy (test
->ensuresConstraints
);
363 if (exprNode_mayEscape (body
))
365 DPRINTF ((message("doIf: the if statement body %s returns or exits", exprNode_unparse(body
))));
366 e
->ensuresConstraints
= constraintList_mergeEnsuresFreeFirst (e
->ensuresConstraints
,
367 test
->falseEnsuresConstraints
);
370 DPRINTF ((message ("doIf: if requiers %s ", constraintList_unparse(e
->requiresConstraints
))));
374 Also used for condition i.e. ?: operation
377 This function assumes that p, trueBranch, falseBranch have have all been traversed
378 for constraints i.e. we assume that exprNode_traverseEnsuresConstraints,
379 exprNode_traverseRequiresConstraints, exprNode_traverseTrueEnsuresConstraints,
380 exprNode_traverseFalseEnsuresConstraints have all been run
383 static exprNode
doIfElse (/*@returned@*/ exprNode e
, /*@dependent@*/ exprNode p
,
384 /*@dependent@*/ exprNode trueBranch
, /*@dependent@*/ exprNode falseBranch
)
386 constraintList c1
, cons
, t
, t2
, f
, f2
;
388 llassertfatal (exprNode_isDefined (e
));
389 llassertfatal (exprNode_isDefined (p
));
390 llassertfatal (exprNode_isDefined (trueBranch
));
391 llassertfatal (exprNode_isDefined (falseBranch
));
393 DPRINTF ((message ("doIfElse: %s ", exprNode_unparse(e
))));
395 /* do requires clauses */
396 c1
= constraintList_copy (p
->ensuresConstraints
);
398 t
= constraintList_reflectChanges(trueBranch
->requiresConstraints
, p
->trueEnsuresConstraints
);
399 t
= constraintList_reflectChangesFreePre (t
, p
->ensuresConstraints
);
401 cons
= constraintList_reflectChanges(falseBranch
->requiresConstraints
, p
->falseEnsuresConstraints
);
402 cons
= constraintList_reflectChangesFreePre (cons
, c1
);
404 constraintList_free (e
->requiresConstraints
);
405 e
->requiresConstraints
= constraintList_mergeRequiresFreeFirst (t
, cons
);
406 e
->requiresConstraints
= constraintList_mergeRequiresFreeFirst (e
->requiresConstraints
, p
->requiresConstraints
);
408 /* do ensures clauses
409 find the the ensures lists for each subbranch
412 t
= constraintList_mergeEnsures (p
->trueEnsuresConstraints
, trueBranch
->ensuresConstraints
);
414 t
= constraintList_mergeEnsures (p
->ensuresConstraints
, t
);
415 constraintList_free(t2
);
417 f
= constraintList_mergeEnsures (p
->falseEnsuresConstraints
, falseBranch
->ensuresConstraints
);
419 f
= constraintList_mergeEnsures (p
->ensuresConstraints
, f
);
420 constraintList_free(f2
);
422 /* find ensures for whole if/else statement */
424 constraintList_free(e
->ensuresConstraints
);
426 e
->ensuresConstraints
= constraintList_logicalOr (t
, f
);
428 constraintList_free(t
);
429 constraintList_free(f
);
430 constraintList_free(cons
);
431 constraintList_free(c1
);
433 DPRINTF ((message ("doIfElse: if requires %q ", constraintList_unparse(e
->requiresConstraints
))));
434 DPRINTF ((message ("doIfElse: if ensures %q ", constraintList_unparse(e
->ensuresConstraints
))));
439 static void doWhile (exprNode e
, /*@dependent@*/ exprNode test
, /*@dependent@*/ exprNode body
)
441 DPRINTF ((message ("doWhile: %s ", exprNode_unparse(e
))));
442 doIf (e
, test
, body
);
445 /*@only@*/ constraintList
constraintList_makeFixedArrayConstraints (/*@observer@*/ sRefSet s
)
449 ret
= constraintList_makeNew();
451 sRefSet_elements (s
, el
)
453 if (sRef_isFixedArray(el
))
456 DPRINTF((message("%s is a fixed array",
458 size
= sRef_getArraySize(el
);
459 DPRINTF((message("%s is a fixed array with size %d",
460 sRef_unparse(el
), (int)size
)));
461 con
= constraint_makeSRefSetBufferSize (el
, size_toLong (size
- 1));
462 ret
= constraintList_add(ret
, con
);
466 DPRINTF((message("%s is not a fixed array",
470 if (sRef_isExternallyVisible (el
))
473 DPRINTF((message("%s is externally visible",
475 con = constraint_makeSRefWriteSafeInt(el, 0);
476 ret = constraintList_add(ret, con);
478 con = constraint_makeSRefReadSafeInt(el, 0);
480 ret = constraintList_add(ret, con);
485 end_sRefSet_elements
;
487 DPRINTF((message("constraintList_makeFixedArrayConstraints returning %s",
488 constraintList_unparse(ret
))));
493 exprNode
makeDataTypeConstraints (/*@returned@*/ exprNode e
)
496 DPRINTF(("makeDataTypeConstraints"));
498 c
= constraintList_makeFixedArrayConstraints (e
->uses
);
500 e
->ensuresConstraints
= constraintList_addListFree (e
->ensuresConstraints
, c
);
506 static void doFor (/*@dependent@*/ exprNode e
, /*@dependent@*/ exprNode forPred
, /*@dependent@*/ exprNode forBody
)
508 exprNode
/* init,*/ test
, inc
;
509 /* merge the constraints: modle as if statement */
516 llassertfatal (exprNode_isDefined (e
));
517 llassertfatal (exprNode_isDefined (forPred
));
518 llassertfatal (exprNode_isDefined (forBody
));
520 /* init = exprData_getTripleInit (forPred->edata); */
521 test
= exprData_getTripleTest (forPred
->edata
);
522 inc
= exprData_getTripleInc (forPred
->edata
);
524 if (exprNode_isUndefined (test
) /*|| exprNode_isUndefined(init)*/ || exprNode_isUndefined (inc
))
526 DPRINTF ((message ("strange for statement:%s, ignoring it", exprNode_unparse(e
))));
530 exprNode_forLoopHeuristics(e
, forPred
, forBody
);
532 constraintList_free(e
->requiresConstraints
);
533 e
->requiresConstraints
= constraintList_reflectChanges(forBody
->requiresConstraints
, test
->ensuresConstraints
);
534 e
->requiresConstraints
= constraintList_reflectChangesFreePre (e
->requiresConstraints
, test
->trueEnsuresConstraints
);
535 e
->requiresConstraints
= constraintList_reflectChangesFreePre (e
->requiresConstraints
, forPred
->ensuresConstraints
);
537 if (!forBody
->canBreak
)
539 e
->ensuresConstraints
= constraintList_addListFree(e
->ensuresConstraints
,
540 constraintList_copy(forPred
->ensuresConstraints
));
541 e
->ensuresConstraints
= constraintList_addListFree(e
->ensuresConstraints
,
542 constraintList_copy(test
->falseEnsuresConstraints
));
546 DPRINTF(("Can break"));
550 static /*@dependent@*/ exprNode
exprNode_makeDependent(/*@returned@*/ exprNode e
)
552 /* !!! DRL - this is ridiculous! Read the manual on memory annotations please! */
557 exprNode_doGenerateConstraintSwitch
558 (/*@dependent@*/ exprNode switchExpr
,
559 /*@dependent@*/ exprNode body
,
560 /*@special@*/ constraintList
*currentRequires
,
561 /*@special@*/ constraintList
*currentEnsures
,
562 /*@special@*/ constraintList
*savedRequires
,
563 /*@special@*/ constraintList
*savedEnsures
)
564 /*@post:only *currentRequires, *currentEnsures, *savedRequires, *savedEnsures @*/
565 /*@sets *currentRequires, *currentEnsures, *savedRequires, *savedEnsures @*/
567 exprNode stmt
, stmtList
;
569 DPRINTF((message("exprNode_doGenerateConstraintSwitch: (switch %s) %s",
570 exprNode_unparse(switchExpr
), exprNode_unparse(body
)
573 if (exprNode_isUndefined(body
))
575 *currentRequires
= constraintList_makeNew ();
576 *currentEnsures
= constraintList_makeNew ();
578 *savedRequires
= constraintList_makeNew ();
579 *savedEnsures
= constraintList_makeNew ();
585 if (body
->kind
!= XPR_STMTLIST
)
587 DPRINTF((message("exprNode_doGenerateConstraintSwitch: non stmtlist: %s",
588 exprNode_unparse(body
))));
590 stmtList
= exprNode_undefined
;
591 stmt
= exprNode_makeDependent(stmt
);
592 stmtList
= exprNode_makeDependent(stmtList
);
596 stmt
= exprData_getPairB(body
->edata
);
597 stmtList
= exprData_getPairA(body
->edata
);
598 stmt
= exprNode_makeDependent(stmt
);
599 stmtList
= exprNode_makeDependent(stmtList
);
602 DPRINTF((message("exprNode_doGenerateConstraintSwitch: stmtlist: %s stmt: %s",
603 exprNode_unparse(stmtList
), exprNode_unparse(stmt
))
607 exprNode_doGenerateConstraintSwitch (switchExpr
, stmtList
, currentRequires
, currentEnsures
,
608 savedRequires
, savedEnsures
);
610 if (exprNode_isUndefined(stmt
))
617 switchExpr
= exprNode_makeDependent (switchExpr
);
619 if (! exprNode_isCaseMarker(stmt
))
624 DPRINTF ((message("Got normal statement %s (requires %s ensures %s)", exprNode_unparse(stmt
),
625 constraintList_unparse(stmt
->requiresConstraints
), constraintList_unparse(stmt
->ensuresConstraints
))));
627 temp
= constraintList_reflectChanges (stmt
->requiresConstraints
,
630 *currentRequires
= constraintList_mergeRequiresFreeFirst(
634 constraintList_free(temp
);
636 *currentEnsures
= constraintList_mergeEnsuresFreeFirst
638 stmt
->ensuresConstraints
);
639 DPRINTF((message("returning from exprNode_doGenerateConstraintSwitch: (switch %s) %s currentRequires:"
640 "%s currentEnsures:%s",
641 exprNode_unparse(switchExpr
), exprNode_unparse(body
),
642 constraintList_unparse(*currentRequires
), constraintList_unparse(*currentEnsures
)
650 if (exprNode_isCaseMarker(stmt
) && exprNode_mustEscape(stmtList
))
653 ** merge current and saved constraint with Logical Or...
654 ** make a constraint for ensures
660 DPRINTF ((message("Got case marker")));
662 if (constraintList_isUndefined(*savedEnsures
) &&
663 constraintList_isUndefined(*savedRequires
))
665 llassert(constraintList_isUndefined(*savedEnsures
));
666 llassert(constraintList_isUndefined(*savedRequires
));
667 *savedEnsures
= constraintList_copy(*currentEnsures
);
668 *savedRequires
= constraintList_copy(*currentRequires
);
672 DPRINTF ((message("Doing logical or")));
673 temp
= constraintList_logicalOr (*savedEnsures
, *currentEnsures
);
674 constraintList_free (*savedEnsures
);
675 *savedEnsures
= temp
;
677 *savedRequires
= constraintList_mergeRequiresFreeFirst (*savedRequires
, *currentRequires
);
680 con
= constraint_makeEnsureEqual (switchExpr
, exprData_getSingle (stmt
->edata
), exprNode_loc (stmt
));
682 constraintList_free (*currentEnsures
);
683 *currentEnsures
= constraintList_makeNew();
684 *currentEnsures
= constraintList_add(*currentEnsures
, con
);
686 constraintList_free(*currentRequires
);
687 *currentRequires
= constraintList_makeNew();
688 DPRINTF (("exprNode_doGenerateConstraintSwitch: (switch %s) %s savedRequires:"
689 "%s savedEnsures:%s",
690 exprNode_unparse(switchExpr
), exprNode_unparse(body
),
691 constraintList_unparse(*savedRequires
), constraintList_unparse(*savedEnsures
)
694 else if (exprNode_isCaseMarker(stmt
)) /* prior case has no break. */
697 We don't do anything to the sved constraints because the case hasn't ended
698 The new ensures constraints for the case will be:
699 the constraint for the case statement (CASE_LABEL == SWITCH_EXPR) logicalOr currentEnsures
704 constraintList ensuresTemp
;
706 con
= constraint_makeEnsureEqual (switchExpr
, exprData_getSingle (stmt
->edata
), exprNode_loc (stmt
));
708 ensuresTemp
= constraintList_makeNew ();
709 ensuresTemp
= constraintList_add (ensuresTemp
, con
);
711 if (exprNode_isUndefined (stmtList
))
713 constraintList_free (*currentEnsures
);
714 *currentEnsures
= constraintList_copy (ensuresTemp
);
715 constraintList_free (ensuresTemp
);
719 temp
= constraintList_logicalOr (*currentEnsures
, ensuresTemp
);
720 constraintList_free (*currentEnsures
);
721 constraintList_free (ensuresTemp
);
722 *currentEnsures
= temp
;
725 constraintList_free (*currentRequires
);
726 *currentRequires
= constraintList_makeNew();
731 we handle the case of ! exprNode_isCaseMarker above
732 the else if clause should always be true.
737 DPRINTF (("returning from exprNode_doGenerateConstraintSwitch: (switch %s) %s currentRequires:"
738 "%s currentEnsures:%s",
739 exprNode_unparse(switchExpr
), exprNode_unparse(body
),
740 constraintList_unparse(*currentRequires
), constraintList_unparse(*currentEnsures
)
749 static void exprNode_generateConstraintSwitch (/*@notnull@*/ exprNode switchStmt
)
751 constraintList constraintsRequires
;
752 constraintList constraintsEnsures
;
753 constraintList lastRequires
;
754 constraintList lastEnsures
;
759 switchExpr
= exprData_getPairA (switchStmt
->edata
);
760 body
= exprData_getPairB (switchStmt
->edata
);
762 if (!exprNode_isDefined (body
))
767 DPRINTF((message("")));
769 if (body
->kind
== XPR_BLOCK
)
770 body
= exprData_getSingle(body
->edata
);
773 constraintsRequires
= constraintList_undefined
;
774 constraintsEnsures
= constraintList_undefined
;
776 lastRequires
= constraintList_makeNew();
777 lastEnsures
= constraintList_makeNew();
781 /* evans 2002-01-01: spurious warnings for these becuase of stack allocated storage */
782 exprNode_doGenerateConstraintSwitch (switchExpr
, body
, &lastRequires
,
783 &lastEnsures
, &constraintsRequires
, &constraintsEnsures
);
787 merge current and saved constraint with Logical Or...
788 make a constraint for ensures
791 constraintList_free(switchStmt
->requiresConstraints
);
792 constraintList_free(switchStmt
->ensuresConstraints
);
794 if (constraintList_isDefined(constraintsEnsures
) && constraintList_isDefined(constraintsRequires
))
796 switchStmt
->ensuresConstraints
= constraintList_logicalOr(constraintsEnsures
, lastEnsures
);
797 switchStmt
->requiresConstraints
= constraintList_mergeRequires(constraintsRequires
, lastRequires
);
798 constraintList_free (constraintsRequires
);
799 constraintList_free (constraintsEnsures
);
803 switchStmt
->ensuresConstraints
= constraintList_copy(lastEnsures
);
804 switchStmt
->requiresConstraints
= constraintList_copy(lastRequires
);
807 constraintList_free (lastRequires
);
808 constraintList_free (lastEnsures
);
810 DPRINTF(((message(" exprNode_generateConstraintSwitch returning requires: %s and ensures %s",
811 constraintList_unparse(switchStmt
->requiresConstraints
),
812 constraintList_unparse(switchStmt
->ensuresConstraints
)
817 static exprNode
doSwitch (/*@returned@*/ /*@notnull@*/ exprNode e
)
819 DPRINTF ((message ("doSwitch for: switch (%s) %s",
820 exprNode_unparse (exprData_getPairA (e
->edata
)),
821 exprNode_unparse (exprData_getPairB (e
->edata
)))));
823 exprNode_generateConstraintSwitch (e
);
827 static void exprNode_multiStatement (/*@dependent@*/ exprNode e
)
833 if (exprNode_handleError (e
))
836 DPRINTF((message ("exprNode_multistatement Analysising %s %s at", exprNode_unparse(e
),
837 fileloc_unparse(exprNode_loc(e
)))));
845 e1
= exprData_getPairA (data
);
846 e2
= exprData_getPairB (data
);
848 /* First generate the constraints */
849 exprNode_generateConstraints (e1
);
850 exprNode_generateConstraints (e2
);
856 exprNode_generateConstraints (exprData_getTripleInit (data
));
857 p
= exprData_getTripleTest (data
);
858 exprNode_exprTraverse (p
, FALSE
, FALSE
, exprNode_loc(e
));
859 exprNode_generateConstraints (exprData_getTripleInc (data
));
861 if (exprNode_isDefined(p
))
863 constraintList temp2
;
864 temp2
= p
->trueEnsuresConstraints
;
865 p
->trueEnsuresConstraints
= exprNode_traverseTrueEnsuresConstraints(p
);
866 constraintList_free(temp2
);
869 exprNode_generateConstraints (exprData_getTripleInc (data
));
873 e1
= exprData_getPairA (data
);
874 e2
= exprData_getPairB (data
);
876 if (exprNode_isUndefined (e1
) || exprNode_isUndefined (e2
))
879 exprNode_exprTraverse (e1
, FALSE
, FALSE
, exprNode_loc(e1
));
880 exprNode_generateConstraints (e2
);
886 DPRINTF ((exprNode_unparse(e
)));
887 e1
= exprData_getPairA (data
);
888 e2
= exprData_getPairB (data
);
890 if (exprNode_isUndefined (e1
) || exprNode_isUndefined (e2
))
893 exprNode_exprTraverse (e1
, FALSE
, FALSE
, exprNode_loc(e1
));
895 exprNode_generateConstraints (e2
);
900 DPRINTF(("Starting IFELSE"));
902 p
= exprData_getTriplePred (data
);
903 e1
= exprData_getTripleTrue (data
);
904 e2
= exprData_getTripleFalse (data
);
906 if (exprNode_isUndefined (p
) ||
907 exprNode_isUndefined (e1
) || exprNode_isUndefined (e2
))
910 exprNode_exprTraverse (p
, FALSE
, FALSE
, exprNode_loc(p
));
911 exprNode_generateConstraints (e1
);
912 exprNode_generateConstraints (e2
);
914 temp
= p
->ensuresConstraints
;
915 p
->ensuresConstraints
= exprNode_traverseEnsuresConstraints (p
);
916 constraintList_free(temp
);
918 temp
= p
->requiresConstraints
;
919 p
->requiresConstraints
= exprNode_traverseRequiresConstraints (p
);
920 constraintList_free(temp
);
922 temp
= p
->trueEnsuresConstraints
;
923 p
->trueEnsuresConstraints
= exprNode_traverseTrueEnsuresConstraints(p
);
924 constraintList_free(temp
);
926 DPRINTF ((message("p->trueEnsuresConstraints before substitue %s",
927 constraintList_unparse(p
->trueEnsuresConstraints
))));
929 /*drl 10/10/2002 this is a bit of a hack but the reason why we do this is
930 * so that any function post conditions or similar things get applied
931 * correctly to each branch.
932 * e.g. in strlen(s) < 5 we want the trueEnsures to be maxRead(s) < 5 */
934 p
->trueEnsuresConstraints
= constraintList_substituteFreeTarget (p
->trueEnsuresConstraints
,
935 p
->ensuresConstraints
);
937 DPRINTF ((message ("p->trueEnsuresConstraints after substitue %s",
938 constraintList_unparse(p
->trueEnsuresConstraints
))));
940 temp
= p
->falseEnsuresConstraints
;
941 p
->falseEnsuresConstraints
= exprNode_traverseFalseEnsuresConstraints(p
);
942 constraintList_free(temp
);
944 /*See comment on trueEnsures*/
945 p
->falseEnsuresConstraints
= constraintList_substituteFreeTarget (p
->falseEnsuresConstraints
,
946 p
->ensuresConstraints
);
948 (void) doIfElse (e
, p
, e1
, e2
);
949 DPRINTF(("Done IFELSE"));
953 e2
= exprData_getPairB (data
);
954 e1
= exprData_getPairA (data
);
956 DPRINTF((message ("do { %s } while (%s)", exprNode_unparse(e2
), exprNode_unparse(e1
))));
957 exprNode_generateConstraints (e2
);
958 exprNode_generateConstraints (e1
);
959 e
= exprNode_copyConstraints (e
, e2
);
960 DPRINTF ((message ("e = %s ", constraintList_unparse(e
->requiresConstraints
))));
967 tempExpr
= exprData_getSingle (data
);
969 exprNode_generateConstraints (tempExpr
);
971 if (exprNode_isDefined(tempExpr
))
973 constraintList_free(e
->requiresConstraints
);
974 e
->requiresConstraints
= constraintList_copy (tempExpr
->requiresConstraints
);
975 constraintList_free(e
->ensuresConstraints
);
976 e
->ensuresConstraints
= constraintList_copy (tempExpr
->ensuresConstraints
);
988 exprNode_stmtList (e
);
997 static bool lltok_isBoolean_Op (lltok tok
)
999 /*this should really be a switch statement but
1000 I don't want to violate the abstraction
1001 maybe this should go in lltok.c */
1003 if (lltok_isEqOp (tok
))
1007 if (lltok_isAndOp (tok
))
1013 if (lltok_isOrOp (tok
))
1018 if (lltok_isGt_Op (tok
))
1022 if (lltok_isLt_Op (tok
))
1027 if (lltok_isLe_Op (tok
))
1032 if (lltok_isGe_Op (tok
))
1041 static void exprNode_booleanTraverse (/*@dependent@*/ exprNode e
, fileloc sequencePoint
)
1047 constraintList tempList
, temp
;
1049 if (exprNode_isUndefined(e
))
1054 tok
= exprData_getOpTok (data
);
1055 t1
= exprData_getOpA (data
);
1056 t2
= exprData_getOpB (data
);
1058 if (exprNode_isUndefined (t1
) || exprNode_isUndefined (t2
))
1061 tempList
= constraintList_undefined
;
1063 /* arithmetic tests */
1065 if (lltok_isEqOp (tok
))
1067 cons
= constraint_makeEnsureEqual (t1
, t2
, sequencePoint
);
1068 e
->trueEnsuresConstraints
= constraintList_add(e
->trueEnsuresConstraints
, cons
);
1072 if (lltok_isLt_Op (tok
))
1074 cons
= constraint_makeEnsureLessThan (t1
, t2
, sequencePoint
);
1075 e
->trueEnsuresConstraints
= constraintList_add(e
->trueEnsuresConstraints
, cons
);
1076 cons
= constraint_makeEnsureGreaterThanEqual (t1
, t2
, sequencePoint
);
1077 e
->falseEnsuresConstraints
= constraintList_add(e
->falseEnsuresConstraints
, cons
);
1080 if (lltok_isGe_Op (tok
))
1082 cons
= constraint_makeEnsureGreaterThanEqual (t1
, t2
, sequencePoint
);
1083 e
->trueEnsuresConstraints
= constraintList_add(e
->trueEnsuresConstraints
, cons
);
1085 cons
= constraint_makeEnsureLessThan (t1
, t2
, sequencePoint
);
1086 e
->falseEnsuresConstraints
= constraintList_add(e
->falseEnsuresConstraints
, cons
);
1089 if (lltok_isGt_Op (tok
))
1091 cons
= constraint_makeEnsureGreaterThan (t1
, t2
, sequencePoint
);
1092 e
->trueEnsuresConstraints
= constraintList_add(e
->trueEnsuresConstraints
, cons
);
1093 cons
= constraint_makeEnsureLessThanEqual (t1
, t2
, sequencePoint
);
1094 e
->falseEnsuresConstraints
= constraintList_add(e
->falseEnsuresConstraints
, cons
);
1097 if (lltok_isLe_Op (tok
))
1099 cons
= constraint_makeEnsureLessThanEqual (t1
, t2
, sequencePoint
);
1100 e
->trueEnsuresConstraints
= constraintList_add(e
->trueEnsuresConstraints
, cons
);
1102 cons
= constraint_makeEnsureGreaterThan (t1
, t2
, sequencePoint
);
1103 e
->falseEnsuresConstraints
= constraintList_add(e
->falseEnsuresConstraints
, cons
);
1106 /* Logical operations */
1108 if (lltok_isAndOp (tok
))
1111 tempList
= constraintList_copy (t1
->trueEnsuresConstraints
);
1112 tempList
= constraintList_addList (tempList
, t2
->trueEnsuresConstraints
);
1113 e
->trueEnsuresConstraints
= constraintList_addListFree(e
->trueEnsuresConstraints
, tempList
);
1115 /* false ensures: fens t1 or tens t1 and fens t2 */
1116 tempList
= constraintList_copy (t1
->trueEnsuresConstraints
);
1117 tempList
= constraintList_addList (tempList
, t2
->falseEnsuresConstraints
);
1119 tempList
= constraintList_logicalOr (tempList
, t1
->falseEnsuresConstraints
);
1120 constraintList_free (temp
);
1122 /* evans - was constraintList_addList - memory leak detected by splint */
1123 e
->falseEnsuresConstraints
= constraintList_addListFree (e
->falseEnsuresConstraints
, tempList
);
1125 else if (lltok_isOrOp (tok
))
1128 tempList
= constraintList_copy (t1
->falseEnsuresConstraints
);
1129 tempList
= constraintList_addList (tempList
, t2
->falseEnsuresConstraints
);
1130 e
->falseEnsuresConstraints
= constraintList_addListFree(e
->falseEnsuresConstraints
, tempList
);
1132 /* true ensures: tens t1 or fens t1 and tens t2 */
1133 tempList
= constraintList_copy (t1
->falseEnsuresConstraints
);
1134 tempList
= constraintList_addList (tempList
, t2
->trueEnsuresConstraints
);
1137 tempList
= constraintList_logicalOr (tempList
, t1
->trueEnsuresConstraints
);
1138 constraintList_free(temp
);
1140 e
->trueEnsuresConstraints
= constraintList_addListFree(e
->trueEnsuresConstraints
, tempList
);
1141 tempList
= constraintList_undefined
;
1145 DPRINTF((message("%s is not a boolean operation", lltok_unparse(tok
))));
1149 static void exprNode_exprTraverse (/*@dependent@*/ exprNode e
,
1150 bool definatelv
, bool definaterv
,
1151 /*@observer@*/ /*@temp@*/ fileloc sequencePoint
)
1153 exprNode t1
, t2
, fcn
;
1157 constraintList temp
;
1159 if (exprNode_isUndefined(e
))
1162 DPRINTF (("exprNode_exprTraverse analyzing %s at %s",
1163 exprNode_unparse (e
),
1164 fileloc_unparse (exprNode_loc (e
))));
1166 if (exprNode_isUnhandled (e
))
1174 t1
= exprData_getSingle (data
);
1175 if (exprNode_isUndefined (t1
))
1177 exprNode_exprTraverse (t1
, definatelv
, definaterv
, sequencePoint
);
1178 e
= exprNode_copyConstraints (e
, t1
);
1185 t1
= (exprData_getPairA (data
));
1186 t2
= (exprData_getPairB (data
));
1187 cons
= constraint_makeWriteSafeExprNode (t1
, t2
);
1191 t1
= (exprData_getPairA (data
));
1192 t2
= (exprData_getPairB (data
));
1193 cons
= constraint_makeReadSafeExprNode (t1
, t2
);
1196 e
->requiresConstraints
= constraintList_add(e
->requiresConstraints
, cons
);
1197 cons
= constraint_makeEnsureMaxReadAtLeast (t1
, t2
, sequencePoint
);
1198 e
->ensuresConstraints
= constraintList_add(e
->ensuresConstraints
, cons
);
1200 cons
= constraint_makeEnsureLteMaxRead (t2
, t1
);
1201 e
->trueEnsuresConstraints
= constraintList_add(e
->trueEnsuresConstraints
, cons
);
1203 exprNode_exprTraverse (exprData_getPairA (data
), FALSE
, TRUE
, sequencePoint
);
1204 exprNode_exprTraverse (exprData_getPairB (data
), FALSE
, TRUE
, sequencePoint
);
1209 exprNode_exprTraverse (exprData_getUopNode (e
->edata
), definatelv
, definaterv
, sequencePoint
);
1213 t2
= exprData_getInitNode (data
);
1215 DPRINTF (("initialization ==> %s",exprNode_unparse (t2
)));
1217 exprNode_exprTraverse (t2
, definatelv
, TRUE
, sequencePoint
);
1219 /* This test is nessecary because some expressions generate a null expression node.
1220 function pointer do that -- drl */
1222 if (exprNode_isDefined (e
) && exprNode_isDefined (t2
))
1224 cons
= constraint_makeEnsureEqual (e
, t2
, sequencePoint
);
1225 e
->ensuresConstraints
= constraintList_add(e
->ensuresConstraints
, cons
);
1231 t1
= exprData_getOpA (data
);
1232 t2
= exprData_getOpB (data
);
1233 DPRINTF (("Assignment constraints t1: %s", constraintList_unparse (t1
->ensuresConstraints
)));
1234 DPRINTF (("Assignment constraints t2: %s", constraintList_unparse (t2
->ensuresConstraints
)));
1235 exprNode_exprTraverse (t1
, TRUE
, definaterv
, sequencePoint
);
1236 DPRINTF (("Assignment constraints t1: %s", constraintList_unparse (t1
->ensuresConstraints
)));
1237 DPRINTF (("Assignment constraints t2: %s", constraintList_unparse (t2
->ensuresConstraints
)));
1238 exprNode_exprTraverse (t2
, definatelv
, TRUE
, sequencePoint
);
1239 DPRINTF (("Assignment constraints t1: %s", constraintList_unparse (t1
->ensuresConstraints
)));
1240 DPRINTF (("Assignment constraints t2: %s", constraintList_unparse (t2
->ensuresConstraints
)));
1242 /* this test is nessecary because some expressions generate a null expression node.
1243 function pointer do that -- drl */
1245 if (exprNode_isDefined (t1
) && exprNode_isDefined (t2
))
1247 cons
= constraint_makeEnsureEqual (t1
, t2
, sequencePoint
);
1248 DPRINTF (("Ensure equal constraint: %s", constraint_unparse (cons
)));
1249 e
->ensuresConstraints
= constraintList_add (e
->ensuresConstraints
, cons
);
1250 DPRINTF (("Assignment constraints: %s", constraintList_unparse (e
->ensuresConstraints
)));
1254 t1
= exprData_getOpA (data
);
1255 t2
= exprData_getOpB (data
);
1256 tok
= exprData_getOpTok (data
);
1258 if (lltok_getTok (tok
) == ADD_ASSIGN
)
1260 exprNode_exprTraverse (t1
, TRUE
, definaterv
, sequencePoint
);
1261 exprNode_exprTraverse (t2
, definatelv
, TRUE
, sequencePoint
);
1263 cons
= constraint_makeAddAssign (t1
, t2
, sequencePoint
);
1264 e
->ensuresConstraints
= constraintList_add(e
->ensuresConstraints
, cons
);
1266 else if (lltok_getTok (tok
) == SUB_ASSIGN
)
1268 exprNode_exprTraverse (t1
, TRUE
, definaterv
, sequencePoint
);
1269 exprNode_exprTraverse (t2
, definatelv
, TRUE
, sequencePoint
);
1271 cons
= constraint_makeSubtractAssign (t1
, t2
, sequencePoint
);
1272 e
->ensuresConstraints
= constraintList_add(e
->ensuresConstraints
, cons
);
1276 exprNode_exprTraverse (t1
, definatelv
, definaterv
, sequencePoint
);
1277 exprNode_exprTraverse (t2
, definatelv
, definaterv
, sequencePoint
);
1280 if (lltok_isBoolean_Op (tok
))
1281 exprNode_booleanTraverse (e
, sequencePoint
);
1286 /*drl 4-11-03 I think this is the same as the next case...*/
1291 C standard says operand to sizeof isn't evaluated unless
1292 its a variable length array. So we don't generate constraints. */
1296 fcn
= exprData_getFcn(data
);
1298 exprNode_exprTraverse (fcn
, definatelv
, definaterv
, sequencePoint
);
1299 DPRINTF (("Got call that %s (%s)",
1300 exprNode_unparse(fcn
), exprNodeList_unparse (exprData_getArgs (data
))));
1302 llassertfatal (exprNode_isDefined(fcn
));
1304 fcn
->requiresConstraints
=
1305 constraintList_addListFree (fcn
->requiresConstraints
,
1306 checkCall (fcn
, exprData_getArgs (data
)));
1308 fcn
->ensuresConstraints
=
1309 constraintList_addListFree (fcn
->ensuresConstraints
,
1310 exprNode_getPostConditions(fcn
, exprData_getArgs (data
),e
));
1312 t1
= exprNode_createNew (exprNode_getType (e
));
1313 checkArgumentList (t1
, exprData_getArgs(data
), sequencePoint
);
1314 exprNode_mergeResolve (e
, t1
, fcn
);
1319 exprNode_exprTraverse (exprData_getSingle (data
), definatelv
, definaterv
, sequencePoint
);
1322 case XPR_NULLRETURN
:
1326 exprNode_exprTraverse (exprData_getFieldNode (data
), definatelv
, definaterv
, sequencePoint
);
1330 exprNode_exprTraverse (exprData_getFieldNode (data
), definatelv
, definaterv
, sequencePoint
);
1333 case XPR_STRINGLITERAL
:
1340 t1
= exprData_getUopNode(data
);
1342 if (exprNode_isUndefined (t1
))
1345 tok
= (exprData_getUopTok (data
));
1346 exprNode_exprTraverse (t1
, definatelv
, definaterv
, sequencePoint
);
1347 /*handle * pointer access */
1348 if (lltok_isIncOp (tok
))
1350 DPRINTF(("doing ++(var)"));
1351 t1
= exprData_getUopNode (data
);
1352 cons
= constraint_makeMaxSetSideEffectPostIncrement (t1
, sequencePoint
);
1353 e
->ensuresConstraints
= constraintList_add (e
->ensuresConstraints
, cons
);
1355 else if (lltok_isDecOp (tok
))
1357 DPRINTF(("doing --(var)"));
1358 t1
= exprData_getUopNode (data
);
1359 cons
= constraint_makeMaxSetSideEffectPostDecrement (t1
, sequencePoint
);
1360 e
->ensuresConstraints
= constraintList_add (e
->ensuresConstraints
, cons
);
1362 else if (lltok_isMult(tok
))
1366 cons
= constraint_makeWriteSafeInt (t1
, 0);
1370 cons
= constraint_makeReadSafeInt (t1
, 0);
1372 e
->requiresConstraints
= constraintList_add(e
->requiresConstraints
, cons
);
1374 else if (lltok_isNotOp (tok
))
1377 constraintList_free(e
->trueEnsuresConstraints
);
1379 e
->trueEnsuresConstraints
= constraintList_copy (t1
->falseEnsuresConstraints
);
1380 constraintList_free(e
->falseEnsuresConstraints
);
1381 e
->falseEnsuresConstraints
= constraintList_copy (t1
->trueEnsuresConstraints
);
1383 else if (lltok_isAmpersand_Op (tok
))
1387 else if (lltok_isPlus_Op (tok
) || lltok_isMinus_Op (tok
))
1391 else if (lltok_isExcl_Op (tok
))
1395 else if (lltok_isTilde_Op (tok
))
1401 llfatalbug (message("Unsupported preop in %s", exprNode_unparse(e
)));
1406 exprNode_exprTraverse (exprData_getUopNode (data
), TRUE
,
1407 definaterv
, sequencePoint
);
1409 if (lltok_isIncOp (exprData_getUopTok (data
)))
1411 DPRINTF(("doing ++"));
1412 t1
= exprData_getUopNode (data
);
1413 cons
= constraint_makeMaxSetSideEffectPostIncrement (t1
, sequencePoint
);
1414 e
->ensuresConstraints
= constraintList_add (e
->ensuresConstraints
, cons
);
1416 if (lltok_isDecOp (exprData_getUopTok (data
)))
1418 DPRINTF(("doing --"));
1419 t1
= exprData_getUopNode (data
);
1420 cons
= constraint_makeMaxSetSideEffectPostDecrement (t1
, sequencePoint
);
1421 e
->ensuresConstraints
= constraintList_add (e
->ensuresConstraints
, cons
);
1426 t2
= exprData_getCastNode (data
);
1427 DPRINTF ((message ("Examining cast (%q)%s",
1428 qtype_unparse (exprData_getCastType (data
)),
1429 exprNode_unparse (t2
))
1431 exprNode_exprTraverse (t2
, definatelv
, definaterv
, sequencePoint
);
1437 exprNode pred
, trueBranch
, falseBranch
;
1439 pred
= exprData_getTriplePred (data
);
1440 trueBranch
= exprData_getTripleTrue (data
);
1441 falseBranch
= exprData_getTripleFalse (data
);
1443 if (exprNode_isUndefined (pred
) ||
1444 exprNode_isUndefined (trueBranch
) || exprNode_isDefined (falseBranch
))
1447 exprNode_exprTraverse (pred
, FALSE
, TRUE
, sequencePoint
);
1449 temp
= pred
->ensuresConstraints
;
1450 pred
->ensuresConstraints
= exprNode_traverseEnsuresConstraints(pred
);
1451 constraintList_free(temp
);
1453 temp
= pred
->requiresConstraints
;
1454 pred
->requiresConstraints
= exprNode_traverseRequiresConstraints(pred
);
1455 constraintList_free(temp
);
1457 temp
= pred
->trueEnsuresConstraints
;
1458 pred
->trueEnsuresConstraints
= exprNode_traverseTrueEnsuresConstraints(pred
);
1459 constraintList_free(temp
);
1461 temp
= pred
->falseEnsuresConstraints
;
1462 pred
->falseEnsuresConstraints
= exprNode_traverseFalseEnsuresConstraints(pred
);
1463 constraintList_free(temp
);
1465 exprNode_exprTraverse (trueBranch
, FALSE
, TRUE
, sequencePoint
);
1467 temp
= trueBranch
->ensuresConstraints
;
1468 trueBranch
->ensuresConstraints
= exprNode_traverseEnsuresConstraints(trueBranch
);
1469 constraintList_free(temp
);
1471 temp
= trueBranch
->requiresConstraints
;
1472 trueBranch
->requiresConstraints
= exprNode_traverseRequiresConstraints(trueBranch
);
1473 constraintList_free(temp
);
1475 temp
= trueBranch
->trueEnsuresConstraints
;
1476 trueBranch
->trueEnsuresConstraints
= exprNode_traverseTrueEnsuresConstraints(trueBranch
);
1477 constraintList_free(temp
);
1479 temp
= trueBranch
->falseEnsuresConstraints
;
1480 trueBranch
->falseEnsuresConstraints
= exprNode_traverseFalseEnsuresConstraints(trueBranch
);
1481 constraintList_free(temp
);
1483 exprNode_exprTraverse (falseBranch
, FALSE
, TRUE
, sequencePoint
);
1485 temp
= falseBranch
->ensuresConstraints
;
1486 falseBranch
->ensuresConstraints
= exprNode_traverseEnsuresConstraints(falseBranch
);
1487 constraintList_free(temp
);
1490 temp
= falseBranch
->requiresConstraints
;
1491 falseBranch
->requiresConstraints
= exprNode_traverseRequiresConstraints(falseBranch
);
1492 constraintList_free(temp
);
1494 temp
= falseBranch
->trueEnsuresConstraints
;
1495 falseBranch
->trueEnsuresConstraints
= exprNode_traverseTrueEnsuresConstraints(falseBranch
);
1496 constraintList_free(temp
);
1498 temp
= falseBranch
->falseEnsuresConstraints
;
1499 falseBranch
->falseEnsuresConstraints
= exprNode_traverseFalseEnsuresConstraints(falseBranch
);
1500 constraintList_free(temp
);
1502 /* if pred is true e equals true otherwise pred equals false */
1504 cons
= constraint_makeEnsureEqual (e
, trueBranch
, sequencePoint
);
1505 trueBranch
->ensuresConstraints
= constraintList_add(trueBranch
->ensuresConstraints
, cons
);
1507 cons
= constraint_makeEnsureEqual (e
, trueBranch
, sequencePoint
);
1508 falseBranch
->ensuresConstraints
= constraintList_add(falseBranch
->ensuresConstraints
, cons
);
1510 e
= doIfElse (e
, pred
, trueBranch
, falseBranch
);
1515 t1
= exprData_getPairA (data
);
1516 t2
= exprData_getPairB (data
);
1517 /* we essiantially treat this like expr1; expr2
1518 of course sequencePoint isn't adjusted so this isn't completely accurate
1521 exprNode_exprTraverse (t1
, FALSE
, FALSE
, sequencePoint
);
1522 exprNode_exprTraverse (t2
, definatelv
, definaterv
, sequencePoint
);
1523 exprNode_mergeResolve (e
, t1
, t2
);
1530 e
->requiresConstraints
= constraintList_preserveOrig (e
->requiresConstraints
);
1531 e
->ensuresConstraints
= constraintList_preserveOrig (e
->ensuresConstraints
);
1532 e
->requiresConstraints
= constraintList_addGeneratingExpr (e
->requiresConstraints
, e
);
1533 e
->ensuresConstraints
= constraintList_addGeneratingExpr (e
->ensuresConstraints
, e
);
1534 e
->requiresConstraints
= constraintList_removeSurpressed (e
->requiresConstraints
);
1536 DPRINTF (("ensures constraints for %s are %s",
1537 exprNode_unparse(e
), constraintList_unparseDetailed (e
->ensuresConstraints
)));
1539 DPRINTF (("Requires constraints for %s are %s", exprNode_unparse(e
),
1540 constraintList_unparseDetailed(e
->ensuresConstraints
)));
1542 DPRINTF (("trueEnsures constraints for %s are %s", exprNode_unparse(e
),
1543 constraintList_unparseDetailed(e
->trueEnsuresConstraints
)));
1545 DPRINTF (("falseEnsures constraints for %s are %s", exprNode_unparse(e
),
1546 constraintList_unparseDetailed(e
->falseEnsuresConstraints
)));
1551 constraintList
exprNode_traverseTrueEnsuresConstraints (exprNode e
)
1557 if (exprNode_handleError (e
))
1559 ret
= constraintList_makeNew();
1563 ret
= constraintList_copy (e
->trueEnsuresConstraints
);
1570 t1
= exprData_getSingle (data
);
1571 ret
= constraintList_addListFree (ret
, exprNode_traverseTrueEnsuresConstraints (t1
));
1575 ret
= constraintList_addListFree (ret
,
1576 exprNode_traverseTrueEnsuresConstraints
1577 (exprData_getPairA (data
)));
1578 ret
= constraintList_addListFree (ret
,
1579 exprNode_traverseTrueEnsuresConstraints
1580 (exprData_getPairB (data
)));
1583 ret
= constraintList_addListFree (ret
,
1584 exprNode_traverseTrueEnsuresConstraints
1585 (exprData_getUopNode (data
)));
1589 ret
= constraintList_addListFree (ret
, exprNode_traverseTrueEnsuresConstraints
1590 (exprData_getUopNode (data
)));
1594 ret
= constraintList_addListFree (ret
,
1595 exprNode_traverseTrueEnsuresConstraints
1596 (exprData_getInitNode (data
)));
1600 ret
= constraintList_addListFree (ret
,
1601 exprNode_traverseTrueEnsuresConstraints
1602 (exprData_getOpA (data
)));
1603 ret
= constraintList_addListFree (ret
,
1604 exprNode_traverseTrueEnsuresConstraints
1605 (exprData_getOpB (data
)));
1609 ret
= constraintList_addListFree (ret
,
1610 exprNode_traverseTrueEnsuresConstraints
1611 (exprData_getOpA (data
)));
1612 ret
= constraintList_addListFree (ret
,
1613 exprNode_traverseTrueEnsuresConstraints
1614 (exprData_getOpB (data
)));
1621 ret
= constraintList_addListFree (ret
,
1622 exprNode_traverseTrueEnsuresConstraints
1623 (exprData_getSingle (data
)));
1627 ret
= constraintList_addListFree (ret
,
1628 exprNode_traverseTrueEnsuresConstraints
1629 (exprData_getFcn (data
)));
1633 ret
= constraintList_addListFree (ret
,
1634 exprNode_traverseTrueEnsuresConstraints
1635 (exprData_getSingle (data
)));
1638 case XPR_NULLRETURN
:
1642 ret
= constraintList_addListFree (ret
,
1643 exprNode_traverseTrueEnsuresConstraints
1644 (exprData_getFieldNode (data
)));
1648 ret
= constraintList_addListFree (ret
,
1649 exprNode_traverseTrueEnsuresConstraints
1650 (exprData_getFieldNode (data
)));
1653 case XPR_STRINGLITERAL
:
1660 ret
= constraintList_addListFree (ret
,
1661 exprNode_traverseTrueEnsuresConstraints
1662 (exprData_getUopNode (data
)));
1666 ret
= constraintList_addListFree (ret
,
1667 exprNode_traverseTrueEnsuresConstraints
1668 (exprData_getCastNode (data
)));
1678 constraintList
exprNode_traverseFalseEnsuresConstraints (exprNode e
)
1684 if (exprNode_handleError (e
))
1686 ret
= constraintList_makeNew();
1690 ret
= constraintList_copy (e
->falseEnsuresConstraints
);
1696 t1
= exprData_getSingle (data
);
1697 ret
= constraintList_addListFree (ret
,exprNode_traverseFalseEnsuresConstraints (t1
));
1701 ret
= constraintList_addListFree (ret
,
1702 exprNode_traverseFalseEnsuresConstraints
1703 (exprData_getPairA (data
)));
1704 ret
= constraintList_addListFree (ret
,
1705 exprNode_traverseFalseEnsuresConstraints
1706 (exprData_getPairB (data
)));
1710 ret
= constraintList_addListFree (ret
,
1711 exprNode_traverseFalseEnsuresConstraints
1712 (exprData_getUopNode (data
)));
1716 ret
= constraintList_addListFree (ret
, exprNode_traverseFalseEnsuresConstraints
1717 (exprData_getUopNode (data
)));
1721 ret
= constraintList_addListFree (ret
,
1722 exprNode_traverseFalseEnsuresConstraints
1723 ( exprData_getInitNode (data
)));
1727 ret
= constraintList_addListFree (ret
,
1728 exprNode_traverseFalseEnsuresConstraints
1729 (exprData_getOpA (data
)));
1730 ret
= constraintList_addListFree (ret
,
1731 exprNode_traverseFalseEnsuresConstraints
1732 (exprData_getOpB (data
)));
1736 ret
= constraintList_addListFree (ret
,
1737 exprNode_traverseFalseEnsuresConstraints
1738 (exprData_getOpA (data
)));
1739 ret
= constraintList_addListFree (ret
,
1740 exprNode_traverseFalseEnsuresConstraints
1741 (exprData_getOpB (data
)));
1748 ret
= constraintList_addListFree (ret
,
1749 exprNode_traverseFalseEnsuresConstraints
1750 (exprData_getSingle (data
)));
1754 ret
= constraintList_addListFree (ret
,
1755 exprNode_traverseFalseEnsuresConstraints
1756 (exprData_getFcn (data
)));
1760 ret
= constraintList_addListFree (ret
,
1761 exprNode_traverseFalseEnsuresConstraints
1762 (exprData_getSingle (data
)));
1765 case XPR_NULLRETURN
:
1769 ret
= constraintList_addListFree (ret
,
1770 exprNode_traverseFalseEnsuresConstraints
1771 (exprData_getFieldNode (data
)));
1775 ret
= constraintList_addListFree (ret
,
1776 exprNode_traverseFalseEnsuresConstraints
1777 (exprData_getFieldNode (data
)));
1780 case XPR_STRINGLITERAL
:
1786 ret
= constraintList_addListFree (ret
,
1787 exprNode_traverseFalseEnsuresConstraints
1788 (exprData_getUopNode (data
)));
1792 ret
= constraintList_addListFree (ret
,
1793 exprNode_traverseFalseEnsuresConstraints
1794 (exprData_getCastNode (data
)));
1805 /* walk down the tree and get all requires Constraints in each subexpression*/
1806 static /*@only@*/ constraintList
exprNode_traverseRequiresConstraints (exprNode e
)
1812 if (exprNode_handleError (e
))
1814 ret
= constraintList_makeNew();
1818 ret
= constraintList_copy (e
->requiresConstraints
);
1824 t1
= exprData_getSingle (data
);
1825 ret
= constraintList_addListFree (ret
, exprNode_traverseRequiresConstraints (t1
));
1829 ret
= constraintList_addListFree (ret
,
1830 exprNode_traverseRequiresConstraints
1831 (exprData_getPairA (data
)));
1832 ret
= constraintList_addListFree (ret
,
1833 exprNode_traverseRequiresConstraints
1834 (exprData_getPairB (data
)));
1838 ret
= constraintList_addListFree (ret
,
1839 exprNode_traverseRequiresConstraints
1840 (exprData_getUopNode (data
)));
1844 ret
= constraintList_addListFree (ret
, exprNode_traverseRequiresConstraints
1845 (exprData_getUopNode (data
)));
1849 ret
= constraintList_addListFree (ret
,
1850 exprNode_traverseRequiresConstraints
1851 (exprData_getInitNode (data
)));
1855 ret
= constraintList_addListFree (ret
,
1856 exprNode_traverseRequiresConstraints
1857 (exprData_getOpA (data
)));
1858 ret
= constraintList_addListFree (ret
,
1859 exprNode_traverseRequiresConstraints
1860 (exprData_getOpB (data
)));
1864 ret
= constraintList_addListFree (ret
,
1865 exprNode_traverseRequiresConstraints
1866 (exprData_getOpA (data
)));
1867 ret
= constraintList_addListFree (ret
,
1868 exprNode_traverseRequiresConstraints
1869 (exprData_getOpB (data
)));
1875 ret
= constraintList_addListFree (ret
,
1876 exprNode_traverseRequiresConstraints
1877 (exprData_getSingle (data
)));
1881 ret
= constraintList_addListFree (ret
,
1882 exprNode_traverseRequiresConstraints
1883 (exprData_getFcn (data
)));
1887 ret
= constraintList_addListFree (ret
,
1888 exprNode_traverseRequiresConstraints
1889 (exprData_getSingle (data
)));
1892 case XPR_NULLRETURN
:
1896 ret
= constraintList_addListFree (ret
,
1897 exprNode_traverseRequiresConstraints
1898 (exprData_getFieldNode (data
)));
1902 ret
= constraintList_addListFree (ret
,
1903 exprNode_traverseRequiresConstraints
1904 (exprData_getFieldNode (data
)));
1907 case XPR_STRINGLITERAL
:
1914 ret
= constraintList_addListFree (ret
,
1915 exprNode_traverseRequiresConstraints
1916 (exprData_getUopNode (data
)));
1920 ret
= constraintList_addListFree (ret
,
1921 exprNode_traverseRequiresConstraints
1922 (exprData_getCastNode (data
)));
1933 /* walk down the tree and get all Ensures Constraints in each subexpression*/
1934 static /*@only@*/ constraintList
exprNode_traverseEnsuresConstraints (exprNode e
)
1940 if (exprNode_handleError (e
))
1942 ret
= constraintList_makeNew();
1946 ret
= constraintList_copy (e
->ensuresConstraints
);
1950 DPRINTF ((message ("exprnode_traversEnsuresConstraints call for %s with "
1951 "constraintList of %s",
1952 exprNode_unparse (e
),
1953 constraintList_unparse(e
->ensuresConstraints
)
1961 t1
= exprData_getSingle (data
);
1962 ret
= constraintList_addListFree (ret
,exprNode_traverseEnsuresConstraints (t1
));
1966 ret
= constraintList_addListFree (ret
,
1967 exprNode_traverseEnsuresConstraints
1968 (exprData_getPairA (data
)));
1970 ret
= constraintList_addListFree (ret
,
1971 exprNode_traverseEnsuresConstraints
1972 (exprData_getPairB (data
)));
1976 ret
= constraintList_addListFree (ret
,
1977 exprNode_traverseEnsuresConstraints
1978 (exprData_getUopNode (data
)));
1982 ret
= constraintList_addListFree (ret
, exprNode_traverseEnsuresConstraints
1983 (exprData_getUopNode (data
)));
1987 ret
= constraintList_addListFree (ret
,
1988 exprNode_traverseEnsuresConstraints
1989 (exprData_getInitNode (data
)));
1994 ret
= constraintList_addListFree (ret
,
1995 exprNode_traverseEnsuresConstraints
1996 (exprData_getOpA (data
)));
1998 ret
= constraintList_addListFree (ret
,
1999 exprNode_traverseEnsuresConstraints
2000 (exprData_getOpB (data
)));
2003 ret
= constraintList_addListFree (ret
,
2004 exprNode_traverseEnsuresConstraints
2005 (exprData_getOpA (data
)));
2007 ret
= constraintList_addListFree (ret
,
2008 exprNode_traverseEnsuresConstraints
2009 (exprData_getOpB (data
)));
2015 ret
= constraintList_addListFree (ret
,
2016 exprNode_traverseEnsuresConstraints
2017 (exprData_getSingle (data
)));
2020 ret
= constraintList_addListFree (ret
,
2021 exprNode_traverseEnsuresConstraints
2022 (exprData_getFcn (data
)));
2025 ret
= constraintList_addListFree (ret
,
2026 exprNode_traverseEnsuresConstraints
2027 (exprData_getSingle (data
)));
2029 case XPR_NULLRETURN
:
2032 ret
= constraintList_addListFree (ret
,
2033 exprNode_traverseEnsuresConstraints
2034 (exprData_getFieldNode (data
)));
2037 ret
= constraintList_addListFree (ret
,
2038 exprNode_traverseEnsuresConstraints
2039 (exprData_getFieldNode (data
)));
2041 case XPR_STRINGLITERAL
:
2046 ret
= constraintList_addListFree (ret
,
2047 exprNode_traverseEnsuresConstraints
2048 (exprData_getUopNode (data
)));
2051 ret
= constraintList_addListFree (ret
,
2052 exprNode_traverseEnsuresConstraints
2053 (exprData_getCastNode (data
)));
2059 DPRINTF((message ("exprnode_traversEnsuresConstraints call for %s with "
2060 "constraintList of is returning %s",
2061 exprNode_unparse (e
),
2062 constraintList_unparse(ret
))));
2067 /*drl moved out of constraintResolve.c 07-02-001 */
2068 void checkArgumentList (/*@out@*/ exprNode temp
, exprNodeList arglist
,
2069 fileloc sequencePoint
)
2071 llassertfatal (temp
!= NULL
);
2073 temp
->requiresConstraints
= constraintList_makeNew();
2074 temp
->ensuresConstraints
= constraintList_makeNew();
2075 temp
->trueEnsuresConstraints
= constraintList_makeNew();
2076 temp
->falseEnsuresConstraints
= constraintList_makeNew();
2078 exprNodeList_elements (arglist
, el
)
2080 constraintList temp2
;
2082 llassertfatal (exprNode_isDefined(el
));
2084 exprNode_exprTraverse (el
, FALSE
, FALSE
, sequencePoint
);
2085 temp2
= el
->requiresConstraints
;
2086 el
->requiresConstraints
= exprNode_traverseRequiresConstraints(el
);
2087 constraintList_free(temp2
);
2089 temp2
= el
->ensuresConstraints
;
2090 el
->ensuresConstraints
= exprNode_traverseEnsuresConstraints(el
);
2091 constraintList_free(temp2
);
2093 temp
->requiresConstraints
= constraintList_addList(temp
->requiresConstraints
,
2094 el
->requiresConstraints
);
2096 temp
->ensuresConstraints
= constraintList_addList(temp
->ensuresConstraints
,
2097 el
->ensuresConstraints
);
2099 end_exprNodeList_elements
;
2103 /*drl moved out of constraintResolve.c 07-03-001 */
2104 static constraintList
exprNode_getPostConditions (exprNode fcn
, exprNodeList arglist
, exprNode fcnCall
)
2106 constraintList postconditions
;
2108 DPRINTF((message ("Got call that %s (%s) ", exprNode_unparse(fcn
), exprNodeList_unparse (arglist
))));
2110 temp
= exprNode_getUentry (fcn
);
2112 postconditions
= uentry_getFcnPostconditions (temp
);
2114 if (constraintList_isDefined (postconditions
))
2116 postconditions
= constraintList_doSRefFixConstraintParam (postconditions
, arglist
);
2117 postconditions
= constraintList_doFixResult (postconditions
, fcnCall
);
2121 postconditions
= constraintList_makeNew();
2124 return postconditions
;
2128 comment this out for now
2129 we'll include it in a production release when its stable...
2131 void findStructs (exprNodeList arglist)
2137 message("doing findStructs: %s", exprNodeList_unparse(arglist))
2141 exprNodeList_elements(arglist, expr)
2143 ct = exprNode_getType(expr);
2145 rt = ctype_realType (ct);
2147 if (ctype_isStruct (rt))
2148 DPRINTF((message("Found structure %s", exprNode_unparse(expr))
2150 if (hasInvariants(ct))
2152 constraintList invars;
2154 invars = getInvariants(ct);
2157 DPRINTF((message ("findStructs has invariants %s ", constraintList_unparse (invars))
2160 invars = constraintList_doSRefFixStructConstraint(invars, exprNode_getSref(expr), ct);
2163 DPRINTF((message ("findStructs finded invariants to be %s ", constraintList_unparse (invars))
2167 end_exprNodeList_elements;
2172 /*drl moved out of constraintResolve.c 07-02-001 */
2173 constraintList
checkCall (/*@dependent@*/ exprNode fcn
, exprNodeList arglist
)
2175 constraintList preconditions
;
2177 DPRINTF((message ("Got call that %s (%s) ", exprNode_unparse(fcn
), exprNodeList_unparse (arglist
))));
2179 temp
= exprNode_getUentry (fcn
);
2181 preconditions
= uentry_getFcnPreconditions (temp
);
2183 if (constraintList_isDefined(preconditions
))
2185 preconditions
= constraintList_togglePost (preconditions
);
2186 preconditions
= constraintList_preserveCallInfo(preconditions
, fcn
);
2187 preconditions
= constraintList_doSRefFixConstraintParam (preconditions
, arglist
);
2191 if (constraintList_isUndefined(preconditions
))
2192 preconditions
= constraintList_makeNew();
2195 if (context_getFlag (FLG_IMPBOUNDSCONSTRAINTS
))
2199 uentryList_elements (arglist, el)
2202 DPRINTF((message("setImplicitfcnConstraints doing: %s", uentry_unparse(el) ) ));
2204 s = uentry_getSref(el);
2205 if (sRef_isReference (s) )
2207 DPRINTF((message ("%s is a pointer", sRef_unparse(s) ) ));
2211 DPRINTF((message ("%s is NOT a pointer", sRef_unparse(s) ) ));
2214 //chagned this from MaxSet(s) == 0 to MaxSet(s) >= 0
2215 c = constraint_makeSRefWriteSafeInt (s, 0);
2217 implicitFcnConstraints = constraintList_add(implicitFcnConstraints , c);
2219 //drl 10/23/2002 added support for out
2220 if (!uentry_isOut(el) )
2222 c = constraint_makeSRefReadSafeInt (s, 0);
2223 implicitFcnConstraints = constraintList_add(implicitFcnConstraints , c);
2231 DPRINTF ((message("Done checkCall\n")));
2232 DPRINTF ((message("Returning list %q ", constraintList_unparseDetailed(preconditions
))));
2235 drl we're going to comment this out for now
2236 we'll include it if we're sure it's working
2238 findStructs(arglist);
2241 return preconditions
;
2244 /*drl added this function 10.29.001
2245 takes an exprNode of the form const + const
2249 I'm a bit nervous about modifying the exprNode
2250 but this is the easy way to do this
2251 If I have time I'd like to cause the exprNode to get created correctly in the first place */
2252 void exprNode_findValue(exprNode e
)
2254 llassertfatal (exprNode_isDefined(e
));
2256 if (exprNode_hasValue(e
))
2259 if (e
->kind
== XPR_OP
)
2266 t1
= exprData_getOpA (data
);
2267 t2
= exprData_getOpB (data
);
2268 tok
= exprData_getOpTok (data
);
2270 exprNode_findValue(t1
);
2271 exprNode_findValue(t2
);
2273 if (!(exprNode_knownIntValue(t1
) && (exprNode_knownIntValue(t2
))))
2276 if (lltok_isPlus_Op (tok
) || lltok_isMinus_Op (tok
))
2280 v1
= exprNode_getLongValue(t1
);
2281 v2
= exprNode_getLongValue(t2
);
2283 if (multiVal_isDefined(e
->val
))
2285 multiVal_free (e
->val
);
2288 e
->val
= multiVal_makeInt (lltok_isMinus_Op (tok
) ? v1
- v2
: v1
+ v2
);
2291 /*drl I should really do '*' and '/' at some point */