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