]> andersk Git - splint.git/blame - src/constraint.c
*** empty log message ***
[splint.git] / src / constraint.c
CommitLineData
616915dd 1/*
4ab867d6 2** constraint.c
616915dd 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"
f0171cff 12
616915dd 13# include "exprChecks.h"
616915dd 14# include "exprNodeSList.h"
616915dd 15
16/*@i33*/
616915dd 17
c3e695ff 18/*@access exprNode @*/
616915dd 19
d46ce6a4 20
28bf4b0b 21static /*@only@*/ cstring constraint_printDetailedPostCondition (/*@observer@*/ /*@temp@*/ constraint p_c);
2934b455 22
23
ccf0a4a8 24static /*@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 @*/;
4ab867d6 27
d46ce6a4 28/* constraint makeConstraintParse (sRef x, lltok relOp, exprNode cconstant) */
616915dd 29
d46ce6a4 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; */
616915dd 38
39
d46ce6a4 40/* ret->lexpr = constraintExpr_makeTermsRef (x); */
41/* #warning fix abstraction */
616915dd 42
d46ce6a4 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") ); */
616915dd 51
52
d46ce6a4 53/* t = cstring_toCharsSafe (exprNode_unparse(cconstant)); */
54/* c = atoi( t ); */
55/* ret->expr = constraintExpr_makeIntLiteral (c); */
616915dd 56
d46ce6a4 57/* ret->post = TRUE; */
58/* // ret->orig = ret; */
59/* DPRINTF(("GENERATED CONSTRAINT:")); */
60/* DPRINTF( (message ("%s", constraint_print(ret) ) ) ); */
61/* return ret; */
62/* } */
616915dd 63
920a3797 64
65static void
66advanceField (char **s)
67{
28bf4b0b 68 reader_checkChar (s, '@');
920a3797 69}
70
71
72
28bf4b0b 73static constraint makeConstraintParse2 (constraintExpr l, lltok relOp, exprNode cconstant)
616915dd 74{
75 char *t;
76 int c;
77 constraint ret;
ccf0a4a8 78 ret = constraint_makeNew ();
28bf4b0b 79 llassert (constraintExpr_isDefined(l) );
d46ce6a4 80
616915dd 81 ret->lexpr = constraintExpr_copy (l);
2934b455 82
616915dd 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
dc92450f 91 llfatalbug(message("Unsupported relational operator") );
616915dd 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
c3e695ff 105bool constraint_same (constraint c1, constraint c2)
90bc41f7 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}
616915dd 119
120constraint makeConstraintParse3 (constraintExpr l, lltok relOp, constraintExpr r)
121{
122 constraint ret;
123 ret = constraint_makeNew();
28bf4b0b 124 llassert (constraintExpr_isDefined(l) );
616915dd 125
126 ret->lexpr = constraintExpr_copy (l);
616915dd 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
dc92450f 135 llfatalbug( message("Unsupported relational operator") );
616915dd 136
137 ret->expr = constraintExpr_copy (r);
138
139 ret->post = TRUE;
90bc41f7 140
141 ret->orig = constraint_copy(ret);
142
143 ret = constraint_simplify (ret);
144
616915dd 145 // ret->orig = ret;
146 DPRINTF(("GENERATED CONSTRAINT:"));
147 DPRINTF( (message ("%s", constraint_print(ret) ) ) );
148 return ret;
149}
150
28bf4b0b 151constraint constraint_copy (/*@temp@*/ /*@observer@*/ constraint c)
616915dd 152{
153 constraint ret;
90bc41f7 154
c3e695ff 155 llassert (constraint_isDefined(c) );
28bf4b0b 156 // DPRINTF((message("Copying constraint %q", constraint_print) ));
90bc41f7 157
616915dd 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;
795e7f34 163 /*@-assignexpose@*/
28bf4b0b 164 ret->generatingExpr = c->generatingExpr;
795e7f34 165 /*@=assignexpose@*/
9280addf 166
616915dd 167 /*@i33 fix this*/
168 if (c->orig != NULL)
169 ret->orig = constraint_copy (c->orig);
170 else
171 ret->orig = NULL;
90bc41f7 172
173 if (c->or != NULL)
174 ret->or = constraint_copy (c->or);
175 else
176 ret->or = NULL;
4ab867d6 177
178 ret->fcnPre = c->fcnPre;
90bc41f7 179
616915dd 180 return ret;
181}
182
183/*like copy expect it doesn't allocate memory for the constraint*/
184
d46ce6a4 185void constraint_overWrite (constraint c1, constraint c2)
616915dd 186{
d46ce6a4 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
616915dd 197 c1->lexpr = constraintExpr_copy (c2->lexpr);
198 c1->ar = c2->ar;
199 c1->expr = constraintExpr_copy (c2->expr);
200 c1->post = c2->post;
d46ce6a4 201
202 if (c1->orig != NULL)
203 constraint_free (c1->orig);
204
616915dd 205 if (c2->orig != NULL)
206 c1->orig = constraint_copy (c2->orig);
207 else
208 c1->orig = NULL;
90bc41f7 209
d46ce6a4 210 /*@i33 make sure that the or is freed correctly*/
211 if (c1->or != NULL)
212 constraint_free (c1->or);
213
90bc41f7 214 if (c2->or != NULL)
215 c1->or = constraint_copy (c2->or);
216 else
217 c1->or = NULL;
4ab867d6 218
219 c1->fcnPre = c2->fcnPre;
795e7f34 220
221 /*@-assignexpose@*/
4ab867d6 222 c1->generatingExpr = c2->generatingExpr;
795e7f34 223 /*@=assignexpose@*/
616915dd 224}
225
616915dd 226
227
d46ce6a4 228static /*@notnull@*/ /*@special@*/ constraint constraint_makeNew (void)
ccf0a4a8 229 /*@post:isnull result->or, result->orig, result->generatingExpr, result->fcnPre @*/
230 /*@defines result->or, result->generatingExpr, result->orig, result->fcnPre @*/
616915dd 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;
90bc41f7 239 ret->or = NULL;
9280addf 240 ret->generatingExpr = NULL;
4ab867d6 241 ret->fcnPre = NULL;
dc92450f 242 return ret;
616915dd 243}
244
b37cf05e 245constraint constraint_addGeneratingExpr (/*@returned@*/ constraint c, /*@exposed@*/ exprNode e)
9280addf 246{
247
248 if (c->generatingExpr == NULL)
249 {
28bf4b0b 250 c->generatingExpr = e;
9280addf 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
4ab867d6 260constraint 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
4ab867d6 274constraint 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;
28bf4b0b 284 // DPRINTF(( message("Warning Setting fcnPre directly") ));
4ab867d6 285 }
286 return c;
287}
288
289
290
291
616915dd 292fileloc constraint_getFileloc (constraint c)
293{
c3e695ff 294 if (exprNode_isDefined(c->generatingExpr) )
d46ce6a4 295 return (fileloc_copy (exprNode_getfileloc (c->generatingExpr) ) );
9280addf 296
616915dd 297 return (constraintExpr_getFileloc (c->lexpr) );
298
299
300}
301
9280addf 302static bool checkForMaxSet (constraint c)
303{
304 if (constraintExpr_hasMaxSet(c->lexpr) || constraintExpr_hasMaxSet(c->expr) )
305 return TRUE;
306
307 return FALSE;
308}
309
310bool constraint_hasMaxSet(constraint c)
311{
03d670b6 312 if (checkForMaxSet(c) )
313 return TRUE;
314
dc92450f 315 if (c->orig != NULL)
9280addf 316 {
317 if (checkForMaxSet(c->orig) )
318 return TRUE;
319 }
320
03d670b6 321 return FALSE;
9280addf 322}
323
28bf4b0b 324constraint constraint_makeReadSafeExprNode ( exprNode po, exprNode ind)
616915dd 325{
326 constraint ret = constraint_makeNew();
327 // constraintTerm term;
28bf4b0b 328 po = po;
329 ind = ind;
616915dd 330 ret->lexpr = constraintExpr_makeMaxReadExpr(po);
331 ret->ar = GTE;
332 ret->expr = constraintExpr_makeValueExpr (ind);
d46ce6a4 333 ret->post = FALSE;
616915dd 334 return ret;
335}
336
28bf4b0b 337constraint constraint_makeWriteSafeInt ( exprNode po, int ind)
616915dd 338{
339 constraint ret = constraint_makeNew();
340
341
342 ret->lexpr =constraintExpr_makeMaxSetExpr(po);
343 ret->ar = GTE;
c3e695ff 344 ret->expr = constraintExpr_makeIntLiteral (ind);
616915dd 345 /*@i1*/return ret;
346}
347
84c9ffbf 348constraint constraint_makeSRefSetBufferSize (sRef s, long int size)
616915dd 349{
350 constraint ret = constraint_makeNew();
4ab867d6 351 ret->lexpr = constraintExpr_makeSRefMaxset (s);
616915dd 352 ret->ar = EQ;
84c9ffbf 353 ret->expr = constraintExpr_makeIntLiteral ((int)size);
616915dd 354 ret->post = TRUE;
355 /*@i1*/return ret;
356}
357
358constraint constraint_makeSRefWriteSafeInt (sRef s, int ind)
359{
360 constraint ret = constraint_makeNew();
361
362
4ab867d6 363 ret->lexpr = constraintExpr_makeSRefMaxset ( s );
616915dd 364 ret->ar = GTE;
c3e695ff 365 ret->expr = constraintExpr_makeIntLiteral (ind);
616915dd 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
374constraint 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
385constraint 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
28bf4b0b 397constraint constraint_makeReadSafeInt ( exprNode t1, int index)
616915dd 398{
399 constraint ret = constraint_makeNew();
400
28bf4b0b 401 ret->lexpr = constraintExpr_makeMaxReadExpr(t1);
616915dd 402 ret->ar = GTE;
28bf4b0b 403 ret->expr = constraintExpr_makeIntLiteral (index);
d46ce6a4 404 ret->post = FALSE;
616915dd 405 return ret;
406}
407
470b7798 408constraint constraint_makeSRefReadSafeInt (sRef s, int ind)
409{
410 constraint ret = constraint_makeNew();
411
412
4ab867d6 413 ret->lexpr = constraintExpr_makeSRefMaxRead (s );
470b7798 414 ret->ar = GTE;
c3e695ff 415 ret->expr = constraintExpr_makeIntLiteral (ind);
470b7798 416 ret->post = TRUE;
417 /*@i1*/return ret;
418}
419
28bf4b0b 420constraint constraint_makeEnsureMaxReadAtLeast (exprNode t1, exprNode t2, fileloc sequencePoint)
616915dd 421{
d46ce6a4 422 constraint ret;
616915dd 423
28bf4b0b 424 ret = constraint_makeReadSafeExprNode(t1, t2);
616915dd 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
d46ce6a4 434static constraint constraint_makeEnsuresOpConstraintExpr (/*@only@*/ constraintExpr c1, /*@only@*/ constraintExpr c2, fileloc sequencePoint, arithType ar)
470b7798 435{
436
437 constraint ret;
438
28bf4b0b 439 llassert(constraintExpr_isDefined(c1) && constraintExpr_isDefined(c2) );
470b7798 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}
616915dd 451
28bf4b0b 452static constraint constraint_makeEnsuresOp (/*@dependent@*/ exprNode e1, /*@dependent@*/ exprNode e2, fileloc sequencePoint, arithType ar)
616915dd 453{
470b7798 454 constraintExpr c1, c2;
455 constraint ret;
616915dd 456 exprNode e;
470b7798 457
28bf4b0b 458 if (! (exprNode_isDefined(e1) && exprNode_isDefined(e2) ) )
616915dd 459 {
460 llcontbug((message("null exprNode, Exprnodes are %s and %s",
461 exprNode_unparse(e1), exprNode_unparse(e2) )
462 ));
463 }
470b7798 464
465 // llassert (sequencePoint);
466
28bf4b0b 467 e = e1;
470b7798 468 c1 = constraintExpr_makeValueExpr (e);
469
28bf4b0b 470 e = e2;
470b7798 471 c2 = constraintExpr_makeValueExpr (e);
472
473 ret = constraint_makeEnsuresOpConstraintExpr (c1, c2, sequencePoint, ar);
616915dd 474
616915dd 475 return ret;
476}
477
478
479/* make constraint ensures e1 == e2 */
480
481constraint 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 */
487constraint constraint_makeEnsureLessThan (exprNode e1, exprNode e2, fileloc sequencePoint)
488{
470b7798 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) );
616915dd 499}
500
501constraint constraint_makeEnsureLessThanEqual (exprNode e1, exprNode e2, fileloc sequencePoint)
502{
503 return ( constraint_makeEnsuresOp (e1, e2, sequencePoint, LTE) );
504}
505
506constraint constraint_makeEnsureGreaterThan (exprNode e1, exprNode e2, fileloc sequencePoint)
507{
470b7798 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) );
616915dd 519}
520
521constraint constraint_makeEnsureGreaterThanEqual (exprNode e1, exprNode e2, fileloc sequencePoint)
522{
523 return ( constraint_makeEnsuresOp (e1, e2, sequencePoint, GTE) );
524}
525
526
527exprNode exprNode_copyConstraints (/*@returned@*/ exprNode dst, exprNode src)
528{
d46ce6a4 529 constraintList_free(dst->ensuresConstraints);
530 constraintList_free(dst->requiresConstraints);
531 constraintList_free(dst->trueEnsuresConstraints);
532 constraintList_free(dst->falseEnsuresConstraints);
533
616915dd 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
2934b455 541/* Makes the constraint e = e + f */
542constraint 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 */
565constraint 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
616915dd 586constraint constraint_makeMaxSetSideEffectPostDecrement (exprNode e, fileloc sequencePoint)
587{
588 constraint ret = constraint_makeNew();
589 //constraintTerm term;
590
28bf4b0b 591 // e = exprNode_fakeCopy(e);
616915dd 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}
603constraint constraint_makeMaxSetSideEffectPostIncrement (exprNode e, fileloc sequencePoint)
604{
605 constraint ret = constraint_makeNew();
606 //constraintTerm term;
607
28bf4b0b 608 // e = exprNode_fakeCopy(e);
616915dd 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
920a3797 622void constraint_free (/*@only@*/ constraint c)
d46ce6a4 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
bb25bea6 632
d46ce6a4 633 constraintExpr_free(c->lexpr);
634 constraintExpr_free(c->expr);
bb25bea6 635
636 c->orig = NULL;
637 c->or = NULL;
638 c->lexpr = NULL;
639 c->expr = NULL;
640
d46ce6a4 641 free (c);
642
643}
644
616915dd 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
dc92450f 661cstring arithType_print (arithType ar) /*@*/
616915dd 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
8f299805 694void 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
616915dd 722void constraint_printError (constraint c, fileloc loc)
723{
724 cstring string;
4ab867d6 725 fileloc errorLoc, temp;
9280addf 726
616915dd 727 string = constraint_printDetailed (c);
9280addf 728
729 errorLoc = loc;
730
4ab867d6 731 temp = constraint_getFileloc(c);
732
733 if (fileloc_isDefined(temp) )
616915dd 734 {
4ab867d6 735 errorLoc = temp;
84380658 736 }
737 else
738 {
739 llassert(FALSE);
740 DPRINTF(( message("constraint %s had undefined fileloc %s", constraint_print(c), fileloc_unparse(temp) ) ));
4ab867d6 741 fileloc_free(temp);
84380658 742 errorLoc = fileloc_copy(errorLoc);
743 }
744
745 if (c->post)
746 {
747 voptgenerror (FLG_FUNCTIONPOST, string, errorLoc);
616915dd 748 }
749 else
750 {
84380658 751 if (constraint_hasMaxSet (c) )
752 voptgenerror (FLG_ARRAYBOUNDS, string, errorLoc);
4ab867d6 753 else
84380658 754 voptgenerror (FLG_ARRAYBOUNDSREAD, string, errorLoc);
616915dd 755 }
84380658 756
757 fileloc_free(errorLoc);
758
616915dd 759}
760
4ab867d6 761
28bf4b0b 762static cstring constraint_printDeep (constraint c)
616915dd 763{
28bf4b0b 764 cstring genExpr;
616915dd 765 cstring st = cstring_undefined;
766
4ab867d6 767 st = constraint_print(c);
768
28bf4b0b 769
4ab867d6 770 if (c->orig != constraint_undefined)
771 {
03d670b6 772 st = cstring_appendChar(st, '\n');
28bf4b0b 773 genExpr = exprNode_unparse(c->orig->generatingExpr);
4ab867d6 774 if (!c->post)
775 {
776 if (c->orig->fcnPre)
28bf4b0b 777 st = cstring_concatFree(st, (message(" derived from %s precondition: %q", genExpr, constraint_printDeep(c->orig) )
4ab867d6 778 ) );
779 else
03d670b6 780 st = cstring_concatFree(st,(message(" needed to satisfy precondition:\n%q",
4ab867d6 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
2934b455 797
798static /*@only@*/ cstring constraint_printDetailedPostCondition (/*@observer@*/ /*@temp@*/ constraint c)
8f299805 799{
800 cstring st = cstring_undefined;
28bf4b0b 801 cstring genExpr;
802
8f299805 803 st = message ("Unsatisfied ensures constraint condition:\nLCLint is unable to verify the constraint %q", constraint_printDeep (c) );
28bf4b0b 804
805 genExpr = exprNode_unparse (c->generatingExpr);
806
8f299805 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) ),
28bf4b0b 812 genExpr );
8f299805 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
4ab867d6 824cstring constraint_printDetailed (constraint c)
825{
826 cstring st = cstring_undefined;
03d670b6 827 cstring temp = cstring_undefined;
828 cstring genExpr;
28bf4b0b 829
616915dd 830 if (!c->post)
831 {
03d670b6 832 st = message ("Unable to resolve constraint:\n%q", constraint_printDeep (c) );
616915dd 833 }
834 else
835 {
4ab867d6 836 st = message ("Block Post condition:\nThis function block has the post condition %q", constraint_printDeep (c) );
616915dd 837 }
9280addf 838
03d670b6 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
28bf4b0b 850 genExpr = exprNode_unparse (c->generatingExpr);
851
9280addf 852 if (context_getFlag (FLG_CONSTRAINTLOCATION) )
853 {
03d670b6 854 temp = message ("\nConstraint generated from expression: %s at %q\n",
855 genExpr,
856 fileloc_unparse( exprNode_getfileloc (c->generatingExpr) )
857 );
d46ce6a4 858 st = cstring_concatFree (st, temp);
9280addf 859 }
616915dd 860 return st;
861}
862
d46ce6a4 863/*@only@*/ cstring constraint_print (constraint c) /*@*/
616915dd 864{
865 cstring st = cstring_undefined;
866 cstring type = cstring_undefined;
dc92450f 867 llassert (c !=NULL);
616915dd 868 if (c->post)
869 {
03d670b6 870 type = cstring_makeLiteral ("ensures: ");
616915dd 871 }
872 else
873 {
03d670b6 874 type = cstring_makeLiteral ("requires: ");
616915dd 875 }
d46ce6a4 876 st = message ("%q: %q %q %q",
616915dd 877 type,
878 constraintExpr_print (c->lexpr),
879 arithType_print(c->ar),
880 constraintExpr_print(c->expr)
881 );
882 return st;
883}
884
90bc41f7 885cstring constraint_printOr (constraint c) /*@*/
886{
887 cstring ret;
888 constraint temp;
889
890 ret = cstring_undefined;
891 temp = c;
892
d46ce6a4 893 ret = cstring_concatFree (ret, constraint_print(temp) );
90bc41f7 894
895 temp = temp->or;
896
c3e695ff 897 while ( constraint_isDefined(temp) )
90bc41f7 898 {
d46ce6a4 899 ret = cstring_concatFree (ret, cstring_makeLiteral (" OR ") );
900 ret = cstring_concatFree (ret, constraint_print(temp) );
90bc41f7 901 temp = temp->or;
902 }
903
904 return ret;
905
906}
907
dc92450f 908/*@only@*/ constraint constraint_doSRefFixBaseParam (/*@returned@*/ /*@only@*/ constraint precondition,
616915dd 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
28bf4b0b 920constraint constraint_doFixResult (constraint postcondition, /*@dependent@*/ exprNode fcnCall)
616915dd 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
d46ce6a4 929/*@only@*/ constraint constraint_doSRefFixConstraintParam (constraint precondition,
616915dd 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
4ab867d6 937 precondition->fcnPre = FALSE;
616915dd 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
d46ce6a4 954constraint constraint_preserveOrig (/*@returned@*/ constraint c) /*@modifies c @*/
616915dd 955{
4ab867d6 956
957 DPRINTF( (message("Doing constraint_preserverOrig for %q ", constraint_printDetailed(c) ) ));
958
d46ce6a4 959 if (c->orig == constraint_undefined)
960 c->orig = constraint_copy (c);
4ab867d6 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)
920a3797 972 {
973 c->orig->orig = temp;
974 temp = NULL;
975 }
4ab867d6 976 else
920a3797 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 }
4ab867d6 983 }
984 else
985 {
986 DPRINTF( (message("Not changing constraint") ));
987 }
d46ce6a4 988
4ab867d6 989 DPRINTF( (message("After Doing constraint_preserverOrig for %q ", constraint_printDetailed(c) ) ));
990
616915dd 991 return c;
992}
993/*@=fcnuse*/
994/*@=assignexpose*/
995/*@=czechfcns@*/
84c9ffbf 996
2934b455 997
84c9ffbf 998constraint constraint_togglePost (/*@returned@*/ constraint c)
999{
1000 c->post = !c->post;
1001 return c;
1002}
2934b455 1003
1004constraint constraint_togglePostOrig (/*@returned@*/ constraint c)
1005{
1006 if (c->orig != NULL)
1007 c->orig = constraint_togglePost(c->orig);
1008 return c;
1009}
1010
1011bool constraint_hasOrig( /*@observer@*/ /*@temp@*/ constraint c)
1012{
1013 if (c->orig == NULL)
1014 return FALSE;
1015 else
1016 return TRUE;
1017}
920a3797 1018
1019
1020constraint constraint_undump (FILE *f)
1021{
1022 constraint c;
1023 bool fcnPre;
1024 bool post;
1025 arithType ar;
1026
1027 constraintExpr lexpr;
1028 constraintExpr expr;
28bf4b0b 1029
920a3797 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
28bf4b0b 1043 fcnPre = (bool) reader_getInt (&s);
920a3797 1044 advanceField(&s);
28bf4b0b 1045 post = (bool) reader_getInt (&s);
920a3797 1046 advanceField(&s);
28bf4b0b 1047 ar = (arithType) reader_getInt (&s);
920a3797 1048
1049 s = fgets(os, MAX_DUMP_LINE_LENGTH, f);
1050
28bf4b0b 1051 reader_checkChar (&s, 'l');
920a3797 1052
1053 lexpr = constraintExpr_undump (f);
1054
1055 s = fgets(os, MAX_DUMP_LINE_LENGTH, f);
1056
28bf4b0b 1057 reader_checkChar (&s, 'r');
920a3797 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);
dc7f6a51 1070 c = constraint_preserveOrig(c);
920a3797 1071 return c;
1072}
1073
1074
1075void constraint_dump (/*@observer@*/ constraint c, FILE *f)
1076{
1077 bool fcnPre;
1078 bool post;
1079 arithType ar;
1080
1081 constraintExpr lexpr;
1082 constraintExpr expr;
28bf4b0b 1083
920a3797 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
02984642 1099int 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
84380658 1133bool 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.236479 seconds and 5 git commands to generate.