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