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