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