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