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) ) ) ); */
68 advanceField (char **s)
75 constraint makeConstraintParse2 (constraintExpr l, lltok relOp, exprNode cconstant)
80 ret = constraint_makeNew();
83 ret->lexpr = constraintExpr_copy (l);
86 if (relOp.tok == GE_OP)
88 else if (relOp.tok == LE_OP)
90 else if (relOp.tok == EQ_OP)
93 llfatalbug(message("Unsupported relational operator") );
96 t = cstring_toCharsSafe (exprNode_unparse(cconstant));
98 ret->expr = constraintExpr_makeIntLiteral (c);
102 DPRINTF(("GENERATED CONSTRAINT:"));
103 DPRINTF( (message ("%s", constraint_print(ret) ) ) );
107 bool constraint_same (constraint c1, constraint c2)
110 if (c1->ar != c2->ar)
113 if (!constraintExpr_similar (c1->lexpr, c2->lexpr) )
116 if (!constraintExpr_similar (c1->expr, c2->expr) )
122 constraint makeConstraintParse3 (constraintExpr l, lltok relOp, constraintExpr r)
125 ret = constraint_makeNew();
128 ret->lexpr = constraintExpr_copy (l);
130 if (relOp.tok == GE_OP)
132 else if (relOp.tok == LE_OP)
134 else if (relOp.tok == EQ_OP)
137 llfatalbug( message("Unsupported relational operator") );
139 ret->expr = constraintExpr_copy (r);
143 ret->orig = constraint_copy(ret);
145 ret = constraint_simplify (ret);
148 DPRINTF(("GENERATED CONSTRAINT:"));
149 DPRINTF( (message ("%s", constraint_print(ret) ) ) );
153 constraint constraint_copy (constraint c)
157 llassert (constraint_isDefined(c) );
158 // TPRINTF((message("Copying constraint %q", constraint_print) ));
160 ret = constraint_makeNew();
161 ret->lexpr = constraintExpr_copy (c->lexpr);
163 ret->expr = constraintExpr_copy (c->expr);
165 ret->generatingExpr = exprNode_fakeCopy(c->generatingExpr);
169 ret->orig = constraint_copy (c->orig);
174 ret->or = constraint_copy (c->or);
178 ret->fcnPre = c->fcnPre;
183 /*like copy expect it doesn't allocate memory for the constraint*/
185 void constraint_overWrite (constraint c1, constraint c2)
187 llassert (constraint_isDefined(c1) );
191 DPRINTF((message("OverWriteing constraint %q with %q", constraint_print(c1),
192 constraint_print(c2) ) ));
194 constraintExpr_free(c1->lexpr);
195 constraintExpr_free(c1->expr);
197 c1->lexpr = constraintExpr_copy (c2->lexpr);
199 c1->expr = constraintExpr_copy (c2->expr);
202 if (c1->orig != NULL)
203 constraint_free (c1->orig);
205 if (c2->orig != NULL)
206 c1->orig = constraint_copy (c2->orig);
210 /*@i33 make sure that the or is freed correctly*/
212 constraint_free (c1->or);
215 c1->or = constraint_copy (c2->or);
219 c1->fcnPre = c2->fcnPre;
221 c1->generatingExpr = c2->generatingExpr;
226 static /*@notnull@*/ /*@special@*/ constraint constraint_makeNew (void)
227 /*@post:isnull result->or, result->orig, result->generatingExpr, result->fcnPre @*/ /*@defines result->or, result->generatingExpr, result->orig, result->fcnPre @*/
230 ret = dmalloc(sizeof (*ret) );
237 ret->generatingExpr = NULL;
242 constraint constraint_addGeneratingExpr (/*@returned@*/ constraint c, exprNode e)
245 if (c->generatingExpr == NULL)
247 c->generatingExpr = exprNode_fakeCopy(e);
248 DPRINTF ((message ("setting generatingExpr for %s to %s", constraint_print(c), exprNode_unparse(e) ) ));
252 DPRINTF ((message ("Not setting generatingExpr for %s to %s", constraint_print(c), exprNode_unparse(e) ) ));
257 constraint constraint_origAddGeneratingExpr (/*@returned@*/ constraint c, exprNode e)
260 if (c->orig != constraint_undefined)
262 c->orig = constraint_addGeneratingExpr(c->orig, e);
266 DPRINTF ((message ("constraint_origAddGeneratingExpr: Not setting generatingExpr for %s to %s", constraint_print(c), exprNode_unparse(e) ) ));
271 constraint constraint_setFcnPre (/*@returned@*/ constraint c )
274 if (c->orig != constraint_undefined)
276 c->orig->fcnPre = TRUE;
281 // TPRINTF(( message("Warning Setting fcnPre directly") ));
289 fileloc constraint_getFileloc (constraint c)
291 if (exprNode_isDefined(c->generatingExpr) )
292 return (fileloc_copy (exprNode_getfileloc (c->generatingExpr) ) );
294 return (constraintExpr_getFileloc (c->lexpr) );
299 static bool checkForMaxSet (constraint c)
301 if (constraintExpr_hasMaxSet(c->lexpr) || constraintExpr_hasMaxSet(c->expr) )
307 bool constraint_hasMaxSet(constraint c)
311 if (checkForMaxSet(c->orig) )
315 return (checkForMaxSet(c) );
318 constraint constraint_makeReadSafeExprNode ( exprNode po, exprNode ind)
320 constraint ret = constraint_makeNew();
321 // constraintTerm term;
322 po = exprNode_fakeCopy(po);
323 ind = exprNode_fakeCopy(ind);
324 ret->lexpr = constraintExpr_makeMaxReadExpr(po);
326 ret->expr = constraintExpr_makeValueExpr (ind);
331 constraint constraint_makeWriteSafeInt (exprNode po, int ind)
333 constraint ret = constraint_makeNew();
336 ret->lexpr =constraintExpr_makeMaxSetExpr(po);
338 ret->expr = constraintExpr_makeIntLiteral (ind);
342 constraint constraint_makeSRefSetBufferSize (sRef s, long int size)
344 constraint ret = constraint_makeNew();
345 ret->lexpr = constraintExpr_makeSRefMaxset (s);
347 ret->expr = constraintExpr_makeIntLiteral ((int)size);
352 constraint constraint_makeSRefWriteSafeInt (sRef s, int ind)
354 constraint ret = constraint_makeNew();
357 ret->lexpr = constraintExpr_makeSRefMaxset ( s );
359 ret->expr = constraintExpr_makeIntLiteral (ind);
364 /* drl added 01/12/2000
366 makes the constraint: Ensures index <= MaxRead(buffer) */
368 constraint constraint_makeEnsureLteMaxRead(exprNode index, exprNode buffer)
370 constraint ret = constraint_makeNew();
372 ret->lexpr = constraintExpr_makeValueExpr (index);
374 ret->expr = constraintExpr_makeMaxReadExpr(buffer);
379 constraint constraint_makeWriteSafeExprNode (exprNode po, exprNode ind)
381 constraint ret = constraint_makeNew();
384 ret->lexpr =constraintExpr_makeMaxSetExpr(po);
386 ret->expr = constraintExpr_makeValueExpr (ind);
391 constraint constraint_makeReadSafeInt ( exprNode po, int ind)
393 constraint ret = constraint_makeNew();
395 po = exprNode_fakeCopy(po);
397 ret->lexpr = constraintExpr_makeMaxReadExpr(po);
399 ret->expr = constraintExpr_makeIntLiteral (ind);
404 constraint constraint_makeSRefReadSafeInt (sRef s, int ind)
406 constraint ret = constraint_makeNew();
409 ret->lexpr = constraintExpr_makeSRefMaxRead (s );
411 ret->expr = constraintExpr_makeIntLiteral (ind);
416 constraint constraint_makeEnsureMaxReadAtLeast (exprNode e1, exprNode t2, fileloc sequencePoint)
420 e1 = exprNode_fakeCopy (e1);
421 t2 = exprNode_fakeCopy (t2);
423 ret = constraint_makeReadSafeExprNode(e1, t2);
425 ret->lexpr = constraintExpr_setFileloc (ret->lexpr, sequencePoint);
429 // fileloc_incColumn (ret->lexpr->term->loc);
433 static constraint constraint_makeEnsuresOpConstraintExpr (/*@only@*/ constraintExpr c1, /*@only@*/ constraintExpr c2, fileloc sequencePoint, arithType ar)
439 // llassert(sequencePoint);
441 ret = constraint_makeNew();
447 ret->lexpr = constraintExpr_setFileloc (ret->lexpr, sequencePoint);
451 static constraint constraint_makeEnsuresOp (exprNode e1, exprNode e2, fileloc sequencePoint, arithType ar)
453 constraintExpr c1, c2;
459 llcontbug((message("null exprNode, Exprnodes are %s and %s",
460 exprNode_unparse(e1), exprNode_unparse(e2) )
464 // llassert (sequencePoint);
466 e = exprNode_fakeCopy(e1);
467 c1 = constraintExpr_makeValueExpr (e);
469 e = exprNode_fakeCopy(e2);
470 c2 = constraintExpr_makeValueExpr (e);
472 ret = constraint_makeEnsuresOpConstraintExpr (c1, c2, sequencePoint, ar);
478 /* make constraint ensures e1 == e2 */
480 constraint constraint_makeEnsureEqual (exprNode e1, exprNode e2, fileloc sequencePoint)
482 return ( constraint_makeEnsuresOp (e1, e2, sequencePoint, EQ) );
485 /*make constraint ensures e1 < e2 */
486 constraint constraint_makeEnsureLessThan (exprNode e1, exprNode e2, fileloc sequencePoint)
488 constraintExpr t1, t2;
490 t1 = constraintExpr_makeValueExpr (e1);
491 t2 = constraintExpr_makeValueExpr (e2);
493 /*change this to e1 <= (e2 -1) */
495 t2 = constraintExpr_makeDecConstraintExpr (t2);
497 return ( constraint_makeEnsuresOpConstraintExpr (t1, t2, sequencePoint, LTE) );
500 constraint constraint_makeEnsureLessThanEqual (exprNode e1, exprNode e2, fileloc sequencePoint)
502 return ( constraint_makeEnsuresOp (e1, e2, sequencePoint, LTE) );
505 constraint constraint_makeEnsureGreaterThan (exprNode e1, exprNode e2, fileloc sequencePoint)
507 constraintExpr t1, t2;
509 t1 = constraintExpr_makeValueExpr (e1);
510 t2 = constraintExpr_makeValueExpr (e2);
513 /* change this to e1 >= (e2 + 1) */
514 t2 = constraintExpr_makeIncConstraintExpr (t2);
517 return ( constraint_makeEnsuresOpConstraintExpr (t1, t2, sequencePoint, GTE) );
520 constraint constraint_makeEnsureGreaterThanEqual (exprNode e1, exprNode e2, fileloc sequencePoint)
522 return ( constraint_makeEnsuresOp (e1, e2, sequencePoint, GTE) );
526 exprNode exprNode_copyConstraints (/*@returned@*/ exprNode dst, exprNode src)
528 constraintList_free(dst->ensuresConstraints);
529 constraintList_free(dst->requiresConstraints);
530 constraintList_free(dst->trueEnsuresConstraints);
531 constraintList_free(dst->falseEnsuresConstraints);
533 dst->ensuresConstraints = constraintList_copy (src->ensuresConstraints );
534 dst->requiresConstraints = constraintList_copy (src->requiresConstraints );
535 dst->trueEnsuresConstraints = constraintList_copy (src->trueEnsuresConstraints );
536 dst->falseEnsuresConstraints = constraintList_copy (src->falseEnsuresConstraints );
540 /* Makes the constraint e = e + f */
541 constraint constraint_makeAddAssign (exprNode e, exprNode f, fileloc sequencePoint)
543 constraintExpr x1, x2, y;
546 ret = constraint_makeNew();
548 x1 = constraintExpr_makeValueExpr (e);
549 x2 = constraintExpr_copy(x1);
550 y = constraintExpr_makeValueExpr (f);
555 ret->expr = constraintExpr_makeAddExpr (x2, y);
557 ret->lexpr = constraintExpr_setFileloc (ret->lexpr, sequencePoint);
563 /* Makes the constraint e = e - f */
564 constraint constraint_makeSubtractAssign (exprNode e, exprNode f, fileloc sequencePoint)
566 constraintExpr x1, x2, y;
569 ret = constraint_makeNew();
571 x1 = constraintExpr_makeValueExpr (e);
572 x2 = constraintExpr_copy(x1);
573 y = constraintExpr_makeValueExpr (f);
578 ret->expr = constraintExpr_makeSubtractExpr (x2, y);
580 ret->lexpr = constraintExpr_setFileloc (ret->lexpr, sequencePoint);
585 constraint constraint_makeMaxSetSideEffectPostDecrement (exprNode e, fileloc sequencePoint)
587 constraint ret = constraint_makeNew();
588 //constraintTerm term;
590 e = exprNode_fakeCopy(e);
591 ret->lexpr = constraintExpr_makeValueExpr (e);
594 ret->expr = constraintExpr_makeValueExpr (e);
595 ret->expr = constraintExpr_makeDecConstraintExpr (ret->expr);
597 ret->lexpr = constraintExpr_setFileloc (ret->lexpr, sequencePoint);
598 // fileloc_incColumn ( ret->lexpr->term->loc);
599 // fileloc_incColumn ( ret->lexpr->term->loc);
602 constraint constraint_makeMaxSetSideEffectPostIncrement (exprNode e, fileloc sequencePoint)
604 constraint ret = constraint_makeNew();
605 //constraintTerm term;
607 e = exprNode_fakeCopy(e);
608 ret->lexpr = constraintExpr_makeValueExpr (e);
611 ret->expr = constraintExpr_makeValueExpr (e);
612 ret->expr = constraintExpr_makeIncConstraintExpr (ret->expr);
614 ret->lexpr = constraintExpr_setFileloc (ret->lexpr, sequencePoint);
615 // fileloc_incColumn ( ret->lexpr->term->loc);
616 // fileloc_incColumn ( ret->lexpr->term->loc);
621 void constraint_free (/*@only@*/ constraint c)
623 llassert(constraint_isDefined (c) );
626 if (constraint_isDefined(c->orig) )
627 constraint_free (c->orig);
628 if ( constraint_isDefined(c->or) )
629 constraint_free (c->or);
632 constraintExpr_free(c->lexpr);
633 constraintExpr_free(c->expr);
645 // constraint constraint_makeMaxReadSideEffectPostIncrement (exprNode e, fileloc sequencePoint)
647 // constraint ret = constraint_makeNew();
648 // //constraintTerm term;
650 // e = exprNode_fakeCopy(e);
651 // ret->lexpr = constraintExpr_makeMaxReadExpr(e);
654 // ret->expr = constraintExpr_makeIncConstraintExpr (e);
655 // ret->lexpr = constraintExpr_setFileLoc (ret->lexpr, sequencePoint);
660 cstring arithType_print (arithType ar) /*@*/
662 cstring st = cstring_undefined;
666 st = cstring_makeLiteral (" < ");
669 st = cstring_makeLiteral (" <= ");
672 st = cstring_makeLiteral (" > ");
675 st = cstring_makeLiteral (" >= ");
678 st = cstring_makeLiteral (" == ");
681 st = cstring_makeLiteral (" NONNEGATIVE ");
684 st = cstring_makeLiteral (" POSITIVE ");
693 void constraint_printErrorPostCondition (constraint c, fileloc loc)
696 fileloc errorLoc, temp;
698 string = constraint_printDetailedPostCondition (c);
704 temp = constraint_getFileloc(c);
706 if (fileloc_isDefined(temp) )
709 voptgenerror ( FLG_CHECKPOST, string, errorLoc);
714 voptgenerror ( FLG_CHECKPOST, string, errorLoc);
721 void constraint_printError (constraint c, fileloc loc)
724 fileloc errorLoc, temp;
726 string = constraint_printDetailed (c);
732 temp = constraint_getFileloc(c);
734 if (fileloc_isDefined(temp) )
740 voptgenerror (FLG_FUNCTIONPOST, string, errorLoc);
744 voptgenerror (FLG_FUNCTIONCONSTRAINT, string, errorLoc);
752 voptgenerror (FLG_FUNCTIONPOST, string, errorLoc);
756 voptgenerror (FLG_FUNCTIONCONSTRAINT, string, errorLoc);
762 cstring constraint_printDeep (constraint c)
764 cstring st = cstring_undefined;
766 st = constraint_print(c);
768 if (c->orig != constraint_undefined)
773 st = cstring_concatFree(st, (message(" derived from %s precondition: %q", exprNode_unparse(c->orig->generatingExpr), constraint_printDeep(c->orig) )
776 st = cstring_concatFree(st,(message(" needed to satisfy %q",
777 constraint_printDeep(c->orig) )
783 st = cstring_concatFree(st,(message("derived from: %q",
784 constraint_printDeep(c->orig) )
794 static /*@only@*/ cstring constraint_printDetailedPostCondition (/*@observer@*/ /*@temp@*/ constraint c)
796 cstring st = cstring_undefined;
798 st = message ("Unsatisfied ensures constraint condition:\nLCLint is unable to verify the constraint %q", constraint_printDeep (c) );
800 if (context_getFlag (FLG_CONSTRAINTLOCATION) )
803 // llassert (c->generatingExpr);
804 temp = message ("\nOriginal Generating expression %q: %s\n", fileloc_unparse( exprNode_getfileloc (c->generatingExpr) ),
805 exprNode_unparse(c->generatingExpr) );
806 st = cstring_concatFree (st, temp);
808 if (constraint_hasMaxSet(c) )
810 temp = message ("Has MaxSet\n");
811 st = cstring_concatFree (st, temp);
817 cstring constraint_printDetailed (constraint c)
819 cstring st = cstring_undefined;
823 st = message ("Unresolved constraint:\nLclint is unable to resolve %q", constraint_printDeep (c) );
827 st = message ("Block Post condition:\nThis function block has the post condition %q", constraint_printDeep (c) );
830 if (context_getFlag (FLG_CONSTRAINTLOCATION) )
833 // llassert (c->generatingExpr);
834 temp = message ("\nOriginal Generating expression %q: %s\n", fileloc_unparse( exprNode_getfileloc (c->generatingExpr) ),
835 exprNode_unparse(c->generatingExpr) );
836 st = cstring_concatFree (st, temp);
838 if (constraint_hasMaxSet(c) )
840 temp = message ("Has MaxSet\n");
841 st = cstring_concatFree (st, temp);
847 /*@only@*/ cstring constraint_print (constraint c) /*@*/
849 cstring st = cstring_undefined;
850 cstring type = cstring_undefined;
854 type = cstring_makeLiteral ("Ensures: ");
858 type = cstring_makeLiteral ("Requires: ");
860 st = message ("%q: %q %q %q",
862 constraintExpr_print (c->lexpr),
863 arithType_print(c->ar),
864 constraintExpr_print(c->expr)
869 cstring constraint_printOr (constraint c) /*@*/
874 ret = cstring_undefined;
877 ret = cstring_concatFree (ret, constraint_print(temp) );
881 while ( constraint_isDefined(temp) )
883 ret = cstring_concatFree (ret, cstring_makeLiteral (" OR ") );
884 ret = cstring_concatFree (ret, constraint_print(temp) );
892 /*@only@*/ constraint constraint_doSRefFixBaseParam (/*@returned@*/ /*@only@*/ constraint precondition,
893 exprNodeList arglist)
895 precondition->lexpr = constraintExpr_doSRefFixBaseParam (precondition->lexpr,
897 precondition->expr = constraintExpr_doSRefFixBaseParam (precondition->expr,
904 constraint constraint_doFixResult (constraint postcondition, exprNode fcnCall)
906 postcondition = constraint_copy (postcondition);
907 postcondition->lexpr = constraintExpr_doFixResult (postcondition->lexpr, fcnCall);
908 postcondition->expr = constraintExpr_doFixResult (postcondition->expr, fcnCall);
910 return postcondition;
913 /*@only@*/ constraint constraint_doSRefFixConstraintParam (constraint precondition,
914 exprNodeList arglist)
917 precondition = constraint_copy (precondition);
918 precondition->lexpr = constraintExpr_doSRefFixConstraintParam (precondition->lexpr, arglist);
919 precondition->expr = constraintExpr_doSRefFixConstraintParam (precondition->expr, arglist);
921 precondition->fcnPre = FALSE;
925 // bool constraint_hasTerm (constraint c, constraintTerm term)
927 // DPRINTF((message ("Constraint %s", constraint_print (c) ) ) );
929 // if (constraintExpr_includesTerm (c->lexpr, term) )
932 // if (constraintExpr_includesTerm (c->expr, term) )
938 constraint constraint_preserveOrig (/*@returned@*/ constraint c) /*@modifies c @*/
941 DPRINTF( (message("Doing constraint_preserverOrig for %q ", constraint_printDetailed(c) ) ));
943 if (c->orig == constraint_undefined)
944 c->orig = constraint_copy (c);
946 else if (c->orig->fcnPre)
952 /* avoid infinite loop */
954 c->orig = constraint_copy (c);
955 if (c->orig->orig == NULL)
957 c->orig->orig = temp;
962 llcontbug((message("Expected c->orig->orig to be null" ) ));
963 constraint_free(c->orig->orig);
964 c->orig->orig = temp;
970 DPRINTF( (message("Not changing constraint") ));
973 DPRINTF( (message("After Doing constraint_preserverOrig for %q ", constraint_printDetailed(c) ) ));
982 constraint constraint_togglePost (/*@returned@*/ constraint c)
988 constraint constraint_togglePostOrig (/*@returned@*/ constraint c)
991 c->orig = constraint_togglePost(c->orig);
995 bool constraint_hasOrig( /*@observer@*/ /*@temp@*/ constraint c)
1004 constraint constraint_undump (FILE *f)
1011 constraintExpr lexpr;
1012 constraintExpr expr;
1013 // /*@kept@*/ exprNode generatingExpr;
1019 s = mstring_create (MAX_DUMP_LINE_LENGTH);
1023 s = fgets(os, MAX_DUMP_LINE_LENGTH, f);
1025 /*@i33*/ /*this should probably be wrappered...*/
1027 fcnPre = (bool) getInt (&s);
1029 post = (bool) getInt (&s);
1031 ar = (arithType) getInt (&s);
1033 s = fgets(os, MAX_DUMP_LINE_LENGTH, f);
1035 checkChar (&s, 'l');
1037 lexpr = constraintExpr_undump (f);
1039 s = fgets(os, MAX_DUMP_LINE_LENGTH, f);
1041 checkChar (&s, 'r');
1042 expr = constraintExpr_undump (f);
1044 c = constraint_makeNew();
1058 void constraint_dump (/*@observer@*/ constraint c, FILE *f)
1064 constraintExpr lexpr;
1065 constraintExpr expr;
1066 // /*@kept@*/ exprNode generatingExpr;
1074 fprintf(f, "%d@%d@%d\n", (int) fcnPre, (int) post, (int) ar);
1076 constraintExpr_dump (lexpr, f);
1078 constraintExpr_dump (expr, f);