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