7 # include <ctype.h> /* for isdigit */
8 # include "lclintMacros.nf"
10 # include "cgrammar.h"
11 # include "cgrammar_tokens.h"
13 # include "exprChecks.h"
14 # include "aliasChecks.h"
15 # include "exprNodeSList.h"
16 //# include "exprData.i"
22 /*@access exprNode @*/
25 static /*@notnull@*/ /*@special@*/ constraint constraint_makeNew (void)
26 /*@post:isnull result->or, result->orig, result->generatingExpr, result->fcnPre @*/ /*@defines result->or, result->generatingExpr, result->orig, result->fcnPre @*/;
28 /* constraint makeConstraintParse (sRef x, lltok relOp, exprNode cconstant) */
34 /* ret = constraint_makeNew(); */
35 /* llassert (sRef_isValid(x) ); */
36 /* if (!sRef_isValid(x)) */
40 /* ret->lexpr = constraintExpr_makeTermsRef (x); */
41 /* #warning fix abstraction */
43 /* if (relOp.tok == GE_OP) */
45 /* else if (relOp.tok == LE_OP) */
47 /* else if (relOp.tok == EQ_OP) */
50 /* llfatalbug(message ("Unsupported relational operator") ); */
53 /* t = cstring_toCharsSafe (exprNode_unparse(cconstant)); */
55 /* ret->expr = constraintExpr_makeIntLiteral (c); */
57 /* ret->post = TRUE; */
58 /* // ret->orig = ret; */
59 /* DPRINTF(("GENERATED CONSTRAINT:")); */
60 /* DPRINTF( (message ("%s", constraint_print(ret) ) ) ); */
64 constraint makeConstraintParse2 (constraintExpr l, lltok relOp, exprNode cconstant)
69 ret = constraint_makeNew();
72 ret->lexpr = constraintExpr_copy (l);
73 #warning fix abstraction
75 if (relOp.tok == GE_OP)
77 else if (relOp.tok == LE_OP)
79 else if (relOp.tok == EQ_OP)
82 llfatalbug(message("Unsupported relational operator") );
85 t = cstring_toCharsSafe (exprNode_unparse(cconstant));
87 ret->expr = constraintExpr_makeIntLiteral (c);
91 DPRINTF(("GENERATED CONSTRAINT:"));
92 DPRINTF( (message ("%s", constraint_print(ret) ) ) );
96 bool constraint_same (constraint c1, constraint c2)
102 if (!constraintExpr_similar (c1->lexpr, c2->lexpr) )
105 if (!constraintExpr_similar (c1->expr, c2->expr) )
111 constraint makeConstraintParse3 (constraintExpr l, lltok relOp, constraintExpr r)
114 ret = constraint_makeNew();
117 ret->lexpr = constraintExpr_copy (l);
118 #warning fix abstraction
120 if (relOp.tok == GE_OP)
122 else if (relOp.tok == LE_OP)
124 else if (relOp.tok == EQ_OP)
127 llfatalbug( message("Unsupported relational operator") );
129 ret->expr = constraintExpr_copy (r);
133 ret->orig = constraint_copy(ret);
135 ret = constraint_simplify (ret);
138 DPRINTF(("GENERATED CONSTRAINT:"));
139 DPRINTF( (message ("%s", constraint_print(ret) ) ) );
143 constraint constraint_copy (constraint c)
147 llassert (constraint_isDefined(c) );
148 // TPRINTF((message("Copying constraint %q", constraint_print) ));
150 ret = constraint_makeNew();
151 ret->lexpr = constraintExpr_copy (c->lexpr);
153 ret->expr = constraintExpr_copy (c->expr);
155 ret->generatingExpr = exprNode_fakeCopy(c->generatingExpr);
159 ret->orig = constraint_copy (c->orig);
164 ret->or = constraint_copy (c->or);
168 ret->fcnPre = c->fcnPre;
173 /*like copy expect it doesn't allocate memory for the constraint*/
175 void constraint_overWrite (constraint c1, constraint c2)
177 llassert (constraint_isDefined(c1) );
181 DPRINTF((message("OverWriteing constraint %q with %q", constraint_print(c1),
182 constraint_print(c2) ) ));
184 constraintExpr_free(c1->lexpr);
185 constraintExpr_free(c1->expr);
187 c1->lexpr = constraintExpr_copy (c2->lexpr);
189 c1->expr = constraintExpr_copy (c2->expr);
192 if (c1->orig != NULL)
193 constraint_free (c1->orig);
195 if (c2->orig != NULL)
196 c1->orig = constraint_copy (c2->orig);
200 /*@i33 make sure that the or is freed correctly*/
202 constraint_free (c1->or);
205 c1->or = constraint_copy (c2->or);
209 c1->fcnPre = c2->fcnPre;
211 c1->generatingExpr = c2->generatingExpr;
216 static /*@notnull@*/ /*@special@*/ constraint constraint_makeNew (void)
217 /*@post:isnull result->or, result->orig, result->generatingExpr, result->fcnPre @*/ /*@defines result->or, result->generatingExpr, result->orig, result->fcnPre @*/
220 ret = dmalloc(sizeof (*ret) );
227 ret->generatingExpr = NULL;
232 constraint constraint_addGeneratingExpr (/*@returned@*/ constraint c, exprNode e)
235 if (c->generatingExpr == NULL)
237 c->generatingExpr = exprNode_fakeCopy(e);
238 DPRINTF ((message ("setting generatingExpr for %s to %s", constraint_print(c), exprNode_unparse(e) ) ));
242 DPRINTF ((message ("Not setting generatingExpr for %s to %s", constraint_print(c), exprNode_unparse(e) ) ));
247 constraint constraint_origAddGeneratingExpr (/*@returned@*/ constraint c, exprNode e)
250 if (c->orig != constraint_undefined)
252 c->orig = constraint_addGeneratingExpr(c->orig, e);
256 DPRINTF ((message ("constraint_origAddGeneratingExpr: Not setting generatingExpr for %s to %s", constraint_print(c), exprNode_unparse(e) ) ));
263 constraint constraint_setFcnPre (/*@returned@*/ constraint c )
266 if (c->orig != constraint_undefined)
268 c->orig->fcnPre = TRUE;
273 TPRINTF(( message("Warning Setting fcnPre directly") ));
281 fileloc constraint_getFileloc (constraint c)
283 if (exprNode_isDefined(c->generatingExpr) )
284 return (fileloc_copy (exprNode_getfileloc (c->generatingExpr) ) );
286 return (constraintExpr_getFileloc (c->lexpr) );
291 static bool checkForMaxSet (constraint c)
293 if (constraintExpr_hasMaxSet(c->lexpr) || constraintExpr_hasMaxSet(c->expr) )
299 bool constraint_hasMaxSet(constraint c)
303 if (checkForMaxSet(c->orig) )
307 return (checkForMaxSet(c) );
310 constraint constraint_makeReadSafeExprNode ( exprNode po, exprNode ind)
312 constraint ret = constraint_makeNew();
313 // constraintTerm term;
314 po = exprNode_fakeCopy(po);
315 ind = exprNode_fakeCopy(ind);
316 ret->lexpr = constraintExpr_makeMaxReadExpr(po);
318 ret->expr = constraintExpr_makeValueExpr (ind);
323 constraint constraint_makeWriteSafeInt (exprNode po, int ind)
325 constraint ret = constraint_makeNew();
328 ret->lexpr =constraintExpr_makeMaxSetExpr(po);
330 ret->expr = constraintExpr_makeIntLiteral (ind);
334 constraint constraint_makeSRefSetBufferSize (sRef s, long int size)
336 constraint ret = constraint_makeNew();
337 ret->lexpr = constraintExpr_makeSRefMaxset (s);
339 ret->expr = constraintExpr_makeIntLiteral ((int)size);
344 constraint constraint_makeSRefWriteSafeInt (sRef s, int ind)
346 constraint ret = constraint_makeNew();
349 ret->lexpr = constraintExpr_makeSRefMaxset ( s );
351 ret->expr = constraintExpr_makeIntLiteral (ind);
356 /* drl added 01/12/2000
358 makes the constraint: Ensures index <= MaxRead(buffer) */
360 constraint constraint_makeEnsureLteMaxRead(exprNode index, exprNode buffer)
362 constraint ret = constraint_makeNew();
364 ret->lexpr = constraintExpr_makeValueExpr (index);
366 ret->expr = constraintExpr_makeMaxReadExpr(buffer);
371 constraint constraint_makeWriteSafeExprNode (exprNode po, exprNode ind)
373 constraint ret = constraint_makeNew();
376 ret->lexpr =constraintExpr_makeMaxSetExpr(po);
378 ret->expr = constraintExpr_makeValueExpr (ind);
383 constraint constraint_makeReadSafeInt ( exprNode po, int ind)
385 constraint ret = constraint_makeNew();
387 po = exprNode_fakeCopy(po);
389 ret->lexpr = constraintExpr_makeMaxReadExpr(po);
391 ret->expr = constraintExpr_makeIntLiteral (ind);
396 constraint constraint_makeSRefReadSafeInt (sRef s, int ind)
398 constraint ret = constraint_makeNew();
401 ret->lexpr = constraintExpr_makeSRefMaxRead (s );
403 ret->expr = constraintExpr_makeIntLiteral (ind);
408 constraint constraint_makeEnsureMaxReadAtLeast (exprNode e1, exprNode t2, fileloc sequencePoint)
412 e1 = exprNode_fakeCopy (e1);
413 t2 = exprNode_fakeCopy (t2);
415 ret = constraint_makeReadSafeExprNode(e1, t2);
417 ret->lexpr = constraintExpr_setFileloc (ret->lexpr, sequencePoint);
421 // fileloc_incColumn (ret->lexpr->term->loc);
425 static constraint constraint_makeEnsuresOpConstraintExpr (/*@only@*/ constraintExpr c1, /*@only@*/ constraintExpr c2, fileloc sequencePoint, arithType ar)
431 // llassert(sequencePoint);
433 ret = constraint_makeNew();
439 ret->lexpr = constraintExpr_setFileloc (ret->lexpr, sequencePoint);
443 static constraint constraint_makeEnsuresOp (exprNode e1, exprNode e2, fileloc sequencePoint, arithType ar)
445 constraintExpr c1, c2;
451 llcontbug((message("null exprNode, Exprnodes are %s and %s",
452 exprNode_unparse(e1), exprNode_unparse(e2) )
456 // llassert (sequencePoint);
458 e = exprNode_fakeCopy(e1);
459 c1 = constraintExpr_makeValueExpr (e);
461 e = exprNode_fakeCopy(e2);
462 c2 = constraintExpr_makeValueExpr (e);
464 ret = constraint_makeEnsuresOpConstraintExpr (c1, c2, sequencePoint, ar);
470 /* make constraint ensures e1 == e2 */
472 constraint constraint_makeEnsureEqual (exprNode e1, exprNode e2, fileloc sequencePoint)
474 return ( constraint_makeEnsuresOp (e1, e2, sequencePoint, EQ) );
477 /*make constraint ensures e1 < e2 */
478 constraint constraint_makeEnsureLessThan (exprNode e1, exprNode e2, fileloc sequencePoint)
480 constraintExpr t1, t2;
482 t1 = constraintExpr_makeValueExpr (e1);
483 t2 = constraintExpr_makeValueExpr (e2);
485 /*change this to e1 <= (e2 -1) */
487 t2 = constraintExpr_makeDecConstraintExpr (t2);
489 return ( constraint_makeEnsuresOpConstraintExpr (t1, t2, sequencePoint, LTE) );
492 constraint constraint_makeEnsureLessThanEqual (exprNode e1, exprNode e2, fileloc sequencePoint)
494 return ( constraint_makeEnsuresOp (e1, e2, sequencePoint, LTE) );
497 constraint constraint_makeEnsureGreaterThan (exprNode e1, exprNode e2, fileloc sequencePoint)
499 constraintExpr t1, t2;
501 t1 = constraintExpr_makeValueExpr (e1);
502 t2 = constraintExpr_makeValueExpr (e2);
505 /* change this to e1 >= (e2 + 1) */
506 t2 = constraintExpr_makeIncConstraintExpr (t2);
509 return ( constraint_makeEnsuresOpConstraintExpr (t1, t2, sequencePoint, GTE) );
512 constraint constraint_makeEnsureGreaterThanEqual (exprNode e1, exprNode e2, fileloc sequencePoint)
514 return ( constraint_makeEnsuresOp (e1, e2, sequencePoint, GTE) );
518 exprNode exprNode_copyConstraints (/*@returned@*/ exprNode dst, exprNode src)
520 constraintList_free(dst->ensuresConstraints);
521 constraintList_free(dst->requiresConstraints);
522 constraintList_free(dst->trueEnsuresConstraints);
523 constraintList_free(dst->falseEnsuresConstraints);
525 dst->ensuresConstraints = constraintList_copy (src->ensuresConstraints );
526 dst->requiresConstraints = constraintList_copy (src->requiresConstraints );
527 dst->trueEnsuresConstraints = constraintList_copy (src->trueEnsuresConstraints );
528 dst->falseEnsuresConstraints = constraintList_copy (src->falseEnsuresConstraints );
532 constraint constraint_makeMaxSetSideEffectPostDecrement (exprNode e, fileloc sequencePoint)
534 constraint ret = constraint_makeNew();
535 //constraintTerm term;
537 e = exprNode_fakeCopy(e);
538 ret->lexpr = constraintExpr_makeValueExpr (e);
541 ret->expr = constraintExpr_makeValueExpr (e);
542 ret->expr = constraintExpr_makeDecConstraintExpr (ret->expr);
544 ret->lexpr = constraintExpr_setFileloc (ret->lexpr, sequencePoint);
545 // fileloc_incColumn ( ret->lexpr->term->loc);
546 // fileloc_incColumn ( ret->lexpr->term->loc);
549 constraint constraint_makeMaxSetSideEffectPostIncrement (exprNode e, fileloc sequencePoint)
551 constraint ret = constraint_makeNew();
552 //constraintTerm term;
554 e = exprNode_fakeCopy(e);
555 ret->lexpr = constraintExpr_makeValueExpr (e);
558 ret->expr = constraintExpr_makeValueExpr (e);
559 ret->expr = constraintExpr_makeIncConstraintExpr (ret->expr);
561 ret->lexpr = constraintExpr_setFileloc (ret->lexpr, sequencePoint);
562 // fileloc_incColumn ( ret->lexpr->term->loc);
563 // fileloc_incColumn ( ret->lexpr->term->loc);
568 void constraint_free (/*@only@*/ /*@notnull@*/ constraint c)
570 llassert(constraint_isDefined (c) );
573 if (constraint_isDefined(c->orig) )
574 constraint_free (c->orig);
575 if ( constraint_isDefined(c->or) )
576 constraint_free (c->or);
579 constraintExpr_free(c->lexpr);
580 constraintExpr_free(c->expr);
592 // constraint constraint_makeMaxReadSideEffectPostIncrement (exprNode e, fileloc sequencePoint)
594 // constraint ret = constraint_makeNew();
595 // //constraintTerm term;
597 // e = exprNode_fakeCopy(e);
598 // ret->lexpr = constraintExpr_makeMaxReadExpr(e);
601 // ret->expr = constraintExpr_makeIncConstraintExpr (e);
602 // ret->lexpr = constraintExpr_setFileLoc (ret->lexpr, sequencePoint);
607 cstring arithType_print (arithType ar) /*@*/
609 cstring st = cstring_undefined;
613 st = cstring_makeLiteral (" < ");
616 st = cstring_makeLiteral (" <= ");
619 st = cstring_makeLiteral (" > ");
622 st = cstring_makeLiteral (" >= ");
625 st = cstring_makeLiteral (" == ");
628 st = cstring_makeLiteral (" NONNEGATIVE ");
631 st = cstring_makeLiteral (" POSITIVE ");
641 void constraint_printErrorPostCondition (constraint c, fileloc loc)
644 fileloc errorLoc, temp;
646 string = constraint_printDetailedPostCondition (c);
652 temp = constraint_getFileloc(c);
654 if (fileloc_isDefined(temp) )
657 voptgenerror ( FLG_CHECKPOST, string, errorLoc);
662 voptgenerror ( FLG_CHECKPOST, string, errorLoc);
669 void constraint_printError (constraint c, fileloc loc)
672 fileloc errorLoc, temp;
674 string = constraint_printDetailed (c);
680 temp = constraint_getFileloc(c);
682 if (fileloc_isDefined(temp) )
688 voptgenerror (FLG_FUNCTIONPOST, string, errorLoc);
692 voptgenerror (FLG_FUNCTIONCONSTRAINT, string, errorLoc);
700 voptgenerror (FLG_FUNCTIONPOST, string, errorLoc);
704 voptgenerror (FLG_FUNCTIONCONSTRAINT, string, errorLoc);
710 cstring constraint_printDeep (constraint c)
712 cstring st = cstring_undefined;
714 st = constraint_print(c);
716 if (c->orig != constraint_undefined)
721 st = cstring_concatFree(st, (message(" derived from %s precondition: %q", exprNode_unparse(c->orig->generatingExpr), constraint_printDeep(c->orig) )
724 st = cstring_concatFree(st,(message(" needed to satisfy %q",
725 constraint_printDeep(c->orig) )
731 st = cstring_concatFree(st,(message("derived from: %q",
732 constraint_printDeep(c->orig) )
741 cstring constraint_printDetailedPostCondition (constraint c)
743 cstring st = cstring_undefined;
745 st = message ("Unsatisfied ensures constraint condition:\nLCLint is unable to verify the constraint %q", constraint_printDeep (c) );
747 if (context_getFlag (FLG_CONSTRAINTLOCATION) )
750 // llassert (c->generatingExpr);
751 temp = message ("\nOriginal Generating expression %q: %s\n", fileloc_unparse( exprNode_getfileloc (c->generatingExpr) ),
752 exprNode_unparse(c->generatingExpr) );
753 st = cstring_concatFree (st, temp);
755 if (constraint_hasMaxSet(c) )
757 temp = message ("Has MaxSet\n");
758 st = cstring_concatFree (st, temp);
764 cstring constraint_printDetailed (constraint c)
766 cstring st = cstring_undefined;
770 st = message ("Unresolved constraint:\nLclint is unable to resolve %q", constraint_printDeep (c) );
774 st = message ("Block Post condition:\nThis function block has the post condition %q", constraint_printDeep (c) );
777 if (context_getFlag (FLG_CONSTRAINTLOCATION) )
780 // llassert (c->generatingExpr);
781 temp = message ("\nOriginal Generating expression %q: %s\n", fileloc_unparse( exprNode_getfileloc (c->generatingExpr) ),
782 exprNode_unparse(c->generatingExpr) );
783 st = cstring_concatFree (st, temp);
785 if (constraint_hasMaxSet(c) )
787 temp = message ("Has MaxSet\n");
788 st = cstring_concatFree (st, temp);
794 /*@only@*/ cstring constraint_print (constraint c) /*@*/
796 cstring st = cstring_undefined;
797 cstring type = cstring_undefined;
801 type = cstring_makeLiteral ("Ensures: ");
805 type = cstring_makeLiteral ("Requires: ");
807 st = message ("%q: %q %q %q",
809 constraintExpr_print (c->lexpr),
810 arithType_print(c->ar),
811 constraintExpr_print(c->expr)
816 cstring constraint_printOr (constraint c) /*@*/
821 ret = cstring_undefined;
824 ret = cstring_concatFree (ret, constraint_print(temp) );
828 while ( constraint_isDefined(temp) )
830 ret = cstring_concatFree (ret, cstring_makeLiteral (" OR ") );
831 ret = cstring_concatFree (ret, constraint_print(temp) );
839 /*@only@*/ constraint constraint_doSRefFixBaseParam (/*@returned@*/ /*@only@*/ constraint precondition,
840 exprNodeList arglist)
842 precondition->lexpr = constraintExpr_doSRefFixBaseParam (precondition->lexpr,
844 precondition->expr = constraintExpr_doSRefFixBaseParam (precondition->expr,
851 constraint constraint_doFixResult (constraint postcondition, exprNode fcnCall)
853 postcondition = constraint_copy (postcondition);
854 postcondition->lexpr = constraintExpr_doFixResult (postcondition->lexpr, fcnCall);
855 postcondition->expr = constraintExpr_doFixResult (postcondition->expr, fcnCall);
857 return postcondition;
860 /*@only@*/ constraint constraint_doSRefFixConstraintParam (constraint precondition,
861 exprNodeList arglist)
864 precondition = constraint_copy (precondition);
865 precondition->lexpr = constraintExpr_doSRefFixConstraintParam (precondition->lexpr, arglist);
866 precondition->expr = constraintExpr_doSRefFixConstraintParam (precondition->expr, arglist);
868 precondition->fcnPre = FALSE;
872 // bool constraint_hasTerm (constraint c, constraintTerm term)
874 // DPRINTF((message ("Constraint %s", constraint_print (c) ) ) );
876 // if (constraintExpr_includesTerm (c->lexpr, term) )
879 // if (constraintExpr_includesTerm (c->expr, term) )
885 constraint constraint_preserveOrig (/*@returned@*/ constraint c) /*@modifies c @*/
888 DPRINTF( (message("Doing constraint_preserverOrig for %q ", constraint_printDetailed(c) ) ));
890 if (c->orig == constraint_undefined)
891 c->orig = constraint_copy (c);
893 else if (c->orig->fcnPre)
899 /* avoid infinite loop */
901 c->orig = constraint_copy (c);
902 if (c->orig->orig == NULL)
903 c->orig->orig = temp;
905 llcontbug((message("Expected c->orig->orig to be null" ) ));
909 DPRINTF( (message("Not changing constraint") ));
912 DPRINTF( (message("After Doing constraint_preserverOrig for %q ", constraint_printDetailed(c) ) ));
920 constraint constraint_togglePost (/*@returned@*/ constraint c)