]> andersk Git - splint.git/blame - src/constraintGeneration.c
Fix tracker issue 1837229.
[splint.git] / src / constraintGeneration.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*/
616915dd 24
25/*
26** constraintGeneration.c
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"
920a3797 34
616915dd 35# include "cgrammar_tokens.h"
36
37# include "exprChecks.h"
616915dd 38# include "exprNodeSList.h"
39
965143f0 40/*drl We need to access the internal representation of exprNode
41 because these functions walk down the parse tree and need a richer
42information than is accessible through the exprNode interface.*/
43
44/*@access exprNode@*/
470b7798 45
965143f0 46static /*@nullwhentrue@*/ bool exprNode_handleError (/*@temp@*/ exprNode p_e);
616915dd 47
abd7f895 48static void exprNode_stmt (/*@temp@*/ /*@temp@*/ exprNode p_e);
49static void exprNode_multiStatement (/*@temp@*/ exprNode p_e);
24633cea 50
ae133592 51static constraintList exprNode_traverseTrueEnsuresConstraints (/*@temp@*/ exprNode p_e);
52static constraintList exprNode_traverseFalseEnsuresConstraints (/*@temp@*/ exprNode p_e);
616915dd 53
28bf4b0b 54static void checkArgumentList (/*@out@*/ exprNode p_temp, exprNodeList p_arglist, fileloc p_sequencePoint) /*@modifies p_temp @*/;
55
6317f163 56static constraintList checkCall (/*@temp@*/ exprNode p_fcn, exprNodeList p_arglist);
4ab867d6 57
abd7f895 58static bool exprNode_isUnhandled (/*@temp@*/ /*@observer@*/ exprNode e)
616915dd 59{
abd7f895 60 llassert(exprNode_isDefined(e));
616915dd 61 switch (e->kind)
62 {
63 case XPR_INITBLOCK:
64 case XPR_EMPTY:
65 case XPR_LABEL:
66 case XPR_CONST:
67 case XPR_VAR:
68 case XPR_BODY:
69 case XPR_OFFSETOF:
70 case XPR_ALIGNOFT:
71 case XPR_ALIGNOF:
72 case XPR_VAARG:
73 case XPR_ITERCALL:
74 case XPR_ITER:
616915dd 75 case XPR_GOTO:
76 case XPR_CONTINUE:
77 case XPR_BREAK:
78 case XPR_COMMA:
79 case XPR_COND:
80 case XPR_TOK:
81 case XPR_FTDEFAULT:
82 case XPR_DEFAULT:
616915dd 83 case XPR_FTCASE:
84 case XPR_CASE:
616915dd 85 case XPR_NODE:
abd7f895 86 DPRINTF((message ("Warning current constraint generation does not handle expression %s", exprNode_unparse(e))));
616915dd 87 return TRUE;
88 /*@notreached@*/
89 break;
90 default:
91 return FALSE;
92
93 }
94 /*not reached*/
95 return FALSE;
96}
97
965143f0 98/*@nullwhentrue@*/ bool exprNode_handleError (exprNode e)
616915dd 99{
abd7f895 100 if (exprNode_isError (e) || exprNode_isUnhandled (e))
616915dd 101 {
abd7f895 102 return TRUE;
616915dd 103 }
abd7f895 104
616915dd 105 return FALSE;
106}
107
abd7f895 108/* evans 2002-03-2 - parameter was dependent */
109bool /*@alt void@*/ exprNode_generateConstraints (/*@temp@*/ exprNode e)
616915dd 110{
abd7f895 111 if (exprNode_isError (e))
616915dd 112 return FALSE;
9280addf 113
abd7f895 114 if (exprNode_isUnhandled (e))
616915dd 115 {
abd7f895 116 DPRINTF((message("Warning ignoring %s", exprNode_unparse (e))));
24633cea 117 return FALSE;
616915dd 118 }
119
ae133592 120 DPRINTF ((message ("exprNode_generateConstraints Analyzing %s at %s", exprNode_unparse(e),
121 fileloc_unparse(exprNode_loc (e)))));
122
abd7f895 123 if (exprNode_isMultiStatement (e))
616915dd 124 {
125 exprNode_multiStatement(e);
126 }
127 else
128 {
ae133592 129 /* fileloc loc; */
9280addf 130
ae133592 131 /* loc = exprNode_getNextSequencePoint(e); */
132 /* exprNode_exprTraverse(e, FALSE, FALSE, loc); */
133
134 /* fileloc_free(loc); */
9280addf 135
24633cea 136 exprNode_stmt(e);
616915dd 137 return FALSE;
24633cea 138
616915dd 139 }
140
141 {
142 constraintList c;
ae133592 143
616915dd 144 c = constraintList_makeFixedArrayConstraints (e->uses);
28bf4b0b 145 e->requiresConstraints = constraintList_reflectChangesFreePre (e->requiresConstraints, c);
bb25bea6 146 constraintList_free(c);
616915dd 147 }
ae133592 148
149 DPRINTF ((message ("e->requiresConstraints %s",
150 constraintList_unparseDetailed (e->requiresConstraints))));
616915dd 151 return FALSE;
616915dd 152}
153
abd7f895 154static void exprNode_stmt (/*@temp@*/ exprNode e)
616915dd 155{
156 exprNode snode;
157 fileloc loc;
9280addf 158
ae133592 159 DPRINTF (("Generating constraint for: %s", exprNode_unparse (e)));
160
abd7f895 161 if (exprNode_isError(e))
616915dd 162 {
b7b694d6 163 return;
616915dd 164 }
b7b694d6 165
bb25bea6 166 /*e->requiresConstraints = constraintList_makeNew();
167 e->ensuresConstraints = constraintList_makeNew(); */
ae133592 168
169 /*!! s = exprNode_unparse (e); */
9280addf 170
616915dd 171 if (e->kind == XPR_INIT)
172 {
bb25bea6 173 constraintList tempList;
ae133592 174 DPRINTF (("Init: %s ", exprNode_unparse (e)));
175 loc = exprNode_getNextSequencePoint (e); /* reduces to an expression */
176 DPRINTF (("Location: %s", fileloc_unparse (loc)));
177 DPRINTF (("Ensures before: %s", constraintList_unparse (e->ensuresConstraints)));
84c9ffbf 178 exprNode_exprTraverse (e, FALSE, FALSE, loc);
ae133592 179 DPRINTF (("Ensures after: %s", constraintList_unparse (e->ensuresConstraints)));
180 DPRINTF (("After traversing..."));
bb25bea6 181 fileloc_free(loc);
ae133592 182
bb25bea6 183 tempList = e->requiresConstraints;
ae133592 184 DPRINTF (("Requires before: %s", constraintList_unparse (e->requiresConstraints)));
185 e->requiresConstraints = exprNode_traverseRequiresConstraints (e);
186 DPRINTF (("Requires after: %s", constraintList_unparse (e->requiresConstraints)));
bb25bea6 187 constraintList_free(tempList);
188
189 tempList = e->ensuresConstraints;
ae133592 190 DPRINTF (("Ensures before: %s", constraintList_unparse (e->ensuresConstraints)));
191 e->ensuresConstraints = exprNode_traverseEnsuresConstraints(e);
192 DPRINTF (("Ensures before: %s", constraintList_unparse (e->ensuresConstraints)));
bb25bea6 193 constraintList_free(tempList);
b7b694d6 194 return;
616915dd 195 }
24633cea 196
197 /*drl 2/13/002 patched bug so return statement will be checked*/
198 /*return is a stmt not not expression ...*/
199 if (e->kind == XPR_RETURN)
200 {
201 constraintList tempList;
202
203 loc = exprNode_getNextSequencePoint(e); /* reduces to an expression */
204
205 exprNode_exprTraverse (exprData_getSingle (e->edata), FALSE, TRUE, loc);
206 fileloc_free(loc);
207
208 tempList = e->requiresConstraints;
ae133592 209 e->requiresConstraints = exprNode_traverseRequiresConstraints(e);
24633cea 210 constraintList_free(tempList);
211 }
616915dd 212
213 if (e->kind != XPR_STMT)
214 {
abd7f895 215 DPRINTF (("Not Stmt"));
216 DPRINTF ((message ("%s ", exprNode_unparse (e))));
b7e84605 217
218 if (exprNode_isMultiStatement (e))
616915dd 219 {
b7e84605 220 exprNode_multiStatement (e); /* evans 2001-08-21: spurious return removed */
616915dd 221 }
24633cea 222 else
223 {
224 loc = exprNode_getNextSequencePoint(e); /* reduces to an expression */
225
226 exprNode_exprTraverse (e, FALSE, TRUE, loc);
227 fileloc_free(loc);
228
229 }
230 return;
616915dd 231 }
232
abd7f895 233 DPRINTF (("Stmt"));
234 DPRINTF ((message ("%s ", exprNode_unparse (e))));
616915dd 235
236 snode = exprData_getUopNode (e->edata);
237
238 /* could be stmt involving multiple statements:
239 i.e. if, while for ect.
240 */
241
242 if (exprNode_isMultiStatement (snode))
243 {
b7e84605 244 exprNode_multiStatement (snode);
84c9ffbf 245 (void) exprNode_copyConstraints (e, snode);
246 return;
616915dd 247 }
248
249 loc = exprNode_getNextSequencePoint(e); /* reduces to an expression */
84c9ffbf 250 exprNode_exprTraverse (snode, FALSE, FALSE, loc);
bb25bea6 251
252 fileloc_free(loc);
253
254 constraintList_free (e->requiresConstraints);
ae133592 255 e->requiresConstraints = exprNode_traverseRequiresConstraints(snode);
bb25bea6 256
257 constraintList_free (e->ensuresConstraints);
ae133592 258 e->ensuresConstraints = exprNode_traverseEnsuresConstraints(snode);
259
bb7c2085 260 DPRINTF ((message ("smtlist constraints are: pre: %s \n and \t post %s\n",
9a48d98c 261 constraintList_unparse(e->requiresConstraints),
262 constraintList_unparse(e->ensuresConstraints))));
bb25bea6 263
b7b694d6 264 return;
616915dd 265}
266
28bf4b0b 267static void exprNode_stmtList (/*@dependent@*/ exprNode e)
616915dd 268{
269 exprNode stmt1, stmt2;
abd7f895 270 if (exprNode_isError (e))
616915dd 271 {
b7b694d6 272 return;
616915dd 273 }
274
bb25bea6 275 /*
b7b694d6 276 Handle case of stmtList with only one statement:
277 The parse tree stores this as stmt instead of stmtList
bb25bea6 278 */
b7b694d6 279
616915dd 280 if (e->kind != XPR_STMTLIST)
281 {
84c9ffbf 282 exprNode_stmt(e);
283 return;
616915dd 284 }
285 llassert (e->kind == XPR_STMTLIST);
abd7f895 286 DPRINTF(("exprNode_stmtList STMTLIST:"));
287 DPRINTF ((cstring_toCharsSafe (exprNode_unparse(e))));
616915dd 288 stmt1 = exprData_getPairA (e->edata);
289 stmt2 = exprData_getPairB (e->edata);
290
291
abd7f895 292 DPRINTF(("exprNode_stmtlist "));
293 DPRINTF ((message("XW%s | %s", exprNode_unparse(stmt1), exprNode_unparse(stmt2))));
616915dd 294
295 exprNode_stmt (stmt1);
abd7f895 296 DPRINTF(("\nstmt after stmtList call "));
616915dd 297
298 exprNode_stmt (stmt2);
abd7f895 299 exprNode_mergeResolve (e, stmt1, stmt2);
616915dd 300
bb7c2085 301 DPRINTF ((message ("smtlist constraints are: pre: %s \n and \t post %s\n",
9a48d98c 302 constraintList_unparse(e->requiresConstraints),
303 constraintList_unparse(e->ensuresConstraints))));
b7b694d6 304 return;
a8e557d3 305}
306
28bf4b0b 307static exprNode doIf (/*@returned@*/ exprNode e, /*@dependent@*/ exprNode test, /*@dependent@*/ exprNode body)
616915dd 308{
bb25bea6 309 constraintList temp;
310
abd7f895 311 DPRINTF ((message ("doIf: %s ", exprNode_unparse(e))));
470b7798 312
ae133592 313 llassert (exprNode_isDefined(test));
abd7f895 314 llassert (exprNode_isDefined (e));
315 llassert (exprNode_isDefined (body));
bb25bea6 316
ae133592 317 DPRINTF((message ("ensures constraints for %s are %s", exprNode_unparse(e), constraintList_unparseDetailed(e->ensuresConstraints))));
bb25bea6 318
9a48d98c 319 DPRINTF((message ("Requires constraints for %s are %s", exprNode_unparse(e), constraintList_unparseDetailed(e->ensuresConstraints))));
bb25bea6 320
9a48d98c 321 DPRINTF((message ("trueEnsures constraints for %s are %s", exprNode_unparse(e), constraintList_unparseDetailed(e->trueEnsuresConstraints))));
bb25bea6 322
9a48d98c 323 DPRINTF((message ("falseEnsures constraints for %s are %s", exprNode_unparse(e), constraintList_unparseDetailed(e->falseEnsuresConstraints))));
bb25bea6 324
325
326
9a48d98c 327 DPRINTF((message ("ensures constraints for %s are %s", exprNode_unparse(test), constraintList_unparseDetailed(test->ensuresConstraints))));
bb25bea6 328
9a48d98c 329 DPRINTF((message ("Requires constraints for %s are %s", exprNode_unparse(test), constraintList_unparseDetailed(test->ensuresConstraints))));
bb25bea6 330
9a48d98c 331 DPRINTF((message ("trueEnsures constraints for %s are %s", exprNode_unparse(test), constraintList_unparseDetailed(test->trueEnsuresConstraints))));
bb25bea6 332
9a48d98c 333 DPRINTF((message ("falseEnsures constraints for %s are %s", exprNode_unparse(test), constraintList_unparseDetailed(test->falseEnsuresConstraints))));
bb25bea6 334
335
336
337 temp = test->trueEnsuresConstraints;
ae133592 338 test->trueEnsuresConstraints = exprNode_traverseTrueEnsuresConstraints(test);
bb25bea6 339 constraintList_free(temp);
340
341 temp = test->ensuresConstraints;
ae133592 342 test->ensuresConstraints = exprNode_traverseEnsuresConstraints (test);
bb25bea6 343 constraintList_free(temp);
344
345 temp = test->requiresConstraints;
ae133592 346 test->requiresConstraints = exprNode_traverseRequiresConstraints (test);
bb25bea6 347 constraintList_free(temp);
616915dd 348
bb25bea6 349
350 test->trueEnsuresConstraints = constraintList_substituteFreeTarget(test->trueEnsuresConstraints, test->ensuresConstraints);
c3e695ff 351
9a48d98c 352 DPRINTF ((message ("doIf: test ensures %s ", constraintList_unparse(test->ensuresConstraints))));
c3e695ff 353
9a48d98c 354 DPRINTF ((message ("doIf: test true ensures %s ", constraintList_unparse(test->trueEnsuresConstraints))));
bb25bea6 355
356 constraintList_free(e->requiresConstraints);
dc7f6a51 357
358
28bf4b0b 359 e->requiresConstraints = constraintList_reflectChanges(body->requiresConstraints, test->trueEnsuresConstraints);
bb25bea6 360
28bf4b0b 361 e->requiresConstraints = constraintList_reflectChangesFreePre (e->requiresConstraints,
616915dd 362 test->ensuresConstraints);
bb25bea6 363 temp = e->requiresConstraints;
470b7798 364 e->requiresConstraints = constraintList_mergeRequires (e->requiresConstraints, test->requiresConstraints);
bb25bea6 365 constraintList_free(temp);
366
367
b7b694d6 368 /* drl possible problem : warning bad */
bb25bea6 369 constraintList_free(e->ensuresConstraints);
616915dd 370 e->ensuresConstraints = constraintList_copy (test->ensuresConstraints);
90bc41f7 371
abd7f895 372 if (exprNode_mayEscape (body))
90bc41f7 373 {
abd7f895 374 DPRINTF ((message("doIf: the if statement body %s returns or exits", exprNode_unparse(body))));
bb25bea6 375 e->ensuresConstraints = constraintList_mergeEnsuresFreeFirst (e->ensuresConstraints,
470b7798 376 test->falseEnsuresConstraints);
90bc41f7 377 }
378
9a48d98c 379 DPRINTF ((message ("doIf: if requiers %s ", constraintList_unparse(e->requiresConstraints))));
9280addf 380
616915dd 381 return e;
382}
383
470b7798 384/*drl added 3/4/2001
385 Also used for condition i.e. ?: operation
386
387 Precondition
388 This function assumes that p, trueBranch, falseBranch have have all been traversed
ae133592 389 for constraints i.e. we assume that exprNode_traverseEnsuresConstraints,
390 exprNode_traverseRequiresConstraints, exprNode_traverseTrueEnsuresConstraints,
391 exprNode_traverseFalseEnsuresConstraints have all been run
470b7798 392*/
393
28bf4b0b 394static exprNode doIfElse (/*@returned@*/ exprNode e, /*@dependent@*/ exprNode p, /*@dependent@*/ exprNode trueBranch, /*@dependent@*/ exprNode falseBranch)
470b7798 395{
b7b694d6 396 constraintList c1, cons, t, t2, f, f2;
470b7798 397
abd7f895 398 llassert (exprNode_isDefined (e));
399 llassert (exprNode_isDefined (p));
400 llassert (exprNode_isDefined (trueBranch));
401 llassert (exprNode_isDefined (falseBranch));
402 DPRINTF ((message ("doIfElse: %s ", exprNode_unparse(e))));
b7b694d6 403
404 /* do requires clauses */
405 c1 = constraintList_copy (p->ensuresConstraints);
406
407 t = constraintList_reflectChanges(trueBranch->requiresConstraints, p->trueEnsuresConstraints);
408 t = constraintList_reflectChangesFreePre (t, p->ensuresConstraints);
409
410 cons = constraintList_reflectChanges(falseBranch->requiresConstraints, p->falseEnsuresConstraints);
411 cons = constraintList_reflectChangesFreePre (cons, c1);
412
abd7f895 413 constraintList_free (e->requiresConstraints);
b7b694d6 414 e->requiresConstraints = constraintList_mergeRequiresFreeFirst (t, cons);
415 e->requiresConstraints = constraintList_mergeRequiresFreeFirst (e->requiresConstraints, p->requiresConstraints);
416
417 /* do ensures clauses
418 find the the ensures lists for each subbranch
419 */
bb25bea6 420
b7b694d6 421 t = constraintList_mergeEnsures (p->trueEnsuresConstraints, trueBranch->ensuresConstraints);
422 t2 = t;
423 t = constraintList_mergeEnsures (p->ensuresConstraints, t);
424 constraintList_free(t2);
425
426 f = constraintList_mergeEnsures (p->falseEnsuresConstraints, falseBranch->ensuresConstraints);
427 f2 = f;
428 f = constraintList_mergeEnsures (p->ensuresConstraints, f);
429 constraintList_free(f2);
430
431 /* find ensures for whole if/else statement */
432
433 constraintList_free(e->ensuresConstraints);
434
435 e->ensuresConstraints = constraintList_logicalOr (t, f);
436
437 constraintList_free(t);
438 constraintList_free(f);
439 constraintList_free(cons);
440 constraintList_free(c1);
441
9a48d98c 442 DPRINTF ((message ("doIfElse: if requires %q ", constraintList_unparse(e->requiresConstraints))));
443 DPRINTF ((message ("doIfElse: if ensures %q ", constraintList_unparse(e->ensuresConstraints))));
b7b694d6 444
445 return e;
470b7798 446}
9280addf 447
28bf4b0b 448static exprNode doWhile (/*@returned@*/ exprNode e, /*@dependent@*/ exprNode test, /*@dependent@*/ exprNode body)
9280addf 449{
abd7f895 450 DPRINTF ((message ("doWhile: %s ", exprNode_unparse(e))));
9280addf 451 return doIf (e, test, body);
452}
453
920a3797 454/*@only@*/ constraintList constraintList_makeFixedArrayConstraints (/*@observer@*/ sRefSet s)
616915dd 455{
456 constraintList ret;
470b7798 457 constraint con;
c3e695ff 458 ret = constraintList_makeNew();
616915dd 459
460 sRefSet_elements (s, el)
461 {
abd7f895 462 if (sRef_isFixedArray(el))
b7b694d6 463 {
37ae0b5e 464 size_t size;
bb7c2085 465 DPRINTF((message("%s is a fixed array",
abd7f895 466 sRef_unparse(el))));
b7b694d6 467 size = sRef_getArraySize(el);
bb7c2085 468 DPRINTF((message("%s is a fixed array with size %d",
abd7f895 469 sRef_unparse(el), (int)size)));
e5081f8c 470 con = constraint_makeSRefSetBufferSize (el, size_toLong (size - 1));
b7b694d6 471 ret = constraintList_add(ret, con);
472 }
473 else
474 {
bb7c2085 475 DPRINTF((message("%s is not a fixed array",
abd7f895 476 sRef_unparse(el))));
b7b694d6 477
478
abd7f895 479 if (sRef_isExternallyVisible (el))
b7b694d6 480 {
481 /*
bb7c2085 482 DPRINTF((message("%s is externally visible",
abd7f895 483 sRef_unparse(el))));
b7b694d6 484 con = constraint_makeSRefWriteSafeInt(el, 0);
485 ret = constraintList_add(ret, con);
486
487 con = constraint_makeSRefReadSafeInt(el, 0);
488
489 ret = constraintList_add(ret, con);
490 */
491 }
492 }
616915dd 493 }
b7b694d6 494 end_sRefSet_elements ;
495
abd7f895 496 DPRINTF((message("constraintList_makeFixedArrayConstraints returning %s",
9a48d98c 497 constraintList_unparse(ret))));
b7b694d6 498 return ret;
616915dd 499}
500
b7b694d6 501# if 0
4ab867d6 502exprNode makeDataTypeConstraints (/*@returned@*/ exprNode e)
616915dd 503{
504 constraintList c;
505 DPRINTF(("makeDataTypeConstraints"));
506
507 c = constraintList_makeFixedArrayConstraints (e->uses);
508
4ab867d6 509 e->ensuresConstraints = constraintList_addListFree (e->ensuresConstraints, c);
616915dd 510
511 return e;
512}
b7b694d6 513# endif
616915dd 514
28bf4b0b 515static void doFor (/*@dependent@*/ exprNode e, /*@dependent@*/ exprNode forPred, /*@dependent@*/ exprNode forBody)
616915dd 516{
517 exprNode init, test, inc;
b7b694d6 518 /* merge the constraints: modle as if statement */
519
abd7f895 520 /* init
521 if (test)
522 for body
523 inc */
b7b694d6 524
abd7f895 525 llassert (exprNode_isDefined (e));
526 llassert (exprNode_isDefined (forPred));
527 llassert (exprNode_isDefined (forBody));
528
529 init = exprData_getTripleInit (forPred->edata);
530 test = exprData_getTripleTest (forPred->edata);
531 inc = exprData_getTripleInc (forPred->edata);
532
533 if (((exprNode_isError (test) /*|| (exprNode_isError(init))*/) || (exprNode_isError (inc))))
b7b694d6 534 {
abd7f895 535 DPRINTF ((message ("strange for statement:%s, ignoring it", exprNode_unparse(e))));
b7b694d6 536 return;
537 }
538
539 exprNode_forLoopHeuristics(e, forPred, forBody);
540
541 constraintList_free(e->requiresConstraints);
542 e->requiresConstraints = constraintList_reflectChanges(forBody->requiresConstraints, test->ensuresConstraints);
543 e->requiresConstraints = constraintList_reflectChangesFreePre (e->requiresConstraints, test->trueEnsuresConstraints);
544 e->requiresConstraints = constraintList_reflectChangesFreePre (e->requiresConstraints, forPred->ensuresConstraints);
545
546 if (!forBody->canBreak)
547 {
abd7f895 548 e->ensuresConstraints = constraintList_addListFree(e->ensuresConstraints, constraintList_copy(forPred->ensuresConstraints));
549 e->ensuresConstraints = constraintList_addListFree(e->ensuresConstraints,constraintList_copy(test->falseEnsuresConstraints));
b7b694d6 550 }
551 else
552 {
abd7f895 553 DPRINTF(("Can break"));
b7b694d6 554 }
616915dd 555}
556
03d670b6 557static /*@dependent@*/ exprNode exprNode_makeDependent(/*@returned@*/ exprNode e)
558{
393e573f 559 /* !!! DRL - this is ridiculous! Read the manual on memory annotations please! */
03d670b6 560 return e;
03d670b6 561}
562
3e3ec469 563static void
564exprNode_doGenerateConstraintSwitch
565 (/*@dependent@*/ exprNode switchExpr,
566 /*@dependent@*/ exprNode body,
567 /*@special@*/ constraintList *currentRequires,
568 /*@special@*/ constraintList *currentEnsures,
569 /*@special@*/ constraintList *savedRequires,
570 /*@special@*/ constraintList *savedEnsures)
571 /*@post:only *currentRequires, *currentEnsures, *savedRequires, *savedEnsures @*/
572 /*@sets *currentRequires, *currentEnsures, *savedRequires, *savedEnsures @*/
7c9c4a67 573{
574 exprNode stmt, stmtList;
575
abd7f895 576 DPRINTF((message("exprNode_doGenerateConstraintSwitch: (switch %s) %s",
7c9c4a67 577 exprNode_unparse(switchExpr), exprNode_unparse(body)
abd7f895 578 )));
7c9c4a67 579
abd7f895 580 if (exprNode_isError(body))
7c9c4a67 581 {
3e3ec469 582 *currentRequires = constraintList_makeNew ();
583 *currentEnsures = constraintList_makeNew ();
03d670b6 584
3e3ec469 585 *savedRequires = constraintList_makeNew ();
586 *savedEnsures = constraintList_makeNew ();
03d670b6 587 /*@-onlytrans@*/
7c9c4a67 588 return;
03d670b6 589 /*@=onlytrans@*/
7c9c4a67 590 }
591
abd7f895 592 if (body->kind != XPR_STMTLIST)
7c9c4a67 593 {
dc7f6a51 594 DPRINTF((message("exprNode_doGenerateConstraintSwitch: non stmtlist: %s",
abd7f895 595 exprNode_unparse(body))));
7c9c4a67 596 stmt = body;
597 stmtList = exprNode_undefined;
03d670b6 598 stmt = exprNode_makeDependent(stmt);
599 stmtList = exprNode_makeDependent(stmtList);
600 }
601 else
602 {
603 stmt = exprData_getPairB(body->edata);
604 stmtList = exprData_getPairA(body->edata);
605 stmt = exprNode_makeDependent(stmt);
606 stmtList = exprNode_makeDependent(stmtList);
7c9c4a67 607 }
7c9c4a67 608
dc7f6a51 609 DPRINTF((message("exprNode_doGenerateConstraintSwitch: stmtlist: %s stmt: %s",
abd7f895 610 exprNode_unparse(stmtList), exprNode_unparse(stmt))
611 ));
7c9c4a67 612
613
614 exprNode_doGenerateConstraintSwitch (switchExpr, stmtList, currentRequires, currentEnsures,
abd7f895 615 savedRequires, savedEnsures);
7c9c4a67 616
abd7f895 617 if (exprNode_isError(stmt))
03d670b6 618 /*@-onlytrans@*/
7c9c4a67 619 return;
03d670b6 620 /*@=onlytrans@*/
7c9c4a67 621
622 exprNode_stmt(stmt);
03d670b6 623
624 switchExpr = exprNode_makeDependent (switchExpr);
625
abd7f895 626 if (! exprNode_isCaseMarker(stmt))
7c9c4a67 627 {
628
629 constraintList temp;
630
abd7f895 631 DPRINTF ((message("Got normal statement %s (requires %s ensures %s)", exprNode_unparse(stmt),
632 constraintList_unparse(stmt->requiresConstraints), constraintList_unparse(stmt->ensuresConstraints))));
7c9c4a67 633
634 temp = constraintList_reflectChanges (stmt->requiresConstraints,
635 *currentEnsures);
636
03d670b6 637 *currentRequires = constraintList_mergeRequiresFreeFirst(
638 *currentRequires,
639 temp);
7c9c4a67 640
641 constraintList_free(temp);
642
643 *currentEnsures = constraintList_mergeEnsuresFreeFirst
644 (*currentEnsures,
645 stmt->ensuresConstraints);
abd7f895 646 DPRINTF((message("returning from exprNode_doGenerateConstraintSwitch: (switch %s) %s currentRequires:"
7c9c4a67 647 "%s currentEnsures:%s",
648 exprNode_unparse(switchExpr), exprNode_unparse(body),
9a48d98c 649 constraintList_unparse(*currentRequires), constraintList_unparse(*currentEnsures)
abd7f895 650 )));
03d670b6 651 /*@-onlytrans@*/
7c9c4a67 652 return;
03d670b6 653 /*@=onlytrans@*/
654
7c9c4a67 655 }
656
abd7f895 657 if (exprNode_isCaseMarker(stmt) && exprNode_mustEscape(stmtList))
7c9c4a67 658 {
b7b694d6 659 /*
660 ** merge current and saved constraint with Logical Or...
661 ** make a constraint for ensures
662 */
7c9c4a67 663
664 constraintList temp;
665 constraint con;
666
abd7f895 667 DPRINTF ((message("Got case marker")));
7c9c4a67 668
669 if (constraintList_isUndefined(*savedEnsures) &&
abd7f895 670 constraintList_isUndefined(*savedRequires))
7c9c4a67 671 {
abd7f895 672 llassert(constraintList_isUndefined(*savedEnsures));
673 llassert(constraintList_isUndefined(*savedRequires));
7c9c4a67 674 *savedEnsures = constraintList_copy(*currentEnsures);
675 *savedRequires = constraintList_copy(*currentRequires);
676 }
03d670b6 677 else
678 {
abd7f895 679 DPRINTF ((message("Doing logical or")));
03d670b6 680 temp = constraintList_logicalOr (*savedEnsures, *currentEnsures);
681 constraintList_free (*savedEnsures);
682 *savedEnsures = temp;
683
684 *savedRequires = constraintList_mergeRequiresFreeFirst (*savedRequires, *currentRequires);
685 }
686
517a2db3 687 con = constraint_makeEnsureEqual (switchExpr, exprData_getSingle (stmt->edata), exprNode_loc (stmt));
7c9c4a67 688
517a2db3 689 constraintList_free (*currentEnsures);
7c9c4a67 690 *currentEnsures = constraintList_makeNew();
691 *currentEnsures = constraintList_add(*currentEnsures, con);
692
693 constraintList_free(*currentRequires);
694 *currentRequires = constraintList_makeNew();
517a2db3 695 DPRINTF (("exprNode_doGenerateConstraintSwitch: (switch %s) %s savedRequires:"
696 "%s savedEnsures:%s",
697 exprNode_unparse(switchExpr), exprNode_unparse(body),
698 constraintList_unparse(*savedRequires), constraintList_unparse(*savedEnsures)
699 ));
7c9c4a67 700 }
517a2db3 701 else if (exprNode_isCaseMarker(stmt)) /* prior case has no break. */
7c9c4a67 702 {
b7b694d6 703 /*
704 We don't do anything to the sved constraints because the case hasn't ended
705 The new ensures constraints for the case will be:
706 the constraint for the case statement (CASE_LABEL == SWITCH_EXPR) logicalOr currentEnsures
707 */
708
7c9c4a67 709 constraintList temp;
710 constraint con;
7c9c4a67 711 constraintList ensuresTemp;
712
517a2db3 713 con = constraint_makeEnsureEqual (switchExpr, exprData_getSingle (stmt->edata), exprNode_loc (stmt));
714
715 ensuresTemp = constraintList_makeNew ();
7c9c4a67 716 ensuresTemp = constraintList_add (ensuresTemp, con);
717
517a2db3 718 if (exprNode_isError (stmtList))
7c9c4a67 719 {
517a2db3 720 constraintList_free (*currentEnsures);
721 *currentEnsures = constraintList_copy (ensuresTemp);
722 constraintList_free (ensuresTemp);
03d670b6 723 }
724 else
725 {
03d670b6 726 temp = constraintList_logicalOr (*currentEnsures, ensuresTemp);
517a2db3 727 constraintList_free (*currentEnsures);
728 constraintList_free (ensuresTemp);
03d670b6 729 *currentEnsures = temp;
730 }
517a2db3 731
732 constraintList_free (*currentRequires);
7c9c4a67 733 *currentRequires = constraintList_makeNew();
734 }
03d670b6 735 else
736 {
b7b694d6 737 /*
738 we handle the case of ! exprNode_isCaseMarker above
739 the else if clause should always be true.
740 */
03d670b6 741 BADEXIT;
742 }
7c9c4a67 743
517a2db3 744 DPRINTF (("returning from exprNode_doGenerateConstraintSwitch: (switch %s) %s currentRequires:"
745 "%s currentEnsures:%s",
746 exprNode_unparse(switchExpr), exprNode_unparse(body),
747 constraintList_unparse(*currentRequires), constraintList_unparse(*currentEnsures)
748 ));
749
03d670b6 750 /*@-onlytrans@*/
7c9c4a67 751 return;
03d670b6 752 /*@=onlytrans@*/
7c9c4a67 753}
754
755
abd7f895 756static void exprNode_generateConstraintSwitch (/*@notnull@*/ exprNode switchStmt)
7c9c4a67 757{
758 constraintList constraintsRequires;
759 constraintList constraintsEnsures;
760 constraintList lastRequires;
761 constraintList lastEnsures;
762
763 exprNode body;
764 exprNode switchExpr;
765
abd7f895 766 switchExpr = exprData_getPairA (switchStmt->edata);
767 body = exprData_getPairB (switchStmt->edata);
768
769 if (!exprNode_isDefined (body))
770 {
771 return;
772 }
7c9c4a67 773
abd7f895 774 DPRINTF((message("")));
a779b61e 775
abd7f895 776 if (body->kind == XPR_BLOCK)
7c9c4a67 777 body = exprData_getSingle(body->edata);
778
b941db6b 779
7c9c4a67 780 constraintsRequires = constraintList_undefined;
781 constraintsEnsures = constraintList_undefined;
782
783 lastRequires = constraintList_makeNew();
784 lastEnsures = constraintList_makeNew();
b941db6b 785
7c9c4a67 786
3e3ec469 787 /*@-mustfree@*/
b73d1009 788 /* evans 2002-01-01: spurious warnings for these becuase of stack allocated storage */
3e3ec469 789 exprNode_doGenerateConstraintSwitch (switchExpr, body, &lastRequires,
790 &lastEnsures, &constraintsRequires, &constraintsEnsures);
791 /*@=mustfree@*/
7c9c4a67 792
b7b694d6 793 /*
794 merge current and saved constraint with Logical Or...
795 make a constraint for ensures
796 */
7c9c4a67 797
798 constraintList_free(switchStmt->requiresConstraints);
799 constraintList_free(switchStmt->ensuresConstraints);
800
abd7f895 801 if (constraintList_isDefined(constraintsEnsures) && constraintList_isDefined(constraintsRequires))
7c9c4a67 802 {
803 switchStmt->ensuresConstraints = constraintList_logicalOr(constraintsEnsures, lastEnsures);
804 switchStmt->requiresConstraints = constraintList_mergeRequires(constraintsRequires, lastRequires);
805 constraintList_free (constraintsRequires);
806 constraintList_free (constraintsEnsures);
807 }
03d670b6 808 else
809 {
810 switchStmt->ensuresConstraints = constraintList_copy(lastEnsures);
811 switchStmt->requiresConstraints = constraintList_copy(lastRequires);
812 }
7c9c4a67 813
814 constraintList_free (lastRequires);
815 constraintList_free (lastEnsures);
816
bb7c2085 817 DPRINTF(((message(" exprNode_generateConstraintSwitch returning requires: %s and ensures %s",
9a48d98c 818 constraintList_unparse(switchStmt->requiresConstraints),
819 constraintList_unparse(switchStmt->ensuresConstraints)
abd7f895 820 )
821 )));
7c9c4a67 822}
823
abd7f895 824static exprNode doSwitch (/*@returned@*/ /*@notnull@*/ exprNode e)
470b7798 825{
826 exprNode body;
827 exprData data;
828
829 data = e->edata;
abd7f895 830 DPRINTF ((message ("doSwitch for: switch (%s) %s",
2681ee39 831 exprNode_unparse (exprData_getPairA (data)),
abd7f895 832 exprNode_unparse (exprData_getPairB (data)))));
7c9c4a67 833
470b7798 834 body = exprData_getPairB (data);
7c9c4a67 835 exprNode_generateConstraintSwitch (e);
470b7798 836 return e;
837}
9280addf 838
28bf4b0b 839void exprNode_multiStatement (/*@dependent@*/ exprNode e)
616915dd 840{
841
842 bool ret;
843 exprData data;
844 exprNode e1, e2;
845 exprNode p, trueBranch, falseBranch;
846 exprNode forPred, forBody;
470b7798 847 exprNode test;
bb25bea6 848
849 constraintList temp;
850
abd7f895 851 DPRINTF((message ("exprNode_multistatement Analysising %s %s at", exprNode_unparse(e),
566b8b82 852 fileloc_unparse(exprNode_getNextSequencePoint(e)))));
616915dd 853
854 if (exprNode_handleError (e))
855 {
b7b694d6 856 return;
616915dd 857 }
858
859 data = e->edata;
860
861 ret = TRUE;
862
863 switch (e->kind)
864 {
865
866 case XPR_FOR:
616915dd 867 forPred = exprData_getPairA (data);
868 forBody = exprData_getPairB (data);
869
b7b694d6 870 /* First generate the constraints */
616915dd 871 exprNode_generateConstraints (forPred);
872 exprNode_generateConstraints (forBody);
873
874
875 doFor (e, forPred, forBody);
876
877 break;
878
879 case XPR_FORPRED:
abd7f895 880 exprNode_generateConstraints (exprData_getTripleInit (data));
616915dd 881 test = exprData_getTripleTest (data);
882 exprNode_exprTraverse (test,FALSE, FALSE, exprNode_loc(e));
abd7f895 883 exprNode_generateConstraints (exprData_getTripleInc (data));
9280addf 884
abd7f895 885 if (!exprNode_isError(test))
bb25bea6 886 {
887 constraintList temp2;
888 temp2 = test->trueEnsuresConstraints;
ae133592 889 test->trueEnsuresConstraints = exprNode_traverseTrueEnsuresConstraints(test);
bb25bea6 890 constraintList_free(temp2);
891 }
892
616915dd 893 exprNode_generateConstraints (exprData_getTripleInc (data));
894 break;
9280addf 895
896 case XPR_WHILE:
897 e1 = exprData_getPairA (data);
898 e2 = exprData_getPairB (data);
899
900 exprNode_exprTraverse (e1,
901 FALSE, FALSE, exprNode_loc(e1));
902
903 exprNode_generateConstraints (e2);
904
905 e = doWhile (e, e1, e2);
906
907 break;
908
616915dd 909 case XPR_IF:
abd7f895 910 DPRINTF(("IF:"));
911 DPRINTF ((exprNode_unparse(e)));
616915dd 912 e1 = exprData_getPairA (data);
913 e2 = exprData_getPairB (data);
914
b7b694d6 915 exprNode_exprTraverse (e1, FALSE, FALSE, exprNode_loc(e1));
616915dd 916
917 exprNode_generateConstraints (e2);
616915dd 918 e = doIf (e, e1, e2);
616915dd 919 break;
9280addf 920
616915dd 921 case XPR_IFELSE:
922 DPRINTF(("Starting IFELSE"));
616915dd 923 p = exprData_getTriplePred (data);
abd7f895 924
616915dd 925 trueBranch = exprData_getTripleTrue (data);
926 falseBranch = exprData_getTripleFalse (data);
927
928 exprNode_exprTraverse (p,
929 FALSE, FALSE, exprNode_loc(p));
930 exprNode_generateConstraints (trueBranch);
931 exprNode_generateConstraints (falseBranch);
932
abd7f895 933 llassert (exprNode_isDefined (p));
bb25bea6 934 temp = p->ensuresConstraints;
ae133592 935 p->ensuresConstraints = exprNode_traverseEnsuresConstraints (p);
bb25bea6 936 constraintList_free(temp);
937
938 temp = p->requiresConstraints;
ae133592 939 p->requiresConstraints = exprNode_traverseRequiresConstraints (p);
bb25bea6 940 constraintList_free(temp);
941
942 temp = p->trueEnsuresConstraints;
ae133592 943 p->trueEnsuresConstraints = exprNode_traverseTrueEnsuresConstraints(p);
bb25bea6 944 constraintList_free(temp);
945
cf38ca4d 946
947
9a48d98c 948 DPRINTF((message("p->trueEnsuresConstraints before substitue %s", constraintList_unparse(p->trueEnsuresConstraints) )
cf38ca4d 949 ));
950
951 /*drl 10/10/2002 this is a bit of a hack but the reason why we do this is so that any function post conditions or similar things get applied correctly to each branch. e.g. in strlen(s) < 5 we want the trueEnsures to be maxRead(s) < 5*/
952
953 p->trueEnsuresConstraints = constraintList_substituteFreeTarget (p->trueEnsuresConstraints,
954 p->ensuresConstraints);
955
9a48d98c 956 DPRINTF(( message ("p->trueEnsuresConstraints after substitue %s", constraintList_unparse(p->trueEnsuresConstraints) )
cf38ca4d 957 ));
958
bb25bea6 959 temp = p->falseEnsuresConstraints;
ae133592 960 p->falseEnsuresConstraints = exprNode_traverseFalseEnsuresConstraints(p);
bb25bea6 961 constraintList_free(temp);
616915dd 962
cf38ca4d 963 /*See comment on trueEnsures*/
964 p->falseEnsuresConstraints = constraintList_substituteFreeTarget (p->falseEnsuresConstraints,
965 p->ensuresConstraints);
966
abd7f895 967 e = doIfElse (e, p, trueBranch, falseBranch);
968 DPRINTF(("Done IFELSE"));
616915dd 969 break;
cf38ca4d 970
616915dd 971 case XPR_DOWHILE:
470b7798 972
973 e2 = (exprData_getPairB (data));
974 e1 = (exprData_getPairA (data));
975
abd7f895 976 DPRINTF((message ("do { %s } while (%s)", exprNode_unparse(e2), exprNode_unparse(e1))));
470b7798 977 exprNode_generateConstraints (e2);
978 exprNode_generateConstraints (e1);
979 e = exprNode_copyConstraints (e, e2);
9a48d98c 980 DPRINTF ((message ("e = %s ", constraintList_unparse(e->requiresConstraints))));
470b7798 981
616915dd 982 break;
983
984 case XPR_BLOCK:
965143f0 985 {
986 exprNode tempExpr;
987
988 tempExpr = exprData_getSingle (data);
989
990 exprNode_generateConstraints (tempExpr);
991
992 if (exprNode_isDefined(tempExpr) )
993 {
994 constraintList_free(e->requiresConstraints);
995 e->requiresConstraints = constraintList_copy (tempExpr->requiresConstraints);
996 constraintList_free(e->ensuresConstraints);
997 e->ensuresConstraints = constraintList_copy (tempExpr->ensuresConstraints);
998 }
999 else
1000 {
1001 llassert(FALSE);
1002 }
1003 }
616915dd 1004 break;
1005
470b7798 1006 case XPR_SWITCH:
1007 e = doSwitch (e);
1008 break;
616915dd 1009 case XPR_STMT:
1010 case XPR_STMTLIST:
84c9ffbf 1011 exprNode_stmtList (e);
1012 return ;
616915dd 1013 /*@notreached@*/
1014 break;
1015 default:
1016 ret=FALSE;
1017 }
b7b694d6 1018 return;
616915dd 1019}
1020
bb25bea6 1021static bool lltok_isBoolean_Op (lltok tok)
616915dd 1022{
1023 /*this should really be a switch statement but
1024 I don't want to violate the abstraction
1025 maybe this should go in lltok.c */
1026
16c024b5 1027 if (lltok_isEqOp (tok))
616915dd 1028 {
1029 return TRUE;
1030 }
16c024b5 1031 if (lltok_isAndOp (tok))
616915dd 1032
1033 {
1034
1035 return TRUE;
1036 }
16c024b5 1037 if (lltok_isOrOp (tok))
616915dd 1038 {
1039 return TRUE;
1040 }
1041
abd7f895 1042 if (lltok_isGt_Op (tok))
616915dd 1043 {
1044 return TRUE;
1045 }
abd7f895 1046 if (lltok_isLt_Op (tok))
616915dd 1047 {
1048 return TRUE;
1049 }
1050
abd7f895 1051 if (lltok_isLe_Op (tok))
616915dd 1052 {
1053 return TRUE;
1054 }
1055
abd7f895 1056 if (lltok_isGe_Op (tok))
616915dd 1057 {
1058 return TRUE;
1059 }
1060
1061 return FALSE;
1062
1063}
1064
1065
28bf4b0b 1066static void exprNode_booleanTraverse (/*@dependent@*/ exprNode e, /*@unused@*/ bool definatelv, /*@unused@*/ bool definaterv, fileloc sequencePoint)
616915dd 1067{
b7b694d6 1068 constraint cons;
1069 exprNode t1, t2;
1070 exprData data;
1071 lltok tok;
1072 constraintList tempList, temp;
965143f0 1073
1074 if (exprNode_isUndefined(e) )
1075 {
1076 llassert (exprNode_isDefined(e) );
1077 return;
1078 }
1079
b7b694d6 1080 data = e->edata;
616915dd 1081
b7b694d6 1082 tok = exprData_getOpTok (data);
1083 t1 = exprData_getOpA (data);
1084 t2 = exprData_getOpB (data);
965143f0 1085
1086 /* drl 3/2/2003 we know this because of the type of expression*/
1087 llassert( exprNode_isDefined(t1) && exprNode_isDefined(t2) );
1088
616915dd 1089
b7b694d6 1090 tempList = constraintList_undefined;
616915dd 1091
b7b694d6 1092 /* arithmetic tests */
616915dd 1093
16c024b5 1094 if (lltok_isEqOp (tok))
b7b694d6 1095 {
1096 cons = constraint_makeEnsureEqual (t1, t2, sequencePoint);
1097 e->trueEnsuresConstraints = constraintList_add(e->trueEnsuresConstraints, cons);
1098 }
616915dd 1099
b7b694d6 1100
abd7f895 1101 if (lltok_isLt_Op (tok))
b7b694d6 1102 {
1103 cons = constraint_makeEnsureLessThan (t1, t2, sequencePoint);
1104 e->trueEnsuresConstraints = constraintList_add(e->trueEnsuresConstraints, cons);
1105 cons = constraint_makeEnsureGreaterThanEqual (t1, t2, sequencePoint);
1106 e->falseEnsuresConstraints = constraintList_add(e->falseEnsuresConstraints, cons);
1107 }
616915dd 1108
abd7f895 1109 if (lltok_isGe_Op (tok))
b7b694d6 1110 {
1111 cons = constraint_makeEnsureGreaterThanEqual (t1, t2, sequencePoint);
1112 e->trueEnsuresConstraints = constraintList_add(e->trueEnsuresConstraints, cons);
1113
1114 cons = constraint_makeEnsureLessThan (t1, t2, sequencePoint);
1115 e->falseEnsuresConstraints = constraintList_add(e->falseEnsuresConstraints, cons);
1116 }
1117
abd7f895 1118 if (lltok_isGt_Op (tok))
b7b694d6 1119 {
1120 cons = constraint_makeEnsureGreaterThan (t1, t2, sequencePoint);
1121 e->trueEnsuresConstraints = constraintList_add(e->trueEnsuresConstraints, cons);
1122 cons = constraint_makeEnsureLessThanEqual (t1, t2, sequencePoint);
1123 e->falseEnsuresConstraints = constraintList_add(e->falseEnsuresConstraints, cons);
1124 }
1125
abd7f895 1126 if (lltok_isLe_Op (tok))
b7b694d6 1127 {
1128 cons = constraint_makeEnsureLessThanEqual (t1, t2, sequencePoint);
1129 e->trueEnsuresConstraints = constraintList_add(e->trueEnsuresConstraints, cons);
1130
1131 cons = constraint_makeEnsureGreaterThan (t1, t2, sequencePoint);
1132 e->falseEnsuresConstraints = constraintList_add(e->falseEnsuresConstraints, cons);
1133 }
1134
1135 /* Logical operations */
1136
16c024b5 1137 if (lltok_isAndOp (tok))
b7b694d6 1138 {
1139 /* true ensures */
1140 tempList = constraintList_copy (t1->trueEnsuresConstraints);
1141 tempList = constraintList_addList (tempList, t2->trueEnsuresConstraints);
1142 e->trueEnsuresConstraints = constraintList_addListFree(e->trueEnsuresConstraints, tempList);
1143
1144 /* false ensures: fens t1 or tens t1 and fens t2 */
1145 tempList = constraintList_copy (t1->trueEnsuresConstraints);
1146 tempList = constraintList_addList (tempList, t2->falseEnsuresConstraints);
1147 temp = tempList;
1148 tempList = constraintList_logicalOr (tempList, t1->falseEnsuresConstraints);
1149 constraintList_free (temp);
1150
1b8ae690 1151 /* evans - was constraintList_addList - memory leak detected by splint */
b7b694d6 1152 e->falseEnsuresConstraints = constraintList_addListFree (e->falseEnsuresConstraints, tempList);
1153 }
16c024b5 1154 else if (lltok_isOrOp (tok))
b7b694d6 1155 {
1156 /* false ensures */
616915dd 1157 tempList = constraintList_copy (t1->falseEnsuresConstraints);
1158 tempList = constraintList_addList (tempList, t2->falseEnsuresConstraints);
4ab867d6 1159 e->falseEnsuresConstraints = constraintList_addListFree(e->falseEnsuresConstraints, tempList);
616915dd 1160
b7b694d6 1161 /* true ensures: tens t1 or fens t1 and tens t2 */
616915dd 1162 tempList = constraintList_copy (t1->falseEnsuresConstraints);
1163 tempList = constraintList_addList (tempList, t2->trueEnsuresConstraints);
bb25bea6 1164
1165 temp = tempList;
616915dd 1166 tempList = constraintList_logicalOr (tempList, t1->trueEnsuresConstraints);
bb25bea6 1167 constraintList_free(temp);
1168
60eced23 1169 e->trueEnsuresConstraints = constraintList_addListFree(e->trueEnsuresConstraints, tempList);
920a3797 1170 tempList = constraintList_undefined;
616915dd 1171 }
b7b694d6 1172 else
84c9ffbf 1173 {
abd7f895 1174 DPRINTF((message("%s is not a boolean operation", lltok_unparse(tok))));
60eced23 1175 }
616915dd 1176}
1177
ae133592 1178void exprNode_exprTraverse (/*@dependent@*/ exprNode e,
1179 bool definatelv, bool definaterv,
1180 /*@observer@*/ /*@temp@*/ fileloc sequencePoint)
616915dd 1181{
9280addf 1182 exprNode t1, t2, fcn;
616915dd 1183 lltok tok;
616915dd 1184 exprData data;
1185 constraint cons;
bb25bea6 1186 constraintList temp;
1187
abd7f895 1188 if (exprNode_isError(e))
470b7798 1189 {
b7b694d6 1190 return;
470b7798 1191 }
1192
ae133592 1193 DPRINTF (("exprNode_exprTraverse analyzing %s at %s",
1194 exprNode_unparse (e),
1195 fileloc_unparse (exprNode_loc (e))));
470b7798 1196
abd7f895 1197 if (exprNode_isUnhandled (e))
ae133592 1198 {
1199 return;
1200 }
b7b694d6 1201
616915dd 1202 data = e->edata;
1203
1204 switch (e->kind)
1205 {
616915dd 1206 case XPR_WHILEPRED:
1207 t1 = exprData_getSingle (data);
1208 exprNode_exprTraverse (t1, definatelv, definaterv, sequencePoint);
1209 e = exprNode_copyConstraints (e, t1);
1210 break;
1211
1212 case XPR_FETCH:
1213
abd7f895 1214 if (definatelv)
616915dd 1215 {
abd7f895 1216 t1 = (exprData_getPairA (data));
1217 t2 = (exprData_getPairB (data));
616915dd 1218 cons = constraint_makeWriteSafeExprNode (t1, t2);
1219 }
1220 else
1221 {
abd7f895 1222 t1 = (exprData_getPairA (data));
1223 t2 = (exprData_getPairB (data));
1224 cons = constraint_makeReadSafeExprNode (t1, t2);
616915dd 1225 }
1226
1227 e->requiresConstraints = constraintList_add(e->requiresConstraints, cons);
1228 cons = constraint_makeEnsureMaxReadAtLeast (t1, t2, sequencePoint);
1229 e->ensuresConstraints = constraintList_add(e->ensuresConstraints, cons);
1230
9280addf 1231 cons = constraint_makeEnsureLteMaxRead (t2, t1);
616915dd 1232 e->trueEnsuresConstraints = constraintList_add(e->trueEnsuresConstraints, cons);
1233
616915dd 1234 exprNode_exprTraverse (exprData_getPairA (data), FALSE, TRUE, sequencePoint);
1235 exprNode_exprTraverse (exprData_getPairB (data), FALSE, TRUE, sequencePoint);
1236
616915dd 1237 break;
1238
1239 case XPR_PARENS:
1240 exprNode_exprTraverse (exprData_getUopNode (e->edata), definatelv, definaterv, sequencePoint);
616915dd 1241 break;
1242 case XPR_INIT:
920a3797 1243 {
920a3797 1244 t2 = exprData_getInitNode (data);
ae133592 1245
1246 DPRINTF (("initialization ==> %s",exprNode_unparse (t2)));
920a3797 1247
abd7f895 1248 exprNode_exprTraverse (t2, definatelv, TRUE, sequencePoint);
920a3797 1249
ae133592 1250 /* This test is nessecary because some expressions generate a null expression node.
1251 function pointer do that -- drl */
1252
1253 if (!exprNode_isError (e) && !exprNode_isError (t2))
920a3797 1254 {
1255 cons = constraint_makeEnsureEqual (e, t2, sequencePoint);
1256 e->ensuresConstraints = constraintList_add(e->ensuresConstraints, cons);
1257 }
1258 }
616915dd 1259
1260 break;
1261 case XPR_ASSIGN:
1262 t1 = exprData_getOpA (data);
1263 t2 = exprData_getOpB (data);
ae133592 1264 DPRINTF (("Assignment constraints t1: %s", constraintList_unparse (t1->ensuresConstraints)));
1265 DPRINTF (("Assignment constraints t2: %s", constraintList_unparse (t2->ensuresConstraints)));
abd7f895 1266 exprNode_exprTraverse (t1, TRUE, definaterv, sequencePoint);
ae133592 1267 DPRINTF (("Assignment constraints t1: %s", constraintList_unparse (t1->ensuresConstraints)));
1268 DPRINTF (("Assignment constraints t2: %s", constraintList_unparse (t2->ensuresConstraints)));
abd7f895 1269 exprNode_exprTraverse (t2, definatelv, TRUE, sequencePoint);
ae133592 1270 DPRINTF (("Assignment constraints t1: %s", constraintList_unparse (t1->ensuresConstraints)));
1271 DPRINTF (("Assignment constraints t2: %s", constraintList_unparse (t2->ensuresConstraints)));
616915dd 1272
ae133592 1273 /* this test is nessecary because some expressions generate a null expression node.
1274 function pointer do that -- drl */
1275
1276 if ((!exprNode_isError (t1)) && (!exprNode_isError(t2)))
616915dd 1277 {
ae133592 1278 cons = constraint_makeEnsureEqual (t1, t2, sequencePoint);
1279 DPRINTF (("Ensure equal constraint: %s", constraint_unparse (cons)));
1280 e->ensuresConstraints = constraintList_add (e->ensuresConstraints, cons);
1281 DPRINTF (("Assignment constraints: %s", constraintList_unparse (e->ensuresConstraints)));
616915dd 1282 }
1283 break;
1284 case XPR_OP:
1285 t1 = exprData_getOpA (data);
1286 t2 = exprData_getOpB (data);
abd7f895 1287 tok = exprData_getOpTok (data);
920a3797 1288
80489f0a 1289 if (lltok_getTok (tok) == ADD_ASSIGN)
2934b455 1290 {
abd7f895 1291 exprNode_exprTraverse (t1, TRUE, definaterv, sequencePoint);
1292 exprNode_exprTraverse (t2, definatelv, TRUE, sequencePoint);
920a3797 1293
abd7f895 1294 cons = constraint_makeAddAssign (t1, t2, sequencePoint);
2934b455 1295 e->ensuresConstraints = constraintList_add(e->ensuresConstraints, cons);
1296 }
80489f0a 1297 else if (lltok_getTok (tok) == SUB_ASSIGN)
2934b455 1298 {
abd7f895 1299 exprNode_exprTraverse (t1, TRUE, definaterv, sequencePoint);
1300 exprNode_exprTraverse (t2, definatelv, TRUE, sequencePoint);
920a3797 1301
abd7f895 1302 cons = constraint_makeSubtractAssign (t1, t2, sequencePoint);
2934b455 1303 e->ensuresConstraints = constraintList_add(e->ensuresConstraints, cons);
1304 }
920a3797 1305 else
1306 {
abd7f895 1307 exprNode_exprTraverse (t1, definatelv, definaterv, sequencePoint);
1308 exprNode_exprTraverse (t2, definatelv, definaterv, sequencePoint);
920a3797 1309 }
2934b455 1310
abd7f895 1311 if (lltok_isBoolean_Op (tok))
616915dd 1312 exprNode_booleanTraverse (e, definatelv, definaterv, sequencePoint);
1313
616915dd 1314 break;
1315 case XPR_SIZEOFT:
b941db6b 1316 /*drl 4-11-03 I think this is the same as the next case...*/
616915dd 1317
1318 break;
1319
b4085262 1320 case XPR_SIZEOF:
1321 /* drl 7-16-01
1322 C standard says operand to sizeof isn't evaluated unless
1323 its a variable length array. So we don't generate constraints.
1324 */
1325
616915dd 1326 break;
1327
1328 case XPR_CALL:
9280addf 1329 fcn = exprData_getFcn(data);
1330
abd7f895 1331 exprNode_exprTraverse (fcn, definatelv, definaterv, sequencePoint);
ae133592 1332 DPRINTF (("Got call that %s (%s)",
1333 exprNode_unparse(fcn), exprNodeList_unparse (exprData_getArgs (data))));
616915dd 1334
965143f0 1335 llassert( exprNode_isDefined(fcn) );
ae133592 1336
1337 fcn->requiresConstraints =
1338 constraintList_addListFree (fcn->requiresConstraints,
6317f163 1339 checkCall (fcn, exprData_getArgs (data)));
ae133592 1340
1341 fcn->ensuresConstraints =
1342 constraintList_addListFree (fcn->ensuresConstraints,
1343 exprNode_getPostConditions(fcn, exprData_getArgs (data),e ));
1344
abd7f895 1345 t1 = exprNode_createNew (exprNode_getType (e));
9280addf 1346 checkArgumentList (t1, exprData_getArgs(data), sequencePoint);
28bf4b0b 1347 exprNode_mergeResolve (e, t1, fcn);
920a3797 1348 exprNode_free(t1);
616915dd 1349 break;
1350
1351 case XPR_RETURN:
abd7f895 1352 exprNode_exprTraverse (exprData_getSingle (data), definatelv, definaterv, sequencePoint);
616915dd 1353 break;
1354
1355 case XPR_NULLRETURN:
84c9ffbf 1356
616915dd 1357 break;
1358
1359
1360 case XPR_FACCESS:
abd7f895 1361 exprNode_exprTraverse (exprData_getFieldNode (data), definatelv, definaterv, sequencePoint);
616915dd 1362 break;
1363
1364 case XPR_ARROW:
abd7f895 1365 exprNode_exprTraverse (exprData_getFieldNode (data), definatelv, definaterv, sequencePoint);
616915dd 1366 break;
1367
1368 case XPR_STRINGLITERAL:
84c9ffbf 1369
616915dd 1370 break;
1371
1372 case XPR_NUMLIT:
84c9ffbf 1373
616915dd 1374 break;
1375
1376 case XPR_PREOP:
1377 t1 = exprData_getUopNode(data);
965143f0 1378
1379
1380 /* drl 3/2/2003 we know this because of the type of expression*/
1381 llassert( exprNode_isDefined(t1) );
1382
1383
616915dd 1384 tok = (exprData_getUopTok (data));
abd7f895 1385 exprNode_exprTraverse (t1, definatelv, definaterv, sequencePoint);
616915dd 1386 /*handle * pointer access */
16c024b5 1387 if (lltok_isIncOp (tok))
616915dd 1388 {
1389 DPRINTF(("doing ++(var)"));
1390 t1 = exprData_getUopNode (data);
abd7f895 1391 cons = constraint_makeMaxSetSideEffectPostIncrement (t1, sequencePoint);
616915dd 1392 e->ensuresConstraints = constraintList_add (e->ensuresConstraints, cons);
1393 }
16c024b5 1394 else if (lltok_isDecOp (tok))
616915dd 1395 {
1396 DPRINTF(("doing --(var)"));
1397 t1 = exprData_getUopNode (data);
abd7f895 1398 cons = constraint_makeMaxSetSideEffectPostDecrement (t1, sequencePoint);
616915dd 1399 e->ensuresConstraints = constraintList_add (e->ensuresConstraints, cons);
1400 }
abd7f895 1401 else if (lltok_isMult(tok ))
616915dd 1402 {
1403 if (definatelv)
1404 {
1405 cons = constraint_makeWriteSafeInt (t1, 0);
1406 }
1407 else
1408 {
1409 cons = constraint_makeReadSafeInt (t1, 0);
1410 }
1411 e->requiresConstraints = constraintList_add(e->requiresConstraints, cons);
1412 }
16c024b5 1413 else if (lltok_isNotOp (tok))
84c9ffbf 1414 /* ! expr */
616915dd 1415 {
bb25bea6 1416 constraintList_free(e->trueEnsuresConstraints);
1417
616915dd 1418 e->trueEnsuresConstraints = constraintList_copy (t1->falseEnsuresConstraints);
bb25bea6 1419 constraintList_free(e->falseEnsuresConstraints);
616915dd 1420 e->falseEnsuresConstraints = constraintList_copy (t1->trueEnsuresConstraints);
1421 }
bb25bea6 1422
abd7f895 1423 else if (lltok_isAmpersand_Op (tok))
84c9ffbf 1424 {
1425 break;
1426 }
abd7f895 1427 else if (lltok_isMinus_Op (tok))
bb25bea6 1428 {
1429 break;
1430 }
69db2541 1431 else if (lltok_isPlus_Op (tok))
1432 {
1433 break;
1434 }
abd7f895 1435 else if (lltok_isExcl_Op (tok))
4ab867d6 1436 {
1437 break;
1438 }
abd7f895 1439 else if (lltok_isTilde_Op (tok))
4ab867d6 1440 {
1441 break;
1442 }
84c9ffbf 1443 else
1444 {
abd7f895 1445 llcontbug (message("Unsupported preop in %s", exprNode_unparse(e)));
84c9ffbf 1446 BADEXIT;
1447 }
616915dd 1448 break;
1449
1450 case XPR_POSTOP:
abd7f895 1451 exprNode_exprTraverse (exprData_getUopNode (data), TRUE,
1452 definaterv, sequencePoint);
616915dd 1453
16c024b5 1454 if (lltok_isIncOp (exprData_getUopTok (data)))
616915dd 1455 {
1456 DPRINTF(("doing ++"));
1457 t1 = exprData_getUopNode (data);
abd7f895 1458 cons = constraint_makeMaxSetSideEffectPostIncrement (t1, sequencePoint);
616915dd 1459 e->ensuresConstraints = constraintList_add (e->ensuresConstraints, cons);
1460 }
16c024b5 1461 if (lltok_isDecOp (exprData_getUopTok (data)))
616915dd 1462 {
1463 DPRINTF(("doing --"));
1464 t1 = exprData_getUopNode (data);
abd7f895 1465 cons = constraint_makeMaxSetSideEffectPostDecrement (t1, sequencePoint);
616915dd 1466 e->ensuresConstraints = constraintList_add (e->ensuresConstraints, cons);
1467 }
1468 break;
470b7798 1469 case XPR_CAST:
920a3797 1470 {
1471 t2 = exprData_getCastNode (data);
abd7f895 1472 DPRINTF ((message ("Examining cast (%q)%s",
920a3797 1473 qtype_unparse (exprData_getCastType (data)),
abd7f895 1474 exprNode_unparse (t2))
1475 ));
1476 exprNode_exprTraverse (t2, definatelv, definaterv, sequencePoint);
920a3797 1477 }
470b7798 1478 break;
920a3797 1479
470b7798 1480 case XPR_COND:
1481 {
28bf4b0b 1482 exprNode pred, trueBranch, falseBranch;
abd7f895 1483 llassert(FALSE);
1484 pred = exprData_getTriplePred (data);
1485 trueBranch = exprData_getTripleTrue (data);
1486 falseBranch = exprData_getTripleFalse (data);
1487
1488 llassert (exprNode_isDefined (pred));
1489 llassert (exprNode_isDefined (trueBranch));
1490 llassert (exprNode_isDefined (falseBranch));
470b7798 1491
abd7f895 1492 exprNode_exprTraverse (pred, FALSE, TRUE, sequencePoint);
1493
1494 temp = pred->ensuresConstraints;
ae133592 1495 pred->ensuresConstraints = exprNode_traverseEnsuresConstraints(pred);
abd7f895 1496 constraintList_free(temp);
1497
1498 temp = pred->requiresConstraints;
ae133592 1499 pred->requiresConstraints = exprNode_traverseRequiresConstraints(pred);
abd7f895 1500 constraintList_free(temp);
1501
1502 temp = pred->trueEnsuresConstraints;
ae133592 1503 pred->trueEnsuresConstraints = exprNode_traverseTrueEnsuresConstraints(pred);
abd7f895 1504 constraintList_free(temp);
1505
1506 temp = pred->falseEnsuresConstraints;
ae133592 1507 pred->falseEnsuresConstraints = exprNode_traverseFalseEnsuresConstraints(pred);
abd7f895 1508 constraintList_free(temp);
1509
1510 exprNode_exprTraverse (trueBranch, FALSE, TRUE, sequencePoint);
1511
1512 temp = trueBranch->ensuresConstraints;
ae133592 1513 trueBranch->ensuresConstraints = exprNode_traverseEnsuresConstraints(trueBranch);
abd7f895 1514 constraintList_free(temp);
1515
1516 temp = trueBranch->requiresConstraints;
ae133592 1517 trueBranch->requiresConstraints = exprNode_traverseRequiresConstraints(trueBranch);
abd7f895 1518 constraintList_free(temp);
1519
ae133592 1520 temp = trueBranch->trueEnsuresConstraints;
1521 trueBranch->trueEnsuresConstraints = exprNode_traverseTrueEnsuresConstraints(trueBranch);
abd7f895 1522 constraintList_free(temp);
1523
ae133592 1524 temp = trueBranch->falseEnsuresConstraints;
1525 trueBranch->falseEnsuresConstraints = exprNode_traverseFalseEnsuresConstraints(trueBranch);
abd7f895 1526 constraintList_free(temp);
1527
1528 exprNode_exprTraverse (falseBranch, FALSE, TRUE, sequencePoint);
1529
1530 temp = falseBranch->ensuresConstraints;
ae133592 1531 falseBranch->ensuresConstraints = exprNode_traverseEnsuresConstraints(falseBranch);
abd7f895 1532 constraintList_free(temp);
1533
1534
1535 temp = falseBranch->requiresConstraints;
ae133592 1536 falseBranch->requiresConstraints = exprNode_traverseRequiresConstraints(falseBranch);
abd7f895 1537 constraintList_free(temp);
1538
1539 temp = falseBranch->trueEnsuresConstraints;
ae133592 1540 falseBranch->trueEnsuresConstraints = exprNode_traverseTrueEnsuresConstraints(falseBranch);
abd7f895 1541 constraintList_free(temp);
1542
1543 temp = falseBranch->falseEnsuresConstraints;
ae133592 1544 falseBranch->falseEnsuresConstraints = exprNode_traverseFalseEnsuresConstraints(falseBranch);
abd7f895 1545 constraintList_free(temp);
1546
1547 /* if pred is true e equals true otherwise pred equals false */
1548
1549 cons = constraint_makeEnsureEqual (e, trueBranch, sequencePoint);
1550 trueBranch->ensuresConstraints = constraintList_add(trueBranch->ensuresConstraints, cons);
1551
1552 cons = constraint_makeEnsureEqual (e, trueBranch, sequencePoint);
1553 falseBranch->ensuresConstraints = constraintList_add(falseBranch->ensuresConstraints, cons);
1554
1555 e = doIfElse (e, pred, trueBranch, falseBranch);
470b7798 1556 }
1557 break;
1558 case XPR_COMMA:
1559 llassert(FALSE);
1560 t1 = exprData_getPairA (data);
1561 t2 = exprData_getPairB (data);
ae133592 1562 /* we essiantially treat this like expr1; expr2
1563 of course sequencePoint isn't adjusted so this isn't completely accurate
1564 problems...
1565 */
abd7f895 1566 exprNode_exprTraverse (t1, FALSE, FALSE, sequencePoint);
1567 exprNode_exprTraverse (t2, definatelv, definaterv, sequencePoint);
28bf4b0b 1568 exprNode_mergeResolve (e, t1, t2);
470b7798 1569 break;
920a3797 1570
616915dd 1571 default:
ae133592 1572 break;
616915dd 1573 }
1574
ae133592 1575 e->requiresConstraints = constraintList_preserveOrig (e->requiresConstraints);
1576 e->ensuresConstraints = constraintList_preserveOrig (e->ensuresConstraints);
abd7f895 1577 e->requiresConstraints = constraintList_addGeneratingExpr (e->requiresConstraints, e);
ae133592 1578 e->ensuresConstraints = constraintList_addGeneratingExpr (e->ensuresConstraints, e);
1579 e->requiresConstraints = constraintList_removeSurpressed (e->requiresConstraints);
7edb30e6 1580
ae133592 1581 DPRINTF (("ensures constraints for %s are %s",
1582 exprNode_unparse(e), constraintList_unparseDetailed (e->ensuresConstraints)));
616915dd 1583
ae133592 1584 DPRINTF (("Requires constraints for %s are %s", exprNode_unparse(e),
1585 constraintList_unparseDetailed(e->ensuresConstraints)));
bb25bea6 1586
ae133592 1587 DPRINTF (("trueEnsures constraints for %s are %s", exprNode_unparse(e),
1588 constraintList_unparseDetailed(e->trueEnsuresConstraints)));
1589
1590 DPRINTF (("falseEnsures constraints for %s are %s", exprNode_unparse(e),
1591 constraintList_unparseDetailed(e->falseEnsuresConstraints)));
b7b694d6 1592 return;
616915dd 1593}
1594
1595
ae133592 1596constraintList exprNode_traverseTrueEnsuresConstraints (exprNode e)
616915dd 1597{
470b7798 1598 exprNode t1;
616915dd 1599
1600 bool handledExprNode;
616915dd 1601 exprData data;
1602 constraintList ret;
1603
2681ee39 1604 if (exprNode_handleError (e))
1605 {
1606 ret = constraintList_makeNew();
1607 return ret;
1608 }
abd7f895 1609
1610 ret = constraintList_copy (e->trueEnsuresConstraints);
616915dd 1611
2681ee39 1612 handledExprNode = TRUE;
616915dd 1613
1614 data = e->edata;
1615
1616 switch (e->kind)
1617 {
9280addf 1618 case XPR_WHILEPRED:
1619 t1 = exprData_getSingle (data);
ae133592 1620 ret = constraintList_addListFree (ret, exprNode_traverseTrueEnsuresConstraints (t1));
9280addf 1621 break;
616915dd 1622
1623 case XPR_FETCH:
1624
4ab867d6 1625 ret = constraintList_addListFree (ret,
ae133592 1626 exprNode_traverseTrueEnsuresConstraints
abd7f895 1627 (exprData_getPairA (data)));
616915dd 1628
4ab867d6 1629 ret = constraintList_addListFree (ret,
ae133592 1630 exprNode_traverseTrueEnsuresConstraints
abd7f895 1631 (exprData_getPairB (data)));
616915dd 1632 break;
1633 case XPR_PREOP:
1634
4ab867d6 1635 ret = constraintList_addListFree (ret,
ae133592 1636 exprNode_traverseTrueEnsuresConstraints
abd7f895 1637 (exprData_getUopNode (data)));
616915dd 1638 break;
1639
1640 case XPR_PARENS:
ae133592 1641 ret = constraintList_addListFree (ret, exprNode_traverseTrueEnsuresConstraints
abd7f895 1642 (exprData_getUopNode (data)));
616915dd 1643 break;
2681ee39 1644
1645 case XPR_INIT:
1646 ret = constraintList_addListFree (ret,
ae133592 1647 exprNode_traverseTrueEnsuresConstraints
abd7f895 1648 (exprData_getInitNode (data)));
2681ee39 1649 break;
1650
1651
616915dd 1652 case XPR_ASSIGN:
4ab867d6 1653 ret = constraintList_addListFree (ret,
ae133592 1654 exprNode_traverseTrueEnsuresConstraints
abd7f895 1655 (exprData_getOpA (data)));
616915dd 1656
4ab867d6 1657 ret = constraintList_addListFree (ret,
ae133592 1658 exprNode_traverseTrueEnsuresConstraints
abd7f895 1659 (exprData_getOpB (data)));
616915dd 1660 break;
1661 case XPR_OP:
4ab867d6 1662 ret = constraintList_addListFree (ret,
ae133592 1663 exprNode_traverseTrueEnsuresConstraints
abd7f895 1664 (exprData_getOpA (data)));
616915dd 1665
4ab867d6 1666 ret = constraintList_addListFree (ret,
ae133592 1667 exprNode_traverseTrueEnsuresConstraints
abd7f895 1668 (exprData_getOpB (data)));
616915dd 1669 break;
1670 case XPR_SIZEOFT:
616915dd 1671 break;
1672
1673 case XPR_SIZEOF:
1674
4ab867d6 1675 ret = constraintList_addListFree (ret,
ae133592 1676 exprNode_traverseTrueEnsuresConstraints
abd7f895 1677 (exprData_getSingle (data)));
616915dd 1678 break;
1679
1680 case XPR_CALL:
4ab867d6 1681 ret = constraintList_addListFree (ret,
ae133592 1682 exprNode_traverseTrueEnsuresConstraints
abd7f895 1683 (exprData_getFcn (data)));
b7b694d6 1684 break;
616915dd 1685
1686 case XPR_RETURN:
4ab867d6 1687 ret = constraintList_addListFree (ret,
ae133592 1688 exprNode_traverseTrueEnsuresConstraints
abd7f895 1689 (exprData_getSingle (data)));
616915dd 1690 break;
1691
1692 case XPR_NULLRETURN:
616915dd 1693 break;
1694
1695 case XPR_FACCESS:
b7b694d6 1696 ret = constraintList_addListFree (ret,
ae133592 1697 exprNode_traverseTrueEnsuresConstraints
abd7f895 1698 (exprData_getFieldNode (data)));
616915dd 1699 break;
1700
1701 case XPR_ARROW:
b7b694d6 1702 ret = constraintList_addListFree (ret,
ae133592 1703 exprNode_traverseTrueEnsuresConstraints
abd7f895 1704 (exprData_getFieldNode (data)));
616915dd 1705 break;
1706
1707 case XPR_STRINGLITERAL:
616915dd 1708 break;
1709
1710 case XPR_NUMLIT:
616915dd 1711 break;
1712 case XPR_POSTOP:
1713
4ab867d6 1714 ret = constraintList_addListFree (ret,
ae133592 1715 exprNode_traverseTrueEnsuresConstraints
abd7f895 1716 (exprData_getUopNode (data)));
616915dd 1717 break;
470b7798 1718
1719 case XPR_CAST:
1720
4ab867d6 1721 ret = constraintList_addListFree (ret,
ae133592 1722 exprNode_traverseTrueEnsuresConstraints
abd7f895 1723 (exprData_getCastNode (data)));
470b7798 1724 break;
84c9ffbf 1725
616915dd 1726 default:
1727 break;
1728 }
1729
1730 return ret;
1731}
1732
ae133592 1733constraintList exprNode_traverseFalseEnsuresConstraints (exprNode e)
9280addf 1734{
b7b694d6 1735 exprNode t1;
9280addf 1736 bool handledExprNode;
9280addf 1737 exprData data;
1738 constraintList ret;
abd7f895 1739
1740 if (exprNode_handleError (e))
1741 {
1742 ret = constraintList_makeNew();
1743 return ret;
1744 }
1745
1746 ret = constraintList_copy (e->falseEnsuresConstraints);
1747 handledExprNode = TRUE;
9280addf 1748 data = e->edata;
1749
1750 switch (e->kind)
1751 {
1752 case XPR_WHILEPRED:
1753 t1 = exprData_getSingle (data);
ae133592 1754 ret = constraintList_addListFree (ret,exprNode_traverseFalseEnsuresConstraints (t1));
9280addf 1755 break;
1756
1757 case XPR_FETCH:
1758
4ab867d6 1759 ret = constraintList_addListFree (ret,
ae133592 1760 exprNode_traverseFalseEnsuresConstraints
abd7f895 1761 (exprData_getPairA (data)));
9280addf 1762
4ab867d6 1763 ret = constraintList_addListFree (ret,
ae133592 1764 exprNode_traverseFalseEnsuresConstraints
abd7f895 1765 (exprData_getPairB (data)));
9280addf 1766 break;
1767 case XPR_PREOP:
1768
4ab867d6 1769 ret = constraintList_addListFree (ret,
ae133592 1770 exprNode_traverseFalseEnsuresConstraints
abd7f895 1771 (exprData_getUopNode (data)));
9280addf 1772 break;
1773
1774 case XPR_PARENS:
ae133592 1775 ret = constraintList_addListFree (ret, exprNode_traverseFalseEnsuresConstraints
abd7f895 1776 (exprData_getUopNode (data)));
9280addf 1777 break;
2681ee39 1778 case XPR_INIT:
1779 ret = constraintList_addListFree (ret,
ae133592 1780 exprNode_traverseFalseEnsuresConstraints
abd7f895 1781 ( exprData_getInitNode (data)));
2681ee39 1782 break;
1783
9280addf 1784 case XPR_ASSIGN:
4ab867d6 1785 ret = constraintList_addListFree (ret,
ae133592 1786 exprNode_traverseFalseEnsuresConstraints
abd7f895 1787 (exprData_getOpA (data)));
9280addf 1788
4ab867d6 1789 ret = constraintList_addListFree (ret,
ae133592 1790 exprNode_traverseFalseEnsuresConstraints
abd7f895 1791 (exprData_getOpB (data)));
9280addf 1792 break;
1793 case XPR_OP:
4ab867d6 1794 ret = constraintList_addListFree (ret,
ae133592 1795 exprNode_traverseFalseEnsuresConstraints
abd7f895 1796 (exprData_getOpA (data)));
9280addf 1797
4ab867d6 1798 ret = constraintList_addListFree (ret,
ae133592 1799 exprNode_traverseFalseEnsuresConstraints
abd7f895 1800 (exprData_getOpB (data)));
9280addf 1801 break;
1802 case XPR_SIZEOFT:
9280addf 1803 break;
1804
1805 case XPR_SIZEOF:
1806
4ab867d6 1807 ret = constraintList_addListFree (ret,
ae133592 1808 exprNode_traverseFalseEnsuresConstraints
abd7f895 1809 (exprData_getSingle (data)));
9280addf 1810 break;
1811
1812 case XPR_CALL:
4ab867d6 1813 ret = constraintList_addListFree (ret,
ae133592 1814 exprNode_traverseFalseEnsuresConstraints
abd7f895 1815 (exprData_getFcn (data)));
b7b694d6 1816 break;
9280addf 1817
1818 case XPR_RETURN:
4ab867d6 1819 ret = constraintList_addListFree (ret,
ae133592 1820 exprNode_traverseFalseEnsuresConstraints
abd7f895 1821 (exprData_getSingle (data)));
9280addf 1822 break;
1823
1824 case XPR_NULLRETURN:
9280addf 1825 break;
1826
1827 case XPR_FACCESS:
b7b694d6 1828 ret = constraintList_addListFree (ret,
ae133592 1829 exprNode_traverseFalseEnsuresConstraints
abd7f895 1830 (exprData_getFieldNode (data)));
9280addf 1831 break;
b7b694d6 1832
9280addf 1833 case XPR_ARROW:
b7b694d6 1834 ret = constraintList_addListFree (ret,
ae133592 1835 exprNode_traverseFalseEnsuresConstraints
abd7f895 1836 (exprData_getFieldNode (data)));
9280addf 1837 break;
1838
1839 case XPR_STRINGLITERAL:
9280addf 1840 break;
1841
1842 case XPR_NUMLIT:
9280addf 1843 break;
1844 case XPR_POSTOP:
1845
4ab867d6 1846 ret = constraintList_addListFree (ret,
ae133592 1847 exprNode_traverseFalseEnsuresConstraints
abd7f895 1848 (exprData_getUopNode (data)));
9280addf 1849 break;
470b7798 1850
1851 case XPR_CAST:
1852
4ab867d6 1853 ret = constraintList_addListFree (ret,
ae133592 1854 exprNode_traverseFalseEnsuresConstraints
abd7f895 1855 (exprData_getCastNode (data)));
470b7798 1856 break;
1857
9280addf 1858 default:
1859 break;
1860 }
1861
1862 return ret;
1863}
1864
616915dd 1865
1866/* walk down the tree and get all requires Constraints in each subexpression*/
ae133592 1867/*@only@*/ constraintList exprNode_traverseRequiresConstraints (exprNode e)
616915dd 1868{
470b7798 1869 exprNode t1;
616915dd 1870
1871 bool handledExprNode;
616915dd 1872 exprData data;
1873 constraintList ret;
1874
1875 if (exprNode_handleError (e))
1876 {
c3e695ff 1877 ret = constraintList_makeNew();
616915dd 1878 return ret;
1879 }
abd7f895 1880
1881 ret = constraintList_copy (e->requiresConstraints);
1882 handledExprNode = TRUE;
616915dd 1883 data = e->edata;
1884
1885 switch (e->kind)
1886 {
9280addf 1887 case XPR_WHILEPRED:
1888 t1 = exprData_getSingle (data);
ae133592 1889 ret = constraintList_addListFree (ret, exprNode_traverseRequiresConstraints (t1));
9280addf 1890 break;
616915dd 1891
1892 case XPR_FETCH:
1893
4ab867d6 1894 ret = constraintList_addListFree (ret,
ae133592 1895 exprNode_traverseRequiresConstraints
abd7f895 1896 (exprData_getPairA (data)));
616915dd 1897
4ab867d6 1898 ret = constraintList_addListFree (ret,
ae133592 1899 exprNode_traverseRequiresConstraints
abd7f895 1900 (exprData_getPairB (data)));
616915dd 1901 break;
1902 case XPR_PREOP:
1903
4ab867d6 1904 ret = constraintList_addListFree (ret,
ae133592 1905 exprNode_traverseRequiresConstraints
abd7f895 1906 (exprData_getUopNode (data)));
616915dd 1907 break;
1908
1909 case XPR_PARENS:
ae133592 1910 ret = constraintList_addListFree (ret, exprNode_traverseRequiresConstraints
abd7f895 1911 (exprData_getUopNode (data)));
616915dd 1912 break;
2681ee39 1913 case XPR_INIT:
1914 ret = constraintList_addListFree (ret,
ae133592 1915 exprNode_traverseRequiresConstraints
abd7f895 1916 (exprData_getInitNode (data)));
2681ee39 1917 break;
1918
616915dd 1919 case XPR_ASSIGN:
4ab867d6 1920 ret = constraintList_addListFree (ret,
ae133592 1921 exprNode_traverseRequiresConstraints
abd7f895 1922 (exprData_getOpA (data)));
616915dd 1923
4ab867d6 1924 ret = constraintList_addListFree (ret,
ae133592 1925 exprNode_traverseRequiresConstraints
abd7f895 1926 (exprData_getOpB (data)));
616915dd 1927 break;
1928 case XPR_OP:
4ab867d6 1929 ret = constraintList_addListFree (ret,
ae133592 1930 exprNode_traverseRequiresConstraints
abd7f895 1931 (exprData_getOpA (data)));
616915dd 1932
4ab867d6 1933 ret = constraintList_addListFree (ret,
ae133592 1934 exprNode_traverseRequiresConstraints
abd7f895 1935 (exprData_getOpB (data)));
616915dd 1936 break;
1937 case XPR_SIZEOFT:
616915dd 1938 break;
1939
1940 case XPR_SIZEOF:
1941
4ab867d6 1942 ret = constraintList_addListFree (ret,
ae133592 1943 exprNode_traverseRequiresConstraints
abd7f895 1944 (exprData_getSingle (data)));
616915dd 1945 break;
1946
1947 case XPR_CALL:
4ab867d6 1948 ret = constraintList_addListFree (ret,
ae133592 1949 exprNode_traverseRequiresConstraints
abd7f895 1950 (exprData_getFcn (data)));
b7b694d6 1951 break;
616915dd 1952
1953 case XPR_RETURN:
4ab867d6 1954 ret = constraintList_addListFree (ret,
ae133592 1955 exprNode_traverseRequiresConstraints
abd7f895 1956 (exprData_getSingle (data)));
616915dd 1957 break;
1958
1959 case XPR_NULLRETURN:
616915dd 1960 break;
1961
1962 case XPR_FACCESS:
b7b694d6 1963 ret = constraintList_addListFree (ret,
ae133592 1964 exprNode_traverseRequiresConstraints
abd7f895 1965 (exprData_getFieldNode (data)));
616915dd 1966 break;
b7b694d6 1967
616915dd 1968 case XPR_ARROW:
b7b694d6 1969 ret = constraintList_addListFree (ret,
ae133592 1970 exprNode_traverseRequiresConstraints
abd7f895 1971 (exprData_getFieldNode (data)));
616915dd 1972 break;
1973
1974 case XPR_STRINGLITERAL:
616915dd 1975 break;
1976
1977 case XPR_NUMLIT:
616915dd 1978 break;
1979 case XPR_POSTOP:
1980
4ab867d6 1981 ret = constraintList_addListFree (ret,
ae133592 1982 exprNode_traverseRequiresConstraints
abd7f895 1983 (exprData_getUopNode (data)));
616915dd 1984 break;
470b7798 1985
1986 case XPR_CAST:
1987
4ab867d6 1988 ret = constraintList_addListFree (ret,
ae133592 1989 exprNode_traverseRequiresConstraints
abd7f895 1990 (exprData_getCastNode (data)));
470b7798 1991 break;
1992
616915dd 1993 default:
1994 break;
1995 }
1996
1997 return ret;
1998}
1999
2000
2001/* walk down the tree and get all Ensures Constraints in each subexpression*/
ae133592 2002/*@only@*/ constraintList exprNode_traverseEnsuresConstraints (exprNode e)
616915dd 2003{
470b7798 2004 exprNode t1;
616915dd 2005
2006 bool handledExprNode;
616915dd 2007 exprData data;
616915dd 2008 constraintList ret;
2009
abd7f895 2010 if (exprNode_handleError (e))
2011 {
2012 ret = constraintList_makeNew();
2013 return ret;
2014 }
2015
2016 ret = constraintList_copy (e->ensuresConstraints);
2017 handledExprNode = TRUE;
2018
616915dd 2019 data = e->edata;
abd7f895 2020
2021 DPRINTF ((message ("exprnode_traversEnsuresConstraints call for %s with "
2022 "constraintList of %s",
616915dd 2023 exprNode_unparse (e),
9a48d98c 2024 constraintList_unparse(e->ensuresConstraints)
616915dd 2025 )
2026 ));
2027
2028
2029 switch (e->kind)
2030 {
abd7f895 2031 case XPR_WHILEPRED:
9280addf 2032 t1 = exprData_getSingle (data);
ae133592 2033 ret = constraintList_addListFree (ret,exprNode_traverseEnsuresConstraints (t1));
9280addf 2034 break;
616915dd 2035
2036 case XPR_FETCH:
4ab867d6 2037 ret = constraintList_addListFree (ret,
ae133592 2038 exprNode_traverseEnsuresConstraints
abd7f895 2039 (exprData_getPairA (data)));
2040
4ab867d6 2041 ret = constraintList_addListFree (ret,
ae133592 2042 exprNode_traverseEnsuresConstraints
abd7f895 2043 (exprData_getPairB (data)));
616915dd 2044 break;
2045 case XPR_PREOP:
4ab867d6 2046 ret = constraintList_addListFree (ret,
ae133592 2047 exprNode_traverseEnsuresConstraints
abd7f895 2048 (exprData_getUopNode (data)));
616915dd 2049 break;
2050
2051 case XPR_PARENS:
ae133592 2052 ret = constraintList_addListFree (ret, exprNode_traverseEnsuresConstraints
abd7f895 2053 (exprData_getUopNode (data)));
616915dd 2054 break;
2681ee39 2055
2056 case XPR_INIT:
2057 ret = constraintList_addListFree (ret,
ae133592 2058 exprNode_traverseEnsuresConstraints
abd7f895 2059 (exprData_getInitNode (data)));
2060 break;
2061
2062
616915dd 2063 case XPR_ASSIGN:
abd7f895 2064 ret = constraintList_addListFree (ret,
ae133592 2065 exprNode_traverseEnsuresConstraints
abd7f895 2066 (exprData_getOpA (data)));
2067
2068 ret = constraintList_addListFree (ret,
ae133592 2069 exprNode_traverseEnsuresConstraints
abd7f895 2070 (exprData_getOpB (data)));
2071 break;
616915dd 2072 case XPR_OP:
abd7f895 2073 ret = constraintList_addListFree (ret,
ae133592 2074 exprNode_traverseEnsuresConstraints
abd7f895 2075 (exprData_getOpA (data)));
2076
2077 ret = constraintList_addListFree (ret,
ae133592 2078 exprNode_traverseEnsuresConstraints
abd7f895 2079 (exprData_getOpB (data)));
2080 break;
616915dd 2081 case XPR_SIZEOFT:
616915dd 2082 break;
2083
2084 case XPR_SIZEOF:
abd7f895 2085 ret = constraintList_addListFree (ret,
ae133592 2086 exprNode_traverseEnsuresConstraints
abd7f895 2087 (exprData_getSingle (data)));
2088 break;
616915dd 2089 case XPR_CALL:
4ab867d6 2090 ret = constraintList_addListFree (ret,
ae133592 2091 exprNode_traverseEnsuresConstraints
abd7f895 2092 (exprData_getFcn (data)));
b7b694d6 2093 break;
616915dd 2094 case XPR_RETURN:
4ab867d6 2095 ret = constraintList_addListFree (ret,
ae133592 2096 exprNode_traverseEnsuresConstraints
abd7f895 2097 (exprData_getSingle (data)));
616915dd 2098 break;
616915dd 2099 case XPR_NULLRETURN:
616915dd 2100 break;
616915dd 2101 case XPR_FACCESS:
b7b694d6 2102 ret = constraintList_addListFree (ret,
ae133592 2103 exprNode_traverseEnsuresConstraints
abd7f895 2104 (exprData_getFieldNode (data)));
616915dd 2105 break;
616915dd 2106 case XPR_ARROW:
b7b694d6 2107 ret = constraintList_addListFree (ret,
ae133592 2108 exprNode_traverseEnsuresConstraints
abd7f895 2109 (exprData_getFieldNode (data)));
616915dd 2110 break;
616915dd 2111 case XPR_STRINGLITERAL:
616915dd 2112 break;
616915dd 2113 case XPR_NUMLIT:
616915dd 2114 break;
2115 case XPR_POSTOP:
abd7f895 2116 ret = constraintList_addListFree (ret,
ae133592 2117 exprNode_traverseEnsuresConstraints
abd7f895 2118 (exprData_getUopNode (data)));
2119 break;
470b7798 2120 case XPR_CAST:
4ab867d6 2121 ret = constraintList_addListFree (ret,
ae133592 2122 exprNode_traverseEnsuresConstraints
abd7f895 2123 (exprData_getCastNode (data)));
470b7798 2124 break;
616915dd 2125 default:
2126 break;
2127 }
abd7f895 2128
2129 DPRINTF((message ("exprnode_traversEnsuresConstraints call for %s with "
2130 "constraintList of is returning %s",
2131 exprNode_unparse (e),
9a48d98c 2132 constraintList_unparse(ret))));
616915dd 2133
616915dd 2134 return ret;
2135}
2136
28bf4b0b 2137/*drl moved out of constraintResolve.c 07-02-001 */
abd7f895 2138void checkArgumentList (/*@out@*/ exprNode temp, exprNodeList arglist,
2139 fileloc sequencePoint)
28bf4b0b 2140{
965143f0 2141
2142 llassert(temp != NULL );
2143
28bf4b0b 2144 temp->requiresConstraints = constraintList_makeNew();
2145 temp->ensuresConstraints = constraintList_makeNew();
2146 temp->trueEnsuresConstraints = constraintList_makeNew();
2147 temp->falseEnsuresConstraints = constraintList_makeNew();
2148
2149 exprNodeList_elements (arglist, el)
2150 {
2151 constraintList temp2;
965143f0 2152
2153 llassert(exprNode_isDefined(el) );
2154
28bf4b0b 2155 exprNode_exprTraverse (el, FALSE, FALSE, sequencePoint);
2156 temp2 = el->requiresConstraints;
ae133592 2157 el->requiresConstraints = exprNode_traverseRequiresConstraints(el);
28bf4b0b 2158 constraintList_free(temp2);
2159
2160 temp2 = el->ensuresConstraints;
ae133592 2161 el->ensuresConstraints = exprNode_traverseEnsuresConstraints(el);
28bf4b0b 2162 constraintList_free(temp2);
2163
2164 temp->requiresConstraints = constraintList_addList(temp->requiresConstraints,
2165 el->requiresConstraints);
2166
2167 temp->ensuresConstraints = constraintList_addList(temp->ensuresConstraints,
2168 el->ensuresConstraints);
2169 }
2170 end_exprNodeList_elements;
2171
2172}
2173
2174/*drl moved out of constraintResolve.c 07-03-001 */
2175constraintList exprNode_getPostConditions (exprNode fcn, exprNodeList arglist, exprNode fcnCall)
2176{
2177 constraintList postconditions;
2178 uentry temp;
abd7f895 2179 DPRINTF((message ("Got call that %s (%s) ", exprNode_unparse(fcn), exprNodeList_unparse (arglist))));
28bf4b0b 2180
2181 temp = exprNode_getUentry (fcn);
2182
2183 postconditions = uentry_getFcnPostconditions (temp);
2184
ccf0a4a8 2185 if (constraintList_isDefined (postconditions))
28bf4b0b 2186 {
2187 postconditions = constraintList_doSRefFixConstraintParam (postconditions, arglist);
2188 postconditions = constraintList_doFixResult (postconditions, fcnCall);
2189 }
2190 else
2191 {
2192 postconditions = constraintList_makeNew();
2193 }
2194
2195 return postconditions;
2196}
2197
86d93ed3 2198/*
2199comment this out for now
2200we'll include it in a production release when its stable...
2201
abd7f895 2202 void findStructs (exprNodeList arglist)
86d93ed3 2203{
2204
2205 ctype ct, rt;
2206
24633cea 2207 DPRINTF((
abd7f895 2208 message("doing findStructs: %s", exprNodeList_unparse(arglist))
2209 ));
86d93ed3 2210
2211
2212 exprNodeList_elements(arglist, expr)
2213 {
2214 ct = exprNode_getType(expr);
2215
2216 rt = ctype_realType (ct);
2217
abd7f895 2218 if (ctype_isStruct (rt))
8f58355a 2219 DPRINTF((message("Found structure %s", exprNode_unparse(expr))
abd7f895 2220 ));
2221 if (hasInvariants(ct))
86d93ed3 2222 {
2223 constraintList invars;
2224
2225 invars = getInvariants(ct);
2226
2227
8f58355a 2228 DPRINTF((message ("findStructs has invariants %s ", constraintList_unparse (invars))
abd7f895 2229 ));
86d93ed3 2230
abd7f895 2231 invars = constraintList_doSRefFixStructConstraint(invars, exprNode_getSref(expr), ct);
86d93ed3 2232
2233
8f58355a 2234 DPRINTF((message ("findStructs finded invariants to be %s ", constraintList_unparse (invars))
abd7f895 2235 ));
86d93ed3 2236 }
2237 }
2238 end_exprNodeList_elements;
2239}
2240
2241*/
28bf4b0b 2242
2243/*drl moved out of constraintResolve.c 07-02-001 */
2244constraintList checkCall (/*@dependent@*/ exprNode fcn, exprNodeList arglist)
2245{
2246 constraintList preconditions;
2247 uentry temp;
abd7f895 2248 DPRINTF((message ("Got call that %s (%s) ", exprNode_unparse(fcn), exprNodeList_unparse (arglist))));
28bf4b0b 2249
2250 temp = exprNode_getUentry (fcn);
2251
2252 preconditions = uentry_getFcnPreconditions (temp);
2253
abd7f895 2254 if (constraintList_isDefined(preconditions))
28bf4b0b 2255 {
2256 preconditions = constraintList_togglePost (preconditions);
2257 preconditions = constraintList_preserveCallInfo(preconditions, fcn);
2258 preconditions = constraintList_doSRefFixConstraintParam (preconditions, arglist);
2259 }
2260 else
2261 {
abd7f895 2262 if (constraintList_isUndefined(preconditions))
28bf4b0b 2263 preconditions = constraintList_makeNew();
2264 }
312c9815 2265
6317f163 2266 if (context_getFlag (FLG_IMPBOUNDSCONSTRAINTS))
312c9815 2267 {
4287634e 2268
2269 /*
2270 uentryList_elements (arglist, el)
312c9815 2271 {
4287634e 2272 sRef s;
8f58355a 2273 DPRINTF((message("setImplicitfcnConstraints doing: %s", uentry_unparse(el) ) ));
312c9815 2274
2275 s = uentry_getSref(el);
2276 if (sRef_isReference (s) )
2277 {
8f58355a 2278 DPRINTF((message ("%s is a pointer", sRef_unparse(s) ) ));
312c9815 2279 }
2280 else
2281 {
8f58355a 2282 DPRINTF((message ("%s is NOT a pointer", sRef_unparse(s) ) ));
312c9815 2283 }
2284 //drl 4/26/01
2285 //chagned this from MaxSet(s) == 0 to MaxSet(s) >= 0
2286 c = constraint_makeSRefWriteSafeInt (s, 0);
2287
2288 implicitFcnConstraints = constraintList_add(implicitFcnConstraints , c);
2289
2290 //drl 10/23/2002 added support for out
2291 if (!uentry_isOut(el) )
2292 {
2293 c = constraint_makeSRefReadSafeInt (s, 0);
312c9815 2294 implicitFcnConstraints = constraintList_add(implicitFcnConstraints , c);
2295 }
4287634e 2296
312c9815 2297
2298 }
4287634e 2299 */
312c9815 2300 }
4287634e 2301
abd7f895 2302 DPRINTF ((message("Done checkCall\n")));
9a48d98c 2303 DPRINTF ((message("Returning list %q ", constraintList_unparseDetailed(preconditions))));
86d93ed3 2304
2305 /*
2306 drl we're going to comment this out for now
2307 we'll include it if we're sure it's working
2308
2309 findStructs(arglist);
2310 */
2311
28bf4b0b 2312 return preconditions;
2313}
e5f31c00 2314
2315/*drl added this function 10.29.001
2316 takes an exprNode of the form const + const
2317 and sets the value
2318*/
2319/*drl
2320 I'm a bit nervous about modifying the exprNode
2321 but this is the easy way to do this
2322 If I have time I'd like to cause the exprNode to get created correctly in the first place */
abd7f895 2323void exprNode_findValue(exprNode e)
e5f31c00 2324{
2325 exprData data;
2326
2327 exprNode t1, t2;
2328 lltok tok;
2329
965143f0 2330 llassert(exprNode_isDefined(e) );
2331
e5f31c00 2332 data = e->edata;
2333
abd7f895 2334 if (exprNode_hasValue(e))
e5f31c00 2335 return;
2336
2337 if (e->kind == XPR_OP)
2338 {
2339 t1 = exprData_getOpA (data);
2340 t2 = exprData_getOpB (data);
2341 tok = exprData_getOpTok (data);
2342
2343 exprNode_findValue(t1);
2344 exprNode_findValue(t2);
2345
abd7f895 2346 if (!(exprNode_knownIntValue(t1) && (exprNode_knownIntValue(t2))))
e5f31c00 2347 return;
2348
abd7f895 2349 if (lltok_isPlus_Op (tok))
e5f31c00 2350 {
2351 long v1, v2;
2352
2353 v1 = exprNode_getLongValue(t1);
2354 v2 = exprNode_getLongValue(t2);
2355
abd7f895 2356 if (multiVal_isDefined(e->val))
e5f31c00 2357 multiVal_free (e->val);
2358
2359 e->val = multiVal_makeInt (v1 + v2);
2360 }
2361
abd7f895 2362 if (lltok_isMinus_Op (tok))
e5f31c00 2363 {
2364 long v1, v2;
2365
2366 v1 = exprNode_getLongValue(t1);
2367 v2 = exprNode_getLongValue(t2);
2368
abd7f895 2369 if (multiVal_isDefined(e->val))
2370 {
2371 multiVal_free (e->val);
2372 }
e5f31c00 2373
2374 e->val = multiVal_makeInt (v1 - v2);
2375 }
2376
2377 /*drl I should really do * and / at some point */
2378
2379 }
2380
2381}
2382
This page took 0.500538 seconds and 5 git commands to generate.