]> andersk Git - splint.git/blob - src/constraint.c
Renaming - LCLint => Splint
[splint.git] / src / constraint.c
1 /*
2 ** Splint - 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://www.splint.org
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
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         voptgenerror (FLG_ARRAYBOUNDS, string, errorLoc);
739       else
740         voptgenerror (FLG_ARRAYBOUNDSREAD, string, errorLoc);
741     }
742
743   fileloc_free(errorLoc);
744
745 }
746
747
748 static 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
784 static /*@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:\nSplint 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
811 cstring  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
898 cstring  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
933 constraint 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
954 constraint 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
998 constraint constraint_togglePost (/*@returned@*/ constraint c)
999 {
1000   c->post = !c->post;
1001   return c;
1002 }
1003
1004 constraint constraint_togglePostOrig (/*@returned@*/ constraint c)
1005 {
1006   if (c->orig != NULL)
1007     c->orig = constraint_togglePost(c->orig);
1008   return c;
1009 }
1010
1011 bool constraint_hasOrig( /*@observer@*/ /*@temp@*/ constraint c)
1012 {
1013   if (c->orig == NULL)
1014     return FALSE;
1015   else
1016     return TRUE;
1017 }
1018
1019
1020 constraint 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
1073 void 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
1097 int 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
1131 bool 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
1142 static 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
1162 bool 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.134185 seconds and 5 git commands to generate.