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