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