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 /*@notnull@*/ constraint constraint_makeNew (void);
25 constraint makeConstraintParse (sRef x, lltok relOp, exprNode cconstant)
31 ret = constraint_makeNew();
32 llassert (sRef_isValid(x) );
37 ret->lexpr = constraintExpr_makeTermsRef (x);
38 #warning fix abstraction
40 if (relOp.tok == GE_OP)
42 else if (relOp.tok == LE_OP)
44 else if (relOp.tok == EQ_OP)
47 llfatalbug(message ("Unsupported relational operator") );
50 t = cstring_toCharsSafe (exprNode_unparse(cconstant));
52 ret->expr = constraintExpr_makeIntLiteral (c);
56 DPRINTF(("GENERATED CONSTRAINT:"));
57 DPRINTF( (message ("%s", constraint_print(ret) ) ) );
61 constraint makeConstraintParse2 (constraintExpr l, lltok relOp, exprNode cconstant)
67 ret = constraint_makeNew();
73 ret->lexpr = constraintExpr_copy (l);
74 #warning fix abstraction
76 if (relOp.tok == GE_OP)
78 else if (relOp.tok == LE_OP)
80 else if (relOp.tok == EQ_OP)
83 llfatalbug(message("Unsupported relational operator") );
86 t = cstring_toCharsSafe (exprNode_unparse(cconstant));
88 ret->expr = constraintExpr_makeIntLiteral (c);
92 DPRINTF(("GENERATED CONSTRAINT:"));
93 DPRINTF( (message ("%s", constraint_print(ret) ) ) );
97 constraint constraint_same (constraint c1, constraint c2)
100 if (c1->ar != c2->ar)
103 if (!constraintExpr_similar (c1->lexpr, c2->lexpr) )
106 if (!constraintExpr_similar (c1->expr, c2->expr) )
112 constraint makeConstraintParse3 (constraintExpr l, lltok relOp, constraintExpr r)
115 ret = constraint_makeNew();
121 ret->lexpr = constraintExpr_copy (l);
122 #warning fix abstraction
124 if (relOp.tok == GE_OP)
126 else if (relOp.tok == LE_OP)
128 else if (relOp.tok == EQ_OP)
131 llfatalbug( message("Unsupported relational operator") );
133 ret->expr = constraintExpr_copy (r);
137 ret->orig = constraint_copy(ret);
139 ret = constraint_simplify (ret);
142 DPRINTF(("GENERATED CONSTRAINT:"));
143 DPRINTF( (message ("%s", constraint_print(ret) ) ) );
147 constraint constraint_copy (constraint c)
153 ret = constraint_makeNew();
154 ret->lexpr = constraintExpr_copy (c->lexpr);
156 ret->expr = constraintExpr_copy (c->expr);
158 ret->generatingExpr = exprNode_fakeCopy(c->generatingExpr);
162 ret->orig = constraint_copy (c->orig);
167 ret->or = constraint_copy (c->or);
174 /*like copy expect it doesn't allocate memory for the constraint*/
176 void constraint_overWrite (constraint c1, constraint c2)
178 c1->lexpr = constraintExpr_copy (c2->lexpr);
180 c1->expr = constraintExpr_copy (c2->expr);
183 if (c2->orig != NULL)
184 c1->orig = constraint_copy (c2->orig);
189 c1->or = constraint_copy (c2->or);
193 c1->generatingExpr = exprNode_fakeCopy (c2->generatingExpr );
196 bool constraint_resolve (/*@unused@*/ constraint c)
203 /*@notnull@*/ constraint constraint_makeNew (void)
206 ret = dmalloc(sizeof (*ret) );
213 ret->generatingExpr = NULL;
217 constraint constraint_addGeneratingExpr (/*@returned@*/ constraint c, exprNode e)
220 if (c->generatingExpr == NULL)
222 c->generatingExpr = exprNode_fakeCopy(e);
223 DPRINTF ((message ("setting generatingExpr for %s to %s", constraint_print(c), exprNode_unparse(e) ) ));
227 DPRINTF ((message ("Not setting generatingExpr for %s to %s", constraint_print(c), exprNode_unparse(e) ) ));
232 fileloc constraint_getFileloc (constraint c)
234 if (c->generatingExpr)
235 return (exprNode_getfileloc (c->generatingExpr) );
237 return (constraintExpr_getFileloc (c->lexpr) );
242 static bool checkForMaxSet (constraint c)
244 if (constraintExpr_hasMaxSet(c->lexpr) || constraintExpr_hasMaxSet(c->expr) )
250 bool constraint_hasMaxSet(constraint c)
254 if (checkForMaxSet(c->orig) )
258 return (checkForMaxSet(c) );
261 constraint constraint_makeReadSafeExprNode ( exprNode po, exprNode ind)
263 constraint ret = constraint_makeNew();
264 // constraintTerm term;
265 po = exprNode_fakeCopy(po);
266 ind = exprNode_fakeCopy(ind);
267 ret->lexpr = constraintExpr_makeMaxReadExpr(po);
269 ret->expr = constraintExpr_makeValueExpr (ind);
273 constraint constraint_makeWriteSafeInt (exprNode po, int ind)
275 constraint ret = constraint_makeNew();
278 ret->lexpr =constraintExpr_makeMaxSetExpr(po);
280 ret->expr = constraintExpr_makeValueInt (ind);
284 constraint constraint_makeSRefSetBufferSize (sRef s, int size)
286 constraint ret = constraint_makeNew();
287 ret->lexpr = constraintExpr_makeSRefMaxset (s);
289 ret->expr = constraintExpr_makeValueInt (size);
294 constraint constraint_makeSRefWriteSafeInt (sRef s, int ind)
296 constraint ret = constraint_makeNew();
299 ret->lexpr = constraintExpr_makeSRefMaxset (s);
301 ret->expr = constraintExpr_makeValueInt (ind);
306 /* drl added 01/12/2000
308 makes the constraint: Ensures index <= MaxRead(buffer) */
310 constraint constraint_makeEnsureLteMaxRead(exprNode index, exprNode buffer)
312 constraint ret = constraint_makeNew();
314 ret->lexpr = constraintExpr_makeValueExpr (index);
316 ret->expr = constraintExpr_makeMaxReadExpr(buffer);
321 constraint constraint_makeWriteSafeExprNode (exprNode po, exprNode ind)
323 constraint ret = constraint_makeNew();
326 ret->lexpr =constraintExpr_makeMaxSetExpr(po);
328 ret->expr = constraintExpr_makeValueExpr (ind);
333 constraint constraint_makeReadSafeInt ( exprNode po, int ind)
335 constraint ret = constraint_makeNew();
337 po = exprNode_fakeCopy(po);
339 ret->lexpr = constraintExpr_makeMaxReadExpr(po);
341 ret->expr = constraintExpr_makeValueInt (ind);
345 constraint constraint_makeSRefReadSafeInt (sRef s, int ind)
347 constraint ret = constraint_makeNew();
350 ret->lexpr = constraintExpr_makeSRefMaxRead (s);
352 ret->expr = constraintExpr_makeValueInt (ind);
357 constraint constraint_makeEnsureMaxReadAtLeast (exprNode e1, exprNode t2, fileloc sequencePoint)
359 constraint ret = constraint_makeNew();
362 e1 = exprNode_fakeCopy (e1);
363 t2 = exprNode_fakeCopy (t2);
365 ret = constraint_makeReadSafeExprNode(e1, t2);
367 ret->lexpr = constraintExpr_setFileloc (ret->lexpr, sequencePoint);
371 // fileloc_incColumn (ret->lexpr->term->loc);
375 static constraint constraint_makeEnsuresOpConstraintExpr (constraintExpr c1, constraintExpr c2, fileloc sequencePoint, arithType ar)
381 // llassert(sequencePoint);
383 ret = constraint_makeNew();
389 ret->lexpr = constraintExpr_setFileloc (ret->lexpr, sequencePoint);
393 static constraint constraint_makeEnsuresOp (exprNode e1, exprNode e2, fileloc sequencePoint, arithType ar)
395 constraintExpr c1, c2;
401 llcontbug((message("null exprNode, Exprnodes are %s and %s",
402 exprNode_unparse(e1), exprNode_unparse(e2) )
406 // llassert (sequencePoint);
408 e = exprNode_fakeCopy(e1);
409 c1 = constraintExpr_makeValueExpr (e);
411 e = exprNode_fakeCopy(e2);
412 c2 = constraintExpr_makeValueExpr (e);
414 ret = constraint_makeEnsuresOpConstraintExpr (c1, c2, sequencePoint, ar);
420 /* make constraint ensures e1 == e2 */
422 constraint constraint_makeEnsureEqual (exprNode e1, exprNode e2, fileloc sequencePoint)
424 return ( constraint_makeEnsuresOp (e1, e2, sequencePoint, EQ) );
427 /*make constraint ensures e1 < e2 */
428 constraint constraint_makeEnsureLessThan (exprNode e1, exprNode e2, fileloc sequencePoint)
430 constraintExpr t1, t2;
432 t1 = constraintExpr_makeValueExpr (e1);
433 t2 = constraintExpr_makeValueExpr (e2);
435 /*change this to e1 <= (e2 -1) */
437 t2 = constraintExpr_makeDecConstraintExpr (t2);
439 return ( constraint_makeEnsuresOpConstraintExpr (t1, t2, sequencePoint, LTE) );
442 constraint constraint_makeEnsureLessThanEqual (exprNode e1, exprNode e2, fileloc sequencePoint)
444 return ( constraint_makeEnsuresOp (e1, e2, sequencePoint, LTE) );
447 constraint constraint_makeEnsureGreaterThan (exprNode e1, exprNode e2, fileloc sequencePoint)
449 constraintExpr t1, t2;
451 t1 = constraintExpr_makeValueExpr (e1);
452 t2 = constraintExpr_makeValueExpr (e2);
455 /* change this to e1 >= (e2 + 1) */
456 t2 = constraintExpr_makeIncConstraintExpr (t2);
459 return ( constraint_makeEnsuresOpConstraintExpr (t1, t2, sequencePoint, GTE) );
462 constraint constraint_makeEnsureGreaterThanEqual (exprNode e1, exprNode e2, fileloc sequencePoint)
464 return ( constraint_makeEnsuresOp (e1, e2, sequencePoint, GTE) );
468 exprNode exprNode_copyConstraints (/*@returned@*/ exprNode dst, exprNode src)
470 dst->ensuresConstraints = constraintList_copy (src->ensuresConstraints );
471 dst->requiresConstraints = constraintList_copy (src->requiresConstraints );
472 dst->trueEnsuresConstraints = constraintList_copy (src->trueEnsuresConstraints );
473 dst->falseEnsuresConstraints = constraintList_copy (src->falseEnsuresConstraints );
477 constraint constraint_makeMaxSetSideEffectPostDecrement (exprNode e, fileloc sequencePoint)
479 constraint ret = constraint_makeNew();
480 //constraintTerm term;
482 e = exprNode_fakeCopy(e);
483 ret->lexpr = constraintExpr_makeValueExpr (e);
486 ret->expr = constraintExpr_makeValueExpr (e);
487 ret->expr = constraintExpr_makeDecConstraintExpr (ret->expr);
489 ret->lexpr = constraintExpr_setFileloc (ret->lexpr, sequencePoint);
490 // fileloc_incColumn ( ret->lexpr->term->loc);
491 // fileloc_incColumn ( ret->lexpr->term->loc);
494 constraint constraint_makeMaxSetSideEffectPostIncrement (exprNode e, fileloc sequencePoint)
496 constraint ret = constraint_makeNew();
497 //constraintTerm term;
499 e = exprNode_fakeCopy(e);
500 ret->lexpr = constraintExpr_makeValueExpr (e);
503 ret->expr = constraintExpr_makeValueExpr (e);
504 ret->expr = constraintExpr_makeIncConstraintExpr (ret->expr);
506 ret->lexpr = constraintExpr_setFileloc (ret->lexpr, sequencePoint);
507 // fileloc_incColumn ( ret->lexpr->term->loc);
508 // fileloc_incColumn ( ret->lexpr->term->loc);
514 // constraint constraint_makeMaxReadSideEffectPostIncrement (exprNode e, fileloc sequencePoint)
516 // constraint ret = constraint_makeNew();
517 // //constraintTerm term;
519 // e = exprNode_fakeCopy(e);
520 // ret->lexpr = constraintExpr_makeMaxReadExpr(e);
523 // ret->expr = constraintExpr_makeIncConstraintExpr (e);
524 // ret->lexpr = constraintExpr_setFileLoc (ret->lexpr, sequencePoint);
529 cstring arithType_print (arithType ar) /*@*/
531 cstring st = cstring_undefined;
535 st = cstring_makeLiteral (" < ");
538 st = cstring_makeLiteral (" <= ");
541 st = cstring_makeLiteral (" > ");
544 st = cstring_makeLiteral (" >= ");
547 st = cstring_makeLiteral (" == ");
550 st = cstring_makeLiteral (" NONNEGATIVE ");
553 st = cstring_makeLiteral (" POSITIVE ");
562 void constraint_printError (constraint c, fileloc loc)
567 string = constraint_printDetailed (c);
571 if (constraint_getFileloc(c) )
573 errorLoc = constraint_getFileloc(c);
578 voptgenerror (FLG_FUNCTIONPOST, string, errorLoc);
582 voptgenerror (FLG_FUNCTIONCONSTRAINT, string, errorLoc);
587 cstring constraint_printDetailed (constraint c)
589 cstring st = cstring_undefined;
595 st = message ("Unresolved constraint:\nLclint is unable to resolve %s needed to satisfy %s", constraint_print (c), constraint_print(c->orig) );
597 st = message ("Unresolved constraint:\nLclint is unable to resolve %s", constraint_print (c));
603 st = message ("Block Post condition:\nThis function block has the post condition %s\n based on %s", constraint_print (c), constraint_print(c->orig) );
605 st = message ("Block Post condition:\nThis function block has the post condition %s", constraint_print (c));
608 if (context_getFlag (FLG_CONSTRAINTLOCATION) )
611 // llassert (c->generatingExpr);
612 temp = message ("\nOriginal Generating expression %s: %s\n", fileloc_unparse( exprNode_getfileloc (c->generatingExpr) ),
613 exprNode_unparse(c->generatingExpr) );
614 st = cstring_concat (st, temp);
616 if (constraint_hasMaxSet(c) )
619 temp2 = message ("\nHas MaxSet\n");
620 st = cstring_concat (st, temp2);
626 cstring constraint_print (constraint c) /*@*/
628 cstring st = cstring_undefined;
629 cstring type = cstring_undefined;
633 type = cstring_makeLiteral ("Ensures: ");
637 type = cstring_makeLiteral ("Requires: ");
639 st = message ("%s: %s %s %s",
641 constraintExpr_print (c->lexpr),
642 arithType_print(c->ar),
643 constraintExpr_print(c->expr)
648 cstring constraint_printOr (constraint c) /*@*/
653 ret = cstring_undefined;
656 ret = cstring_concat (ret, constraint_print(temp) );
662 ret = cstring_concat (ret, cstring_makeLiteral (" OR ") );
663 ret = cstring_concat (ret, constraint_print(temp) );
671 /*@only@*/ constraint constraint_doSRefFixBaseParam (/*@returned@*/ /*@only@*/ constraint precondition,
672 exprNodeList arglist)
674 precondition->lexpr = constraintExpr_doSRefFixBaseParam (precondition->lexpr,
676 precondition->expr = constraintExpr_doSRefFixBaseParam (precondition->expr,
683 constraint constraint_doFixResult (constraint postcondition, exprNode fcnCall)
685 postcondition = constraint_copy (postcondition);
686 postcondition->lexpr = constraintExpr_doFixResult (postcondition->lexpr, fcnCall);
687 postcondition->expr = constraintExpr_doFixResult (postcondition->expr, fcnCall);
689 return postcondition;
692 constraint constraint_doSRefFixConstraintParam (constraint precondition,
693 exprNodeList arglist)
696 precondition = constraint_copy (precondition);
697 precondition->lexpr = constraintExpr_doSRefFixConstraintParam (precondition->lexpr, arglist);
698 precondition->expr = constraintExpr_doSRefFixConstraintParam (precondition->expr, arglist);
703 // bool constraint_hasTerm (constraint c, constraintTerm term)
705 // DPRINTF((message ("Constraint %s", constraint_print (c) ) ) );
707 // if (constraintExpr_includesTerm (c->lexpr, term) )
710 // if (constraintExpr_includesTerm (c->expr, term) )
716 /*@only@*/ constraint constraint_preserveOrig (/*@returned@*/ /*@only@*/ constraint c) /*@modifies c @*/
718 c->orig = constraint_copy (c);