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