]> andersk Git - splint.git/blame_incremental - src/constraint.c
Fixed /*@i@*/ splintme errors.
[splint.git] / src / constraint.c
... / ...
CommitLineData
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.
19**
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
23*/
24
25/*
26** constraint.c
27*/
28
29/* #define DEBUGPRINT 1 */
30
31# include "splintMacros.nf"
32# include "basic.h"
33# include "cgrammar.h"
34# include "cgrammar_tokens.h"
35# include "exprChecks.h"
36# include "exprNodeSList.h"
37
38static /*@only@*/ cstring
39constraint_unparseDetailedPostCondition (/*@observer@*/ /*@temp@*/ constraint p_c);
40
41static /*@notnull@*/ /*@special@*/ constraint constraint_makeNew (void)
42 /*@post:isnull result->or, result->orig, result->generatingExpr, result->fcnPre @*/
43 /*@defines result->or, result->generatingExpr, result->orig, result->fcnPre @*/;
44
45static void
46advanceField (char **s)
47{
48 reader_checkChar (s, '@');
49}
50
51bool constraint_same (constraint c1, constraint c2)
52{
53 llassert (c1 != NULL);
54 llassert (c2 != NULL);
55
56 if (c1->ar != c2->ar)
57 {
58 return FALSE;
59 }
60
61 if (!constraintExpr_similar (c1->lexpr, c2->lexpr))
62 {
63 return FALSE;
64 }
65
66 if (!constraintExpr_similar (c1->expr, c2->expr))
67 {
68 return FALSE;
69 }
70
71 return TRUE;
72}
73
74constraint makeConstraintParse3 (constraintExpr l, lltok relOp, constraintExpr r)
75{
76 constraint ret;
77 ret = constraint_makeNew ();
78 llassert (constraintExpr_isDefined (l));
79
80 ret->lexpr = constraintExpr_copy (l);
81
82 if (lltok_getTok (relOp) == GE_OP)
83 {
84 ret->ar = GTE;
85 }
86 else if (lltok_getTok (relOp) == LE_OP)
87 {
88 ret->ar = LTE;
89 }
90 else if (lltok_getTok (relOp) == EQ_OP)
91 {
92 ret->ar = EQ;
93 }
94 else
95 llfatalbug ( message ("Unsupported relational operator"));
96
97 ret->expr = constraintExpr_copy (r);
98
99 ret->post = TRUE;
100
101 ret->orig = constraint_copy (ret);
102
103 ret = constraint_simplify (ret);
104 /* ret->orig = ret; */
105
106 DPRINTF (("GENERATED CONSTRAINT:"));
107 DPRINTF ((message ("%s", constraint_unparse (ret))));
108 return ret;
109}
110
111constraint constraint_copy (/*@temp@*/ /*@observer@*/ constraint c)
112{
113 constraint ret;
114
115 llassert (constraint_isDefined (c));
116
117 ret = constraint_makeNew ();
118 ret->lexpr = constraintExpr_copy (c->lexpr);
119 ret->ar = c->ar;
120 ret->expr = constraintExpr_copy (c->expr);
121 ret->post = c->post;
122 /*@-assignexpose@*/
123 ret->generatingExpr = c->generatingExpr;
124 /*@=assignexpose@*/
125
126 /*@i33 fix this*/
127 if (c->orig != NULL)
128 ret->orig = constraint_copy (c->orig);
129 else
130 ret->orig = NULL;
131
132 if (c->or != NULL)
133 ret->or = constraint_copy (c->or);
134 else
135 ret->or = NULL;
136
137 ret->fcnPre = c->fcnPre;
138
139 return ret;
140}
141
142/*like copy expect it doesn't allocate memory for the constraint*/
143
144void constraint_overWrite (constraint c1, constraint c2)
145{
146 llassert (constraint_isDefined (c1) && constraint_isDefined (c2));
147
148 llassert (c1 != c2);
149
150 DPRINTF ((message ("OverWriteing constraint %q with %q", constraint_unparse (c1),
151 constraint_unparse (c2))));
152
153 constraintExpr_free (c1->lexpr);
154 constraintExpr_free (c1->expr);
155
156 c1->lexpr = constraintExpr_copy (c2->lexpr);
157 c1->ar = c2->ar;
158 c1->expr = constraintExpr_copy (c2->expr);
159 c1->post = c2->post;
160
161 if (c1->orig != NULL)
162 constraint_free (c1->orig);
163
164 if (c2->orig != NULL)
165 c1->orig = constraint_copy (c2->orig);
166 else
167 c1->orig = NULL;
168
169 /*@i33 make sure that the or is freed correctly*/
170 if (c1->or != NULL)
171 constraint_free (c1->or);
172
173 if (c2->or != NULL)
174 c1->or = constraint_copy (c2->or);
175 else
176 c1->or = NULL;
177
178 c1->fcnPre = c2->fcnPre;
179
180 /*@-assignexpose@*/
181 c1->generatingExpr = c2->generatingExpr;
182 /*@=assignexpose@*/
183}
184
185
186
187static /*@notnull@*/ /*@special@*/ constraint constraint_makeNew (void)
188 /*@post:isnull result->or, result->orig, result->generatingExpr, result->fcnPre @*/
189 /*@defines result->or, result->generatingExpr, result->orig, result->fcnPre @*/
190{
191 constraint ret;
192 ret = dmalloc (sizeof (*ret));
193 ret->lexpr = NULL;
194 ret->expr = NULL;
195 ret->ar = LT;
196 ret->post = FALSE;
197 ret->orig = NULL;
198 ret->or = NULL;
199 ret->generatingExpr = NULL;
200 ret->fcnPre = NULL;
201 return ret;
202}
203
204/*@access exprNode@*/
205
206constraint constraint_addGeneratingExpr (/*@returned@*/ constraint c, /*@exposed@*/ exprNode e)
207{
208
209 llassert (constraint_isDefined (c) );
210
211 if (c->generatingExpr == NULL)
212 {
213 c->generatingExpr = e;
214 DPRINTF ((message ("setting generatingExpr for %s to %s", constraint_unparse (c), exprNode_unparse (e)) ));
215 }
216 else
217 {
218 DPRINTF ((message ("Not setting generatingExpr for %s to %s", constraint_unparse (c), exprNode_unparse (e)) ));
219 }
220 return c;
221}
222/*@noaccess exprNode@*/
223
224constraint constraint_origAddGeneratingExpr (/*@returned@*/ constraint c, exprNode e)
225{
226 llassert (constraint_isDefined (c) );
227
228 if (c->orig != constraint_undefined)
229 {
230 c->orig = constraint_addGeneratingExpr (c->orig, e);
231 }
232 else
233 {
234 DPRINTF ((message ("constraint_origAddGeneratingExpr: Not setting generatingExpr for %s to %s", constraint_unparse (c), exprNode_unparse (e)) ));
235 }
236 return c;
237}
238
239constraint constraint_setFcnPre (/*@returned@*/ constraint c)
240{
241
242 llassert (constraint_isDefined (c) );
243
244 if (c->orig != constraint_undefined)
245 {
246 c->orig->fcnPre = TRUE;
247 }
248 else
249 {
250 c->fcnPre = TRUE;
251 DPRINTF (( message ("Warning Setting fcnPre directly")));
252 }
253 return c;
254}
255
256
257
258
259fileloc constraint_getFileloc (constraint c)
260{
261
262 llassert (constraint_isDefined (c) );
263
264 if (exprNode_isDefined (c->generatingExpr))
265 return (fileloc_copy (exprNode_getfileloc (c->generatingExpr)));
266
267 return (constraintExpr_getFileloc (c->lexpr));
268
269
270}
271
272static bool checkForMaxSet (constraint c)
273{
274
275 llassert (constraint_isDefined (c) );
276
277 if (constraintExpr_hasMaxSet (c->lexpr) || constraintExpr_hasMaxSet (c->expr))
278 return TRUE;
279
280 return FALSE;
281}
282
283bool constraint_hasMaxSet (constraint c)
284{
285
286 llassert (constraint_isDefined (c) );
287
288 if (checkForMaxSet (c))
289 return TRUE;
290
291 if (c->orig != NULL)
292 {
293 if (checkForMaxSet (c->orig))
294 return TRUE;
295 }
296
297 return FALSE;
298}
299
300constraint constraint_makeReadSafeExprNode (exprNode po, exprNode ind)
301{
302 constraint ret = constraint_makeNew ();
303
304 po = po;
305 ind = ind;
306 ret->lexpr = constraintExpr_makeMaxReadExpr (po);
307 ret->ar = GTE;
308 ret->expr = constraintExpr_makeValueExpr (ind);
309 ret->post = FALSE;
310 return ret;
311}
312
313constraint constraint_makeWriteSafeInt ( exprNode po, int ind)
314{
315 constraint ret = constraint_makeNew ();
316
317 ret->lexpr =constraintExpr_makeMaxSetExpr (po);
318 ret->ar = GTE;
319 ret->expr = constraintExpr_makeIntLiteral (ind);
320 /*@i1*/return ret;
321}
322
323constraint constraint_makeSRefSetBufferSize (sRef s, long int size)
324{
325 constraint ret = constraint_makeNew ();
326 ret->lexpr = constraintExpr_makeSRefMaxset (s);
327 ret->ar = EQ;
328 ret->expr = constraintExpr_makeIntLiteral ((int)size);
329 ret->post = TRUE;
330 /*@i1*/
331 return ret;
332}
333
334constraint constraint_makeSRefWriteSafeInt (sRef s, int ind)
335{
336 constraint ret = constraint_makeNew ();
337
338
339 ret->lexpr = constraintExpr_makeSRefMaxset ( s);
340 ret->ar = GTE;
341 ret->expr = constraintExpr_makeIntLiteral (ind);
342 ret->post = TRUE;
343 /*@i1*/
344 return ret;
345}
346
347/* drl added 01/12/2000
348
349 makes the constraint: Ensures index <= MaxRead (buffer) */
350
351constraint constraint_makeEnsureLteMaxRead (exprNode index, exprNode buffer)
352{
353 constraint ret = constraint_makeNew ();
354
355 ret->lexpr = constraintExpr_makeValueExpr (index);
356 ret->ar = LTE;
357 ret->expr = constraintExpr_makeMaxReadExpr (buffer);
358 ret->post = TRUE;
359 return ret;
360}
361
362constraint constraint_makeWriteSafeExprNode (exprNode po, exprNode ind)
363{
364 constraint ret = constraint_makeNew ();
365
366
367 ret->lexpr =constraintExpr_makeMaxSetExpr (po);
368 ret->ar = GTE;
369 ret->expr = constraintExpr_makeValueExpr (ind);
370 /*@i1*/return ret;
371}
372
373
374constraint constraint_makeReadSafeInt ( exprNode t1, int index)
375{
376 constraint ret = constraint_makeNew ();
377
378 ret->lexpr = constraintExpr_makeMaxReadExpr (t1);
379 ret->ar = GTE;
380 ret->expr = constraintExpr_makeIntLiteral (index);
381 ret->post = FALSE;
382 return ret;
383}
384
385constraint constraint_makeSRefReadSafeInt (sRef s, int ind)
386{
387 constraint ret = constraint_makeNew ();
388
389
390 ret->lexpr = constraintExpr_makeSRefMaxRead (s);
391 ret->ar = GTE;
392 ret->expr = constraintExpr_makeIntLiteral (ind);
393 ret->post = TRUE;
394 return ret;
395}
396
397constraint constraint_makeEnsureMaxReadAtLeast (exprNode t1, exprNode t2, fileloc sequencePoint)
398{
399 constraint ret;
400
401 ret = constraint_makeReadSafeExprNode (t1, t2);
402 llassert (constraint_isDefined (ret) );
403
404 ret->lexpr = constraintExpr_setFileloc (ret->lexpr, sequencePoint);
405 ret->post = TRUE;
406
407 return ret;
408}
409
410static constraint constraint_makeEnsuresOpConstraintExpr (/*@only@*/ constraintExpr c1, /*@only@*/ constraintExpr c2, fileloc sequencePoint, arithType ar)
411{
412
413 constraint ret;
414
415 llassert (constraintExpr_isDefined (c1) && constraintExpr_isDefined (c2));
416
417 ret = constraint_makeNew ();
418
419 ret->lexpr = c1;
420 ret->ar = ar;
421 ret->post = TRUE;
422 ret->expr = c2;
423 ret->lexpr = constraintExpr_setFileloc (ret->lexpr, sequencePoint);
424 return ret;
425}
426
427static constraint constraint_makeEnsuresOp (/*@dependent@*/ exprNode e1, /*@dependent@*/ exprNode e2, fileloc sequencePoint, arithType ar)
428{
429 constraintExpr c1, c2;
430 constraint ret;
431 exprNode e;
432
433 if (! (exprNode_isDefined (e1) && exprNode_isDefined (e2)))
434 {
435 llcontbug ((message ("null exprNode, Exprnodes are %s and %s",
436 exprNode_unparse (e1), exprNode_unparse (e2))
437 ));
438 }
439
440 e = e1;
441 c1 = constraintExpr_makeValueExpr (e);
442
443 e = e2;
444 c2 = constraintExpr_makeValueExpr (e);
445
446 ret = constraint_makeEnsuresOpConstraintExpr (c1, c2, sequencePoint, ar);
447
448 return ret;
449}
450
451
452/* make constraint ensures e1 == e2 */
453
454constraint constraint_makeEnsureEqual (exprNode e1, exprNode e2, fileloc sequencePoint)
455{
456 return ( constraint_makeEnsuresOp (e1, e2, sequencePoint, EQ));
457}
458
459/*make constraint ensures e1 < e2 */
460constraint constraint_makeEnsureLessThan (exprNode e1, exprNode e2, fileloc sequencePoint)
461{
462 constraintExpr t1, t2;
463 constraint t3;
464
465 t1 = constraintExpr_makeValueExpr (e1);
466 t2 = constraintExpr_makeValueExpr (e2);
467
468 /*change this to e1 <= (e2 -1) */
469
470 t2 = constraintExpr_makeDecConstraintExpr (t2);
471
472 t3 = constraint_makeEnsuresOpConstraintExpr (t1, t2, sequencePoint, LTE);
473
474 t3 = constraint_simplify(t3);
475 return (t3);
476}
477
478constraint constraint_makeEnsureLessThanEqual (exprNode e1, exprNode e2, fileloc sequencePoint)
479{
480 return ( constraint_makeEnsuresOp (e1, e2, sequencePoint, LTE));
481}
482
483constraint constraint_makeEnsureGreaterThan (exprNode e1, exprNode e2, fileloc sequencePoint)
484{
485 constraintExpr t1, t2;
486 constraint t3;
487
488 t1 = constraintExpr_makeValueExpr (e1);
489 t2 = constraintExpr_makeValueExpr (e2);
490
491
492 /* change this to e1 >= (e2 + 1) */
493 t2 = constraintExpr_makeIncConstraintExpr (t2);
494
495 t3 = constraint_makeEnsuresOpConstraintExpr (t1, t2, sequencePoint, GTE);
496
497 t3 = constraint_simplify(t3);
498
499 return t3;
500}
501
502constraint constraint_makeEnsureGreaterThanEqual (exprNode e1, exprNode e2, fileloc sequencePoint)
503{
504 return ( constraint_makeEnsuresOp (e1, e2, sequencePoint, GTE));
505}
506
507
508
509/* Makes the constraint e = e + f */
510constraint constraint_makeAddAssign (exprNode e, exprNode f, fileloc sequencePoint)
511{
512 constraintExpr x1, x2, y;
513 constraint ret;
514
515 ret = constraint_makeNew ();
516
517 x1 = constraintExpr_makeValueExpr (e);
518 x2 = constraintExpr_copy (x1);
519 y = constraintExpr_makeValueExpr (f);
520
521 ret->lexpr = x1;
522 ret->ar = EQ;
523 ret->post = TRUE;
524 ret->expr = constraintExpr_makeAddExpr (x2, y);
525
526 ret->lexpr = constraintExpr_setFileloc (ret->lexpr, sequencePoint);
527
528 return ret;
529}
530
531
532/* Makes the constraint e = e - f */
533constraint constraint_makeSubtractAssign (exprNode e, exprNode f, fileloc sequencePoint)
534{
535 constraintExpr x1, x2, y;
536 constraint ret;
537
538 ret = constraint_makeNew ();
539
540 x1 = constraintExpr_makeValueExpr (e);
541 x2 = constraintExpr_copy (x1);
542 y = constraintExpr_makeValueExpr (f);
543
544 ret->lexpr = x1;
545 ret->ar = EQ;
546 ret->post = TRUE;
547 ret->expr = constraintExpr_makeSubtractExpr (x2, y);
548
549 ret->lexpr = constraintExpr_setFileloc (ret->lexpr, sequencePoint);
550
551 return ret;
552}
553
554constraint constraint_makeMaxSetSideEffectPostDecrement (exprNode e, fileloc sequencePoint)
555{
556 constraint ret = constraint_makeNew ();
557
558 ret->lexpr = constraintExpr_makeValueExpr (e);
559 ret->ar = EQ;
560 ret->post = TRUE;
561 ret->expr = constraintExpr_makeValueExpr (e);
562 ret->expr = constraintExpr_makeDecConstraintExpr (ret->expr);
563 ret->lexpr = constraintExpr_setFileloc (ret->lexpr, sequencePoint);
564 return ret;
565}
566constraint constraint_makeMaxSetSideEffectPostIncrement (exprNode e, fileloc sequencePoint)
567{
568 constraint ret = constraint_makeNew ();
569
570 ret->lexpr = constraintExpr_makeValueExpr (e);
571 ret->ar = EQ;
572 ret->post = TRUE;
573 ret->expr = constraintExpr_makeValueExpr (e);
574 ret->expr = constraintExpr_makeIncConstraintExpr (ret->expr);
575
576 ret->lexpr = constraintExpr_setFileloc (ret->lexpr, sequencePoint);
577 return ret;
578}
579
580
581void constraint_free (/*@only@*/ constraint c)
582{
583 llassert (constraint_isDefined (c));
584
585
586 if (constraint_isDefined (c->orig))
587 constraint_free (c->orig);
588 if ( constraint_isDefined (c->or))
589 constraint_free (c->or);
590
591
592 constraintExpr_free (c->lexpr);
593 constraintExpr_free (c->expr);
594
595 c->orig = NULL;
596 c->or = NULL;
597 c->lexpr = NULL;
598 c->expr = NULL;
599
600 free (c);
601
602}
603
604cstring arithType_print (arithType ar) /*@*/
605{
606 cstring st = cstring_undefined;
607 switch (ar)
608 {
609 case LT:
610 st = cstring_makeLiteral ("<");
611 break;
612 case LTE:
613 st = cstring_makeLiteral ("<=");
614 break;
615 case GT:
616 st = cstring_makeLiteral (">");
617 break;
618 case GTE:
619 st = cstring_makeLiteral (">=");
620 break;
621 case EQ:
622 st = cstring_makeLiteral ("==");
623 break;
624 case NONNEGATIVE:
625 st = cstring_makeLiteral ("NONNEGATIVE");
626 break;
627 case POSITIVE:
628 st = cstring_makeLiteral ("POSITIVE");
629 break;
630 default:
631 llassert (FALSE);
632 break;
633 }
634 return st;
635}
636
637void constraint_printErrorPostCondition (constraint c, fileloc loc)
638{
639 cstring string;
640 fileloc errorLoc, temp;
641
642 string = constraint_unparseDetailedPostCondition (c);
643
644 errorLoc = loc;
645
646 loc = NULL;
647
648 temp = constraint_getFileloc (c);
649
650
651 if (context_getFlag (FLG_BOUNDSCOMPACTERRORMESSAGES ) )
652 {
653 string = cstring_replaceChar(string, '\n', ' ');
654 }
655
656 if (fileloc_isDefined (temp))
657 {
658 errorLoc = temp;
659 voptgenerror ( FLG_CHECKPOST, string, errorLoc);
660 fileloc_free (temp);
661 }
662 else
663 {
664 voptgenerror ( FLG_CHECKPOST, string, errorLoc);
665 }
666}
667
668 /*drl added 8-11-001*/
669cstring constraint_printLocation (/*@observer@*/ /*@temp@*/ constraint c) /*@*/
670{
671 cstring string, ret;
672 fileloc errorLoc;
673
674 string = constraint_unparse (c);
675
676 errorLoc = constraint_getFileloc (c);
677
678 ret = message ("constraint: %q @ %q", string, fileloc_unparse (errorLoc));
679
680 fileloc_free (errorLoc);
681 return ret;
682
683}
684
685
686
687void constraint_printError (constraint c, fileloc loc)
688{
689 cstring string;
690 fileloc errorLoc, temp;
691
692 bool isLikely;
693
694
695 llassert (constraint_isDefined (c) );
696
697 /*drl 11/26/2001 avoid printing tautological constraints */
698 if (constraint_isAlwaysTrue (c))
699 {
700 return;
701 }
702
703
704 string = constraint_unparseDetailed (c);
705
706 errorLoc = loc;
707
708 temp = constraint_getFileloc (c);
709
710 if (fileloc_isDefined (temp))
711 {
712 errorLoc = temp;
713 }
714 else
715 {
716 llassert (FALSE);
717 DPRINTF (("constraint %s had undefined fileloc %s", constraint_unparse (c), fileloc_unparse (temp)));
718 fileloc_free (temp);
719 errorLoc = fileloc_copy (errorLoc);
720 }
721
722
723 if (context_getFlag (FLG_BOUNDSCOMPACTERRORMESSAGES ) )
724 {
725 string = cstring_replaceChar(string, '\n', ' ');
726 }
727
728 /*drl added 12/19/2002 print
729 a different error fro "likely" bounds-errors*/
730
731 isLikely = constraint_isConstantOnly(c);
732
733 if (isLikely)
734 {
735 if (c->post)
736 {
737 voptgenerror (FLG_FUNCTIONPOST, string, errorLoc);
738 }
739 else
740 {
741 if (constraint_hasMaxSet (c))
742 {
743 voptgenerror (FLG_LIKELYBOUNDSWRITE, string, errorLoc);
744 }
745 else
746 {
747 voptgenerror (FLG_LIKELYBOUNDSREAD, string, errorLoc);
748 }
749 }
750 }
751 else if (c->post)
752 {
753 voptgenerror (FLG_FUNCTIONPOST, string, errorLoc);
754 }
755 else
756 {
757 if (constraint_hasMaxSet (c))
758 {
759 voptgenerror (FLG_BOUNDSWRITE, string, errorLoc);
760 }
761 else
762 {
763 voptgenerror (FLG_BOUNDSREAD, string, errorLoc);
764 }
765 }
766
767 fileloc_free(errorLoc);
768}
769
770static cstring constraint_unparseDeep (constraint c)
771{
772 cstring genExpr;
773 cstring st;
774
775 llassert (constraint_isDefined (c));
776 st = constraint_unparse (c);
777
778 if (c->orig != constraint_undefined)
779 {
780 st = cstring_appendChar (st, '\n');
781 genExpr = exprNode_unparse (c->orig->generatingExpr);
782
783 if (!c->post)
784 {
785 if (c->orig->fcnPre)
786 {
787 st = cstring_concatFree (st, message (" derived from %s precondition: %q",
788 genExpr, constraint_unparseDeep (c->orig)));
789 }
790 else
791 {
792 st = cstring_concatFree (st, message (" needed to satisfy precondition:\n%q",
793 constraint_unparseDeep (c->orig)));
794 }
795 }
796 else
797 {
798 st = cstring_concatFree (st, message ("derived from: %q",
799 constraint_unparseDeep (c->orig)));
800 }
801 }
802
803 return st;
804}
805
806
807static /*@only@*/ cstring constraint_unparseDetailedPostCondition (/*@observer@*/ /*@temp@*/ constraint c)
808{
809 cstring st = cstring_undefined;
810 cstring genExpr;
811
812 llassert (constraint_isDefined (c) );
813
814 st = message ("Unsatisfied ensures constraint condition:\nSplint is unable to verify the constraint %q",
815 constraint_unparseDeep (c));
816
817 genExpr = exprNode_unparse (c->generatingExpr);
818
819 if (context_getFlag (FLG_CONSTRAINTLOCATION))
820 {
821 cstring temp;
822
823 temp = message ("\nOriginal Generating expression %q: %s\n",
824 fileloc_unparse ( exprNode_getfileloc (c->generatingExpr)),
825 genExpr);
826 st = cstring_concatFree (st, temp);
827
828 if (constraint_hasMaxSet (c))
829 {
830 temp = message ("Has MaxSet\n");
831 st = cstring_concatFree (st, temp);
832 }
833 }
834 return st;
835}
836
837cstring constraint_unparseDetailed (constraint c)
838{
839 cstring st = cstring_undefined;
840 cstring temp = cstring_undefined;
841 cstring genExpr;
842 bool isLikely;
843
844 llassert (constraint_isDefined (c) );
845
846 if (!c->post)
847 {
848 st = message ("Unable to resolve constraint:\n%q", constraint_unparseDeep (c));
849 }
850 else
851 {
852 st = message ("Block Post condition:\nThis function block has the post condition %q", constraint_unparseDeep (c));
853 }
854
855 isLikely = constraint_isConstantOnly(c);
856
857 if (isLikely)
858 {
859 if (constraint_hasMaxSet (c))
860 {
861 temp = cstring_makeLiteral ("Likely out-of-bounds store:\n");
862 }
863 else
864 {
865 temp = cstring_makeLiteral ("Likely out-of-bounds read:\n");
866 }
867 }
868 else
869 {
870
871 if (constraint_hasMaxSet (c))
872 {
873 temp = cstring_makeLiteral ("Possible out-of-bounds store:\n");
874 }
875 else
876 {
877 temp = cstring_makeLiteral ("Possible out-of-bounds read:\n");
878 }
879 }
880
881 genExpr = exprNode_unparse (c->generatingExpr);
882
883 if (context_getFlag (FLG_CONSTRAINTLOCATION))
884 {
885 cstring temp2;
886 temp2 = message ("%s\n", genExpr);
887 temp = cstring_concatFree (temp, temp2);
888 }
889
890 st = cstring_concatFree (temp,st);
891
892 return st;
893}
894
895/*@only@*/ cstring constraint_unparse (constraint c) /*@*/
896{
897 cstring st = cstring_undefined;
898 cstring type = cstring_undefined;
899 llassert (c !=NULL);
900 if (c->post)
901 {
902 if (context_getFlag (FLG_PARENCONSTRAINT))
903 {
904 type = cstring_makeLiteral ("ensures: ");
905 }
906 else
907 {
908 type = cstring_makeLiteral ("ensures");
909 }
910 }
911 else
912 {
913 if (context_getFlag (FLG_PARENCONSTRAINT))
914 {
915 type = cstring_makeLiteral ("requires: ");
916 }
917 else
918 {
919 type = cstring_makeLiteral ("requires");
920 }
921
922 }
923 if (context_getFlag (FLG_PARENCONSTRAINT))
924 {
925 st = message ("%q: %q %q %q",
926 type,
927 constraintExpr_print (c->lexpr),
928 arithType_print (c->ar),
929 constraintExpr_print (c->expr));
930 }
931 else
932 {
933 st = message ("%q %q %q %q",
934 type,
935 constraintExpr_print (c->lexpr),
936 arithType_print (c->ar),
937 constraintExpr_print (c->expr));
938 }
939 return st;
940}
941
942cstring constraint_unparseOr (constraint c) /*@*/
943{
944 cstring ret;
945 constraint temp;
946
947 ret = cstring_undefined;
948
949 llassert (constraint_isDefined (c) );
950
951 temp = c;
952
953 ret = cstring_concatFree (ret, constraint_unparse (temp));
954
955 temp = temp->or;
956
957 while ( constraint_isDefined (temp))
958 {
959 ret = cstring_concatFree (ret, cstring_makeLiteral (" OR "));
960 ret = cstring_concatFree (ret, constraint_unparse (temp));
961 temp = temp->or;
962 }
963
964 return ret;
965
966}
967
968/*@only@*/ constraint constraint_doSRefFixBaseParam (/*@returned@*/ /*@only@*/ constraint precondition,
969 exprNodeList arglist)
970{
971
972 llassert (constraint_isDefined (precondition) );
973
974 precondition->lexpr = constraintExpr_doSRefFixBaseParam (precondition->lexpr,
975 arglist);
976 precondition->expr = constraintExpr_doSRefFixBaseParam (precondition->expr,
977 arglist);
978
979 return precondition;
980}
981
982
983constraint constraint_doFixResult (constraint postcondition, /*@dependent@*/ exprNode fcnCall)
984{
985 postcondition = constraint_copy (postcondition);
986
987 llassert (constraint_isDefined (postcondition) );
988
989
990 postcondition->lexpr = constraintExpr_doFixResult (postcondition->lexpr, fcnCall);
991 postcondition->expr = constraintExpr_doFixResult (postcondition->expr, fcnCall);
992
993 return postcondition;
994}
995/*Commenting out temporally
996
997/ *@only@* /constraint constraint_doSRefFixInvarConstraint(constraint invar, sRef s, ctype ct )
998{
999
1000 invar = constraint_copy (invar);
1001 invar->lexpr = constraintExpr_doSRefFixInvarConstraint (invar->lexpr, s, ct);
1002 invar->expr = constraintExpr_doSRefFixInvarConstraint (invar->expr, s, ct);
1003
1004 return invar;
1005}
1006*/
1007
1008/*@only@*/ constraint constraint_doSRefFixConstraintParam (constraint precondition,
1009 exprNodeList arglist)
1010{
1011
1012 precondition = constraint_copy (precondition);
1013
1014 llassert (constraint_isDefined (precondition) );
1015
1016 precondition->lexpr = constraintExpr_doSRefFixConstraintParam (precondition->lexpr, arglist);
1017 precondition->expr = constraintExpr_doSRefFixConstraintParam (precondition->expr, arglist);
1018
1019 precondition->fcnPre = FALSE;
1020 return constraint_simplify(precondition);
1021}
1022
1023constraint constraint_preserveOrig (/*@returned@*/ constraint c) /*@modifies c @*/
1024{
1025 DPRINTF (("Doing constraint_preserverOrig for %q", constraint_printDetailed (c)));
1026 llassert (constraint_isDefined (c));
1027
1028 if (c->orig == constraint_undefined)
1029 {
1030 c->orig = constraint_copy (c);
1031 }
1032 else if (c->orig->fcnPre)
1033 {
1034 constraint temp = c->orig;
1035
1036 /* avoid infinite loop */
1037 c->orig = NULL;
1038 c->orig = constraint_copy (c);
1039 /*drl 03/2/2003 if c != NULL then the copy of c will != null*/
1040 llassert (constraint_isDefined (c->orig) );
1041
1042 if (c->orig->orig == NULL)
1043 {
1044 c->orig->orig = temp;
1045 temp = NULL;
1046 }
1047 else
1048 {
1049 llcontbug ((message ("Expected c->orig->orig to be null")));
1050 constraint_free (c->orig->orig);
1051 c->orig->orig = temp;
1052 temp = NULL;
1053 }
1054 }
1055 else
1056 {
1057 DPRINTF (("Not changing constraint"));
1058 }
1059
1060 DPRINTF ((message ("After Doing constraint_preserverOrig for %q ", constraint_unparseDetailed (c))));
1061 return c;
1062}
1063
1064constraint constraint_togglePost (/*@returned@*/ constraint c)
1065{
1066 llassert (constraint_isDefined (c));
1067 c->post = !c->post;
1068 return c;
1069}
1070
1071constraint constraint_togglePostOrig (/*@returned@*/ constraint c)
1072{
1073 llassert (constraint_isDefined (c));
1074
1075 if (c->orig != NULL)
1076 {
1077 c->orig = constraint_togglePost (c->orig);
1078 }
1079
1080 return c;
1081}
1082
1083bool constraint_hasOrig ( /*@observer@*/ /*@temp@*/ constraint c)
1084{
1085 llassert (constraint_isDefined (c));
1086 return (c->orig != NULL);
1087}
1088
1089
1090constraint constraint_undump (FILE *f)
1091{
1092 constraint c;
1093 bool fcnPre, post;
1094 arithType ar;
1095 constraintExpr lexpr, expr;
1096 char *s, *os;
1097
1098 os = mstring_create (MAX_DUMP_LINE_LENGTH);
1099 s = fgets (os, MAX_DUMP_LINE_LENGTH, f);
1100
1101 if (!mstring_isDefined (s))
1102 {
1103 llfatalbug (message ("Library file is corrupted") );
1104 }
1105
1106 fcnPre = (bool) reader_getInt (&s);
1107 advanceField (&s);
1108 post = (bool) reader_getInt (&s);
1109 advanceField (&s);
1110 ar = (arithType) reader_getInt (&s);
1111
1112 s = fgets (os, MAX_DUMP_LINE_LENGTH, f);
1113
1114 if (! mstring_isDefined(s) )
1115 {
1116 llfatalbug(message("Library file is corrupted") );
1117 }
1118
1119 reader_checkChar (&s, 'l');
1120
1121 lexpr = constraintExpr_undump (f);
1122
1123 s = fgets (os, MAX_DUMP_LINE_LENGTH, f);
1124
1125 reader_checkChar (&s, 'r');
1126
1127 if (! mstring_isDefined(s) )
1128 {
1129 llfatalbug(message("Library file is corrupted") );
1130 }
1131
1132 expr = constraintExpr_undump (f);
1133
1134 c = constraint_makeNew ();
1135
1136 c->fcnPre = fcnPre;
1137 c->post = post;
1138 c->ar = ar;
1139
1140 c->lexpr = lexpr;
1141 c->expr = expr;
1142
1143 free (os);
1144 c = constraint_preserveOrig (c);
1145 return c;
1146}
1147
1148
1149void constraint_dump (/*@observer@*/ constraint c, FILE *f)
1150{
1151 bool fcnPre;
1152 bool post;
1153 arithType ar;
1154
1155 constraintExpr lexpr;
1156 constraintExpr expr;
1157
1158 llassert (constraint_isDefined (c) );
1159
1160 fcnPre = c->fcnPre;
1161 post = c->post;
1162 ar = c->ar;
1163 lexpr = c->lexpr;
1164 expr = c->expr;
1165
1166 fprintf (f, "%d@%d@%d\n", (int) fcnPre, (int) post, (int) ar);
1167 fprintf (f,"l\n");
1168 constraintExpr_dump (lexpr, f);
1169 fprintf (f,"r\n");
1170 constraintExpr_dump (expr, f);
1171}
1172
1173
1174int constraint_compare (/*@observer@*/ /*@temp@*/ const constraint * c1, /*@observer@*/ /*@temp@*/ const constraint * c2) /*@*/
1175{
1176 fileloc loc1, loc2;
1177
1178 int ret;
1179
1180 llassert (constraint_isDefined (*c1));
1181 llassert (constraint_isDefined (*c2));
1182
1183 if (constraint_isUndefined (*c1))
1184 {
1185 if (constraint_isUndefined (*c2))
1186 return 0;
1187 else
1188 return 1;
1189 }
1190
1191 if (constraint_isUndefined (*c2))
1192 {
1193 return -1;
1194 }
1195
1196 loc1 = constraint_getFileloc (*c1);
1197 loc2 = constraint_getFileloc (*c2);
1198
1199 ret = fileloc_compare (loc1, loc2);
1200
1201 fileloc_free (loc1);
1202 fileloc_free (loc2);
1203
1204 return ret;
1205}
1206
1207
1208bool constraint_isPost (/*@observer@*/ /*@temp@*/ constraint c)
1209{
1210 llassert (constraint_isDefined (c));
1211
1212 if (constraint_isUndefined (c))
1213 return FALSE;
1214
1215 return (c->post);
1216}
1217
1218
1219static int constraint_getDepth (/*@observer@*/ /*@temp@*/ constraint c)
1220{
1221 int l , r;
1222
1223 llassert (constraint_isDefined (c) );
1224
1225 l = constraintExpr_getDepth (c->lexpr);
1226 r = constraintExpr_getDepth (c->expr);
1227
1228 if (l > r)
1229 {
1230 DPRINTF (( message ("constraint depth returning %d for %s", l, constraint_unparse (c))));
1231 return l;
1232 }
1233 else
1234 {
1235 DPRINTF (( message ("constraint depth returning %d for %s", r, constraint_unparse (c))));
1236 return r;
1237 }
1238}
1239
1240
1241bool constraint_tooDeep (/*@observer@*/ /*@temp@*/ constraint c)
1242{
1243 int temp;
1244
1245 temp = constraint_getDepth (c);
1246
1247 if (temp >= 20)
1248 {
1249 return TRUE;
1250 }
1251
1252 return FALSE;
1253
1254}
1255
1256/*drl added 12/19/2002*/
1257/*whether constraints consist only of
1258 terms which are constants*/
1259bool constraint_isConstantOnly (constraint c)
1260{
1261 bool l, r;
1262
1263 llassert (constraint_isDefined (c) );
1264
1265 l = constraintExpr_isConstantOnly(c->lexpr);
1266 r = constraintExpr_isConstantOnly(c->expr);
1267
1268 if (l && r)
1269 {
1270 return TRUE;
1271 }
1272
1273 else
1274 {
1275 return FALSE;
1276 }
1277
1278}
This page took 0.054722 seconds and 5 git commands to generate.