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