]> andersk Git - splint.git/blame - src/constraint.c
Modified the doc/Makefile.am so that the man page is install under make install.
[splint.git] / src / constraint.c
CommitLineData
65f973be 1/*
11db3170 2** Splint - annotation-assisted static program checker
77d37419 3** Copyright (C) 1994-2002 University of Virginia,
65f973be 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**
155af98d 20** For information on splint: info@splint.org
21** To report a bug: splint-bug@splint.org
11db3170 22** For more information: http://www.splint.org
65f973be 23*/
24
616915dd 25/*
4ab867d6 26** constraint.c
616915dd 27*/
28
b7b694d6 29/* #define DEBUGPRINT 1 */
616915dd 30
31# include <ctype.h> /* for isdigit */
1b8ae690 32# include "splintMacros.nf"
616915dd 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 ();
bb7c2085 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
bb7c2085 77 llfatalbug (message ("Unsupported relational operator"));
616915dd 78
79
bb7c2085 80 t = cstring_toCharsSafe (exprNode_unparse (cconstant));
81 c = atoi ( t);
616915dd 82 ret->expr = constraintExpr_makeIntLiteral (c);
83
84 ret->post = TRUE;
bb7c2085 85 DPRINTF (("GENERATED CONSTRAINT:"));
86 DPRINTF ((message ("%s", constraint_print (ret))));
616915dd 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
bb7c2085 101 if (!constraintExpr_similar (c1->lexpr, c2->lexpr))
15b3d2b2 102 {
103 return FALSE;
104 }
90bc41f7 105
bb7c2085 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;
bb7c2085 117 ret = constraint_makeNew ();
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
bb7c2085 129 llfatalbug ( message ("Unsupported relational operator"));
616915dd 130
131 ret->expr = constraintExpr_copy (r);
132
133 ret->post = TRUE;
90bc41f7 134
bb7c2085 135 ret->orig = constraint_copy (ret);
90bc41f7 136
137 ret = constraint_simplify (ret);
b7b694d6 138 /* ret->orig = ret; */
139
bb7c2085 140 DPRINTF (("GENERATED CONSTRAINT:"));
141 DPRINTF ((message ("%s", constraint_print (ret))));
616915dd 142 return ret;
143}
144
28bf4b0b 145constraint constraint_copy (/*@temp@*/ /*@observer@*/ constraint c)
616915dd 146{
147 constraint ret;
90bc41f7 148
bb7c2085 149 llassert (constraint_isDefined (c));
b7b694d6 150
bb7c2085 151 ret = constraint_makeNew ();
616915dd 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{
bb7c2085 180 llassert (constraint_isDefined (c1));
d46ce6a4 181
182 llassert (c1 != c2);
183
bb7c2085 184 DPRINTF ((message ("OverWriteing constraint %q with %q", constraint_print (c1),
185 constraint_print (c2))));
d46ce6a4 186
bb7c2085 187 constraintExpr_free (c1->lexpr);
188 constraintExpr_free (c1->expr);
d46ce6a4 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;
bb7c2085 226 ret = dmalloc (sizeof (*ret));
616915dd 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;
bb7c2085 244 DPRINTF ((message ("setting generatingExpr for %s to %s", constraint_print (c), exprNode_unparse (e)) ));
9280addf 245 }
246 else
247 {
bb7c2085 248 DPRINTF ((message ("Not setting generatingExpr for %s to %s", constraint_print (c), exprNode_unparse (e)) ));
9280addf 249 }
250 return c;
251}
252
4ab867d6 253constraint constraint_origAddGeneratingExpr (/*@returned@*/ constraint c, exprNode e)
254{
255
256 if (c->orig != constraint_undefined)
257 {
bb7c2085 258 c->orig = constraint_addGeneratingExpr (c->orig, e);
4ab867d6 259 }
260 else
261 {
bb7c2085 262 DPRINTF ((message ("constraint_origAddGeneratingExpr: Not setting generatingExpr for %s to %s", constraint_print (c), exprNode_unparse (e)) ));
4ab867d6 263 }
264 return c;
265}
266
bb7c2085 267constraint constraint_setFcnPre (/*@returned@*/ constraint c)
4ab867d6 268{
269
270 if (c->orig != constraint_undefined)
271 {
272 c->orig->fcnPre = TRUE;
273 }
274 else
275 {
276 c->fcnPre = TRUE;
bb7c2085 277 DPRINTF (( message ("Warning Setting fcnPre directly")));
4ab867d6 278 }
279 return c;
280}
281
282
283
284
616915dd 285fileloc constraint_getFileloc (constraint c)
286{
bb7c2085 287 if (exprNode_isDefined (c->generatingExpr))
288 return (fileloc_copy (exprNode_getfileloc (c->generatingExpr)));
9280addf 289
bb7c2085 290 return (constraintExpr_getFileloc (c->lexpr));
616915dd 291
292
293}
294
9280addf 295static bool checkForMaxSet (constraint c)
296{
bb7c2085 297 if (constraintExpr_hasMaxSet (c->lexpr) || constraintExpr_hasMaxSet (c->expr))
9280addf 298 return TRUE;
299
300 return FALSE;
301}
302
bb7c2085 303bool constraint_hasMaxSet (constraint c)
9280addf 304{
bb7c2085 305 if (checkForMaxSet (c))
03d670b6 306 return TRUE;
307
dc92450f 308 if (c->orig != NULL)
9280addf 309 {
bb7c2085 310 if (checkForMaxSet (c->orig))
9280addf 311 return TRUE;
312 }
313
03d670b6 314 return FALSE;
9280addf 315}
316
28bf4b0b 317constraint constraint_makeReadSafeExprNode ( exprNode po, exprNode ind)
616915dd 318{
bb7c2085 319 constraint ret = constraint_makeNew ();
b7b694d6 320
28bf4b0b 321 po = po;
322 ind = ind;
bb7c2085 323 ret->lexpr = constraintExpr_makeMaxReadExpr (po);
616915dd 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{
bb7c2085 332 constraint ret = constraint_makeNew ();
616915dd 333
334
bb7c2085 335 ret->lexpr =constraintExpr_makeMaxSetExpr (po);
616915dd 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{
bb7c2085 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{
bb7c2085 353 constraint ret = constraint_makeNew ();
616915dd 354
355
bb7c2085 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
bb7c2085 365 makes the constraint: Ensures index <= MaxRead (buffer) */
616915dd 366
bb7c2085 367constraint constraint_makeEnsureLteMaxRead (exprNode index, exprNode buffer)
616915dd 368{
bb7c2085 369 constraint ret = constraint_makeNew ();
616915dd 370
371 ret->lexpr = constraintExpr_makeValueExpr (index);
372 ret->ar = LTE;
bb7c2085 373 ret->expr = constraintExpr_makeMaxReadExpr (buffer);
616915dd 374 ret->post = TRUE;
375 return ret;
376}
377
378constraint constraint_makeWriteSafeExprNode (exprNode po, exprNode ind)
379{
bb7c2085 380 constraint ret = constraint_makeNew ();
616915dd 381
382
bb7c2085 383 ret->lexpr =constraintExpr_makeMaxSetExpr (po);
616915dd 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{
bb7c2085 392 constraint ret = constraint_makeNew ();
616915dd 393
bb7c2085 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{
bb7c2085 403 constraint ret = constraint_makeNew ();
470b7798 404
405
bb7c2085 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
bb7c2085 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
bb7c2085 429 llassert (constraintExpr_isDefined (c1) && constraintExpr_isDefined (c2));
470b7798 430
bb7c2085 431 ret = constraint_makeNew ();
470b7798 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
bb7c2085 447 if (! (exprNode_isDefined (e1) && exprNode_isDefined (e2)))
616915dd 448 {
bb7c2085 449 llcontbug ((message ("null exprNode, Exprnodes are %s and %s",
450 exprNode_unparse (e1), exprNode_unparse (e2))
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{
bb7c2085 470 return ( constraint_makeEnsuresOp (e1, e2, sequencePoint, EQ));
616915dd 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
bb7c2085 485 return ( constraint_makeEnsuresOpConstraintExpr (t1, t2, sequencePoint, LTE));
616915dd 486}
487
488constraint constraint_makeEnsureLessThanEqual (exprNode e1, exprNode e2, fileloc sequencePoint)
489{
bb7c2085 490 return ( constraint_makeEnsuresOp (e1, e2, sequencePoint, LTE));
616915dd 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
bb7c2085 505 return ( constraint_makeEnsuresOpConstraintExpr (t1, t2, sequencePoint, GTE));
616915dd 506}
507
508constraint constraint_makeEnsureGreaterThanEqual (exprNode e1, exprNode e2, fileloc sequencePoint)
509{
bb7c2085 510 return ( constraint_makeEnsuresOp (e1, e2, sequencePoint, GTE));
616915dd 511}
512
513
514exprNode exprNode_copyConstraints (/*@returned@*/ exprNode dst, exprNode src)
515{
bb7c2085 516 constraintList_free (dst->ensuresConstraints);
517 constraintList_free (dst->requiresConstraints);
518 constraintList_free (dst->trueEnsuresConstraints);
519 constraintList_free (dst->falseEnsuresConstraints);
d46ce6a4 520
bb7c2085 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);
616915dd 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
bb7c2085 534 ret = constraint_makeNew ();
2934b455 535
536 x1 = constraintExpr_makeValueExpr (e);
bb7c2085 537 x2 = constraintExpr_copy (x1);
2934b455 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
bb7c2085 557 ret = constraint_makeNew ();
2934b455 558
559 x1 = constraintExpr_makeValueExpr (e);
bb7c2085 560 x2 = constraintExpr_copy (x1);
2934b455 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{
bb7c2085 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{
bb7c2085 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{
bb7c2085 602 llassert (constraint_isDefined (c));
d46ce6a4 603
604
bb7c2085 605 if (constraint_isDefined (c->orig))
d46ce6a4 606 constraint_free (c->orig);
bb7c2085 607 if ( constraint_isDefined (c->or))
d46ce6a4 608 constraint_free (c->or);
609
bb25bea6 610
bb7c2085 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:
bb7c2085 650 llassert (FALSE);
616915dd 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
bb7c2085 667 temp = constraint_getFileloc (c);
8f299805 668
9276a168 669
670 if (context_getFlag (FLG_BOUNDSCOMPACTERRORMESSAGES ) )
671 {
672 string = cstring_replaceChar(string, '\n', ' ');
673 }
674
bb7c2085 675 if (fileloc_isDefined (temp))
8f299805 676 {
677 errorLoc = temp;
678 voptgenerror ( FLG_CHECKPOST, string, errorLoc);
bb7c2085 679 fileloc_free (temp);
8f299805 680 }
681 else
682 {
683 voptgenerror ( FLG_CHECKPOST, string, errorLoc);
684 }
685}
686
f4ec8018 687 /*drl added 8-11-001*/
688cstring constraint_printLocation (/*@observer@*/ /*@temp@*/ constraint c) /*@*/
689{
690 cstring string, ret;
691 fileloc errorLoc;
692
bb7c2085 693 string = constraint_print (c);
f4ec8018 694
bb7c2085 695 errorLoc = constraint_getFileloc (c);
f4ec8018 696
bb7c2085 697 ret = message ("constraint: %q @ %q", string, fileloc_unparse (errorLoc));
f4ec8018 698
bb7c2085 699 fileloc_free (errorLoc);
f4ec8018 700 return ret;
701
702}
8f299805 703
704
705
616915dd 706void constraint_printError (constraint c, fileloc loc)
707{
708 cstring string;
4ab867d6 709 fileloc errorLoc, temp;
e5f31c00 710
711
712 /*drl 11/26/2001 avoid printing tautological constraints */
bb7c2085 713 if (constraint_isAlwaysTrue (c))
e5f31c00 714 {
715 return;
716 }
717
718
616915dd 719 string = constraint_printDetailed (c);
9280addf 720
721 errorLoc = loc;
722
bb7c2085 723 temp = constraint_getFileloc (c);
4ab867d6 724
bb7c2085 725 if (fileloc_isDefined (temp))
616915dd 726 {
4ab867d6 727 errorLoc = temp;
84380658 728 }
729 else
730 {
bb7c2085 731 llassert (FALSE);
732 DPRINTF (("constraint %s had undefined fileloc %s", constraint_print (c), fileloc_unparse (temp)));
733 fileloc_free (temp);
734 errorLoc = fileloc_copy (errorLoc);
84380658 735 }
9276a168 736
737
738 if (context_getFlag (FLG_BOUNDSCOMPACTERRORMESSAGES ) )
739 {
740 string = cstring_replaceChar(string, '\n', ' ');
741 }
742
743
84380658 744 if (c->post)
745 {
746 voptgenerror (FLG_FUNCTIONPOST, string, errorLoc);
616915dd 747 }
748 else
749 {
bb7c2085 750 if (constraint_hasMaxSet (c))
751 {
752 voptgenerror (FLG_BOUNDSWRITE, string, errorLoc);
753 }
4ab867d6 754 else
bb7c2085 755 {
756 voptgenerror (FLG_BOUNDSREAD, string, errorLoc);
757 }
616915dd 758 }
84380658 759
86d93ed3 760 fileloc_free(errorLoc);
616915dd 761}
762
28bf4b0b 763static cstring constraint_printDeep (constraint c)
616915dd 764{
28bf4b0b 765 cstring genExpr;
616915dd 766 cstring st = cstring_undefined;
767
86d93ed3 768 st = constraint_print(c);
28bf4b0b 769
4ab867d6 770 if (c->orig != constraint_undefined)
771 {
bb7c2085 772 st = cstring_appendChar (st, '\n');
773 genExpr = exprNode_unparse (c->orig->generatingExpr);
774
4ab867d6 775 if (!c->post)
776 {
777 if (c->orig->fcnPre)
bb7c2085 778 {
779 st = cstring_concatFree (st, message (" derived from %s precondition: %q",
780 genExpr, constraint_printDeep (c->orig)));
781 }
4ab867d6 782 else
bb7c2085 783 {
784 st = cstring_concatFree (st, message (" needed to satisfy precondition:\n%q",
785 constraint_printDeep (c->orig)));
786 }
4ab867d6 787 }
788 else
789 {
bb7c2085 790 st = cstring_concatFree (st, message ("derived from: %q",
791 constraint_printDeep (c->orig)));
4ab867d6 792 }
793 }
794
795 return st;
4ab867d6 796}
797
2934b455 798
799static /*@only@*/ cstring constraint_printDetailedPostCondition (/*@observer@*/ /*@temp@*/ constraint c)
8f299805 800{
801 cstring st = cstring_undefined;
28bf4b0b 802 cstring genExpr;
803
bb7c2085 804 st = message ("Unsatisfied ensures constraint condition:\nSplint is unable to verify the constraint %q", constraint_printDeep (c));
28bf4b0b 805
806 genExpr = exprNode_unparse (c->generatingExpr);
807
bb7c2085 808 if (context_getFlag (FLG_CONSTRAINTLOCATION))
8f299805 809 {
810 cstring temp;
b7b694d6 811
812 temp = message ("\nOriginal Generating expression %q: %s\n",
bb7c2085 813 fileloc_unparse ( exprNode_getfileloc (c->generatingExpr)),
814 genExpr);
8f299805 815 st = cstring_concatFree (st, temp);
816
bb7c2085 817 if (constraint_hasMaxSet (c))
8f299805 818 {
819 temp = message ("Has MaxSet\n");
820 st = cstring_concatFree (st, temp);
821 }
822 }
823 return st;
824}
825
4ab867d6 826cstring constraint_printDetailed (constraint c)
827{
828 cstring st = cstring_undefined;
03d670b6 829 cstring temp = cstring_undefined;
9276a168 830 cstring genExpr;
28bf4b0b 831
616915dd 832 if (!c->post)
833 {
bb7c2085 834 st = message ("Unable to resolve constraint:\n%q", constraint_printDeep (c));
616915dd 835 }
836 else
837 {
bb7c2085 838 st = message ("Block Post condition:\nThis function block has the post condition %q", constraint_printDeep (c));
616915dd 839 }
9280addf 840
bb7c2085 841 if (constraint_hasMaxSet (c))
03d670b6 842 {
bb7c2085 843 temp = cstring_makeLiteral ("Possible out-of-bounds store:\n");
03d670b6 844 }
845 else
846 {
bb7c2085 847 temp = cstring_makeLiteral ("Possible out-of-bounds read:\n");
03d670b6 848 }
03d670b6 849
28bf4b0b 850 genExpr = exprNode_unparse (c->generatingExpr);
7bf96067 851
bb7c2085 852 if (context_getFlag (FLG_CONSTRAINTLOCATION))
9280addf 853 {
7bf96067 854 cstring temp2;
bb7c2085 855 temp2 = message ("%s\n", genExpr);
7bf96067 856 temp = cstring_concatFree (temp, temp2);
9280addf 857 }
7bf96067 858
bb7c2085 859 st = cstring_concatFree (temp,st);
7bf96067 860
616915dd 861 return st;
862}
863
d46ce6a4 864/*@only@*/ cstring constraint_print (constraint c) /*@*/
616915dd 865{
866 cstring st = cstring_undefined;
867 cstring type = cstring_undefined;
dc92450f 868 llassert (c !=NULL);
616915dd 869 if (c->post)
870 {
bb7c2085 871 if (context_getFlag (FLG_PARENCONSTRAINT))
a779b61e 872 {
873 type = cstring_makeLiteral ("ensures: ");
874 }
875 else
876 {
877 type = cstring_makeLiteral ("ensures");
878 }
616915dd 879 }
880 else
881 {
bb7c2085 882 if (context_getFlag (FLG_PARENCONSTRAINT))
a779b61e 883 {
884 type = cstring_makeLiteral ("requires: ");
885 }
886 else
887 {
888 type = cstring_makeLiteral ("requires");
889 }
890
616915dd 891 }
bb7c2085 892 if (context_getFlag (FLG_PARENCONSTRAINT))
a779b61e 893 {
894 st = message ("%q: %q %q %q",
895 type,
896 constraintExpr_print (c->lexpr),
bb7c2085 897 arithType_print (c->ar),
898 constraintExpr_print (c->expr)
a779b61e 899 );
900 }
901 else
902 {
903 st = message ("%q %q %q %q",
904 type,
905 constraintExpr_print (c->lexpr),
bb7c2085 906 arithType_print (c->ar),
907 constraintExpr_print (c->expr)
616915dd 908 );
a779b61e 909 }
616915dd 910 return st;
911}
912
90bc41f7 913cstring constraint_printOr (constraint c) /*@*/
914{
915 cstring ret;
916 constraint temp;
917
918 ret = cstring_undefined;
919 temp = c;
920
bb7c2085 921 ret = cstring_concatFree (ret, constraint_print (temp));
90bc41f7 922
923 temp = temp->or;
924
bb7c2085 925 while ( constraint_isDefined (temp))
90bc41f7 926 {
bb7c2085 927 ret = cstring_concatFree (ret, cstring_makeLiteral (" OR "));
928 ret = cstring_concatFree (ret, constraint_print (temp));
90bc41f7 929 temp = temp->or;
930 }
931
932 return ret;
933
934}
935
dc92450f 936/*@only@*/ constraint constraint_doSRefFixBaseParam (/*@returned@*/ /*@only@*/ constraint precondition,
616915dd 937 exprNodeList arglist)
938{
939 precondition->lexpr = constraintExpr_doSRefFixBaseParam (precondition->lexpr,
940 arglist);
941 precondition->expr = constraintExpr_doSRefFixBaseParam (precondition->expr,
942 arglist);
943
944 return precondition;
945}
946
947
28bf4b0b 948constraint constraint_doFixResult (constraint postcondition, /*@dependent@*/ exprNode fcnCall)
616915dd 949{
950 postcondition = constraint_copy (postcondition);
951 postcondition->lexpr = constraintExpr_doFixResult (postcondition->lexpr, fcnCall);
952 postcondition->expr = constraintExpr_doFixResult (postcondition->expr, fcnCall);
953
954 return postcondition;
955}
86d93ed3 956/*Commenting out temporally
957
958/ *@only@* /constraint constraint_doSRefFixInvarConstraint(constraint invar, sRef s, ctype ct )
959{
960
961 invar = constraint_copy (invar);
962 invar->lexpr = constraintExpr_doSRefFixInvarConstraint (invar->lexpr, s, ct);
963 invar->expr = constraintExpr_doSRefFixInvarConstraint (invar->expr, s, ct);
964
965 return invar;
966}
967*/
616915dd 968
d46ce6a4 969/*@only@*/ constraint constraint_doSRefFixConstraintParam (constraint precondition,
616915dd 970 exprNodeList arglist)
971{
972
973 precondition = constraint_copy (precondition);
974 precondition->lexpr = constraintExpr_doSRefFixConstraintParam (precondition->lexpr, arglist);
975 precondition->expr = constraintExpr_doSRefFixConstraintParam (precondition->expr, arglist);
976
4ab867d6 977 precondition->fcnPre = FALSE;
616915dd 978 return precondition;
979}
980
d46ce6a4 981constraint constraint_preserveOrig (/*@returned@*/ constraint c) /*@modifies c @*/
616915dd 982{
4ab867d6 983
bb7c2085 984 DPRINTF ((message ("Doing constraint_preserverOrig for %q ", constraint_printDetailed (c))));
4ab867d6 985
d46ce6a4 986 if (c->orig == constraint_undefined)
987 c->orig = constraint_copy (c);
4ab867d6 988
989 else if (c->orig->fcnPre)
990 {
991 constraint temp;
992
993 temp = c->orig;
994
995 /* avoid infinite loop */
996 c->orig = NULL;
997 c->orig = constraint_copy (c);
998 if (c->orig->orig == NULL)
920a3797 999 {
1000 c->orig->orig = temp;
1001 temp = NULL;
1002 }
4ab867d6 1003 else
920a3797 1004 {
bb7c2085 1005 llcontbug ((message ("Expected c->orig->orig to be null")));
1006 constraint_free (c->orig->orig);
920a3797 1007 c->orig->orig = temp;
1008 temp = NULL;
1009 }
4ab867d6 1010 }
1011 else
1012 {
bb7c2085 1013 DPRINTF ((message ("Not changing constraint")));
4ab867d6 1014 }
d46ce6a4 1015
bb7c2085 1016 DPRINTF ((message ("After Doing constraint_preserverOrig for %q ", constraint_printDetailed (c))));
4ab867d6 1017
616915dd 1018 return c;
1019}
1020/*@=fcnuse*/
1021/*@=assignexpose*/
1022/*@=czechfcns@*/
84c9ffbf 1023
2934b455 1024
84c9ffbf 1025constraint constraint_togglePost (/*@returned@*/ constraint c)
1026{
1027 c->post = !c->post;
1028 return c;
1029}
2934b455 1030
1031constraint constraint_togglePostOrig (/*@returned@*/ constraint c)
1032{
1033 if (c->orig != NULL)
bb7c2085 1034 c->orig = constraint_togglePost (c->orig);
2934b455 1035 return c;
1036}
1037
bb7c2085 1038bool constraint_hasOrig ( /*@observer@*/ /*@temp@*/ constraint c)
2934b455 1039{
1040 if (c->orig == NULL)
1041 return FALSE;
1042 else
1043 return TRUE;
1044}
920a3797 1045
1046
1047constraint constraint_undump (FILE *f)
1048{
1049 constraint c;
1050 bool fcnPre;
1051 bool post;
1052 arithType ar;
1053
1054 constraintExpr lexpr;
1055 constraintExpr expr;
28bf4b0b 1056
920a3797 1057
1058 char * s;
1059
1060 char *os;
1061
3be9a165 1062 os = mstring_create (MAX_DUMP_LINE_LENGTH);
920a3797 1063
bb7c2085 1064 s = fgets (os, MAX_DUMP_LINE_LENGTH, f);
920a3797 1065
1066 /*@i33*/ /*this should probably be wrappered...*/
1067
28bf4b0b 1068 fcnPre = (bool) reader_getInt (&s);
bb7c2085 1069 advanceField (&s);
28bf4b0b 1070 post = (bool) reader_getInt (&s);
bb7c2085 1071 advanceField (&s);
28bf4b0b 1072 ar = (arithType) reader_getInt (&s);
920a3797 1073
bb7c2085 1074 s = fgets (os, MAX_DUMP_LINE_LENGTH, f);
920a3797 1075
28bf4b0b 1076 reader_checkChar (&s, 'l');
920a3797 1077
1078 lexpr = constraintExpr_undump (f);
1079
bb7c2085 1080 s = fgets (os, MAX_DUMP_LINE_LENGTH, f);
920a3797 1081
28bf4b0b 1082 reader_checkChar (&s, 'r');
920a3797 1083 expr = constraintExpr_undump (f);
1084
bb7c2085 1085 c = constraint_makeNew ();
920a3797 1086
1087 c->fcnPre = fcnPre;
1088 c->post = post;
1089 c->ar = ar;
1090
1091 c->lexpr = lexpr;
1092 c->expr = expr;
1093
bb7c2085 1094 free (os);
1095 c = constraint_preserveOrig (c);
920a3797 1096 return c;
1097}
1098
1099
1100void constraint_dump (/*@observer@*/ constraint c, FILE *f)
1101{
1102 bool fcnPre;
1103 bool post;
1104 arithType ar;
1105
1106 constraintExpr lexpr;
1107 constraintExpr expr;
28bf4b0b 1108
920a3797 1109
1110 fcnPre = c->fcnPre;
1111 post = c->post;
1112 ar = c->ar;
1113 lexpr = c->lexpr;
1114 expr = c->expr;
1115
bb7c2085 1116 fprintf (f, "%d@%d@%d\n", (int) fcnPre, (int) post, (int) ar);
1117 fprintf (f,"l\n");
920a3797 1118 constraintExpr_dump (lexpr, f);
bb7c2085 1119 fprintf (f,"r\n");
920a3797 1120 constraintExpr_dump (expr, f);
1121}
1122
1123
f4ec8018 1124int constraint_compare (/*@observer@*/ /*@temp@*/ const constraint * c1, /*@observer@*/ /*@temp@*/ const constraint * c2) /*@*/
02984642 1125{
1126 fileloc loc1, loc2;
1127
1128 int ret;
1129
bb7c2085 1130 llassert (constraint_isDefined (*c1));
1131 llassert (constraint_isDefined (*c2));
02984642 1132
bb7c2085 1133 if (constraint_isUndefined (*c1))
02984642 1134 {
bb7c2085 1135 if (constraint_isUndefined (*c2))
02984642 1136 return 0;
1137 else
1138 return 1;
1139 }
1140
bb7c2085 1141 if (constraint_isUndefined (*c2))
02984642 1142 {
1143 return -1;
1144 }
1145
bb7c2085 1146 loc1 = constraint_getFileloc (*c1);
1147 loc2 = constraint_getFileloc (*c2);
02984642 1148
bb7c2085 1149 ret = fileloc_compare (loc1, loc2);
02984642 1150
bb7c2085 1151 fileloc_free (loc1);
1152 fileloc_free (loc2);
02984642 1153
1154 return ret;
1155}
1156
1157
84380658 1158bool constraint_isPost (/*@observer@*/ /*@temp@*/ constraint c)
1159{
bb7c2085 1160 llassert (constraint_isDefined (c));
84380658 1161
bb7c2085 1162 if (constraint_isUndefined (c))
84380658 1163 return FALSE;
1164
1165 return (c->post);
1166}
a779b61e 1167
1168
bb7c2085 1169static int constraint_getDepth (/*@observer@*/ /*@temp@*/ constraint c)
a779b61e 1170{
1171 int l , r;
1172
bb7c2085 1173 l = constraintExpr_getDepth (c->lexpr);
1174 r = constraintExpr_getDepth (c->expr);
a779b61e 1175
1176 if (l > r)
1177 {
bb7c2085 1178 DPRINTF (( message ("constraint depth returning %d for %s", l, constraint_print (c))));
a779b61e 1179 return l;
1180 }
1181 else
1182 {
bb7c2085 1183 DPRINTF (( message ("constraint depth returning %d for %s", r, constraint_print (c))));
a779b61e 1184 return r;
1185 }
1186}
1187
1188
1189bool constraint_tooDeep (/*@observer@*/ /*@temp@*/ constraint c)
1190{
1191 int temp;
1192
bb7c2085 1193 temp = constraint_getDepth (c);
a779b61e 1194
bb7c2085 1195 if (temp >= 20)
a779b61e 1196 {
1197 return TRUE;
1198 }
1199
1200 return FALSE;
1201
1202}
This page took 0.299056 seconds and 5 git commands to generate.