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