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"
21 /*@access exprNode @*/
24 static /*@only@*/ cstring constraint_printDetailedPostCondition (/*@observer@*/ /*@temp@*/ constraint c);
27 static /*@notnull@*/ /*@special@*/ constraint constraint_makeNew (void)
28 /*@post:isnull result->or, result->orig, result->generatingExpr, result->fcnPre @*/ /*@defines result->or, result->generatingExpr, result->orig, result->fcnPre @*/;
30 /* constraint makeConstraintParse (sRef x, lltok relOp, exprNode cconstant) */
36 /* ret = constraint_makeNew(); */
37 /* llassert (sRef_isValid(x) ); */
38 /* if (!sRef_isValid(x)) */
42 /* ret->lexpr = constraintExpr_makeTermsRef (x); */
43 /* #warning fix abstraction */
45 /* if (relOp.tok == GE_OP) */
47 /* else if (relOp.tok == LE_OP) */
49 /* else if (relOp.tok == EQ_OP) */
52 /* llfatalbug(message ("Unsupported relational operator") ); */
55 /* t = cstring_toCharsSafe (exprNode_unparse(cconstant)); */
57 /* ret->expr = constraintExpr_makeIntLiteral (c); */
59 /* ret->post = TRUE; */
60 /* // ret->orig = ret; */
61 /* DPRINTF(("GENERATED CONSTRAINT:")); */
62 /* DPRINTF( (message ("%s", constraint_print(ret) ) ) ); */
66 constraint makeConstraintParse2 (constraintExpr l, lltok relOp, exprNode cconstant)
71 ret = constraint_makeNew();
74 ret->lexpr = constraintExpr_copy (l);
77 if (relOp.tok == GE_OP)
79 else if (relOp.tok == LE_OP)
81 else if (relOp.tok == EQ_OP)
84 llfatalbug(message("Unsupported relational operator") );
87 t = cstring_toCharsSafe (exprNode_unparse(cconstant));
89 ret->expr = constraintExpr_makeIntLiteral (c);
93 DPRINTF(("GENERATED CONSTRAINT:"));
94 DPRINTF( (message ("%s", constraint_print(ret) ) ) );
98 bool constraint_same (constraint c1, constraint c2)
101 if (c1->ar != c2->ar)
104 if (!constraintExpr_similar (c1->lexpr, c2->lexpr) )
107 if (!constraintExpr_similar (c1->expr, c2->expr) )
113 constraint makeConstraintParse3 (constraintExpr l, lltok relOp, constraintExpr r)
116 ret = constraint_makeNew();
119 ret->lexpr = constraintExpr_copy (l);
121 if (relOp.tok == GE_OP)
123 else if (relOp.tok == LE_OP)
125 else if (relOp.tok == EQ_OP)
128 llfatalbug( message("Unsupported relational operator") );
130 ret->expr = constraintExpr_copy (r);
134 ret->orig = constraint_copy(ret);
136 ret = constraint_simplify (ret);
139 DPRINTF(("GENERATED CONSTRAINT:"));
140 DPRINTF( (message ("%s", constraint_print(ret) ) ) );
144 constraint constraint_copy (constraint c)
148 llassert (constraint_isDefined(c) );
149 // TPRINTF((message("Copying constraint %q", constraint_print) ));
151 ret = constraint_makeNew();
152 ret->lexpr = constraintExpr_copy (c->lexpr);
154 ret->expr = constraintExpr_copy (c->expr);
156 ret->generatingExpr = exprNode_fakeCopy(c->generatingExpr);
160 ret->orig = constraint_copy (c->orig);
165 ret->or = constraint_copy (c->or);
169 ret->fcnPre = c->fcnPre;
174 /*like copy expect it doesn't allocate memory for the constraint*/
176 void constraint_overWrite (constraint c1, constraint c2)
178 llassert (constraint_isDefined(c1) );
182 DPRINTF((message("OverWriteing constraint %q with %q", constraint_print(c1),
183 constraint_print(c2) ) ));
185 constraintExpr_free(c1->lexpr);
186 constraintExpr_free(c1->expr);
188 c1->lexpr = constraintExpr_copy (c2->lexpr);
190 c1->expr = constraintExpr_copy (c2->expr);
193 if (c1->orig != NULL)
194 constraint_free (c1->orig);
196 if (c2->orig != NULL)
197 c1->orig = constraint_copy (c2->orig);
201 /*@i33 make sure that the or is freed correctly*/
203 constraint_free (c1->or);
206 c1->or = constraint_copy (c2->or);
210 c1->fcnPre = c2->fcnPre;
212 c1->generatingExpr = c2->generatingExpr;
217 static /*@notnull@*/ /*@special@*/ constraint constraint_makeNew (void)
218 /*@post:isnull result->or, result->orig, result->generatingExpr, result->fcnPre @*/ /*@defines result->or, result->generatingExpr, result->orig, result->fcnPre @*/
221 ret = dmalloc(sizeof (*ret) );
228 ret->generatingExpr = NULL;
233 constraint constraint_addGeneratingExpr (/*@returned@*/ constraint c, exprNode e)
236 if (c->generatingExpr == NULL)
238 c->generatingExpr = exprNode_fakeCopy(e);
239 DPRINTF ((message ("setting generatingExpr for %s to %s", constraint_print(c), exprNode_unparse(e) ) ));
243 DPRINTF ((message ("Not setting generatingExpr for %s to %s", constraint_print(c), exprNode_unparse(e) ) ));
248 constraint constraint_origAddGeneratingExpr (/*@returned@*/ constraint c, exprNode e)
251 if (c->orig != constraint_undefined)
253 c->orig = constraint_addGeneratingExpr(c->orig, e);
257 DPRINTF ((message ("constraint_origAddGeneratingExpr: Not setting generatingExpr for %s to %s", constraint_print(c), exprNode_unparse(e) ) ));
262 constraint constraint_setFcnPre (/*@returned@*/ constraint c )
265 if (c->orig != constraint_undefined)
267 c->orig->fcnPre = TRUE;
272 TPRINTF(( message("Warning Setting fcnPre directly") ));
280 fileloc constraint_getFileloc (constraint c)
282 if (exprNode_isDefined(c->generatingExpr) )
283 return (fileloc_copy (exprNode_getfileloc (c->generatingExpr) ) );
285 return (constraintExpr_getFileloc (c->lexpr) );
290 static bool checkForMaxSet (constraint c)
292 if (constraintExpr_hasMaxSet(c->lexpr) || constraintExpr_hasMaxSet(c->expr) )
298 bool constraint_hasMaxSet(constraint c)
302 if (checkForMaxSet(c->orig) )
306 return (checkForMaxSet(c) );
309 constraint constraint_makeReadSafeExprNode ( exprNode po, exprNode ind)
311 constraint ret = constraint_makeNew();
312 // constraintTerm term;
313 po = exprNode_fakeCopy(po);
314 ind = exprNode_fakeCopy(ind);
315 ret->lexpr = constraintExpr_makeMaxReadExpr(po);
317 ret->expr = constraintExpr_makeValueExpr (ind);
322 constraint constraint_makeWriteSafeInt (exprNode po, int ind)
324 constraint ret = constraint_makeNew();
327 ret->lexpr =constraintExpr_makeMaxSetExpr(po);
329 ret->expr = constraintExpr_makeIntLiteral (ind);
333 constraint constraint_makeSRefSetBufferSize (sRef s, long int size)
335 constraint ret = constraint_makeNew();
336 ret->lexpr = constraintExpr_makeSRefMaxset (s);
338 ret->expr = constraintExpr_makeIntLiteral ((int)size);
343 constraint constraint_makeSRefWriteSafeInt (sRef s, int ind)
345 constraint ret = constraint_makeNew();
348 ret->lexpr = constraintExpr_makeSRefMaxset ( s );
350 ret->expr = constraintExpr_makeIntLiteral (ind);
355 /* drl added 01/12/2000
357 makes the constraint: Ensures index <= MaxRead(buffer) */
359 constraint constraint_makeEnsureLteMaxRead(exprNode index, exprNode buffer)
361 constraint ret = constraint_makeNew();
363 ret->lexpr = constraintExpr_makeValueExpr (index);
365 ret->expr = constraintExpr_makeMaxReadExpr(buffer);
370 constraint constraint_makeWriteSafeExprNode (exprNode po, exprNode ind)
372 constraint ret = constraint_makeNew();
375 ret->lexpr =constraintExpr_makeMaxSetExpr(po);
377 ret->expr = constraintExpr_makeValueExpr (ind);
382 constraint constraint_makeReadSafeInt ( exprNode po, int ind)
384 constraint ret = constraint_makeNew();
386 po = exprNode_fakeCopy(po);
388 ret->lexpr = constraintExpr_makeMaxReadExpr(po);
390 ret->expr = constraintExpr_makeIntLiteral (ind);
395 constraint constraint_makeSRefReadSafeInt (sRef s, int ind)
397 constraint ret = constraint_makeNew();
400 ret->lexpr = constraintExpr_makeSRefMaxRead (s );
402 ret->expr = constraintExpr_makeIntLiteral (ind);
407 constraint constraint_makeEnsureMaxReadAtLeast (exprNode e1, exprNode t2, fileloc sequencePoint)
411 e1 = exprNode_fakeCopy (e1);
412 t2 = exprNode_fakeCopy (t2);
414 ret = constraint_makeReadSafeExprNode(e1, t2);
416 ret->lexpr = constraintExpr_setFileloc (ret->lexpr, sequencePoint);
420 // fileloc_incColumn (ret->lexpr->term->loc);
424 static constraint constraint_makeEnsuresOpConstraintExpr (/*@only@*/ constraintExpr c1, /*@only@*/ constraintExpr c2, fileloc sequencePoint, arithType ar)
430 // llassert(sequencePoint);
432 ret = constraint_makeNew();
438 ret->lexpr = constraintExpr_setFileloc (ret->lexpr, sequencePoint);
442 static constraint constraint_makeEnsuresOp (exprNode e1, exprNode e2, fileloc sequencePoint, arithType ar)
444 constraintExpr c1, c2;
450 llcontbug((message("null exprNode, Exprnodes are %s and %s",
451 exprNode_unparse(e1), exprNode_unparse(e2) )
455 // llassert (sequencePoint);
457 e = exprNode_fakeCopy(e1);
458 c1 = constraintExpr_makeValueExpr (e);
460 e = exprNode_fakeCopy(e2);
461 c2 = constraintExpr_makeValueExpr (e);
463 ret = constraint_makeEnsuresOpConstraintExpr (c1, c2, sequencePoint, ar);
469 /* make constraint ensures e1 == e2 */
471 constraint constraint_makeEnsureEqual (exprNode e1, exprNode e2, fileloc sequencePoint)
473 return ( constraint_makeEnsuresOp (e1, e2, sequencePoint, EQ) );
476 /*make constraint ensures e1 < e2 */
477 constraint constraint_makeEnsureLessThan (exprNode e1, exprNode e2, fileloc sequencePoint)
479 constraintExpr t1, t2;
481 t1 = constraintExpr_makeValueExpr (e1);
482 t2 = constraintExpr_makeValueExpr (e2);
484 /*change this to e1 <= (e2 -1) */
486 t2 = constraintExpr_makeDecConstraintExpr (t2);
488 return ( constraint_makeEnsuresOpConstraintExpr (t1, t2, sequencePoint, LTE) );
491 constraint constraint_makeEnsureLessThanEqual (exprNode e1, exprNode e2, fileloc sequencePoint)
493 return ( constraint_makeEnsuresOp (e1, e2, sequencePoint, LTE) );
496 constraint constraint_makeEnsureGreaterThan (exprNode e1, exprNode e2, fileloc sequencePoint)
498 constraintExpr t1, t2;
500 t1 = constraintExpr_makeValueExpr (e1);
501 t2 = constraintExpr_makeValueExpr (e2);
504 /* change this to e1 >= (e2 + 1) */
505 t2 = constraintExpr_makeIncConstraintExpr (t2);
508 return ( constraint_makeEnsuresOpConstraintExpr (t1, t2, sequencePoint, GTE) );
511 constraint constraint_makeEnsureGreaterThanEqual (exprNode e1, exprNode e2, fileloc sequencePoint)
513 return ( constraint_makeEnsuresOp (e1, e2, sequencePoint, GTE) );
517 exprNode exprNode_copyConstraints (/*@returned@*/ exprNode dst, exprNode src)
519 constraintList_free(dst->ensuresConstraints);
520 constraintList_free(dst->requiresConstraints);
521 constraintList_free(dst->trueEnsuresConstraints);
522 constraintList_free(dst->falseEnsuresConstraints);
524 dst->ensuresConstraints = constraintList_copy (src->ensuresConstraints );
525 dst->requiresConstraints = constraintList_copy (src->requiresConstraints );
526 dst->trueEnsuresConstraints = constraintList_copy (src->trueEnsuresConstraints );
527 dst->falseEnsuresConstraints = constraintList_copy (src->falseEnsuresConstraints );
531 /* Makes the constraint e = e + f */
532 constraint constraint_makeAddAssign (exprNode e, exprNode f, fileloc sequencePoint)
534 constraintExpr x1, x2, y;
537 ret = constraint_makeNew();
539 x1 = constraintExpr_makeValueExpr (e);
540 x2 = constraintExpr_copy(x1);
541 y = constraintExpr_makeValueExpr (f);
546 ret->expr = constraintExpr_makeAddExpr (x2, y);
548 ret->lexpr = constraintExpr_setFileloc (ret->lexpr, sequencePoint);
554 /* Makes the constraint e = e - f */
555 constraint constraint_makeSubtractAssign (exprNode e, exprNode f, fileloc sequencePoint)
557 constraintExpr x1, x2, y;
560 ret = constraint_makeNew();
562 x1 = constraintExpr_makeValueExpr (e);
563 x2 = constraintExpr_copy(x1);
564 y = constraintExpr_makeValueExpr (f);
569 ret->expr = constraintExpr_makeSubtractExpr (x2, y);
571 ret->lexpr = constraintExpr_setFileloc (ret->lexpr, sequencePoint);
576 constraint constraint_makeMaxSetSideEffectPostDecrement (exprNode e, fileloc sequencePoint)
578 constraint ret = constraint_makeNew();
579 //constraintTerm term;
581 e = exprNode_fakeCopy(e);
582 ret->lexpr = constraintExpr_makeValueExpr (e);
585 ret->expr = constraintExpr_makeValueExpr (e);
586 ret->expr = constraintExpr_makeDecConstraintExpr (ret->expr);
588 ret->lexpr = constraintExpr_setFileloc (ret->lexpr, sequencePoint);
589 // fileloc_incColumn ( ret->lexpr->term->loc);
590 // fileloc_incColumn ( ret->lexpr->term->loc);
593 constraint constraint_makeMaxSetSideEffectPostIncrement (exprNode e, fileloc sequencePoint)
595 constraint ret = constraint_makeNew();
596 //constraintTerm term;
598 e = exprNode_fakeCopy(e);
599 ret->lexpr = constraintExpr_makeValueExpr (e);
602 ret->expr = constraintExpr_makeValueExpr (e);
603 ret->expr = constraintExpr_makeIncConstraintExpr (ret->expr);
605 ret->lexpr = constraintExpr_setFileloc (ret->lexpr, sequencePoint);
606 // fileloc_incColumn ( ret->lexpr->term->loc);
607 // fileloc_incColumn ( ret->lexpr->term->loc);
612 void constraint_free (/*@only@*/ /*@notnull@*/ constraint c)
614 llassert(constraint_isDefined (c) );
617 if (constraint_isDefined(c->orig) )
618 constraint_free (c->orig);
619 if ( constraint_isDefined(c->or) )
620 constraint_free (c->or);
623 constraintExpr_free(c->lexpr);
624 constraintExpr_free(c->expr);
636 // constraint constraint_makeMaxReadSideEffectPostIncrement (exprNode e, fileloc sequencePoint)
638 // constraint ret = constraint_makeNew();
639 // //constraintTerm term;
641 // e = exprNode_fakeCopy(e);
642 // ret->lexpr = constraintExpr_makeMaxReadExpr(e);
645 // ret->expr = constraintExpr_makeIncConstraintExpr (e);
646 // ret->lexpr = constraintExpr_setFileLoc (ret->lexpr, sequencePoint);
651 cstring arithType_print (arithType ar) /*@*/
653 cstring st = cstring_undefined;
657 st = cstring_makeLiteral (" < ");
660 st = cstring_makeLiteral (" <= ");
663 st = cstring_makeLiteral (" > ");
666 st = cstring_makeLiteral (" >= ");
669 st = cstring_makeLiteral (" == ");
672 st = cstring_makeLiteral (" NONNEGATIVE ");
675 st = cstring_makeLiteral (" POSITIVE ");
684 void constraint_printErrorPostCondition (constraint c, fileloc loc)
687 fileloc errorLoc, temp;
689 string = constraint_printDetailedPostCondition (c);
695 temp = constraint_getFileloc(c);
697 if (fileloc_isDefined(temp) )
700 voptgenerror ( FLG_CHECKPOST, string, errorLoc);
705 voptgenerror ( FLG_CHECKPOST, string, errorLoc);
712 void constraint_printError (constraint c, fileloc loc)
715 fileloc errorLoc, temp;
717 string = constraint_printDetailed (c);
723 temp = constraint_getFileloc(c);
725 if (fileloc_isDefined(temp) )
731 voptgenerror (FLG_FUNCTIONPOST, string, errorLoc);
735 voptgenerror (FLG_FUNCTIONCONSTRAINT, string, errorLoc);
743 voptgenerror (FLG_FUNCTIONPOST, string, errorLoc);
747 voptgenerror (FLG_FUNCTIONCONSTRAINT, string, errorLoc);
753 cstring constraint_printDeep (constraint c)
755 cstring st = cstring_undefined;
757 st = constraint_print(c);
759 if (c->orig != constraint_undefined)
764 st = cstring_concatFree(st, (message(" derived from %s precondition: %q", exprNode_unparse(c->orig->generatingExpr), constraint_printDeep(c->orig) )
767 st = cstring_concatFree(st,(message(" needed to satisfy %q",
768 constraint_printDeep(c->orig) )
774 st = cstring_concatFree(st,(message("derived from: %q",
775 constraint_printDeep(c->orig) )
785 static /*@only@*/ cstring constraint_printDetailedPostCondition (/*@observer@*/ /*@temp@*/ constraint c)
787 cstring st = cstring_undefined;
789 st = message ("Unsatisfied ensures constraint condition:\nLCLint is unable to verify the constraint %q", constraint_printDeep (c) );
791 if (context_getFlag (FLG_CONSTRAINTLOCATION) )
794 // llassert (c->generatingExpr);
795 temp = message ("\nOriginal Generating expression %q: %s\n", fileloc_unparse( exprNode_getfileloc (c->generatingExpr) ),
796 exprNode_unparse(c->generatingExpr) );
797 st = cstring_concatFree (st, temp);
799 if (constraint_hasMaxSet(c) )
801 temp = message ("Has MaxSet\n");
802 st = cstring_concatFree (st, temp);
808 cstring constraint_printDetailed (constraint c)
810 cstring st = cstring_undefined;
814 st = message ("Unresolved constraint:\nLclint is unable to resolve %q", constraint_printDeep (c) );
818 st = message ("Block Post condition:\nThis function block has the post condition %q", constraint_printDeep (c) );
821 if (context_getFlag (FLG_CONSTRAINTLOCATION) )
824 // llassert (c->generatingExpr);
825 temp = message ("\nOriginal Generating expression %q: %s\n", fileloc_unparse( exprNode_getfileloc (c->generatingExpr) ),
826 exprNode_unparse(c->generatingExpr) );
827 st = cstring_concatFree (st, temp);
829 if (constraint_hasMaxSet(c) )
831 temp = message ("Has MaxSet\n");
832 st = cstring_concatFree (st, temp);
838 /*@only@*/ cstring constraint_print (constraint c) /*@*/
840 cstring st = cstring_undefined;
841 cstring type = cstring_undefined;
845 type = cstring_makeLiteral ("Ensures: ");
849 type = cstring_makeLiteral ("Requires: ");
851 st = message ("%q: %q %q %q",
853 constraintExpr_print (c->lexpr),
854 arithType_print(c->ar),
855 constraintExpr_print(c->expr)
860 cstring constraint_printOr (constraint c) /*@*/
865 ret = cstring_undefined;
868 ret = cstring_concatFree (ret, constraint_print(temp) );
872 while ( constraint_isDefined(temp) )
874 ret = cstring_concatFree (ret, cstring_makeLiteral (" OR ") );
875 ret = cstring_concatFree (ret, constraint_print(temp) );
883 /*@only@*/ constraint constraint_doSRefFixBaseParam (/*@returned@*/ /*@only@*/ constraint precondition,
884 exprNodeList arglist)
886 precondition->lexpr = constraintExpr_doSRefFixBaseParam (precondition->lexpr,
888 precondition->expr = constraintExpr_doSRefFixBaseParam (precondition->expr,
895 constraint constraint_doFixResult (constraint postcondition, exprNode fcnCall)
897 postcondition = constraint_copy (postcondition);
898 postcondition->lexpr = constraintExpr_doFixResult (postcondition->lexpr, fcnCall);
899 postcondition->expr = constraintExpr_doFixResult (postcondition->expr, fcnCall);
901 return postcondition;
904 /*@only@*/ constraint constraint_doSRefFixConstraintParam (constraint precondition,
905 exprNodeList arglist)
908 precondition = constraint_copy (precondition);
909 precondition->lexpr = constraintExpr_doSRefFixConstraintParam (precondition->lexpr, arglist);
910 precondition->expr = constraintExpr_doSRefFixConstraintParam (precondition->expr, arglist);
912 precondition->fcnPre = FALSE;
916 // bool constraint_hasTerm (constraint c, constraintTerm term)
918 // DPRINTF((message ("Constraint %s", constraint_print (c) ) ) );
920 // if (constraintExpr_includesTerm (c->lexpr, term) )
923 // if (constraintExpr_includesTerm (c->expr, term) )
929 constraint constraint_preserveOrig (/*@returned@*/ constraint c) /*@modifies c @*/
932 DPRINTF( (message("Doing constraint_preserverOrig for %q ", constraint_printDetailed(c) ) ));
934 if (c->orig == constraint_undefined)
935 c->orig = constraint_copy (c);
937 else if (c->orig->fcnPre)
943 /* avoid infinite loop */
945 c->orig = constraint_copy (c);
946 if (c->orig->orig == NULL)
947 c->orig->orig = temp;
949 llcontbug((message("Expected c->orig->orig to be null" ) ));
953 DPRINTF( (message("Not changing constraint") ));
956 DPRINTF( (message("After Doing constraint_preserverOrig for %q ", constraint_printDetailed(c) ) ));
965 constraint constraint_togglePost (/*@returned@*/ constraint c)
971 constraint constraint_togglePostOrig (/*@returned@*/ constraint c)
974 c->orig = constraint_togglePost(c->orig);
978 bool constraint_hasOrig( /*@observer@*/ /*@temp@*/ constraint c)