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