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