]> andersk Git - splint.git/blob - src/constraint.c
e7db524a22ddee6917c1dfcaf86cb5f23558da50
[splint.git] / src / constraint.c
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: splint@cs.virginia.edu
21 ** To report a bug: splint-bug@cs.virginia.edu
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 @*/
43
44
45 static /*@only@*/ cstring  constraint_printDetailedPostCondition (/*@observer@*/ /*@temp@*/ constraint p_c);
46
47
48 static /*@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      
52 static void
53 advanceField (char **s)
54 {
55   reader_checkChar (s, '@');
56 }
57
58 # if 0
59 static 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
91 bool 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
114 constraint 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
145 constraint 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
178 void 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
221 static /*@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
238 constraint 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
253 constraint 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
267 constraint 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
285 fileloc 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
295 static bool checkForMaxSet (constraint c)
296 {
297   if (constraintExpr_hasMaxSet (c->lexpr) || constraintExpr_hasMaxSet (c->expr))
298     return TRUE;
299
300   return FALSE;
301 }
302
303 bool 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
317 constraint 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
330 constraint 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
341 constraint 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
351 constraint 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
367 constraint 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
378 constraint 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
390 constraint 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
401 constraint 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
413 constraint 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
424 static 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
441 static 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
468 constraint 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 */
474 constraint 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
488 constraint constraint_makeEnsureLessThanEqual (exprNode e1, exprNode e2, fileloc sequencePoint)
489 {
490  return ( constraint_makeEnsuresOp (e1, e2, sequencePoint, LTE));
491 }
492
493 constraint 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
508 constraint constraint_makeEnsureGreaterThanEqual (exprNode e1, exprNode e2, fileloc sequencePoint)
509 {
510  return ( constraint_makeEnsuresOp (e1, e2, sequencePoint, GTE));
511 }
512
513
514 exprNode 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 */
529 constraint 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 */
552 constraint 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
573 constraint 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 }
585 constraint 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
600 void 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
623 cstring 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
656 void 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*/
682 cstring 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
700 void 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         {
739           voptgenerror (FLG_BOUNDSWRITE, string, errorLoc);
740         }
741       else
742         {
743           voptgenerror (FLG_BOUNDSREAD, string, errorLoc);
744         }
745     }
746
747   fileloc_free(errorLoc);
748 }
749
750 static cstring constraint_printDeep (constraint c)
751 {
752   cstring genExpr;
753   cstring st = cstring_undefined;
754
755   st = constraint_print(c);
756   
757   if (c->orig != constraint_undefined)
758     {
759       st = cstring_appendChar (st, '\n');
760       genExpr =  exprNode_unparse (c->orig->generatingExpr);
761
762       if (!c->post)
763         {
764           if (c->orig->fcnPre)
765             {
766               st = cstring_concatFree (st, message (" derived from %s precondition: %q", 
767                                                     genExpr, constraint_printDeep (c->orig)));
768             }
769           else
770             {
771               st = cstring_concatFree (st, message (" needed to satisfy precondition:\n%q",
772                                                    constraint_printDeep (c->orig)));
773             }
774         }
775       else
776         {
777           st = cstring_concatFree (st, message ("derived from: %q",
778                                                constraint_printDeep (c->orig)));
779         }
780     }
781
782   return st;  
783 }
784
785
786 static /*@only@*/ cstring  constraint_printDetailedPostCondition (/*@observer@*/ /*@temp@*/ constraint c)
787 {
788   cstring st = cstring_undefined;
789   cstring genExpr;
790   
791   st = message ("Unsatisfied ensures constraint condition:\nSplint is unable to verify the constraint %q", constraint_printDeep (c));
792
793   genExpr = exprNode_unparse (c->generatingExpr);
794     
795   if (context_getFlag (FLG_CONSTRAINTLOCATION))
796     {
797       cstring temp;
798
799       temp = message ("\nOriginal Generating expression %q: %s\n", 
800                       fileloc_unparse ( exprNode_getfileloc (c->generatingExpr)),
801                       genExpr);
802       st = cstring_concatFree (st, temp);
803
804       if (constraint_hasMaxSet (c))
805         {
806           temp = message ("Has MaxSet\n");
807           st = cstring_concatFree (st, temp);
808         }
809     }
810   return st;
811 }
812
813 cstring  constraint_printDetailed (constraint c)
814 {
815   cstring st = cstring_undefined;
816   cstring temp = cstring_undefined;
817     cstring genExpr;
818   
819   if (!c->post)
820     {
821       st = message ("Unable to resolve constraint:\n%q", constraint_printDeep (c));
822     }
823   else
824     {
825       st = message ("Block Post condition:\nThis function block has the post condition %q", constraint_printDeep (c));
826     }
827
828   if (constraint_hasMaxSet (c))
829     {
830       temp = cstring_makeLiteral ("Possible out-of-bounds store:\n");
831     }
832   else
833     {
834       temp = cstring_makeLiteral ("Possible out-of-bounds read:\n");
835     }
836   
837   genExpr = exprNode_unparse (c->generatingExpr);
838   
839   if (context_getFlag (FLG_CONSTRAINTLOCATION))
840     {
841       cstring temp2;
842       temp2 = message ("%s\n", genExpr);
843       temp = cstring_concatFree (temp, temp2);
844     }
845
846   st  = cstring_concatFree (temp,st);
847   
848   return st;
849 }
850
851 /*@only@*/ cstring  constraint_print (constraint c) /*@*/
852 {
853   cstring st = cstring_undefined;
854   cstring type = cstring_undefined;
855   llassert (c !=NULL);
856   if (c->post)
857     {
858       if (context_getFlag (FLG_PARENCONSTRAINT))
859         {
860           type = cstring_makeLiteral ("ensures: ");
861         }
862       else
863         {
864            type = cstring_makeLiteral ("ensures");
865         }
866     }
867   else
868     {
869       if (context_getFlag (FLG_PARENCONSTRAINT))
870         {
871           type = cstring_makeLiteral ("requires: ");
872         }
873       else
874         {
875           type = cstring_makeLiteral ("requires");
876         }
877         
878     }
879       if (context_getFlag (FLG_PARENCONSTRAINT))
880         {
881           st = message ("%q: %q %q %q",
882                         type,
883                         constraintExpr_print (c->lexpr),
884                         arithType_print (c->ar),
885                         constraintExpr_print (c->expr)
886                         );
887         }
888       else
889         {
890           st = message ("%q %q %q %q",
891                         type,
892                         constraintExpr_print (c->lexpr),
893                         arithType_print (c->ar),
894                         constraintExpr_print (c->expr)
895                 );
896         }
897   return st;
898 }
899
900 cstring  constraint_printOr (constraint c) /*@*/
901 {
902   cstring ret;
903   constraint temp;
904
905   ret = cstring_undefined;
906   temp = c;
907
908   ret = cstring_concatFree (ret, constraint_print (temp));
909
910   temp = temp->or;
911   
912   while ( constraint_isDefined (temp)) 
913     {
914       ret = cstring_concatFree (ret, cstring_makeLiteral (" OR "));
915       ret = cstring_concatFree (ret, constraint_print (temp));
916       temp = temp->or;
917     }
918
919   return ret;
920
921 }
922
923 /*@only@*/ constraint constraint_doSRefFixBaseParam (/*@returned@*/ /*@only@*/ constraint precondition,
924                                                    exprNodeList arglist)
925 {
926   precondition->lexpr = constraintExpr_doSRefFixBaseParam (precondition->lexpr,
927                                                            arglist);
928   precondition->expr = constraintExpr_doSRefFixBaseParam (precondition->expr,
929                                                            arglist);
930
931   return precondition;
932 }
933
934
935 constraint constraint_doFixResult (constraint postcondition, /*@dependent@*/ exprNode fcnCall)
936 {
937   postcondition = constraint_copy (postcondition);
938   postcondition->lexpr = constraintExpr_doFixResult (postcondition->lexpr, fcnCall);
939   postcondition->expr = constraintExpr_doFixResult (postcondition->expr, fcnCall);
940
941   return postcondition;
942 }
943 /*Commenting out temporally
944   
945 / *@only@* /constraint  constraint_doSRefFixInvarConstraint(constraint invar, sRef s, ctype ct )
946 {
947
948   invar = constraint_copy (invar);
949   invar->lexpr = constraintExpr_doSRefFixInvarConstraint (invar->lexpr, s, ct);
950   invar->expr = constraintExpr_doSRefFixInvarConstraint (invar->expr, s, ct);
951
952   return invar;
953 }
954 */
955
956 /*@only@*/ constraint constraint_doSRefFixConstraintParam (constraint precondition,
957                                                    exprNodeList arglist)
958 {
959
960   precondition = constraint_copy (precondition);
961   precondition->lexpr = constraintExpr_doSRefFixConstraintParam (precondition->lexpr, arglist);
962   precondition->expr = constraintExpr_doSRefFixConstraintParam (precondition->expr, arglist);
963
964   precondition->fcnPre = FALSE;
965   return precondition;
966 }
967
968 constraint constraint_preserveOrig (/*@returned@*/ constraint c) /*@modifies c @*/
969 {
970
971   DPRINTF ((message ("Doing constraint_preserverOrig for %q ", constraint_printDetailed (c))));
972   
973   if (c->orig == constraint_undefined)
974     c->orig = constraint_copy (c);
975
976   else if (c->orig->fcnPre)
977     {
978       constraint temp;
979       
980       temp = c->orig;
981       
982       /* avoid infinite loop */
983       c->orig = NULL;
984       c->orig = constraint_copy (c);
985       if (c->orig->orig == NULL)
986         {
987           c->orig->orig = temp;
988           temp = NULL;
989         }
990       else
991         {
992           llcontbug ((message ("Expected c->orig->orig to be null")));
993           constraint_free (c->orig->orig);
994           c->orig->orig = temp;
995           temp = NULL;
996         }
997     }
998   else
999     {
1000       DPRINTF ((message ("Not changing constraint")));
1001     }
1002   
1003   DPRINTF ((message ("After Doing constraint_preserverOrig for %q ", constraint_printDetailed (c))));
1004
1005   return c;
1006 }
1007 /*@=fcnuse*/
1008 /*@=assignexpose*/
1009 /*@=czechfcns@*/
1010
1011
1012 constraint constraint_togglePost (/*@returned@*/ constraint c)
1013 {
1014   c->post = !c->post;
1015   return c;
1016 }
1017
1018 constraint constraint_togglePostOrig (/*@returned@*/ constraint c)
1019 {
1020   if (c->orig != NULL)
1021     c->orig = constraint_togglePost (c->orig);
1022   return c;
1023 }
1024
1025 bool constraint_hasOrig ( /*@observer@*/ /*@temp@*/ constraint c)
1026 {
1027   if (c->orig == NULL)
1028     return FALSE;
1029   else
1030     return TRUE;
1031 }
1032
1033
1034 constraint constraint_undump (FILE *f)
1035 {
1036   constraint c;
1037   bool           fcnPre;
1038   bool post;
1039   arithType       ar;
1040   
1041   constraintExpr lexpr;
1042   constraintExpr  expr;
1043
1044
1045   char * s;
1046
1047   char *os;
1048
1049   os = mstring_create (MAX_DUMP_LINE_LENGTH);
1050
1051   s = fgets (os, MAX_DUMP_LINE_LENGTH, f);
1052
1053   /*@i33*/ /*this should probably be wrappered...*/
1054   
1055   fcnPre = (bool) reader_getInt (&s);
1056   advanceField (&s);
1057   post = (bool) reader_getInt (&s);
1058   advanceField (&s);
1059   ar = (arithType) reader_getInt (&s);
1060
1061   s = fgets (os, MAX_DUMP_LINE_LENGTH, f);
1062
1063   reader_checkChar (&s, 'l');
1064
1065   lexpr = constraintExpr_undump (f);
1066
1067   s = fgets (os, MAX_DUMP_LINE_LENGTH, f);
1068
1069   reader_checkChar (&s, 'r');
1070   expr = constraintExpr_undump (f);
1071
1072   c = constraint_makeNew ();
1073   
1074   c->fcnPre = fcnPre; 
1075   c->post = post;
1076   c->ar = ar;
1077
1078   c->lexpr = lexpr;
1079   c->expr =  expr;
1080
1081   free (os);
1082   c = constraint_preserveOrig (c);
1083   return c;
1084 }
1085
1086
1087 void constraint_dump (/*@observer@*/ constraint c,  FILE *f)
1088 {
1089   bool           fcnPre;
1090   bool post;
1091   arithType       ar;
1092   
1093   constraintExpr lexpr;
1094   constraintExpr  expr;
1095
1096
1097   fcnPre = c->fcnPre;
1098   post   = c->post;
1099   ar     = c->ar;
1100   lexpr = c->lexpr;
1101   expr = c->expr;
1102   
1103   fprintf (f, "%d@%d@%d\n", (int) fcnPre, (int) post, (int) ar);
1104   fprintf (f,"l\n");
1105   constraintExpr_dump (lexpr, f);
1106   fprintf (f,"r\n");
1107   constraintExpr_dump (expr, f);
1108 }
1109
1110
1111 int constraint_compare (/*@observer@*/ /*@temp@*/ const constraint * c1, /*@observer@*/ /*@temp@*/ const constraint * c2) /*@*/
1112 {
1113   fileloc loc1, loc2;
1114
1115   int ret;
1116   
1117   llassert (constraint_isDefined (*c1));
1118   llassert (constraint_isDefined (*c2));
1119
1120   if (constraint_isUndefined (*c1))
1121     {
1122         if (constraint_isUndefined (*c2))
1123           return 0;
1124         else
1125           return 1;
1126     }
1127
1128   if (constraint_isUndefined (*c2))
1129     {
1130       return -1;
1131     }
1132     
1133   loc1 = constraint_getFileloc (*c1);
1134   loc2 = constraint_getFileloc (*c2);
1135
1136   ret = fileloc_compare (loc1, loc2);
1137
1138   fileloc_free (loc1);
1139   fileloc_free (loc2);
1140     
1141   return ret;
1142 }
1143
1144
1145 bool constraint_isPost  (/*@observer@*/ /*@temp@*/ constraint c)
1146 {
1147   llassert (constraint_isDefined (c));
1148
1149   if (constraint_isUndefined (c))
1150     return FALSE;
1151   
1152   return (c->post);
1153 }
1154
1155
1156 static int constraint_getDepth (/*@observer@*/ /*@temp@*/ constraint c)
1157 {
1158   int l , r;
1159
1160   l = constraintExpr_getDepth (c->lexpr);
1161   r = constraintExpr_getDepth (c->expr);
1162
1163   if (l > r)
1164     {
1165       DPRINTF (( message ("constraint depth returning %d for %s", l, constraint_print (c))));
1166       return l;
1167     }
1168   else
1169     {
1170       DPRINTF (( message ("constraint depth returning %d for %s", r, constraint_print (c))));
1171       return r;
1172     }
1173 }
1174
1175
1176 bool constraint_tooDeep (/*@observer@*/ /*@temp@*/ constraint c)
1177 {
1178   int temp;
1179
1180   temp = constraint_getDepth (c);
1181
1182   if (temp >= 20)              
1183     {
1184       return TRUE;
1185     }
1186
1187   return FALSE;
1188   
1189 }
This page took 0.122105 seconds and 3 git commands to generate.