]> andersk Git - splint.git/blob - src/constraint.c
o Make lltok an abstract type, a pointer to structure instead of a plain
[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: 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
47 static /*@only@*/ cstring  constraint_printDetailedPostCondition (/*@observer@*/ /*@temp@*/ constraint p_c);
48
49
50 static /*@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      
54 static void
55 advanceField (char **s)
56 {
57   reader_checkChar (s, '@');
58 }
59
60 # if 0
61 static 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
93 bool 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
116 constraint 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
153 constraint 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
186 void 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
229 static /*@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
246 constraint 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
261 constraint 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
275 constraint 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
293 fileloc 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
303 static bool checkForMaxSet (constraint c)
304 {
305   if (constraintExpr_hasMaxSet (c->lexpr) || constraintExpr_hasMaxSet (c->expr))
306     return TRUE;
307
308   return FALSE;
309 }
310
311 bool 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
325 constraint 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
338 constraint 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
349 constraint 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
359 constraint 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
375 constraint 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
386 constraint 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
398 constraint 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
409 constraint 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
421 constraint 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
432 static 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
449 static 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
476 constraint 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 */
482 constraint 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
496 constraint constraint_makeEnsureLessThanEqual (exprNode e1, exprNode e2, fileloc sequencePoint)
497 {
498  return ( constraint_makeEnsuresOp (e1, e2, sequencePoint, LTE));
499 }
500
501 constraint 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
516 constraint constraint_makeEnsureGreaterThanEqual (exprNode e1, exprNode e2, fileloc sequencePoint)
517 {
518  return ( constraint_makeEnsuresOp (e1, e2, sequencePoint, GTE));
519 }
520
521
522 exprNode 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 */
537 constraint 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 */
560 constraint 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
581 constraint 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 }
593 constraint 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
608 void 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
631 cstring 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
664 void 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*/
696 cstring 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
714 void 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
771 static 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
807 static /*@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
834 cstring  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
921 cstring  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
956 constraint 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
989 constraint 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
1033 constraint constraint_togglePost (/*@returned@*/ constraint c)
1034 {
1035   c->post = !c->post;
1036   return c;
1037 }
1038
1039 constraint constraint_togglePostOrig (/*@returned@*/ constraint c)
1040 {
1041   if (c->orig != NULL)
1042     c->orig = constraint_togglePost (c->orig);
1043   return c;
1044 }
1045
1046 bool constraint_hasOrig ( /*@observer@*/ /*@temp@*/ constraint c)
1047 {
1048   if (c->orig == NULL)
1049     return FALSE;
1050   else
1051     return TRUE;
1052 }
1053
1054
1055 constraint 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
1108 void 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
1132 int 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
1166 bool 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
1177 static 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
1197 bool 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.127582 seconds and 5 git commands to generate.