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