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