]> andersk Git - splint.git/blame - src/constraint.c
Adding redundantconstraints flags. Set constraintor and showconstraintlocation flags...
[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**
1b8ae690 20** For information on splint: splint@cs.virginia.edu
21** To report a bug: splint-bug@cs.virginia.edu
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
bb7c2085 669 if (fileloc_isDefined (temp))
8f299805 670 {
671 errorLoc = temp;
672 voptgenerror ( FLG_CHECKPOST, string, errorLoc);
bb7c2085 673 fileloc_free (temp);
8f299805 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
bb7c2085 687 string = constraint_print (c);
f4ec8018 688
bb7c2085 689 errorLoc = constraint_getFileloc (c);
f4ec8018 690
bb7c2085 691 ret = message ("constraint: %q @ %q", string, fileloc_unparse (errorLoc));
f4ec8018 692
bb7c2085 693 fileloc_free (errorLoc);
f4ec8018 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 */
bb7c2085 707 if (constraint_isAlwaysTrue (c))
e5f31c00 708 {
709 return;
710 }
711
712
616915dd 713 string = constraint_printDetailed (c);
9280addf 714
715 errorLoc = loc;
716
bb7c2085 717 temp = constraint_getFileloc (c);
4ab867d6 718
bb7c2085 719 if (fileloc_isDefined (temp))
616915dd 720 {
4ab867d6 721 errorLoc = temp;
84380658 722 }
723 else
724 {
bb7c2085 725 llassert (FALSE);
726 DPRINTF (("constraint %s had undefined fileloc %s", constraint_print (c), fileloc_unparse (temp)));
727 fileloc_free (temp);
728 errorLoc = fileloc_copy (errorLoc);
84380658 729 }
730
731 if (c->post)
732 {
733 voptgenerror (FLG_FUNCTIONPOST, string, errorLoc);
616915dd 734 }
735 else
736 {
bb7c2085 737 if (constraint_hasMaxSet (c))
738 {
739 voptgenerror (FLG_BOUNDSWRITE, string, errorLoc);
740 }
4ab867d6 741 else
bb7c2085 742 {
743 voptgenerror (FLG_BOUNDSREAD, string, errorLoc);
744 }
616915dd 745 }
84380658 746
bb7c2085 747 fileloc_free (errorLoc);
616915dd 748}
749
28bf4b0b 750static cstring constraint_printDeep (constraint c)
616915dd 751{
28bf4b0b 752 cstring genExpr;
616915dd 753 cstring st = cstring_undefined;
754
bb7c2085 755 st = constraint_print (c);
28bf4b0b 756
4ab867d6 757 if (c->orig != constraint_undefined)
758 {
bb7c2085 759 st = cstring_appendChar (st, '\n');
760 genExpr = exprNode_unparse (c->orig->generatingExpr);
761
4ab867d6 762 if (!c->post)
763 {
764 if (c->orig->fcnPre)
bb7c2085 765 {
766 st = cstring_concatFree (st, message (" derived from %s precondition: %q",
767 genExpr, constraint_printDeep (c->orig)));
768 }
4ab867d6 769 else
bb7c2085 770 {
771 st = cstring_concatFree (st, message (" needed to satisfy precondition:\n%q",
772 constraint_printDeep (c->orig)));
773 }
4ab867d6 774 }
775 else
776 {
bb7c2085 777 st = cstring_concatFree (st, message ("derived from: %q",
778 constraint_printDeep (c->orig)));
4ab867d6 779 }
780 }
781
782 return st;
4ab867d6 783}
784
2934b455 785
786static /*@only@*/ cstring constraint_printDetailedPostCondition (/*@observer@*/ /*@temp@*/ constraint c)
8f299805 787{
788 cstring st = cstring_undefined;
28bf4b0b 789 cstring genExpr;
790
bb7c2085 791 st = message ("Unsatisfied ensures constraint condition:\nSplint is unable to verify the constraint %q", constraint_printDeep (c));
28bf4b0b 792
793 genExpr = exprNode_unparse (c->generatingExpr);
794
bb7c2085 795 if (context_getFlag (FLG_CONSTRAINTLOCATION))
8f299805 796 {
797 cstring temp;
b7b694d6 798
799 temp = message ("\nOriginal Generating expression %q: %s\n",
bb7c2085 800 fileloc_unparse ( exprNode_getfileloc (c->generatingExpr)),
801 genExpr);
8f299805 802 st = cstring_concatFree (st, temp);
803
bb7c2085 804 if (constraint_hasMaxSet (c))
8f299805 805 {
806 temp = message ("Has MaxSet\n");
807 st = cstring_concatFree (st, temp);
808 }
809 }
810 return st;
811}
812
4ab867d6 813cstring constraint_printDetailed (constraint c)
814{
815 cstring st = cstring_undefined;
03d670b6 816 cstring temp = cstring_undefined;
817 cstring genExpr;
28bf4b0b 818
616915dd 819 if (!c->post)
820 {
bb7c2085 821 st = message ("Unable to resolve constraint:\n%q", constraint_printDeep (c));
616915dd 822 }
823 else
824 {
bb7c2085 825 st = message ("Block Post condition:\nThis function block has the post condition %q", constraint_printDeep (c));
616915dd 826 }
9280addf 827
bb7c2085 828 if (constraint_hasMaxSet (c))
03d670b6 829 {
bb7c2085 830 temp = cstring_makeLiteral ("Possible out-of-bounds store:\n");
03d670b6 831 }
832 else
833 {
bb7c2085 834 temp = cstring_makeLiteral ("Possible out-of-bounds read:\n");
03d670b6 835 }
03d670b6 836
28bf4b0b 837 genExpr = exprNode_unparse (c->generatingExpr);
7bf96067 838
bb7c2085 839 if (context_getFlag (FLG_CONSTRAINTLOCATION))
9280addf 840 {
7bf96067 841 cstring temp2;
bb7c2085 842 temp2 = message ("%s\n", genExpr);
7bf96067 843 temp = cstring_concatFree (temp, temp2);
9280addf 844 }
7bf96067 845
bb7c2085 846 st = cstring_concatFree (temp,st);
7bf96067 847
616915dd 848 return st;
849}
850
d46ce6a4 851/*@only@*/ cstring constraint_print (constraint c) /*@*/
616915dd 852{
853 cstring st = cstring_undefined;
854 cstring type = cstring_undefined;
dc92450f 855 llassert (c !=NULL);
616915dd 856 if (c->post)
857 {
bb7c2085 858 if (context_getFlag (FLG_PARENCONSTRAINT))
a779b61e 859 {
860 type = cstring_makeLiteral ("ensures: ");
861 }
862 else
863 {
864 type = cstring_makeLiteral ("ensures");
865 }
616915dd 866 }
867 else
868 {
bb7c2085 869 if (context_getFlag (FLG_PARENCONSTRAINT))
a779b61e 870 {
871 type = cstring_makeLiteral ("requires: ");
872 }
873 else
874 {
875 type = cstring_makeLiteral ("requires");
876 }
877
616915dd 878 }
bb7c2085 879 if (context_getFlag (FLG_PARENCONSTRAINT))
a779b61e 880 {
881 st = message ("%q: %q %q %q",
882 type,
883 constraintExpr_print (c->lexpr),
bb7c2085 884 arithType_print (c->ar),
885 constraintExpr_print (c->expr)
a779b61e 886 );
887 }
888 else
889 {
890 st = message ("%q %q %q %q",
891 type,
892 constraintExpr_print (c->lexpr),
bb7c2085 893 arithType_print (c->ar),
894 constraintExpr_print (c->expr)
616915dd 895 );
a779b61e 896 }
616915dd 897 return st;
898}
899
90bc41f7 900cstring constraint_printOr (constraint c) /*@*/
901{
902 cstring ret;
903 constraint temp;
904
905 ret = cstring_undefined;
906 temp = c;
907
bb7c2085 908 ret = cstring_concatFree (ret, constraint_print (temp));
90bc41f7 909
910 temp = temp->or;
911
bb7c2085 912 while ( constraint_isDefined (temp))
90bc41f7 913 {
bb7c2085 914 ret = cstring_concatFree (ret, cstring_makeLiteral (" OR "));
915 ret = cstring_concatFree (ret, constraint_print (temp));
90bc41f7 916 temp = temp->or;
917 }
918
919 return ret;
920
921}
922
dc92450f 923/*@only@*/ constraint constraint_doSRefFixBaseParam (/*@returned@*/ /*@only@*/ constraint precondition,
616915dd 924 exprNodeList arglist)
925{
926 precondition->lexpr = constraintExpr_doSRefFixBaseParam (precondition->lexpr,
927 arglist);
928 precondition->expr = constraintExpr_doSRefFixBaseParam (precondition->expr,
929 arglist);
930
931 return precondition;
932}
933
934
28bf4b0b 935constraint constraint_doFixResult (constraint postcondition, /*@dependent@*/ exprNode fcnCall)
616915dd 936{
937 postcondition = constraint_copy (postcondition);
938 postcondition->lexpr = constraintExpr_doFixResult (postcondition->lexpr, fcnCall);
939 postcondition->expr = constraintExpr_doFixResult (postcondition->expr, fcnCall);
940
941 return postcondition;
942}
943
d46ce6a4 944/*@only@*/ constraint constraint_doSRefFixConstraintParam (constraint precondition,
616915dd 945 exprNodeList arglist)
946{
947
948 precondition = constraint_copy (precondition);
949 precondition->lexpr = constraintExpr_doSRefFixConstraintParam (precondition->lexpr, arglist);
950 precondition->expr = constraintExpr_doSRefFixConstraintParam (precondition->expr, arglist);
951
4ab867d6 952 precondition->fcnPre = FALSE;
616915dd 953 return precondition;
954}
955
d46ce6a4 956constraint constraint_preserveOrig (/*@returned@*/ constraint c) /*@modifies c @*/
616915dd 957{
4ab867d6 958
bb7c2085 959 DPRINTF ((message ("Doing constraint_preserverOrig for %q ", constraint_printDetailed (c))));
4ab867d6 960
d46ce6a4 961 if (c->orig == constraint_undefined)
962 c->orig = constraint_copy (c);
4ab867d6 963
964 else if (c->orig->fcnPre)
965 {
966 constraint temp;
967
968 temp = c->orig;
969
970 /* avoid infinite loop */
971 c->orig = NULL;
972 c->orig = constraint_copy (c);
973 if (c->orig->orig == NULL)
920a3797 974 {
975 c->orig->orig = temp;
976 temp = NULL;
977 }
4ab867d6 978 else
920a3797 979 {
bb7c2085 980 llcontbug ((message ("Expected c->orig->orig to be null")));
981 constraint_free (c->orig->orig);
920a3797 982 c->orig->orig = temp;
983 temp = NULL;
984 }
4ab867d6 985 }
986 else
987 {
bb7c2085 988 DPRINTF ((message ("Not changing constraint")));
4ab867d6 989 }
d46ce6a4 990
bb7c2085 991 DPRINTF ((message ("After Doing constraint_preserverOrig for %q ", constraint_printDetailed (c))));
4ab867d6 992
616915dd 993 return c;
994}
995/*@=fcnuse*/
996/*@=assignexpose*/
997/*@=czechfcns@*/
84c9ffbf 998
2934b455 999
84c9ffbf 1000constraint constraint_togglePost (/*@returned@*/ constraint c)
1001{
1002 c->post = !c->post;
1003 return c;
1004}
2934b455 1005
1006constraint constraint_togglePostOrig (/*@returned@*/ constraint c)
1007{
1008 if (c->orig != NULL)
bb7c2085 1009 c->orig = constraint_togglePost (c->orig);
2934b455 1010 return c;
1011}
1012
bb7c2085 1013bool constraint_hasOrig ( /*@observer@*/ /*@temp@*/ constraint c)
2934b455 1014{
1015 if (c->orig == NULL)
1016 return FALSE;
1017 else
1018 return TRUE;
1019}
920a3797 1020
1021
1022constraint constraint_undump (FILE *f)
1023{
1024 constraint c;
1025 bool fcnPre;
1026 bool post;
1027 arithType ar;
1028
1029 constraintExpr lexpr;
1030 constraintExpr expr;
28bf4b0b 1031
920a3797 1032
1033 char * s;
1034
1035 char *os;
1036
3be9a165 1037 os = mstring_create (MAX_DUMP_LINE_LENGTH);
920a3797 1038
bb7c2085 1039 s = fgets (os, MAX_DUMP_LINE_LENGTH, f);
920a3797 1040
1041 /*@i33*/ /*this should probably be wrappered...*/
1042
28bf4b0b 1043 fcnPre = (bool) reader_getInt (&s);
bb7c2085 1044 advanceField (&s);
28bf4b0b 1045 post = (bool) reader_getInt (&s);
bb7c2085 1046 advanceField (&s);
28bf4b0b 1047 ar = (arithType) reader_getInt (&s);
920a3797 1048
bb7c2085 1049 s = fgets (os, MAX_DUMP_LINE_LENGTH, f);
920a3797 1050
28bf4b0b 1051 reader_checkChar (&s, 'l');
920a3797 1052
1053 lexpr = constraintExpr_undump (f);
1054
bb7c2085 1055 s = fgets (os, MAX_DUMP_LINE_LENGTH, f);
920a3797 1056
28bf4b0b 1057 reader_checkChar (&s, 'r');
920a3797 1058 expr = constraintExpr_undump (f);
1059
bb7c2085 1060 c = constraint_makeNew ();
920a3797 1061
1062 c->fcnPre = fcnPre;
1063 c->post = post;
1064 c->ar = ar;
1065
1066 c->lexpr = lexpr;
1067 c->expr = expr;
1068
bb7c2085 1069 free (os);
1070 c = constraint_preserveOrig (c);
920a3797 1071 return c;
1072}
1073
1074
1075void constraint_dump (/*@observer@*/ constraint c, FILE *f)
1076{
1077 bool fcnPre;
1078 bool post;
1079 arithType ar;
1080
1081 constraintExpr lexpr;
1082 constraintExpr expr;
28bf4b0b 1083
920a3797 1084
1085 fcnPre = c->fcnPre;
1086 post = c->post;
1087 ar = c->ar;
1088 lexpr = c->lexpr;
1089 expr = c->expr;
1090
bb7c2085 1091 fprintf (f, "%d@%d@%d\n", (int) fcnPre, (int) post, (int) ar);
1092 fprintf (f,"l\n");
920a3797 1093 constraintExpr_dump (lexpr, f);
bb7c2085 1094 fprintf (f,"r\n");
920a3797 1095 constraintExpr_dump (expr, f);
1096}
1097
1098
f4ec8018 1099int constraint_compare (/*@observer@*/ /*@temp@*/ const constraint * c1, /*@observer@*/ /*@temp@*/ const constraint * c2) /*@*/
02984642 1100{
1101 fileloc loc1, loc2;
1102
1103 int ret;
1104
bb7c2085 1105 llassert (constraint_isDefined (*c1));
1106 llassert (constraint_isDefined (*c2));
02984642 1107
bb7c2085 1108 if (constraint_isUndefined (*c1))
02984642 1109 {
bb7c2085 1110 if (constraint_isUndefined (*c2))
02984642 1111 return 0;
1112 else
1113 return 1;
1114 }
1115
bb7c2085 1116 if (constraint_isUndefined (*c2))
02984642 1117 {
1118 return -1;
1119 }
1120
bb7c2085 1121 loc1 = constraint_getFileloc (*c1);
1122 loc2 = constraint_getFileloc (*c2);
02984642 1123
bb7c2085 1124 ret = fileloc_compare (loc1, loc2);
02984642 1125
bb7c2085 1126 fileloc_free (loc1);
1127 fileloc_free (loc2);
02984642 1128
1129 return ret;
1130}
1131
1132
84380658 1133bool constraint_isPost (/*@observer@*/ /*@temp@*/ constraint c)
1134{
bb7c2085 1135 llassert (constraint_isDefined (c));
84380658 1136
bb7c2085 1137 if (constraint_isUndefined (c))
84380658 1138 return FALSE;
1139
1140 return (c->post);
1141}
a779b61e 1142
1143
bb7c2085 1144static int constraint_getDepth (/*@observer@*/ /*@temp@*/ constraint c)
a779b61e 1145{
1146 int l , r;
1147
bb7c2085 1148 l = constraintExpr_getDepth (c->lexpr);
1149 r = constraintExpr_getDepth (c->expr);
a779b61e 1150
1151 if (l > r)
1152 {
bb7c2085 1153 DPRINTF (( message ("constraint depth returning %d for %s", l, constraint_print (c))));
a779b61e 1154 return l;
1155 }
1156 else
1157 {
bb7c2085 1158 DPRINTF (( message ("constraint depth returning %d for %s", r, constraint_print (c))));
a779b61e 1159 return r;
1160 }
1161}
1162
1163
1164bool constraint_tooDeep (/*@observer@*/ /*@temp@*/ constraint c)
1165{
1166 int temp;
1167
bb7c2085 1168 temp = constraint_getDepth (c);
a779b61e 1169
bb7c2085 1170 if (temp >= 20)
a779b61e 1171 {
1172 return TRUE;
1173 }
1174
1175 return FALSE;
1176
1177}
This page took 0.298831 seconds and 5 git commands to generate.