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