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 @*/
24 static /*@notnull@*/ /*@special@*/ constraint constraint_makeNew (void)
25 /*@post:isnull result->or, result->orig, result->generatingExpr @*/ /*@defines result->or, result->generatingExpr, result->orig @*/;
27 /* constraint makeConstraintParse (sRef x, lltok relOp, exprNode cconstant) */
33 /* ret = constraint_makeNew(); */
34 /* llassert (sRef_isValid(x) ); */
35 /* if (!sRef_isValid(x)) */
39 /* ret->lexpr = constraintExpr_makeTermsRef (x); */
40 /* #warning fix abstraction */
42 /* if (relOp.tok == GE_OP) */
44 /* else if (relOp.tok == LE_OP) */
46 /* else if (relOp.tok == EQ_OP) */
49 /* llfatalbug(message ("Unsupported relational operator") ); */
52 /* t = cstring_toCharsSafe (exprNode_unparse(cconstant)); */
54 /* ret->expr = constraintExpr_makeIntLiteral (c); */
56 /* ret->post = TRUE; */
57 /* // ret->orig = ret; */
58 /* DPRINTF(("GENERATED CONSTRAINT:")); */
59 /* DPRINTF( (message ("%s", constraint_print(ret) ) ) ); */
63 constraint makeConstraintParse2 (constraintExpr l, lltok relOp, exprNode cconstant)
68 ret = constraint_makeNew();
71 ret->lexpr = constraintExpr_copy (l);
72 #warning fix abstraction
74 if (relOp.tok == GE_OP)
76 else if (relOp.tok == LE_OP)
78 else if (relOp.tok == EQ_OP)
81 llfatalbug(message("Unsupported relational operator") );
84 t = cstring_toCharsSafe (exprNode_unparse(cconstant));
86 ret->expr = constraintExpr_makeIntLiteral (c);
90 DPRINTF(("GENERATED CONSTRAINT:"));
91 DPRINTF( (message ("%s", constraint_print(ret) ) ) );
95 bool constraint_same (constraint c1, constraint c2)
101 if (!constraintExpr_similar (c1->lexpr, c2->lexpr) )
104 if (!constraintExpr_similar (c1->expr, c2->expr) )
110 constraint makeConstraintParse3 (constraintExpr l, lltok relOp, constraintExpr r)
113 ret = constraint_makeNew();
116 ret->lexpr = constraintExpr_copy (l);
117 #warning fix abstraction
119 if (relOp.tok == GE_OP)
121 else if (relOp.tok == LE_OP)
123 else if (relOp.tok == EQ_OP)
126 llfatalbug( message("Unsupported relational operator") );
128 ret->expr = constraintExpr_copy (r);
132 ret->orig = constraint_copy(ret);
134 ret = constraint_simplify (ret);
137 DPRINTF(("GENERATED CONSTRAINT:"));
138 DPRINTF( (message ("%s", constraint_print(ret) ) ) );
142 constraint constraint_copy (constraint c)
146 llassert (constraint_isDefined(c) );
147 // TPRINTF((message("Copying constraint %q", constraint_print) ));
149 ret = constraint_makeNew();
150 ret->lexpr = constraintExpr_copy (c->lexpr);
152 ret->expr = constraintExpr_copy (c->expr);
154 ret->generatingExpr = exprNode_fakeCopy(c->generatingExpr);
158 ret->orig = constraint_copy (c->orig);
163 ret->or = constraint_copy (c->or);
170 /*like copy expect it doesn't allocate memory for the constraint*/
172 void constraint_overWrite (constraint c1, constraint c2)
174 llassert (constraint_isDefined(c1) );
178 DPRINTF((message("OverWriteing constraint %q with %q", constraint_print(c1),
179 constraint_print(c2) ) ));
181 constraintExpr_free(c1->lexpr);
182 constraintExpr_free(c1->expr);
184 c1->lexpr = constraintExpr_copy (c2->lexpr);
186 c1->expr = constraintExpr_copy (c2->expr);
189 if (c1->orig != NULL)
190 constraint_free (c1->orig);
192 if (c2->orig != NULL)
193 c1->orig = constraint_copy (c2->orig);
197 /*@i33 make sure that the or is freed correctly*/
199 constraint_free (c1->or);
202 c1->or = constraint_copy (c2->or);
206 c1->generatingExpr = exprNode_fakeCopy (c2->generatingExpr );
211 static /*@notnull@*/ /*@special@*/ constraint constraint_makeNew (void)
212 /*@post:isnull result->or, result->orig, result->generatingExpr @*/ /*@defines result->or, result->generatingExpr, result->orig @*/
215 ret = dmalloc(sizeof (*ret) );
222 ret->generatingExpr = NULL;
226 constraint constraint_addGeneratingExpr (/*@returned@*/ constraint c, exprNode e)
229 if (c->generatingExpr == NULL)
231 c->generatingExpr = exprNode_fakeCopy(e);
232 DPRINTF ((message ("setting generatingExpr for %s to %s", constraint_print(c), exprNode_unparse(e) ) ));
236 DPRINTF ((message ("Not setting generatingExpr for %s to %s", constraint_print(c), exprNode_unparse(e) ) ));
241 fileloc constraint_getFileloc (constraint c)
243 if (exprNode_isDefined(c->generatingExpr) )
244 return (fileloc_copy (exprNode_getfileloc (c->generatingExpr) ) );
246 return (constraintExpr_getFileloc (c->lexpr) );
251 static bool checkForMaxSet (constraint c)
253 if (constraintExpr_hasMaxSet(c->lexpr) || constraintExpr_hasMaxSet(c->expr) )
259 bool constraint_hasMaxSet(constraint c)
263 if (checkForMaxSet(c->orig) )
267 return (checkForMaxSet(c) );
270 constraint constraint_makeReadSafeExprNode ( exprNode po, exprNode ind)
272 constraint ret = constraint_makeNew();
273 // constraintTerm term;
274 po = exprNode_fakeCopy(po);
275 ind = exprNode_fakeCopy(ind);
276 ret->lexpr = constraintExpr_makeMaxReadExpr(po);
278 ret->expr = constraintExpr_makeValueExpr (ind);
283 constraint constraint_makeWriteSafeInt (exprNode po, int ind)
285 constraint ret = constraint_makeNew();
288 ret->lexpr =constraintExpr_makeMaxSetExpr(po);
290 ret->expr = constraintExpr_makeIntLiteral (ind);
294 constraint constraint_makeSRefSetBufferSize (sRef s, long int size)
296 constraint ret = constraint_makeNew();
297 ret->lexpr = constraintExpr_makeSRefMaxset (sRef_saveCopy(s) );
299 ret->expr = constraintExpr_makeIntLiteral ((int)size);
304 constraint constraint_makeSRefWriteSafeInt (sRef s, int ind)
306 constraint ret = constraint_makeNew();
309 ret->lexpr = constraintExpr_makeSRefMaxset ( sRef_saveCopy(s) );
311 ret->expr = constraintExpr_makeIntLiteral (ind);
316 /* drl added 01/12/2000
318 makes the constraint: Ensures index <= MaxRead(buffer) */
320 constraint constraint_makeEnsureLteMaxRead(exprNode index, exprNode buffer)
322 constraint ret = constraint_makeNew();
324 ret->lexpr = constraintExpr_makeValueExpr (index);
326 ret->expr = constraintExpr_makeMaxReadExpr(buffer);
331 constraint constraint_makeWriteSafeExprNode (exprNode po, exprNode ind)
333 constraint ret = constraint_makeNew();
336 ret->lexpr =constraintExpr_makeMaxSetExpr(po);
338 ret->expr = constraintExpr_makeValueExpr (ind);
343 constraint constraint_makeReadSafeInt ( exprNode po, int ind)
345 constraint ret = constraint_makeNew();
347 po = exprNode_fakeCopy(po);
349 ret->lexpr = constraintExpr_makeMaxReadExpr(po);
351 ret->expr = constraintExpr_makeIntLiteral (ind);
356 constraint constraint_makeSRefReadSafeInt (sRef s, int ind)
358 constraint ret = constraint_makeNew();
361 ret->lexpr = constraintExpr_makeSRefMaxRead (sRef_saveCopy(s) );
363 ret->expr = constraintExpr_makeIntLiteral (ind);
368 constraint constraint_makeEnsureMaxReadAtLeast (exprNode e1, exprNode t2, fileloc sequencePoint)
372 e1 = exprNode_fakeCopy (e1);
373 t2 = exprNode_fakeCopy (t2);
375 ret = constraint_makeReadSafeExprNode(e1, t2);
377 ret->lexpr = constraintExpr_setFileloc (ret->lexpr, sequencePoint);
381 // fileloc_incColumn (ret->lexpr->term->loc);
385 static constraint constraint_makeEnsuresOpConstraintExpr (/*@only@*/ constraintExpr c1, /*@only@*/ constraintExpr c2, fileloc sequencePoint, arithType ar)
391 // llassert(sequencePoint);
393 ret = constraint_makeNew();
399 ret->lexpr = constraintExpr_setFileloc (ret->lexpr, sequencePoint);
403 static constraint constraint_makeEnsuresOp (exprNode e1, exprNode e2, fileloc sequencePoint, arithType ar)
405 constraintExpr c1, c2;
411 llcontbug((message("null exprNode, Exprnodes are %s and %s",
412 exprNode_unparse(e1), exprNode_unparse(e2) )
416 // llassert (sequencePoint);
418 e = exprNode_fakeCopy(e1);
419 c1 = constraintExpr_makeValueExpr (e);
421 e = exprNode_fakeCopy(e2);
422 c2 = constraintExpr_makeValueExpr (e);
424 ret = constraint_makeEnsuresOpConstraintExpr (c1, c2, sequencePoint, ar);
430 /* make constraint ensures e1 == e2 */
432 constraint constraint_makeEnsureEqual (exprNode e1, exprNode e2, fileloc sequencePoint)
434 return ( constraint_makeEnsuresOp (e1, e2, sequencePoint, EQ) );
437 /*make constraint ensures e1 < e2 */
438 constraint constraint_makeEnsureLessThan (exprNode e1, exprNode e2, fileloc sequencePoint)
440 constraintExpr t1, t2;
442 t1 = constraintExpr_makeValueExpr (e1);
443 t2 = constraintExpr_makeValueExpr (e2);
445 /*change this to e1 <= (e2 -1) */
447 t2 = constraintExpr_makeDecConstraintExpr (t2);
449 return ( constraint_makeEnsuresOpConstraintExpr (t1, t2, sequencePoint, LTE) );
452 constraint constraint_makeEnsureLessThanEqual (exprNode e1, exprNode e2, fileloc sequencePoint)
454 return ( constraint_makeEnsuresOp (e1, e2, sequencePoint, LTE) );
457 constraint constraint_makeEnsureGreaterThan (exprNode e1, exprNode e2, fileloc sequencePoint)
459 constraintExpr t1, t2;
461 t1 = constraintExpr_makeValueExpr (e1);
462 t2 = constraintExpr_makeValueExpr (e2);
465 /* change this to e1 >= (e2 + 1) */
466 t2 = constraintExpr_makeIncConstraintExpr (t2);
469 return ( constraint_makeEnsuresOpConstraintExpr (t1, t2, sequencePoint, GTE) );
472 constraint constraint_makeEnsureGreaterThanEqual (exprNode e1, exprNode e2, fileloc sequencePoint)
474 return ( constraint_makeEnsuresOp (e1, e2, sequencePoint, GTE) );
478 exprNode exprNode_copyConstraints (/*@returned@*/ exprNode dst, exprNode src)
480 constraintList_free(dst->ensuresConstraints);
481 constraintList_free(dst->requiresConstraints);
482 constraintList_free(dst->trueEnsuresConstraints);
483 constraintList_free(dst->falseEnsuresConstraints);
485 dst->ensuresConstraints = constraintList_copy (src->ensuresConstraints );
486 dst->requiresConstraints = constraintList_copy (src->requiresConstraints );
487 dst->trueEnsuresConstraints = constraintList_copy (src->trueEnsuresConstraints );
488 dst->falseEnsuresConstraints = constraintList_copy (src->falseEnsuresConstraints );
492 constraint constraint_makeMaxSetSideEffectPostDecrement (exprNode e, fileloc sequencePoint)
494 constraint ret = constraint_makeNew();
495 //constraintTerm term;
497 e = exprNode_fakeCopy(e);
498 ret->lexpr = constraintExpr_makeValueExpr (e);
501 ret->expr = constraintExpr_makeValueExpr (e);
502 ret->expr = constraintExpr_makeDecConstraintExpr (ret->expr);
504 ret->lexpr = constraintExpr_setFileloc (ret->lexpr, sequencePoint);
505 // fileloc_incColumn ( ret->lexpr->term->loc);
506 // fileloc_incColumn ( ret->lexpr->term->loc);
509 constraint constraint_makeMaxSetSideEffectPostIncrement (exprNode e, fileloc sequencePoint)
511 constraint ret = constraint_makeNew();
512 //constraintTerm term;
514 e = exprNode_fakeCopy(e);
515 ret->lexpr = constraintExpr_makeValueExpr (e);
518 ret->expr = constraintExpr_makeValueExpr (e);
519 ret->expr = constraintExpr_makeIncConstraintExpr (ret->expr);
521 ret->lexpr = constraintExpr_setFileloc (ret->lexpr, sequencePoint);
522 // fileloc_incColumn ( ret->lexpr->term->loc);
523 // fileloc_incColumn ( ret->lexpr->term->loc);
528 void constraint_free (/*@only@*/ /*@notnull@*/ constraint c)
530 llassert(constraint_isDefined (c) );
533 if (constraint_isDefined(c->orig) )
534 constraint_free (c->orig);
535 if ( constraint_isDefined(c->or) )
536 constraint_free (c->or);
539 constraintExpr_free(c->lexpr);
540 constraintExpr_free(c->expr);
552 // constraint constraint_makeMaxReadSideEffectPostIncrement (exprNode e, fileloc sequencePoint)
554 // constraint ret = constraint_makeNew();
555 // //constraintTerm term;
557 // e = exprNode_fakeCopy(e);
558 // ret->lexpr = constraintExpr_makeMaxReadExpr(e);
561 // ret->expr = constraintExpr_makeIncConstraintExpr (e);
562 // ret->lexpr = constraintExpr_setFileLoc (ret->lexpr, sequencePoint);
567 cstring arithType_print (arithType ar) /*@*/
569 cstring st = cstring_undefined;
573 st = cstring_makeLiteral (" < ");
576 st = cstring_makeLiteral (" <= ");
579 st = cstring_makeLiteral (" > ");
582 st = cstring_makeLiteral (" >= ");
585 st = cstring_makeLiteral (" == ");
588 st = cstring_makeLiteral (" NONNEGATIVE ");
591 st = cstring_makeLiteral (" POSITIVE ");
600 void constraint_printError (constraint c, fileloc loc)
605 string = constraint_printDetailed (c);
609 if (constraint_getFileloc(c) )
610 errorLoc = constraint_getFileloc(c);
614 voptgenerror (FLG_FUNCTIONPOST, string, errorLoc);
618 voptgenerror (FLG_FUNCTIONCONSTRAINT, string, errorLoc);
623 cstring constraint_printDetailed (constraint c)
625 cstring st = cstring_undefined;
631 st = message ("Unresolved constraint:\nLclint is unable to resolve %q needed to satisfy %q", constraint_print (c), constraint_print(c->orig) );
633 st = message ("Unresolved constraint:\nLclint is unable to resolve %q", constraint_print (c));
639 st = message ("Block Post condition:\nThis function block has the post condition %q\n based on %q", constraint_print (c), constraint_print(c->orig) );
641 st = message ("Block Post condition:\nThis function block has the post condition %q", constraint_print (c));
644 if (context_getFlag (FLG_CONSTRAINTLOCATION) )
647 // llassert (c->generatingExpr);
648 temp = message ("\nOriginal Generating expression %q: %s\n", fileloc_unparse( exprNode_getfileloc (c->generatingExpr) ),
649 exprNode_unparse(c->generatingExpr) );
650 st = cstring_concatFree (st, temp);
652 if (constraint_hasMaxSet(c) )
654 temp = message ("\nHas MaxSet\n");
655 st = cstring_concatFree (st, temp);
661 /*@only@*/ cstring constraint_print (constraint c) /*@*/
663 cstring st = cstring_undefined;
664 cstring type = cstring_undefined;
668 type = cstring_makeLiteral ("Ensures: ");
672 type = cstring_makeLiteral ("Requires: ");
674 st = message ("%q: %q %q %q",
676 constraintExpr_print (c->lexpr),
677 arithType_print(c->ar),
678 constraintExpr_print(c->expr)
683 cstring constraint_printOr (constraint c) /*@*/
688 ret = cstring_undefined;
691 ret = cstring_concatFree (ret, constraint_print(temp) );
695 while ( constraint_isDefined(temp) )
697 ret = cstring_concatFree (ret, cstring_makeLiteral (" OR ") );
698 ret = cstring_concatFree (ret, constraint_print(temp) );
706 /*@only@*/ constraint constraint_doSRefFixBaseParam (/*@returned@*/ /*@only@*/ constraint precondition,
707 exprNodeList arglist)
709 precondition->lexpr = constraintExpr_doSRefFixBaseParam (precondition->lexpr,
711 precondition->expr = constraintExpr_doSRefFixBaseParam (precondition->expr,
718 constraint constraint_doFixResult (constraint postcondition, exprNode fcnCall)
720 postcondition = constraint_copy (postcondition);
721 postcondition->lexpr = constraintExpr_doFixResult (postcondition->lexpr, fcnCall);
722 postcondition->expr = constraintExpr_doFixResult (postcondition->expr, fcnCall);
724 return postcondition;
727 /*@only@*/ constraint constraint_doSRefFixConstraintParam (constraint precondition,
728 exprNodeList arglist)
731 precondition = constraint_copy (precondition);
732 precondition->lexpr = constraintExpr_doSRefFixConstraintParam (precondition->lexpr, arglist);
733 precondition->expr = constraintExpr_doSRefFixConstraintParam (precondition->expr, arglist);
738 // bool constraint_hasTerm (constraint c, constraintTerm term)
740 // DPRINTF((message ("Constraint %s", constraint_print (c) ) ) );
742 // if (constraintExpr_includesTerm (c->lexpr, term) )
745 // if (constraintExpr_includesTerm (c->expr, term) )
751 constraint constraint_preserveOrig (/*@returned@*/ constraint c) /*@modifies c @*/
753 if (c->orig == constraint_undefined)
754 c->orig = constraint_copy (c);
762 constraint constraint_togglePost (/*@returned@*/ constraint c)