Removed some useless/false comments
[splint-patched.git] / src / constraint.c
blob903f1ab02c6df414ec43ab006efb5118a0027f60
1 /*
2 ** Splint - annotation-assisted static program checker
3 ** Copyright (C) 1994-2003 University of Virginia,
4 ** Massachusetts Institute of Technology
5 **
6 ** This program is free software; you can redistribute it and/or modify it
7 ** under the terms of the GNU General Public License as published by the
8 ** Free Software Foundation; either version 2 of the License, or (at your
9 ** option) any later version.
10 **
11 ** This program is distributed in the hope that it will be useful, but
12 ** WITHOUT ANY WARRANTY; without even the implied warranty of
13 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 ** General Public License for more details.
15 **
16 ** The GNU General Public License is available from http://www.gnu.org/ or
17 ** the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
18 ** MA 02111-1307, USA.
20 ** For information on splint: info@splint.org
21 ** To report a bug: splint-bug@splint.org
22 ** For more information: http://www.splint.org
26 ** constraint.c
29 # include "splintMacros.nf"
30 # include "basic.h"
31 # include "cgrammar.h"
33 static /*@only@*/ cstring
34 constraint_unparseDetailedPostCondition (/*@observer@*/ /*@temp@*/ constraint p_c);
36 /*drl added 12/19/2002 */
37 static bool
38 constraint_isConstantOnly (constraint p_c);
40 static /*@notnull@*/ /*@special@*/ constraint constraint_makeNew (void)
41 /*@post:isnull result->or, result->orig, result->generatingExpr, result->fcnPre @*/
42 /*@defines result->or, result->generatingExpr, result->orig, result->fcnPre @*/;
44 static void
45 advanceField (char **s)
47 reader_checkChar (s, '@');
50 bool constraint_same (constraint c1, constraint c2)
52 llassertfatal (c1 != NULL);
53 llassertfatal (c2 != NULL);
55 if (c1->ar != c2->ar)
57 return FALSE;
60 if (!constraintExpr_similar (c1->lexpr, c2->lexpr))
62 return FALSE;
65 if (!constraintExpr_similar (c1->expr, c2->expr))
67 return FALSE;
70 return TRUE;
73 constraint makeConstraintParse3 (constraintExpr l, lltok relOp, constraintExpr r)
75 constraint ret;
76 ret = constraint_makeNew ();
77 llassert (constraintExpr_isDefined (l));
79 ret->lexpr = constraintExpr_copy (l);
81 if (lltok_getTok (relOp) == GE_OP)
83 ret->ar = GTE;
85 else if (lltok_getTok (relOp) == LE_OP)
87 ret->ar = LTE;
89 else if (lltok_getTok (relOp) == EQ_OP)
91 ret->ar = EQ;
93 else
94 llfatalbug ( message ("Unsupported relational operator"));
96 ret->expr = constraintExpr_copy (r);
98 ret->post = TRUE;
100 ret->orig = constraint_copy (ret);
102 ret = constraint_simplify (ret);
103 /* ret->orig = ret; */
105 DPRINTF (("GENERATED CONSTRAINT:"));
106 DPRINTF ((message ("%s", constraint_unparse (ret))));
107 return ret;
110 constraint constraint_copy (/*@temp@*/ /*@observer@*/ constraint c)
112 if (!constraint_isDefined (c))
114 return constraint_undefined;
116 else
118 constraint ret = constraint_makeNew ();
119 ret->lexpr = constraintExpr_copy (c->lexpr);
120 ret->ar = c->ar;
121 ret->expr = constraintExpr_copy (c->expr);
122 ret->post = c->post;
123 /*@-assignexpose@*/
124 ret->generatingExpr = c->generatingExpr;
125 /*@=assignexpose@*/
127 if (c->orig != NULL)
128 ret->orig = constraint_copy (c->orig);
129 else
130 ret->orig = NULL;
132 if (c->or != NULL)
133 ret->or = constraint_copy (c->or);
134 else
135 ret->or = NULL;
137 ret->fcnPre = c->fcnPre;
139 return ret;
143 # ifdef DEADCODE
144 /*like copy except it doesn't allocate memory for the constraint*/
146 void constraint_overWrite (constraint c1, constraint c2)
148 llassertfatal (constraint_isDefined (c1) && constraint_isDefined (c2));
150 llassert (c1 != c2);
152 DPRINTF ((message ("OverWriteing constraint %q with %q", constraint_unparse (c1),
153 constraint_unparse (c2))));
155 constraintExpr_free (c1->lexpr);
156 constraintExpr_free (c1->expr);
158 c1->lexpr = constraintExpr_copy (c2->lexpr);
159 c1->ar = c2->ar;
160 c1->expr = constraintExpr_copy (c2->expr);
161 c1->post = c2->post;
163 if (c1->orig != NULL)
164 constraint_free (c1->orig);
166 if (c2->orig != NULL)
167 c1->orig = constraint_copy (c2->orig);
168 else
169 c1->orig = NULL;
171 if (c1->or != NULL)
172 constraint_free (c1->or);
174 if (c2->or != NULL)
175 c1->or = constraint_copy (c2->or);
176 else
177 c1->or = NULL;
179 c1->fcnPre = c2->fcnPre;
181 /*@-assignexpose@*/
182 c1->generatingExpr = c2->generatingExpr;
183 /*@=assignexpose@*/
185 # endif /* DEADCODE */
188 static /*@notnull@*/ /*@special@*/ constraint constraint_makeNew (void)
189 /*@post:isnull result->or, result->orig, result->generatingExpr, result->fcnPre @*/
190 /*@defines result->or, result->generatingExpr, result->orig, result->fcnPre @*/
192 constraint ret;
193 ret = dmalloc (sizeof (*ret));
194 ret->lexpr = NULL;
195 ret->expr = NULL;
196 ret->ar = LT;
197 ret->post = FALSE;
198 ret->orig = NULL;
199 ret->or = NULL;
200 ret->generatingExpr = NULL;
201 ret->fcnPre = NULL;
202 return ret;
205 /*@access exprNode@*/
207 constraint constraint_addGeneratingExpr (/*@returned@*/ constraint c, /*@exposed@*/ exprNode e)
209 if (!constraint_isDefined (c))
211 return c;
214 if (c->generatingExpr == NULL)
216 c->generatingExpr = e;
217 DPRINTF ((message ("setting generatingExpr for %s to %s", constraint_unparse (c), exprNode_unparse (e)) ));
219 else
221 DPRINTF ((message ("Not setting generatingExpr for %s to %s", constraint_unparse (c), exprNode_unparse (e)) ));
223 return c;
225 /*@noaccess exprNode@*/
227 constraint constraint_origAddGeneratingExpr (/*@returned@*/ constraint c, exprNode e)
229 llassertfatal (constraint_isDefined (c));
231 if (c->orig != constraint_undefined)
233 c->orig = constraint_addGeneratingExpr (c->orig, e);
235 else
237 DPRINTF ((message ("%s: Not setting generatingExpr for %s to %s", __func__,
238 constraint_unparse (c), exprNode_unparse (e)) ));
240 return c;
243 constraint constraint_setFcnPre (/*@returned@*/ constraint c)
245 llassertfatal (constraint_isDefined (c));
247 if (c->orig != constraint_undefined)
249 c->orig->fcnPre = TRUE;
251 else
253 c->fcnPre = TRUE;
254 DPRINTF (( message ("Warning Setting fcnPre directly")));
256 return c;
260 fileloc constraint_getFileloc (constraint c)
262 llassertfatal (constraint_isDefined (c));
264 if (exprNode_isDefined (c->generatingExpr))
265 return (fileloc_copy (exprNode_loc (c->generatingExpr)));
267 return (constraintExpr_loc (c->lexpr));
270 static bool checkForMaxSet (constraint c)
272 llassertfatal (constraint_isDefined (c));
273 return (constraintExpr_hasMaxSet (c->lexpr) || constraintExpr_hasMaxSet (c->expr));
276 bool constraint_hasMaxSet (constraint c)
278 llassertfatal (constraint_isDefined (c));
280 if (checkForMaxSet (c))
281 return TRUE;
283 if (c->orig != NULL)
285 if (checkForMaxSet (c->orig))
286 return TRUE;
289 return FALSE;
292 constraint constraint_makeReadSafeExprNode (exprNode po, exprNode ind)
294 constraint ret = constraint_makeNew ();
296 ret->lexpr = constraintExpr_makeMaxReadExpr (po);
297 ret->ar = GTE;
298 ret->expr = constraintExpr_makeValueExpr (ind);
299 ret->post = FALSE;
300 return ret;
303 constraint constraint_makeWriteSafeInt (exprNode po, int ind)
305 constraint ret = constraint_makeNew ();
306 ret->lexpr =constraintExpr_makeMaxSetExpr (po);
307 ret->ar = GTE;
308 ret->expr = constraintExpr_makeIntLiteral (ind);
309 /*@i1*/ return ret;
312 constraint constraint_makeSRefSetBufferSize (sRef s, long int size)
314 constraint ret = constraint_makeNew ();
315 ret->lexpr = constraintExpr_makeSRefMaxset (s);
316 ret->ar = EQ;
317 ret->expr = constraintExpr_makeIntLiteral ((int)size);
318 ret->post = TRUE;
319 return ret;
322 constraint constraint_makeSRefWriteSafeInt (sRef s, int ind)
324 constraint ret = constraint_makeNew ();
325 ret->lexpr = constraintExpr_makeSRefMaxset ( s);
326 ret->ar = GTE;
327 ret->expr = constraintExpr_makeIntLiteral (ind);
328 ret->post = TRUE;
329 return ret;
332 /* drl added 01/12/2000
333 ** makes the constraint: Ensures index <= MaxRead (buffer)
336 constraint constraint_makeEnsureLteMaxRead (exprNode index, exprNode buffer)
338 constraint ret = constraint_makeNew ();
340 ret->lexpr = constraintExpr_makeValueExpr (index);
341 ret->ar = LTE;
342 ret->expr = constraintExpr_makeMaxReadExpr (buffer);
343 ret->post = TRUE;
344 return ret;
347 constraint constraint_makeWriteSafeExprNode (exprNode po, exprNode ind)
349 constraint ret = constraint_makeNew ();
351 ret->lexpr =constraintExpr_makeMaxSetExpr (po);
352 ret->ar = GTE;
353 ret->expr = constraintExpr_makeValueExpr (ind);
354 /*@i1*/return ret;
358 constraint constraint_makeReadSafeInt (exprNode t1, int index)
360 constraint ret = constraint_makeNew ();
362 ret->lexpr = constraintExpr_makeMaxReadExpr (t1);
363 ret->ar = GTE;
364 ret->expr = constraintExpr_makeIntLiteral (index);
365 ret->post = FALSE;
366 return ret;
369 constraint constraint_makeSRefReadSafeInt (sRef s, int ind)
371 constraint ret = constraint_makeNew ();
373 ret->lexpr = constraintExpr_makeSRefMaxRead (s);
374 ret->ar = GTE;
375 ret->expr = constraintExpr_makeIntLiteral (ind);
376 ret->post = TRUE;
377 return ret;
380 constraint constraint_makeEnsureMaxReadAtLeast (exprNode t1, exprNode t2, fileloc sequencePoint)
382 constraint ret = constraint_makeReadSafeExprNode (t1, t2);
383 llassertfatal (constraint_isDefined (ret));
385 ret->lexpr = constraintExpr_setFileloc (ret->lexpr, sequencePoint);
386 ret->post = TRUE;
388 return ret;
391 static constraint
392 constraint_makeEnsuresOpConstraintExpr (/*@only@*/ constraintExpr c1, /*@only@*/ constraintExpr c2,
393 fileloc sequencePoint, arithType ar)
395 if (constraintExpr_isDefined (c1) && constraintExpr_isDefined (c2))
397 constraint ret = constraint_makeNew ();
398 ret->lexpr = c1;
399 ret->ar = ar;
400 ret->post = TRUE;
401 ret->expr = c2;
402 ret->lexpr = constraintExpr_setFileloc (ret->lexpr, sequencePoint);
403 return ret;
405 else
407 return constraint_undefined;
411 static constraint
412 constraint_makeEnsuresOp (/*@dependent@*/ exprNode e1, /*@dependent@*/ exprNode e2,
413 fileloc sequencePoint, arithType ar)
415 constraintExpr c1, c2;
417 if (!(exprNode_isDefined (e1) && exprNode_isDefined (e2)))
419 llcontbug (message ("Invalid exprNode, Exprnodes are %s and %s",
420 exprNode_unparse (e1), exprNode_unparse (e2)));
423 c1 = constraintExpr_makeValueExpr (e1);
424 c2 = constraintExpr_makeValueExpr (e2);
426 return constraint_makeEnsuresOpConstraintExpr (c1, c2, sequencePoint, ar);
429 /* make constraint ensures e1 == e2 */
431 constraint constraint_makeEnsureEqual (exprNode e1, exprNode e2, fileloc sequencePoint)
433 return (constraint_makeEnsuresOp (e1, e2, sequencePoint, EQ));
436 /* make constraint ensures e1 < e2 */
437 constraint constraint_makeEnsureLessThan (exprNode e1, exprNode e2, fileloc sequencePoint)
439 constraintExpr t1, t2;
440 constraint t3;
442 t1 = constraintExpr_makeValueExpr (e1);
443 t2 = constraintExpr_makeValueExpr (e2);
445 /* change this to e1 <= (e2 -1) */
447 t2 = constraintExpr_makeDecConstraintExpr (t2);
448 t3 = constraint_makeEnsuresOpConstraintExpr (t1, t2, sequencePoint, LTE);
449 t3 = constraint_simplify (t3);
450 return (t3);
453 constraint constraint_makeEnsureLessThanEqual (exprNode e1, exprNode e2, fileloc sequencePoint)
455 return (constraint_makeEnsuresOp (e1, e2, sequencePoint, LTE));
458 constraint constraint_makeEnsureGreaterThan (exprNode e1, exprNode e2, fileloc sequencePoint)
460 constraintExpr t1, t2;
461 constraint t3;
463 t1 = constraintExpr_makeValueExpr (e1);
464 t2 = constraintExpr_makeValueExpr (e2);
466 /* change this to e1 >= (e2 + 1) */
467 t2 = constraintExpr_makeIncConstraintExpr (t2);
469 t3 = constraint_makeEnsuresOpConstraintExpr (t1, t2, sequencePoint, GTE);
470 t3 = constraint_simplify(t3);
472 return t3;
475 constraint constraint_makeEnsureGreaterThanEqual (exprNode e1, exprNode e2, fileloc sequencePoint)
477 return ( constraint_makeEnsuresOp (e1, e2, sequencePoint, GTE));
482 /* Makes the constraint e = e + f */
483 constraint constraint_makeAddAssign (exprNode e, exprNode f, fileloc sequencePoint)
485 constraintExpr x1, x2, y;
486 constraint ret;
488 ret = constraint_makeNew ();
490 x1 = constraintExpr_makeValueExpr (e);
491 x2 = constraintExpr_copy (x1);
492 y = constraintExpr_makeValueExpr (f);
494 ret->lexpr = x1;
495 ret->ar = EQ;
496 ret->post = TRUE;
497 ret->expr = constraintExpr_makeAddExpr (x2, y);
499 ret->lexpr = constraintExpr_setFileloc (ret->lexpr, sequencePoint);
501 return ret;
505 /* Makes the constraint e = e - f */
506 constraint constraint_makeSubtractAssign (exprNode e, exprNode f, fileloc sequencePoint)
508 constraintExpr x1, x2, y;
509 constraint ret;
511 ret = constraint_makeNew ();
513 x1 = constraintExpr_makeValueExpr (e);
514 x2 = constraintExpr_copy (x1);
515 y = constraintExpr_makeValueExpr (f);
517 ret->lexpr = x1;
518 ret->ar = EQ;
519 ret->post = TRUE;
520 ret->expr = constraintExpr_makeSubtractExpr (x2, y);
522 ret->lexpr = constraintExpr_setFileloc (ret->lexpr, sequencePoint);
524 return ret;
527 constraint constraint_makeMaxSetSideEffectPostDecrement (exprNode e, fileloc sequencePoint)
529 constraint ret = constraint_makeNew ();
531 ret->lexpr = constraintExpr_makeValueExpr (e);
532 ret->ar = EQ;
533 ret->post = TRUE;
534 ret->expr = constraintExpr_makeValueExpr (e);
535 ret->expr = constraintExpr_makeDecConstraintExpr (ret->expr);
536 ret->lexpr = constraintExpr_setFileloc (ret->lexpr, sequencePoint);
537 return ret;
539 constraint constraint_makeMaxSetSideEffectPostIncrement (exprNode e, fileloc sequencePoint)
541 constraint ret = constraint_makeNew ();
543 ret->lexpr = constraintExpr_makeValueExpr (e);
544 ret->ar = EQ;
545 ret->post = TRUE;
546 ret->expr = constraintExpr_makeValueExpr (e);
547 ret->expr = constraintExpr_makeIncConstraintExpr (ret->expr);
549 ret->lexpr = constraintExpr_setFileloc (ret->lexpr, sequencePoint);
550 return ret;
554 void constraint_free (/*@only@*/ constraint c)
556 if (constraint_isDefined (c))
558 constraint_free (c->orig);
559 c->orig = NULL;
561 constraint_free (c->or);
562 c->or = NULL;
564 constraintExpr_free (c->lexpr);
565 c->lexpr = NULL;
567 constraintExpr_free (c->expr);
568 c->expr = NULL;
570 free (c);
574 cstring arithType_print (arithType ar) /*@*/
576 cstring st = cstring_undefined;
577 switch (ar)
579 case LT:
580 st = cstring_makeLiteral ("<");
581 break;
582 case LTE:
583 st = cstring_makeLiteral ("<=");
584 break;
585 case GT:
586 st = cstring_makeLiteral (">");
587 break;
588 case GTE:
589 st = cstring_makeLiteral (">=");
590 break;
591 case EQ:
592 st = cstring_makeLiteral ("==");
593 break;
594 case NONNEGATIVE:
595 st = cstring_makeLiteral ("NONNEGATIVE");
596 break;
597 case POSITIVE:
598 st = cstring_makeLiteral ("POSITIVE");
599 break;
600 default:
601 BADBRANCH;
602 break;
604 return st;
607 void constraint_printErrorPostCondition (constraint c, fileloc loc)
609 cstring string;
610 fileloc errorLoc, temp;
612 string = constraint_unparseDetailedPostCondition (c);
613 errorLoc = loc;
614 loc = NULL;
616 temp = constraint_getFileloc (c);
618 if (context_getFlag (FLG_BOUNDSCOMPACTERRORMESSAGES))
620 string = cstring_replaceChar (string, '\n', ' ');
623 if (fileloc_isDefined (temp))
625 errorLoc = temp;
626 voptgenerror (FLG_CHECKPOST, string, errorLoc);
627 fileloc_free (temp);
629 else
631 voptgenerror (FLG_CHECKPOST, string, errorLoc);
635 # ifdef DEADCODE
636 /*drl added 8-11-001*/
637 cstring constraint_printLocation (/*@observer@*/ /*@temp@*/ constraint c) /*@*/
639 cstring string, ret;
640 fileloc errorLoc;
642 string = constraint_unparse (c);
644 errorLoc = constraint_getFileloc (c);
646 ret = message ("constraint: %q @ %q", string, fileloc_unparse (errorLoc));
647 fileloc_free (errorLoc);
648 return ret;
651 # endif /* DEADCODE */
654 void constraint_printError (constraint c, fileloc loc)
656 cstring string;
657 fileloc errorLoc, temp;
659 bool isLikely;
661 llassertfatal (constraint_isDefined (c));
663 /*drl 11/26/2001 avoid printing tautological constraints */
664 if (constraint_isAlwaysTrue (c))
666 return;
669 string = constraint_unparseDetailed (c);
671 errorLoc = loc;
673 temp = constraint_getFileloc (c);
675 if (fileloc_isDefined (temp))
677 errorLoc = temp;
679 else
681 llassert (FALSE);
682 DPRINTF (("constraint %s had undefined fileloc %s",
683 constraint_unparse (c), fileloc_unparse (temp)));
684 fileloc_free (temp);
685 errorLoc = fileloc_copy (errorLoc);
689 if (context_getFlag (FLG_BOUNDSCOMPACTERRORMESSAGES))
691 string = cstring_replaceChar(string, '\n', ' ');
694 /*drl added 12/19/2002 print
695 a different error for "likely" bounds-errors*/
697 isLikely = constraint_isConstantOnly (c);
699 if (isLikely)
701 if (c->post)
703 voptgenerror (FLG_FUNCTIONPOST, string, errorLoc);
705 else
707 if (constraint_hasMaxSet (c))
709 voptgenerror (FLG_LIKELYBOUNDSWRITE, string, errorLoc);
711 else
713 voptgenerror (FLG_LIKELYBOUNDSREAD, string, errorLoc);
717 else if (c->post)
719 voptgenerror (FLG_FUNCTIONPOST, string, errorLoc);
721 else
723 if (constraint_hasMaxSet (c))
725 voptgenerror (FLG_BOUNDSWRITE, string, errorLoc);
727 else
729 voptgenerror (FLG_BOUNDSREAD, string, errorLoc);
733 fileloc_free(errorLoc);
736 static cstring constraint_unparseDeep (constraint c)
738 cstring genExpr;
739 cstring st;
741 llassertfatal (constraint_isDefined (c));
742 st = constraint_unparse (c);
744 if (c->orig != constraint_undefined)
746 st = cstring_appendChar (st, '\n');
747 genExpr = exprNode_unparse (c->orig->generatingExpr);
749 if (!c->post)
751 if (c->orig->fcnPre)
753 st = cstring_concatFree (st, message (" derived from %s precondition: %q",
754 genExpr, constraint_unparseDeep (c->orig)));
756 else
758 st = cstring_concatFree (st, message (" needed to satisfy precondition:\n%q",
759 constraint_unparseDeep (c->orig)));
762 else
764 st = cstring_concatFree (st, message ("derived from: %q",
765 constraint_unparseDeep (c->orig)));
769 return st;
773 static /*@only@*/ cstring constraint_unparseDetailedPostCondition (/*@observer@*/ /*@temp@*/ constraint c)
775 cstring st;
776 cstring genExpr;
778 llassertfatal (constraint_isDefined (c));
780 st = message ("Unsatisfied ensures constraint condition:\n"
781 "Splint is unable to verify the constraint %q",
782 constraint_unparseDeep (c));
784 genExpr = exprNode_unparse (c->generatingExpr);
786 if (context_getFlag (FLG_CONSTRAINTLOCATION))
788 cstring temp;
790 temp = message ("\nOriginal Generating expression %q: %s\n",
791 fileloc_unparse (exprNode_loc (c->generatingExpr)),
792 genExpr);
793 st = cstring_concatFree (st, temp);
795 if (constraint_hasMaxSet (c))
797 temp = message ("Has MaxSet\n");
798 st = cstring_concatFree (st, temp);
801 return st;
804 cstring constraint_unparseDetailed (constraint c)
806 cstring st;
807 cstring temp;
808 cstring genExpr;
809 bool isLikely;
811 llassertfatal (constraint_isDefined (c));
813 if (!c->post)
815 st = message ("Unable to resolve constraint:\n%q", constraint_unparseDeep (c));
817 else
819 st = message ("Block Post condition:\nThis function block has the post condition %q", constraint_unparseDeep (c));
822 isLikely = constraint_isConstantOnly (c);
824 if (isLikely)
826 if (constraint_hasMaxSet (c))
828 temp = cstring_makeLiteral ("Likely out-of-bounds store: ");
830 else
832 temp = cstring_makeLiteral ("Likely out-of-bounds read: ");
835 else
838 if (constraint_hasMaxSet (c))
840 temp = cstring_makeLiteral ("Possible out-of-bounds store: ");
842 else
844 temp = cstring_makeLiteral ("Possible out-of-bounds read: ");
848 genExpr = exprNode_unparse (c->generatingExpr);
850 if (context_getFlag (FLG_CONSTRAINTLOCATION))
852 cstring temp2;
853 temp2 = message ("%s\n", genExpr);
854 temp = cstring_concatFree (temp, temp2);
857 st = cstring_concatFree (temp,st);
859 return st;
862 /*@only@*/ cstring constraint_unparse (constraint c) /*@*/
864 cstring st;
865 cstring type;
867 llassertfatal (c !=NULL);
869 if (c->post)
871 type = cstring_makeLiteral ("ensures");
873 else
875 type = cstring_makeLiteral ("requires");
878 if (context_getFlag (FLG_PARENCONSTRAINT))
880 st = message ("%q: : %q %q %q",
881 type,
882 constraintExpr_print (c->lexpr),
883 arithType_print (c->ar),
884 constraintExpr_print (c->expr));
886 else
888 st = message ("%q %q %q %q",
889 type,
890 constraintExpr_print (c->lexpr),
891 arithType_print (c->ar),
892 constraintExpr_print (c->expr));
894 return st;
897 cstring constraint_unparseOr (constraint c) /*@*/
899 cstring ret;
900 constraint temp;
902 ret = cstring_undefined;
904 llassertfatal (constraint_isDefined (c));
906 temp = c;
908 ret = cstring_concatFree (ret, constraint_unparse (temp));
910 temp = temp->or;
912 while ( constraint_isDefined (temp))
914 ret = cstring_concatFree (ret, cstring_makeLiteral (" OR "));
915 ret = cstring_concatFree (ret, constraint_unparse (temp));
916 temp = temp->or;
919 return ret;
923 # ifdef DEADCODE
924 /*@only@*/ constraint constraint_doSRefFixBaseParam (/*@returned@*/ /*@only@*/ constraint precondition,
925 exprNodeList arglist)
927 llassertfatal (constraint_isDefined (precondition));
929 precondition->lexpr = constraintExpr_doSRefFixBaseParam (precondition->lexpr,
930 arglist);
931 precondition->expr = constraintExpr_doSRefFixBaseParam (precondition->expr,
932 arglist);
934 return precondition;
936 # endif /* DEADCODE */
938 constraint constraint_doFixResult (constraint postcondition, /*@dependent@*/ exprNode fcnCall)
940 postcondition = constraint_copy (postcondition);
942 llassertfatal (constraint_isDefined (postcondition));
944 postcondition->lexpr = constraintExpr_doFixResult (postcondition->lexpr, fcnCall);
945 postcondition->expr = constraintExpr_doFixResult (postcondition->expr, fcnCall);
947 return postcondition;
949 /*Commenting out temporally
951 / *@only@* /constraint constraint_doSRefFixInvarConstraint(constraint invar, sRef s, ctype ct )
954 invar = constraint_copy (invar);
955 invar->lexpr = constraintExpr_doSRefFixInvarConstraint (invar->lexpr, s, ct);
956 invar->expr = constraintExpr_doSRefFixInvarConstraint (invar->expr, s, ct);
958 return invar;
962 /*@only@*/ constraint constraint_doSRefFixConstraintParam (constraint precondition,
963 exprNodeList arglist)
965 precondition = constraint_copy (precondition);
967 llassertfatal (constraint_isDefined (precondition));
969 precondition->lexpr = constraintExpr_doSRefFixConstraintParam (precondition->lexpr, arglist);
970 precondition->expr = constraintExpr_doSRefFixConstraintParam (precondition->expr, arglist);
972 precondition->fcnPre = FALSE;
973 return constraint_simplify(precondition);
976 constraint constraint_preserveOrig (/*@returned@*/ constraint c) /*@modifies c @*/
978 if (constraint_isDefined (c))
980 DPRINTF (("Doing constraint_preserverOrig for %q", constraint_unparseDetailed (c)));
982 if (c->orig == constraint_undefined)
984 c->orig = constraint_copy (c);
986 else if (c->orig->fcnPre)
988 constraint temp = c->orig;
990 /* avoid infinite loop */
991 c->orig = NULL;
992 c->orig = constraint_copy (c);
993 /*drl 03/2/2003 if c != NULL then the copy of c will != null*/
994 llassertfatal (constraint_isDefined (c->orig));
996 if (c->orig->orig == NULL)
998 c->orig->orig = temp;
1000 else
1002 llcontbug ((message ("Expected c->orig->orig to be null")));
1003 constraint_free (c->orig->orig);
1004 c->orig->orig = temp;
1007 else
1009 DPRINTF (("Not changing constraint"));
1013 DPRINTF ((message ("After Doing constraint_preserverOrig for %q ", constraint_unparseDetailed (c))));
1014 return c;
1017 constraint constraint_togglePost (/*@returned@*/ constraint c)
1019 llassertfatal (constraint_isDefined (c));
1020 c->post = !c->post;
1021 return c;
1024 constraint constraint_togglePostOrig (/*@returned@*/ constraint c)
1026 llassertfatal (constraint_isDefined (c));
1028 if (c->orig != NULL)
1030 c->orig = constraint_togglePost (c->orig);
1033 return c;
1036 bool constraint_hasOrig ( /*@observer@*/ /*@temp@*/ constraint c)
1038 llassertfatal (constraint_isDefined (c));
1039 return (c->orig != NULL);
1043 constraint constraint_undump (FILE *f)
1045 constraint c;
1046 bool fcnPre, post;
1047 arithType ar;
1048 constraintExpr lexpr, expr;
1049 char *s, *os;
1051 os = mstring_create (MAX_DUMP_LINE_LENGTH);
1052 s = fgets (os, MAX_DUMP_LINE_LENGTH, f);
1054 if (!mstring_isDefined (s))
1056 llfatalbug (message ("Library file is corrupted") );
1059 fcnPre = (bool) reader_getInt (&s);
1060 advanceField (&s);
1061 post = (bool) reader_getInt (&s);
1062 advanceField (&s);
1063 ar = (arithType) reader_getInt (&s);
1065 s = fgets (os, MAX_DUMP_LINE_LENGTH, f);
1067 if (! mstring_isDefined(s) )
1069 llfatalbug(message("Library file is corrupted") );
1072 reader_checkChar (&s, 'l');
1074 lexpr = constraintExpr_undump (f);
1076 s = fgets (os, MAX_DUMP_LINE_LENGTH, f);
1078 reader_checkChar (&s, 'r');
1080 if (! mstring_isDefined(s) )
1082 llfatalbug(message("Library file is corrupted") );
1085 expr = constraintExpr_undump (f);
1087 c = constraint_makeNew ();
1089 c->fcnPre = fcnPre;
1090 c->post = post;
1091 c->ar = ar;
1093 c->lexpr = lexpr;
1094 c->expr = expr;
1096 free (os);
1097 c = constraint_preserveOrig (c);
1098 return c;
1102 void constraint_dump (/*@observer@*/ constraint c, FILE *f)
1104 bool fcnPre;
1105 bool post;
1106 arithType ar;
1108 constraintExpr lexpr;
1109 constraintExpr expr;
1111 llassertfatal (constraint_isDefined (c));
1113 fcnPre = c->fcnPre;
1114 post = c->post;
1115 ar = c->ar;
1116 lexpr = c->lexpr;
1117 expr = c->expr;
1119 fprintf (f, "%d@%d@%d\n", (int) fcnPre, (int) post, (int) ar);
1120 fprintf (f,"l\n");
1121 constraintExpr_dump (lexpr, f);
1122 fprintf (f,"r\n");
1123 constraintExpr_dump (expr, f);
1127 int constraint_compare (/*@observer@*/ /*@temp@*/ const constraint * c1, /*@observer@*/ /*@temp@*/ const constraint * c2) /*@*/
1129 fileloc loc1, loc2;
1131 int ret;
1133 llassert (constraint_isDefined (*c1));
1134 llassert (constraint_isDefined (*c2));
1136 if (constraint_isUndefined (*c1))
1138 if (constraint_isUndefined (*c2))
1139 return 0;
1140 else
1141 return 1;
1144 if (constraint_isUndefined (*c2))
1146 return -1;
1149 loc1 = constraint_getFileloc (*c1);
1150 loc2 = constraint_getFileloc (*c2);
1152 ret = fileloc_compare (loc1, loc2);
1154 fileloc_free (loc1);
1155 fileloc_free (loc2);
1157 return ret;
1161 bool constraint_isPost (/*@observer@*/ /*@temp@*/ constraint c)
1163 llassert (constraint_isDefined (c));
1165 if (constraint_isUndefined (c))
1166 return FALSE;
1168 return (c->post);
1172 static int constraint_getDepth (/*@observer@*/ /*@temp@*/ constraint c)
1174 int l , r;
1176 llassertfatal (constraint_isDefined (c));
1178 l = constraintExpr_getDepth (c->lexpr);
1179 r = constraintExpr_getDepth (c->expr);
1181 if (l > r)
1183 DPRINTF (( message ("constraint depth returning %d for %s", l, constraint_unparse (c))));
1184 return l;
1186 else
1188 DPRINTF (( message ("constraint depth returning %d for %s", r, constraint_unparse (c))));
1189 return r;
1194 bool constraint_tooDeep (/*@observer@*/ /*@temp@*/ constraint c)
1196 int temp;
1198 temp = constraint_getDepth (c);
1200 if (temp >= 20)
1202 return TRUE;
1205 return FALSE;
1209 /*drl added 12/19/2002*/
1210 /*whether constraints consist only of
1211 terms which are constants*/
1212 static bool
1213 constraint_isConstantOnly (constraint c)
1215 bool l, r;
1217 llassertfatal (constraint_isDefined (c));
1219 l = constraintExpr_isConstantOnly(c->lexpr);
1220 r = constraintExpr_isConstantOnly(c->expr);
1222 if (l && r)
1224 return TRUE;
1227 else
1229 return FALSE;