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