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 constraint makeConstraintParse (sRef x, lltok relOp, exprNode cconstant)
30 ret = constraint_makeNew();
31 llassert (sRef_isValid(x) );
36 ret->lexpr = constraintExpr_makeTermsRef (x);
37 #warning fix abstraction
39 if (relOp.tok == GE_OP)
41 else if (relOp.tok == LE_OP)
43 else if (relOp.tok == EQ_OP)
46 llfatalbug(message ("Unsupported relational operator") );
49 t = cstring_toCharsSafe (exprNode_unparse(cconstant));
51 ret->expr = constraintExpr_makeIntLiteral (c);
55 DPRINTF(("GENERATED CONSTRAINT:"));
56 DPRINTF( (message ("%s", constraint_print(ret) ) ) );
60 constraint makeConstraintParse2 (constraintExpr l, lltok relOp, exprNode cconstant)
66 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();
120 ret->lexpr = constraintExpr_copy (l);
121 #warning fix abstraction
123 if (relOp.tok == GE_OP)
125 else if (relOp.tok == LE_OP)
127 else if (relOp.tok == EQ_OP)
130 llfatalbug( message("Unsupported relational operator") );
132 ret->expr = constraintExpr_copy (r);
136 ret->orig = constraint_copy(ret);
138 ret = constraint_simplify (ret);
141 DPRINTF(("GENERATED CONSTRAINT:"));
142 DPRINTF( (message ("%s", constraint_print(ret) ) ) );
146 constraint constraint_copy (constraint c)
150 llassert (constraint_isDefined(c) );
152 ret = constraint_makeNew();
153 ret->lexpr = constraintExpr_copy (c->lexpr);
155 ret->expr = constraintExpr_copy (c->expr);
157 ret->generatingExpr = exprNode_fakeCopy(c->generatingExpr);
161 ret->orig = constraint_copy (c->orig);
166 ret->or = constraint_copy (c->or);
173 /*like copy expect it doesn't allocate memory for the constraint*/
175 void constraint_overWrite (constraint c1, constraint c2)
177 c1->lexpr = constraintExpr_copy (c2->lexpr);
179 c1->expr = constraintExpr_copy (c2->expr);
182 if (c2->orig != NULL)
183 c1->orig = constraint_copy (c2->orig);
188 c1->or = constraint_copy (c2->or);
192 c1->generatingExpr = exprNode_fakeCopy (c2->generatingExpr );
195 bool constraint_resolve (/*@unused@*/ constraint c)
202 /*@notnull@*/ constraint constraint_makeNew (void)
205 ret = dmalloc(sizeof (*ret) );
212 ret->generatingExpr = NULL;
216 constraint constraint_addGeneratingExpr (/*@returned@*/ constraint c, exprNode e)
219 if (c->generatingExpr == NULL)
221 c->generatingExpr = exprNode_fakeCopy(e);
222 DPRINTF ((message ("setting generatingExpr for %s to %s", constraint_print(c), exprNode_unparse(e) ) ));
226 DPRINTF ((message ("Not setting generatingExpr for %s to %s", constraint_print(c), exprNode_unparse(e) ) ));
231 fileloc constraint_getFileloc (constraint c)
233 if (exprNode_isDefined(c->generatingExpr) )
234 return (exprNode_getfileloc (c->generatingExpr) );
236 return (constraintExpr_getFileloc (c->lexpr) );
241 static bool checkForMaxSet (constraint c)
243 if (constraintExpr_hasMaxSet(c->lexpr) || constraintExpr_hasMaxSet(c->expr) )
249 bool constraint_hasMaxSet(constraint c)
253 if (checkForMaxSet(c->orig) )
257 return (checkForMaxSet(c) );
260 constraint constraint_makeReadSafeExprNode ( exprNode po, exprNode ind)
262 constraint ret = constraint_makeNew();
263 // constraintTerm term;
264 po = exprNode_fakeCopy(po);
265 ind = exprNode_fakeCopy(ind);
266 ret->lexpr = constraintExpr_makeMaxReadExpr(po);
268 ret->expr = constraintExpr_makeValueExpr (ind);
272 constraint constraint_makeWriteSafeInt (exprNode po, int ind)
274 constraint ret = constraint_makeNew();
277 ret->lexpr =constraintExpr_makeMaxSetExpr(po);
279 ret->expr = constraintExpr_makeIntLiteral (ind);
283 constraint constraint_makeSRefSetBufferSize (sRef s, int size)
285 constraint ret = constraint_makeNew();
286 ret->lexpr = constraintExpr_makeSRefMaxset (s);
288 ret->expr = constraintExpr_makeIntLiteral (size);
293 constraint constraint_makeSRefWriteSafeInt (sRef s, int ind)
295 constraint ret = constraint_makeNew();
298 ret->lexpr = constraintExpr_makeSRefMaxset (s);
300 ret->expr = constraintExpr_makeIntLiteral (ind);
305 /* drl added 01/12/2000
307 makes the constraint: Ensures index <= MaxRead(buffer) */
309 constraint constraint_makeEnsureLteMaxRead(exprNode index, exprNode buffer)
311 constraint ret = constraint_makeNew();
313 ret->lexpr = constraintExpr_makeValueExpr (index);
315 ret->expr = constraintExpr_makeMaxReadExpr(buffer);
320 constraint constraint_makeWriteSafeExprNode (exprNode po, exprNode ind)
322 constraint ret = constraint_makeNew();
325 ret->lexpr =constraintExpr_makeMaxSetExpr(po);
327 ret->expr = constraintExpr_makeValueExpr (ind);
332 constraint constraint_makeReadSafeInt ( exprNode po, int ind)
334 constraint ret = constraint_makeNew();
336 po = exprNode_fakeCopy(po);
338 ret->lexpr = constraintExpr_makeMaxReadExpr(po);
340 ret->expr = constraintExpr_makeIntLiteral (ind);
344 constraint constraint_makeSRefReadSafeInt (sRef s, int ind)
346 constraint ret = constraint_makeNew();
349 ret->lexpr = constraintExpr_makeSRefMaxRead (s);
351 ret->expr = constraintExpr_makeIntLiteral (ind);
356 constraint constraint_makeEnsureMaxReadAtLeast (exprNode e1, exprNode t2, fileloc sequencePoint)
358 constraint ret = constraint_makeNew();
361 e1 = exprNode_fakeCopy (e1);
362 t2 = exprNode_fakeCopy (t2);
364 ret = constraint_makeReadSafeExprNode(e1, t2);
366 ret->lexpr = constraintExpr_setFileloc (ret->lexpr, sequencePoint);
370 // fileloc_incColumn (ret->lexpr->term->loc);
374 static constraint constraint_makeEnsuresOpConstraintExpr (constraintExpr c1, constraintExpr c2, fileloc sequencePoint, arithType ar)
380 // llassert(sequencePoint);
382 ret = constraint_makeNew();
388 ret->lexpr = constraintExpr_setFileloc (ret->lexpr, sequencePoint);
392 static constraint constraint_makeEnsuresOp (exprNode e1, exprNode e2, fileloc sequencePoint, arithType ar)
394 constraintExpr c1, c2;
400 llcontbug((message("null exprNode, Exprnodes are %s and %s",
401 exprNode_unparse(e1), exprNode_unparse(e2) )
405 // llassert (sequencePoint);
407 e = exprNode_fakeCopy(e1);
408 c1 = constraintExpr_makeValueExpr (e);
410 e = exprNode_fakeCopy(e2);
411 c2 = constraintExpr_makeValueExpr (e);
413 ret = constraint_makeEnsuresOpConstraintExpr (c1, c2, sequencePoint, ar);
419 /* make constraint ensures e1 == e2 */
421 constraint constraint_makeEnsureEqual (exprNode e1, exprNode e2, fileloc sequencePoint)
423 return ( constraint_makeEnsuresOp (e1, e2, sequencePoint, EQ) );
426 /*make constraint ensures e1 < e2 */
427 constraint constraint_makeEnsureLessThan (exprNode e1, exprNode e2, fileloc sequencePoint)
429 constraintExpr t1, t2;
431 t1 = constraintExpr_makeValueExpr (e1);
432 t2 = constraintExpr_makeValueExpr (e2);
434 /*change this to e1 <= (e2 -1) */
436 t2 = constraintExpr_makeDecConstraintExpr (t2);
438 return ( constraint_makeEnsuresOpConstraintExpr (t1, t2, sequencePoint, LTE) );
441 constraint constraint_makeEnsureLessThanEqual (exprNode e1, exprNode e2, fileloc sequencePoint)
443 return ( constraint_makeEnsuresOp (e1, e2, sequencePoint, LTE) );
446 constraint constraint_makeEnsureGreaterThan (exprNode e1, exprNode e2, fileloc sequencePoint)
448 constraintExpr t1, t2;
450 t1 = constraintExpr_makeValueExpr (e1);
451 t2 = constraintExpr_makeValueExpr (e2);
454 /* change this to e1 >= (e2 + 1) */
455 t2 = constraintExpr_makeIncConstraintExpr (t2);
458 return ( constraint_makeEnsuresOpConstraintExpr (t1, t2, sequencePoint, GTE) );
461 constraint constraint_makeEnsureGreaterThanEqual (exprNode e1, exprNode e2, fileloc sequencePoint)
463 return ( constraint_makeEnsuresOp (e1, e2, sequencePoint, GTE) );
467 exprNode exprNode_copyConstraints (/*@returned@*/ exprNode dst, exprNode src)
469 dst->ensuresConstraints = constraintList_copy (src->ensuresConstraints );
470 dst->requiresConstraints = constraintList_copy (src->requiresConstraints );
471 dst->trueEnsuresConstraints = constraintList_copy (src->trueEnsuresConstraints );
472 dst->falseEnsuresConstraints = constraintList_copy (src->falseEnsuresConstraints );
476 constraint constraint_makeMaxSetSideEffectPostDecrement (exprNode e, fileloc sequencePoint)
478 constraint ret = constraint_makeNew();
479 //constraintTerm term;
481 e = exprNode_fakeCopy(e);
482 ret->lexpr = constraintExpr_makeValueExpr (e);
485 ret->expr = constraintExpr_makeValueExpr (e);
486 ret->expr = constraintExpr_makeDecConstraintExpr (ret->expr);
488 ret->lexpr = constraintExpr_setFileloc (ret->lexpr, sequencePoint);
489 // fileloc_incColumn ( ret->lexpr->term->loc);
490 // fileloc_incColumn ( ret->lexpr->term->loc);
493 constraint constraint_makeMaxSetSideEffectPostIncrement (exprNode e, fileloc sequencePoint)
495 constraint ret = constraint_makeNew();
496 //constraintTerm term;
498 e = exprNode_fakeCopy(e);
499 ret->lexpr = constraintExpr_makeValueExpr (e);
502 ret->expr = constraintExpr_makeValueExpr (e);
503 ret->expr = constraintExpr_makeIncConstraintExpr (ret->expr);
505 ret->lexpr = constraintExpr_setFileloc (ret->lexpr, sequencePoint);
506 // fileloc_incColumn ( ret->lexpr->term->loc);
507 // fileloc_incColumn ( ret->lexpr->term->loc);
513 // constraint constraint_makeMaxReadSideEffectPostIncrement (exprNode e, fileloc sequencePoint)
515 // constraint ret = constraint_makeNew();
516 // //constraintTerm term;
518 // e = exprNode_fakeCopy(e);
519 // ret->lexpr = constraintExpr_makeMaxReadExpr(e);
522 // ret->expr = constraintExpr_makeIncConstraintExpr (e);
523 // ret->lexpr = constraintExpr_setFileLoc (ret->lexpr, sequencePoint);
528 cstring arithType_print (arithType ar) /*@*/
530 cstring st = cstring_undefined;
534 st = cstring_makeLiteral (" < ");
537 st = cstring_makeLiteral (" <= ");
540 st = cstring_makeLiteral (" > ");
543 st = cstring_makeLiteral (" >= ");
546 st = cstring_makeLiteral (" == ");
549 st = cstring_makeLiteral (" NONNEGATIVE ");
552 st = cstring_makeLiteral (" POSITIVE ");
561 void constraint_printError (constraint c, fileloc loc)
566 string = constraint_printDetailed (c);
570 if (constraint_getFileloc(c) )
572 errorLoc = constraint_getFileloc(c);
577 voptgenerror (FLG_FUNCTIONPOST, string, errorLoc);
581 voptgenerror (FLG_FUNCTIONCONSTRAINT, string, errorLoc);
586 cstring constraint_printDetailed (constraint c)
588 cstring st = cstring_undefined;
594 st = message ("Unresolved constraint:\nLclint is unable to resolve %s needed to satisfy %s", constraint_print (c), constraint_print(c->orig) );
596 st = message ("Unresolved constraint:\nLclint is unable to resolve %s", constraint_print (c));
602 st = message ("Block Post condition:\nThis function block has the post condition %s\n based on %s", constraint_print (c), constraint_print(c->orig) );
604 st = message ("Block Post condition:\nThis function block has the post condition %s", constraint_print (c));
607 if (context_getFlag (FLG_CONSTRAINTLOCATION) )
610 // llassert (c->generatingExpr);
611 temp = message ("\nOriginal Generating expression %s: %s\n", fileloc_unparse( exprNode_getfileloc (c->generatingExpr) ),
612 exprNode_unparse(c->generatingExpr) );
613 st = cstring_concat (st, temp);
615 if (constraint_hasMaxSet(c) )
618 temp2 = message ("\nHas MaxSet\n");
619 st = cstring_concat (st, temp2);
625 cstring constraint_print (constraint c) /*@*/
627 cstring st = cstring_undefined;
628 cstring type = cstring_undefined;
632 type = cstring_makeLiteral ("Ensures: ");
636 type = cstring_makeLiteral ("Requires: ");
638 st = message ("%s: %s %s %s",
640 constraintExpr_print (c->lexpr),
641 arithType_print(c->ar),
642 constraintExpr_print(c->expr)
647 cstring constraint_printOr (constraint c) /*@*/
652 ret = cstring_undefined;
655 ret = cstring_concat (ret, constraint_print(temp) );
659 while ( constraint_isDefined(temp) )
661 ret = cstring_concat (ret, cstring_makeLiteral (" OR ") );
662 ret = cstring_concat (ret, constraint_print(temp) );
670 /*@only@*/ constraint constraint_doSRefFixBaseParam (/*@returned@*/ /*@only@*/ constraint precondition,
671 exprNodeList arglist)
673 precondition->lexpr = constraintExpr_doSRefFixBaseParam (precondition->lexpr,
675 precondition->expr = constraintExpr_doSRefFixBaseParam (precondition->expr,
682 constraint constraint_doFixResult (constraint postcondition, exprNode fcnCall)
684 postcondition = constraint_copy (postcondition);
685 postcondition->lexpr = constraintExpr_doFixResult (postcondition->lexpr, fcnCall);
686 postcondition->expr = constraintExpr_doFixResult (postcondition->expr, fcnCall);
688 return postcondition;
691 constraint constraint_doSRefFixConstraintParam (constraint precondition,
692 exprNodeList arglist)
695 precondition = constraint_copy (precondition);
696 precondition->lexpr = constraintExpr_doSRefFixConstraintParam (precondition->lexpr, arglist);
697 precondition->expr = constraintExpr_doSRefFixConstraintParam (precondition->expr, arglist);
702 // bool constraint_hasTerm (constraint c, constraintTerm term)
704 // DPRINTF((message ("Constraint %s", constraint_print (c) ) ) );
706 // if (constraintExpr_includesTerm (c->lexpr, term) )
709 // if (constraintExpr_includesTerm (c->expr, term) )
715 /*@only@*/ constraint constraint_preserveOrig (/*@returned@*/ /*@only@*/ constraint c) /*@modifies c @*/
717 c->orig = constraint_copy (c);