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