]> andersk Git - splint.git/blame - src/constraintGeneration.c
Added check of user specified post conditions.
[splint.git] / src / constraintGeneration.c
CommitLineData
616915dd 1
2/*
3** constraintGeneration.c
4*/
5
6//#define DEBUGPRINT 1
7
8# include <ctype.h> /* for isdigit */
9# include "lclintMacros.nf"
10# include "basic.h"
11# include "cgrammar.h"
12# include "cgrammar_tokens.h"
13
14# include "exprChecks.h"
15# include "aliasChecks.h"
16# include "exprNodeSList.h"
17
18# include "exprData.i"
19# include "exprDataQuite.i"
20
84c9ffbf 21/*@access exprNode @*/
22
470b7798 23extern void forLoopHeuristics( exprNode e, exprNode forPred, exprNode forBody);
24
616915dd 25bool /*@alt void@*/ exprNode_generateConstraints (/*@temp@*/ exprNode e);
26static bool exprNode_handleError( exprNode p_e);
27
28//static cstring exprNode_findConstraints ( exprNode p_e);
29static bool exprNode_isMultiStatement(exprNode p_e);
84c9ffbf 30static void exprNode_multiStatement (exprNode p_e);
31
616915dd 32//static void exprNode_constraintPropagateUp (exprNode p_e);
616915dd 33
bb25bea6 34static constraintList exprNode_traversTrueEnsuresConstraints (exprNode e);
35static constraintList exprNode_traversFalseEnsuresConstraints (exprNode e);
616915dd 36
4ab867d6 37exprNode makeDataTypeConstraints (/*@returned@*/ exprNode e);
38
616915dd 39constraintList constraintList_makeFixedArrayConstraints (sRefSet s);
616915dd 40
9280addf 41
616915dd 42//bool exprNode_testd()
43//{
44 /* if ( ( (exprNode_isError ) ) )
45 {
46 }
47 if ( ( (e_1 ) ) )
48 {
49 }
50 */
51//}
52
bb25bea6 53static bool exprNode_isUnhandled (exprNode e)
616915dd 54{
55 llassert( exprNode_isDefined(e) );
56 switch (e->kind)
57 {
58 case XPR_INITBLOCK:
59 case XPR_EMPTY:
60 case XPR_LABEL:
61 case XPR_CONST:
62 case XPR_VAR:
63 case XPR_BODY:
64 case XPR_OFFSETOF:
65 case XPR_ALIGNOFT:
66 case XPR_ALIGNOF:
67 case XPR_VAARG:
68 case XPR_ITERCALL:
69 case XPR_ITER:
70 case XPR_CAST:
71 case XPR_GOTO:
72 case XPR_CONTINUE:
73 case XPR_BREAK:
74 case XPR_COMMA:
75 case XPR_COND:
76 case XPR_TOK:
77 case XPR_FTDEFAULT:
78 case XPR_DEFAULT:
79 case XPR_SWITCH:
80 case XPR_FTCASE:
81 case XPR_CASE:
82 // case XPR_INIT:
83 case XPR_NODE:
84 DPRINTF((message ("Warning current constraint generation does not handle expression %s", exprNode_unparse(e)) ) );
85 return TRUE;
86 /*@notreached@*/
87 break;
88 default:
89 return FALSE;
90
91 }
92 /*not reached*/
93 return FALSE;
94}
95
96bool exprNode_handleError( exprNode e)
97{
98 if (exprNode_isError (e) || exprNode_isUnhandled(e) )
99 {
100 static /*@only@*/ cstring error = cstring_undefined;
101
102 if (!cstring_isDefined (error))
103 {
104 error = cstring_makeLiteral ("<error>");
105 }
106
107 /*@-unqualifiedtrans*/ return TRUE; /*@=unqualifiedtrans*/
108 }
109 return FALSE;
110}
111
112bool /*@alt void@*/ exprNode_generateConstraints (/*@temp@*/ exprNode e)
113{
114 if (exprNode_isError (e) )
115 return FALSE;
bb25bea6 116 /*
c3e695ff 117 e->requiresConstraints = constraintList_makeNew();
118 e->ensuresConstraints = constraintList_makeNew();
119 e->trueEnsuresConstraints = constraintList_makeNew();
120 e->falseEnsuresConstraints = constraintList_makeNew();
bb25bea6 121 */
9280addf 122
616915dd 123 if (exprNode_isUnhandled (e) )
124 {
125 DPRINTF( (message("Warning ignoring %s", exprNode_unparse (e) ) ) );
9280addf 126 return FALSE;
616915dd 127 }
128
129
130 // e = makeDataTypeConstraints (e);
131
132 DPRINTF((message ("exprNode_generateConstraints Analysising %s at %s", exprNode_unparse( e),
133 fileloc_unparse(exprNode_getfileloc(e) ) ) ) );
134
135 if (exprNode_isMultiStatement ( e) )
136 {
137 exprNode_multiStatement(e);
138 }
139 else
140 {
9280addf 141 fileloc loc;
142
143 loc = exprNode_getNextSequencePoint(e);
144 exprNode_exprTraverse(e, FALSE, FALSE, loc);
145
bb25bea6 146 fileloc_free(loc);
616915dd 147 return FALSE;
148 }
149
150 {
151 constraintList c;
152
153 c = constraintList_makeFixedArrayConstraints (e->uses);
bb25bea6 154 e->requiresConstraints = reflectChangesFreePre (e->requiresConstraints, c);
616915dd 155
156 // e->ensuresConstraints = constraintList_mergeEnsures(c, e->ensuresConstraints);
157
bb25bea6 158 constraintList_free(c);
616915dd 159 }
160
bb25bea6 161 DPRINTF ( (message ("e->requiresConstraints %s", constraintList_printDetailed (e->requiresConstraints) ) ) );
616915dd 162 return FALSE;
163}
164
165
166/* handles multiple statements */
167
168bool exprNode_isMultiStatement(exprNode e)
169{
170if (exprNode_handleError (e) != NULL)
171 return FALSE;
172
173 switch (e->kind)
174 {
175 case XPR_FOR:
176 case XPR_FORPRED:
177 case XPR_IF:
178 case XPR_IFELSE:
179 case XPR_WHILE:
180 case XPR_WHILEPRED:
181 case XPR_DOWHILE:
182 case XPR_BLOCK:
183 case XPR_STMT:
184 case XPR_STMTLIST:
185 return TRUE;
186 default:
187 return FALSE;
188 }
189
190}
191
bb25bea6 192static void exprNode_stmt (exprNode e)
616915dd 193{
194 exprNode snode;
195 fileloc loc;
d46ce6a4 196 cstring s;
9280addf 197
616915dd 198 if (exprNode_isError(e) )
199 {
84c9ffbf 200 return; // FALSE;
616915dd 201 }
bb25bea6 202 /*e->requiresConstraints = constraintList_makeNew();
203 e->ensuresConstraints = constraintList_makeNew(); */
616915dd 204 // e = makeDataTypeConstraints(e);
205
206
207 DPRINTF(( "STMT:") );
9280addf 208 s = exprNode_unparse(e);
209 // DPRINTF ( ( message("STMT: %s ") ) );
210
616915dd 211 if (e->kind == XPR_INIT)
212 {
bb25bea6 213 constraintList tempList;
616915dd 214 DPRINTF (("Init") );
215 DPRINTF ( (message ("%s ", exprNode_unparse (e)) ) );
216 loc = exprNode_getNextSequencePoint(e); /* reduces to an expression */
84c9ffbf 217 exprNode_exprTraverse (e, FALSE, FALSE, loc);
bb25bea6 218 fileloc_free(loc);
219
220 tempList = e->requiresConstraints;
616915dd 221 e->requiresConstraints = exprNode_traversRequiresConstraints(e);
bb25bea6 222 constraintList_free(tempList);
223
224 tempList = e->ensuresConstraints;
616915dd 225 e->ensuresConstraints = exprNode_traversEnsuresConstraints(e);
bb25bea6 226 constraintList_free(tempList);
84c9ffbf 227 return; // notError;
616915dd 228 }
229
230 if (e->kind != XPR_STMT)
231 {
232
233 DPRINTF (("Not Stmt") );
234 DPRINTF ( (message ("%s ", exprNode_unparse (e)) ) );
235 if (exprNode_isMultiStatement (e) )
236 {
237 return exprNode_multiStatement (e );
238 }
84c9ffbf 239 DPRINTF( (message ("Ignoring non-statement %s", exprNode_unparse(e) ) ) );
240 return; //TRUE;
616915dd 241 // llassert(FALSE);
242 }
243
244 DPRINTF (("Stmt") );
245 DPRINTF ( (message ("%s ", exprNode_unparse (e)) ) );
246
247 snode = exprData_getUopNode (e->edata);
248
249 /* could be stmt involving multiple statements:
250 i.e. if, while for ect.
251 */
252
253 if (exprNode_isMultiStatement (snode))
254 {
84c9ffbf 255 exprNode_multiStatement (snode);
256 (void) exprNode_copyConstraints (e, snode);
257 return;
616915dd 258 }
259
260 loc = exprNode_getNextSequencePoint(e); /* reduces to an expression */
84c9ffbf 261 //notError =
262 exprNode_exprTraverse (snode, FALSE, FALSE, loc);
bb25bea6 263
264 fileloc_free(loc);
265
266 constraintList_free (e->requiresConstraints);
616915dd 267 e->requiresConstraints = exprNode_traversRequiresConstraints(snode);
268 // printf ("For: %s \n", exprNode_unparse (e) );
269 // printf ("%s\n", constraintList_print(e->requiresConstraints) );
bb25bea6 270
271 constraintList_free (e->ensuresConstraints);
616915dd 272 e->ensuresConstraints = exprNode_traversEnsuresConstraints(snode);
273 // printf ("Ensures that:\n %s\n", constraintList_print(e->ensuresConstraints) );
274 // llassert(notError);
bb25bea6 275
276 DPRINTF ( (message ("smtlist constraints are: pre: %s \n and \t post %s\n",
277 constraintList_print(e->requiresConstraints),
278 constraintList_print(e->ensuresConstraints) ) ) );
279
84c9ffbf 280 return; // notError;
616915dd 281
282}
283
284
bb25bea6 285static void exprNode_stmtList (exprNode e)
616915dd 286{
287 exprNode stmt1, stmt2;
288 if (exprNode_isError (e) )
289 {
84c9ffbf 290 return; // FALSE;
616915dd 291 }
292
bb25bea6 293 /*
294 e->requiresConstraints = constraintList_makeNew();
295 e->ensuresConstraints = constraintList_makeNew();
296 */
616915dd 297 // e = makeDataTypeConstraints(e);
298
299 /*Handle case of stmtList with only one statement:
300 The parse tree stores this as stmt instead of stmtList*/
301 if (e->kind != XPR_STMTLIST)
302 {
84c9ffbf 303 exprNode_stmt(e);
304 return;
616915dd 305 }
306 llassert (e->kind == XPR_STMTLIST);
307 DPRINTF(( "STMTLIST:") );
308 DPRINTF ((cstring_toCharsSafe (exprNode_unparse(e)) ) );
309 stmt1 = exprData_getPairA (e->edata);
310 stmt2 = exprData_getPairB (e->edata);
311
312
313 DPRINTF((" stmtlist ") );
314 DPRINTF ((message("XW%s | %s", exprNode_unparse(stmt1), exprNode_unparse(stmt2) ) ) );
315
316 exprNode_stmt (stmt1);
317 DPRINTF(("\nstmt after stmtList call " ));
318
319 exprNode_stmt (stmt2);
320 mergeResolve (e, stmt1, stmt2 );
321
322 DPRINTF ( (message ("smtlist constraints are: pre: %s \n and \t post %s\n",
323 constraintList_print(e->requiresConstraints),
324 constraintList_print(e->ensuresConstraints) ) ) );
84c9ffbf 325 return; // TRUE;
a8e557d3 326}
327
4ab867d6 328static exprNode doIf (/*@returned@*/ exprNode e, exprNode test, exprNode body)
616915dd 329{
bb25bea6 330 constraintList temp;
331
616915dd 332 DPRINTF ((message ("doIf: %s ", exprNode_unparse(e) ) ) );
470b7798 333
a8e557d3 334 llassert(exprNode_isDefined(test) );
84c9ffbf 335 llassert (exprNode_isDefined (e) );
336 llassert (exprNode_isDefined (body) );
bb25bea6 337
616915dd 338
bb25bea6 339 DPRINTF((message ("ensures constraints for %s are %s", exprNode_unparse(e), constraintList_printDetailed(e->ensuresConstraints) ) ));
340
341 DPRINTF((message ("Requires constraints for %s are %s", exprNode_unparse(e), constraintList_printDetailed(e->ensuresConstraints) ) ));
342
343 DPRINTF((message ("trueEnsures constraints for %s are %s", exprNode_unparse(e), constraintList_printDetailed(e->trueEnsuresConstraints) ) ));
344
345 DPRINTF((message ("falseEnsures constraints for %s are %s", exprNode_unparse(e), constraintList_printDetailed(e->falseEnsuresConstraints) ) ));
346
347
348
349 DPRINTF((message ("ensures constraints for %s are %s", exprNode_unparse(test), constraintList_printDetailed(test->ensuresConstraints) ) ));
350
351 DPRINTF((message ("Requires constraints for %s are %s", exprNode_unparse(test), constraintList_printDetailed(test->ensuresConstraints) ) ));
352
353 DPRINTF((message ("trueEnsures constraints for %s are %s", exprNode_unparse(test), constraintList_printDetailed(test->trueEnsuresConstraints) ) ));
354
355 DPRINTF((message ("falseEnsures constraints for %s are %s", exprNode_unparse(test), constraintList_printDetailed(test->falseEnsuresConstraints) ) ));
356
357
358
359 temp = test->trueEnsuresConstraints;
360 test->trueEnsuresConstraints = exprNode_traversTrueEnsuresConstraints(test);
361 constraintList_free(temp);
362
363 temp = test->ensuresConstraints;
616915dd 364 test->ensuresConstraints = exprNode_traversEnsuresConstraints (test);
bb25bea6 365 constraintList_free(temp);
366
367 temp = test->requiresConstraints;
470b7798 368 test->requiresConstraints = exprNode_traversRequiresConstraints (test);
bb25bea6 369 constraintList_free(temp);
616915dd 370
bb25bea6 371
372 test->trueEnsuresConstraints = constraintList_substituteFreeTarget(test->trueEnsuresConstraints, test->ensuresConstraints);
c3e695ff 373
374 DPRINTF ((message ("doIf: test ensures %s ", constraintList_print(test->ensuresConstraints) ) ) );
375
376 DPRINTF ((message ("doIf: test true ensures %s ", constraintList_print(test->trueEnsuresConstraints) ) ) );
bb25bea6 377
378 constraintList_free(e->requiresConstraints);
616915dd 379 e->requiresConstraints = reflectChanges (body->requiresConstraints, test->trueEnsuresConstraints);
bb25bea6 380
381 e->requiresConstraints = reflectChangesFreePre (e->requiresConstraints,
616915dd 382 test->ensuresConstraints);
bb25bea6 383 temp = e->requiresConstraints;
470b7798 384 e->requiresConstraints = constraintList_mergeRequires (e->requiresConstraints, test->requiresConstraints);
bb25bea6 385 constraintList_free(temp);
386
387
616915dd 388#warning bad
bb25bea6 389 constraintList_free(e->ensuresConstraints);
616915dd 390 e->ensuresConstraints = constraintList_copy (test->ensuresConstraints);
90bc41f7 391
392 if (exprNode_mayEscape (body) )
393 {
394 DPRINTF (( message("doIf: the if statement body %s returns or exits", exprNode_unparse(body) ) ));
bb25bea6 395 e->ensuresConstraints = constraintList_mergeEnsuresFreeFirst (e->ensuresConstraints,
470b7798 396 test->falseEnsuresConstraints);
90bc41f7 397 }
398
9280addf 399 DPRINTF ((message ("doIf: if requiers %s ", constraintList_print(e->requiresConstraints) ) ) );
400
616915dd 401 return e;
402}
403
470b7798 404/*drl added 3/4/2001
405 Also used for condition i.e. ?: operation
406
407 Precondition
408 This function assumes that p, trueBranch, falseBranch have have all been traversed
409 for constraints i.e. we assume that exprNode_traversEnsuresConstraints,
410 exprNode_traversRequiresConstraints, exprNode_traversTrueEnsuresConstraints,
411 exprNode_traversFalseEnsuresConstraints have all been run
412*/
413
414
bb25bea6 415static exprNode doIfElse (/*@returned@*/ exprNode e, exprNode p, exprNode trueBranch, exprNode falseBranch)
470b7798 416{
417
bb25bea6 418 constraintList c1, cons, t, t2, f, f2;
419
420 DPRINTF ((message ("doIfElse: %s ", exprNode_unparse(e) ) ) );
470b7798 421
422 // do requires clauses
423 c1 = constraintList_copy (p->ensuresConstraints);
424
425 t = reflectChanges (trueBranch->requiresConstraints, p->trueEnsuresConstraints);
bb25bea6 426 t = reflectChangesFreePre (t, p->ensuresConstraints);
470b7798 427
470b7798 428 cons = reflectChanges (falseBranch->requiresConstraints, p->falseEnsuresConstraints);
bb25bea6 429 cons = reflectChangesFreePre (cons, c1);
470b7798 430
bb25bea6 431 constraintList_free(e->requiresConstraints);
432 e->requiresConstraints = constraintList_mergeRequiresFreeFirst (t, cons);
433 e->requiresConstraints = constraintList_mergeRequiresFreeFirst (e->requiresConstraints, p->requiresConstraints);
470b7798 434
435 // do ensures clauses
436 // find the the ensures lists for each subbranch
437 t = constraintList_mergeEnsures (p->trueEnsuresConstraints, trueBranch->ensuresConstraints);
bb25bea6 438 t2 = t;
470b7798 439 t = constraintList_mergeEnsures (p->ensuresConstraints, t);
bb25bea6 440 constraintList_free(t2);
441
470b7798 442 f = constraintList_mergeEnsures (p->falseEnsuresConstraints, falseBranch->ensuresConstraints);
bb25bea6 443 f2 = f;
470b7798 444 f = constraintList_mergeEnsures (p->ensuresConstraints, f);
bb25bea6 445 constraintList_free(f2);
470b7798 446
447 // find ensures for whole if/else statement
448
bb25bea6 449 constraintList_free(e->ensuresConstraints);
450
470b7798 451 e->ensuresConstraints = constraintList_logicalOr (t, f);
452
bb25bea6 453 constraintList_free(t);
454 constraintList_free(f);
455 constraintList_free(cons);
456 constraintList_free(c1);
457
458 DPRINTF ((message ("doIfElse: if requires %q ", constraintList_print(e->requiresConstraints) ) ) );
459 DPRINTF ((message ("doIfElse: if ensures %q ", constraintList_print(e->ensuresConstraints) ) ) );
460
470b7798 461 return e;
462}
9280addf 463
4ab867d6 464static exprNode doWhile (/*@returned@*/ exprNode e, exprNode test, exprNode body)
9280addf 465{
466 DPRINTF ((message ("doWhile: %s ", exprNode_unparse(e) ) ) );
467 return doIf (e, test, body);
468}
469
616915dd 470constraintList constraintList_makeFixedArrayConstraints (sRefSet s)
471{
472 constraintList ret;
470b7798 473 constraint con;
c3e695ff 474 ret = constraintList_makeNew();
616915dd 475
476 sRefSet_elements (s, el)
477 {
478 // llassert (el);
479 if (sRef_isFixedArray(el) )
480 {
84c9ffbf 481 long int size;
470b7798 482 DPRINTF( (message("%s is a fixed array",
483 sRef_unparse(el)) ) );
484 //if (el->kind == SK_DERIVED)
485 // break; //hack until I find the real problem
84c9ffbf 486 size = sRef_getArraySize(el);
616915dd 487 DPRINTF( (message("%s is a fixed array with size %d",
84c9ffbf 488 sRef_unparse(el), (int)size) ) );
489 con = constraint_makeSRefSetBufferSize (el, (size - 1));
490 //con = constraint_makeSRefWriteSafeInt (el, (size - 1));
616915dd 491 ret = constraintList_add(ret, con);
492 }
493 else
494 {
495 DPRINTF( (message("%s is not a fixed array",
496 sRef_unparse(el)) ) );
470b7798 497
498
499 if (sRef_isExternallyVisible (el) )
500 {
501 /*DPRINTF( (message("%s is externally visible",
502 sRef_unparse(el) ) ));
503 con = constraint_makeSRefWriteSafeInt(el, 0);
504 ret = constraintList_add(ret, con);
505
506 con = constraint_makeSRefReadSafeInt(el, 0);
507
508 ret = constraintList_add(ret, con);*/
509 }
616915dd 510 }
511 }
512 end_sRefSet_elements
513
470b7798 514 DPRINTF(( message("constraintList_makeFixedArrayConstraints returning %s",
515 constraintList_print(ret) ) ));
616915dd 516 return ret;
517}
518
4ab867d6 519exprNode makeDataTypeConstraints (/*@returned@*/ exprNode e)
616915dd 520{
521 constraintList c;
522 DPRINTF(("makeDataTypeConstraints"));
523
524 c = constraintList_makeFixedArrayConstraints (e->uses);
525
4ab867d6 526 e->ensuresConstraints = constraintList_addListFree (e->ensuresConstraints, c);
616915dd 527
528 return e;
529}
530
bb25bea6 531static void doFor (exprNode e, exprNode forPred, exprNode forBody)
616915dd 532{
533 exprNode init, test, inc;
534 //merge the constraints: modle as if statement
535 /* init
536 if (test)
537 for body
538 inc */
539 init = exprData_getTripleInit (forPred->edata);
540 test = exprData_getTripleTest (forPred->edata);
541 inc = exprData_getTripleInc (forPred->edata);
542
543 if ( ( (exprNode_isError (test) /*|| (exprNode_isError(init) )*/ ) || (exprNode_isError (inc) ) ) )
544 {
545 DPRINTF ((message ("strange for statement:%s, ignoring it", exprNode_unparse(e) ) ) );
546 return;
547 }
548
549 forLoopHeuristics(e, forPred, forBody);
550
bb25bea6 551 constraintList_free(e->requiresConstraints);
616915dd 552 e->requiresConstraints = reflectChanges (forBody->requiresConstraints, test->ensuresConstraints);
bb25bea6 553 e->requiresConstraints = reflectChangesFreePre (e->requiresConstraints, test->trueEnsuresConstraints);
554 e->requiresConstraints = reflectChangesFreePre (e->requiresConstraints, forPred->ensuresConstraints);
616915dd 555
556 if (!forBody->canBreak)
557 {
4ab867d6 558 e->ensuresConstraints = constraintList_addListFree(e->ensuresConstraints, constraintList_copy(forPred->ensuresConstraints) );
559 e->ensuresConstraints = constraintList_addListFree(e->ensuresConstraints,constraintList_copy( test->falseEnsuresConstraints));
bb25bea6 560 // forPred->ensuresConstraints = constraintList_undefined;
561 // test->falseEnsuresConstraints = constraintList_undefined;
616915dd 562 }
563 else
564 {
565 DPRINTF(("Can break") );
566 }
567
568}
569
bb25bea6 570static exprNode doSwitch (/*@returned@*/ exprNode e)
470b7798 571{
572 exprNode body;
573 exprData data;
574
575 data = e->edata;
576 llassert(FALSE);
90bc41f7 577 //DPRINTF (( message ("doSwitch for: switch (%s) %s",
470b7798 578 // exprNode_unparse (exprData_getPairA (data)),
579 // exprNode_unparse (exprData_getPairB (data))) ));
580
581 body = exprData_getPairB (data);
582
583 // exprNode_generateConstraints(body);
584
585 // e->requiresConstraints = constraintList_copy ( body->requiresConstraints );
586 //e->ensuresConstraints = constraintList_copy ( body->ensuresConstraints );
587
588 return e;
589}
9280addf 590
591
84c9ffbf 592void exprNode_multiStatement (exprNode e)
616915dd 593{
594
595 bool ret;
596 exprData data;
597 exprNode e1, e2;
598 exprNode p, trueBranch, falseBranch;
599 exprNode forPred, forBody;
470b7798 600 exprNode test;
bb25bea6 601
602 constraintList temp;
603
470b7798 604 // constraintList t, f;
bb25bea6 605 /*e->requiresConstraints = constraintList_makeNew();
c3e695ff 606 e->ensuresConstraints = constraintList_makeNew();
607 e->trueEnsuresConstraints = constraintList_makeNew();
608 e->falseEnsuresConstraints = constraintList_makeNew();
bb25bea6 609 */
616915dd 610 // e = makeDataTypeConstraints(e);
611
612 DPRINTF((message ("exprNode_multistatement Analysising %s %s at", exprNode_unparse( e),
613 fileloc_unparse(exprNode_getfileloc(e) ) ) ) );
614
615 if (exprNode_handleError (e))
616 {
84c9ffbf 617 return; // FALSE;
616915dd 618 }
619
620 data = e->edata;
621
622 ret = TRUE;
623
624 switch (e->kind)
625 {
626
627 case XPR_FOR:
628 // ret = message ("%s %s",
629 forPred = exprData_getPairA (data);
630 forBody = exprData_getPairB (data);
631
632 //first generate the constraints
633 exprNode_generateConstraints (forPred);
634 exprNode_generateConstraints (forBody);
635
636
637 doFor (e, forPred, forBody);
638
639 break;
640
641 case XPR_FORPRED:
642 // ret = message ("for (%s; %s; %s)",
643 exprNode_generateConstraints (exprData_getTripleInit (data) );
644 test = exprData_getTripleTest (data);
645 exprNode_exprTraverse (test,FALSE, FALSE, exprNode_loc(e));
9280addf 646 exprNode_generateConstraints (exprData_getTripleInc (data) );
647
616915dd 648 if (!exprNode_isError(test) )
bb25bea6 649 {
650 constraintList temp2;
651 temp2 = test->trueEnsuresConstraints;
652 test->trueEnsuresConstraints = exprNode_traversTrueEnsuresConstraints(test);
653 constraintList_free(temp2);
654 }
655
616915dd 656 exprNode_generateConstraints (exprData_getTripleInc (data));
657 break;
9280addf 658
659 case XPR_WHILE:
660 e1 = exprData_getPairA (data);
661 e2 = exprData_getPairB (data);
662
663 exprNode_exprTraverse (e1,
664 FALSE, FALSE, exprNode_loc(e1));
665
666 exprNode_generateConstraints (e2);
667
668 e = doWhile (e, e1, e2);
669
670 break;
671
616915dd 672 case XPR_IF:
673 DPRINTF(( "IF:") );
674 DPRINTF ((exprNode_unparse(e) ) );
675 // ret = message ("if (%s) %s",
676 e1 = exprData_getPairA (data);
677 e2 = exprData_getPairB (data);
678
679 exprNode_exprTraverse (e1,
680 FALSE, FALSE, exprNode_loc(e1));
681
682 exprNode_generateConstraints (e2);
616915dd 683 e = doIf (e, e1, e2);
684
685
686 // e->constraints = constraintList_exprNodemerge (exprData_getPairA (data),exprData_getPairB(data));
687 break;
9280addf 688
689
616915dd 690 case XPR_IFELSE:
691 DPRINTF(("Starting IFELSE"));
692 // ret = message ("if (%s) %s else %s",
693 p = exprData_getTriplePred (data);
694 trueBranch = exprData_getTripleTrue (data);
695 falseBranch = exprData_getTripleFalse (data);
696
697 exprNode_exprTraverse (p,
698 FALSE, FALSE, exprNode_loc(p));
699 exprNode_generateConstraints (trueBranch);
700 exprNode_generateConstraints (falseBranch);
701
bb25bea6 702 temp = p->ensuresConstraints;
9280addf 703 p->ensuresConstraints = exprNode_traversEnsuresConstraints (p);
bb25bea6 704 constraintList_free(temp);
705
706 temp = p->requiresConstraints;
470b7798 707 p->requiresConstraints = exprNode_traversRequiresConstraints (p);
bb25bea6 708 constraintList_free(temp);
709
710 temp = p->trueEnsuresConstraints;
9280addf 711 p->trueEnsuresConstraints = exprNode_traversTrueEnsuresConstraints(p);
bb25bea6 712 constraintList_free(temp);
713
714 temp = p->falseEnsuresConstraints;
470b7798 715 p->falseEnsuresConstraints = exprNode_traversFalseEnsuresConstraints(p);
bb25bea6 716 constraintList_free(temp);
616915dd 717
470b7798 718 e = doIfElse (e, p, trueBranch, falseBranch);
616915dd 719 DPRINTF( ("Done IFELSE") );
720 break;
9280addf 721
616915dd 722 case XPR_DOWHILE:
470b7798 723
724 e2 = (exprData_getPairB (data));
725 e1 = (exprData_getPairA (data));
726
727 DPRINTF((message ("do { %s } while (%s)", exprNode_unparse(e2), exprNode_unparse(e1) ) ));
728 exprNode_generateConstraints (e2);
729 exprNode_generateConstraints (e1);
730 e = exprNode_copyConstraints (e, e2);
731 DPRINTF ((message ("e = %s ", constraintList_print(e->requiresConstraints) ) ));
732
616915dd 733 break;
734
735 case XPR_BLOCK:
736 // ret = message ("{ %s }",
737 exprNode_generateConstraints (exprData_getSingle (data));
bb25bea6 738
739 constraintList_free(e->requiresConstraints);
616915dd 740 e->requiresConstraints = constraintList_copy ( (exprData_getSingle (data))->requiresConstraints );
bb25bea6 741
742 constraintList_free(e->ensuresConstraints);
616915dd 743 e->ensuresConstraints = constraintList_copy ( (exprData_getSingle (data))->ensuresConstraints );
744 // e->constraints = (exprData_getSingle (data))->constraints;
745 break;
746
470b7798 747 case XPR_SWITCH:
748 e = doSwitch (e);
749 break;
616915dd 750 case XPR_STMT:
751 case XPR_STMTLIST:
84c9ffbf 752 exprNode_stmtList (e);
753 return ;
616915dd 754 /*@notreached@*/
755 break;
756 default:
757 ret=FALSE;
758 }
84c9ffbf 759 return; // ret;
616915dd 760}
761
bb25bea6 762static bool lltok_isBoolean_Op (lltok tok)
616915dd 763{
764 /*this should really be a switch statement but
765 I don't want to violate the abstraction
766 maybe this should go in lltok.c */
767
768 if (lltok_isEq_Op (tok) )
769 {
770 return TRUE;
771 }
772 if (lltok_isAnd_Op (tok) )
773
774 {
775
776 return TRUE;
777 }
778 if (lltok_isOr_Op (tok) )
779 {
780 return TRUE;
781 }
782
783 if (lltok_isGt_Op (tok) )
784 {
785 return TRUE;
786 }
787 if (lltok_isLt_Op (tok) )
788 {
789 return TRUE;
790 }
791
792 if (lltok_isLe_Op (tok) )
793 {
794 return TRUE;
795 }
796
797 if (lltok_isGe_Op (tok) )
798 {
799 return TRUE;
800 }
801
802 return FALSE;
803
804}
805
806
bb25bea6 807static void exprNode_booleanTraverse (exprNode e, /*@unused@*/ bool definatelv, /*@unused@*/ bool definaterv, fileloc sequencePoint)
616915dd 808{
809 constraint cons;
810exprNode t1, t2;
811exprData data;
812lltok tok;
bb25bea6 813constraintList tempList, temp;
616915dd 814data = e->edata;
815
816tok = exprData_getOpTok (data);
817
818
819t1 = exprData_getOpA (data);
820t2 = exprData_getOpB (data);
821
822
823/* arithmetic tests */
824
825if (lltok_isEq_Op (tok) )
826{
827 cons = constraint_makeEnsureEqual (t1, t2, sequencePoint);
828 e->trueEnsuresConstraints = constraintList_add(e->trueEnsuresConstraints, cons);
829}
830
831
832 if (lltok_isLt_Op (tok) )
833 {
834 cons = constraint_makeEnsureLessThan (t1, t2, sequencePoint);
835 e->trueEnsuresConstraints = constraintList_add(e->trueEnsuresConstraints, cons);
836 cons = constraint_makeEnsureGreaterThanEqual (t1, t2, sequencePoint);
837 e->falseEnsuresConstraints = constraintList_add(e->falseEnsuresConstraints, cons);
838 }
839
840
841if (lltok_isGe_Op (tok) )
842{
843
844 cons = constraint_makeEnsureGreaterThanEqual (t1, t2, sequencePoint);
845 e->trueEnsuresConstraints = constraintList_add(e->trueEnsuresConstraints, cons);
846
847 cons = constraint_makeEnsureLessThan (t1, t2, sequencePoint);
848 e->falseEnsuresConstraints = constraintList_add(e->falseEnsuresConstraints, cons);
849
850}
851
852
853 if (lltok_isGt_Op (tok) )
854{
855 cons = constraint_makeEnsureGreaterThan (t1, t2, sequencePoint);
856 e->trueEnsuresConstraints = constraintList_add(e->trueEnsuresConstraints, cons);
857 cons = constraint_makeEnsureLessThanEqual (t1, t2, sequencePoint);
858 e->falseEnsuresConstraints = constraintList_add(e->falseEnsuresConstraints, cons);
859}
860
861if (lltok_isLe_Op (tok) )
862{
863 cons = constraint_makeEnsureLessThanEqual (t1, t2, sequencePoint);
864 e->trueEnsuresConstraints = constraintList_add(e->trueEnsuresConstraints, cons);
865
866 cons = constraint_makeEnsureGreaterThan (t1, t2, sequencePoint);
867 e->falseEnsuresConstraints = constraintList_add(e->falseEnsuresConstraints, cons);
868}
869
870
871
872/*Logical operations */
873
874 if (lltok_isAnd_Op (tok) )
875
876 {
877 //true ensures
878 tempList = constraintList_copy (t1->trueEnsuresConstraints);
879 tempList = constraintList_addList (tempList, t2->trueEnsuresConstraints);
4ab867d6 880 e->trueEnsuresConstraints = constraintList_addListFree(e->trueEnsuresConstraints, tempList);
616915dd 881
882 //false ensures: fens t1 or tens t1 and fens t2
883 tempList = constraintList_copy (t1->trueEnsuresConstraints);
884 tempList = constraintList_addList (tempList, t2->falseEnsuresConstraints);
bb25bea6 885 temp = tempList;
616915dd 886 tempList = constraintList_logicalOr (tempList, t1->falseEnsuresConstraints);
bb25bea6 887 constraintList_free(temp);
888
616915dd 889 e->falseEnsuresConstraints =constraintList_addList(e->falseEnsuresConstraints, tempList);
890
891 }
84c9ffbf 892 else if (lltok_isOr_Op (tok) )
893 {
616915dd 894 //false ensures
895 tempList = constraintList_copy (t1->falseEnsuresConstraints);
896 tempList = constraintList_addList (tempList, t2->falseEnsuresConstraints);
4ab867d6 897 e->falseEnsuresConstraints = constraintList_addListFree(e->falseEnsuresConstraints, tempList);
616915dd 898
899 //true ensures: tens t1 or fens t1 and tens t2
900 tempList = constraintList_copy (t1->falseEnsuresConstraints);
901 tempList = constraintList_addList (tempList, t2->trueEnsuresConstraints);
bb25bea6 902
903 temp = tempList;
616915dd 904 tempList = constraintList_logicalOr (tempList, t1->trueEnsuresConstraints);
bb25bea6 905 constraintList_free(temp);
906
907
4ab867d6 908 e->trueEnsuresConstraints =constraintList_addListFree(e->trueEnsuresConstraints, tempList);
616915dd 909
910 }
84c9ffbf 911 else
912 {
913 DPRINTF((message("%s is not a boolean operation", lltok_unparse(tok) ) ));
914 }
616915dd 915
916}
917
bb25bea6 918void exprNode_exprTraverse (exprNode e, bool definatelv, bool definaterv, /*@observer@*/ fileloc sequencePoint)
616915dd 919{
9280addf 920 exprNode t1, t2, fcn;
616915dd 921 lltok tok;
922 bool handledExprNode;
923 exprData data;
924 constraint cons;
925
bb25bea6 926 constraintList temp;
927
470b7798 928 if (exprNode_isError(e) )
929 {
84c9ffbf 930 return; // FALSE;
470b7798 931 }
932
933 DPRINTF((message ("exprNode_exprTraverset Analysising %s %s at", exprNode_unparse( e),
616915dd 934 fileloc_unparse(exprNode_getfileloc(e) ) ) ) );
470b7798 935
bb25bea6 936 /*e->requiresConstraints = constraintList_makeNew();
c3e695ff 937 e->ensuresConstraints = constraintList_makeNew();
938 e->trueEnsuresConstraints = constraintList_makeNew();;
939 e->falseEnsuresConstraints = constraintList_makeNew();;
bb25bea6 940 */
470b7798 941 if (exprNode_isUnhandled (e) )
616915dd 942 {
84c9ffbf 943 return; // FALSE;
616915dd 944 }
945 // e = makeDataTypeConstraints (e);
946
947 handledExprNode = TRUE;
948
949 data = e->edata;
950
951 switch (e->kind)
952 {
953
954
955 case XPR_WHILEPRED:
956 t1 = exprData_getSingle (data);
957 exprNode_exprTraverse (t1, definatelv, definaterv, sequencePoint);
958 e = exprNode_copyConstraints (e, t1);
959 break;
960
961 case XPR_FETCH:
962
963 if (definatelv )
964 {
965 t1 = (exprData_getPairA (data) );
966 t2 = (exprData_getPairB (data) );
967 cons = constraint_makeWriteSafeExprNode (t1, t2);
968 }
969 else
970 {
971 t1 = (exprData_getPairA (data) );
972 t2 = (exprData_getPairB (data) );
973 cons = constraint_makeReadSafeExprNode (t1, t2 );
974 }
975
976 e->requiresConstraints = constraintList_add(e->requiresConstraints, cons);
977 cons = constraint_makeEnsureMaxReadAtLeast (t1, t2, sequencePoint);
978 e->ensuresConstraints = constraintList_add(e->ensuresConstraints, cons);
979
9280addf 980 cons = constraint_makeEnsureLteMaxRead (t2, t1);
616915dd 981 e->trueEnsuresConstraints = constraintList_add(e->trueEnsuresConstraints, cons);
982
983 // cons = constraint_makeEnsureMinReadAtMost (t1, t2, sequencePoint);
984 // e->ensuresConstraints = constraintList_add(e->ensuresConstraints, cons);
d46ce6a4 985
616915dd 986 exprNode_exprTraverse (exprData_getPairA (data), FALSE, TRUE, sequencePoint);
987 exprNode_exprTraverse (exprData_getPairB (data), FALSE, TRUE, sequencePoint);
988
989 /*@i325 Should check which is array/index. */
990 break;
991
992 case XPR_PARENS:
993 exprNode_exprTraverse (exprData_getUopNode (e->edata), definatelv, definaterv, sequencePoint);
994 // e->constraints = constraintList_exprNodemerge (exprData_getUopNode (e->edata), exprNode_undefined);
995 break;
996 case XPR_INIT:
997 /* //t1 = exprData_getInitId (data); */
998 t2 = exprData_getInitNode (data);
999 //exprNode_exprTraverse (t1, TRUE, FALSE, sequencePoint );
1000
1001 exprNode_exprTraverse (t2, definatelv, TRUE, sequencePoint );
1002
1003 /* this test is nessecary because some expressions generate a null expression node. function pointer do that -- drl */
1004 if ( (!exprNode_isError (e)) && (!exprNode_isError(t2)) )
1005 {
1006 cons = constraint_makeEnsureEqual (e, t2, sequencePoint);
1007 e->ensuresConstraints = constraintList_add(e->ensuresConstraints, cons);
1008 }
1009
1010 break;
1011 case XPR_ASSIGN:
1012 t1 = exprData_getOpA (data);
1013 t2 = exprData_getOpB (data);
1014 exprNode_exprTraverse (t1, TRUE, definaterv, sequencePoint );
84c9ffbf 1015 //lltok_unparse (exprData_getOpTok (data));
1016 #warning check this for += -= etc
616915dd 1017 exprNode_exprTraverse (t2, definatelv, TRUE, sequencePoint );
1018
1019 /* this test is nessecary because some expressions generate a null expression node. function pointer do that -- drl */
1020 if ( (!exprNode_isError (t1)) && (!exprNode_isError(t2)) )
1021 {
1022 cons = constraint_makeEnsureEqual (t1, t2, sequencePoint);
1023 e->ensuresConstraints = constraintList_add(e->ensuresConstraints, cons);
1024 }
1025 break;
1026 case XPR_OP:
1027 t1 = exprData_getOpA (data);
1028 t2 = exprData_getOpB (data);
1029
1030 exprNode_exprTraverse (t1, definatelv, definaterv, sequencePoint );
1031 tok = exprData_getOpTok (data);
1032 exprNode_exprTraverse (t2, definatelv, definaterv, sequencePoint );
1033
1034 if (lltok_isBoolean_Op (tok) )
1035 exprNode_booleanTraverse (e, definatelv, definaterv, sequencePoint);
1036
1037 // e->constraints = constraintList_exprNodemerge (exprData_getOpA (data), exprData_getOpB (data));
1038 break;
1039 case XPR_SIZEOFT:
84c9ffbf 1040 #warning make sure the case can be ignored..
616915dd 1041
1042 break;
1043
1044 case XPR_SIZEOF:
1045 exprNode_exprTraverse (exprData_getSingle (data), definatelv, definaterv, sequencePoint );
1046 // e->constraints = constraintList_exprNodemerge (exprData_getSingle (e->edata), exprNode_undefined);
1047 break;
1048
1049 case XPR_CALL:
9280addf 1050 fcn = exprData_getFcn(data);
1051
1052 exprNode_exprTraverse (fcn, definatelv, definaterv, sequencePoint );
9280addf 1053 DPRINTF ( (message ("Got call that %s ( %s) ", exprNode_unparse(fcn), exprNodeList_unparse (exprData_getArgs (data) ) ) ) );
616915dd 1054
4ab867d6 1055 fcn->requiresConstraints = constraintList_addListFree (fcn->requiresConstraints,
9280addf 1056 checkCall (fcn, exprData_getArgs (data) ) );
616915dd 1057
4ab867d6 1058 fcn->ensuresConstraints = constraintList_addListFree (fcn->ensuresConstraints,
9280addf 1059 getPostConditions(fcn, exprData_getArgs (data),e ) );
1060
1061 t1 = exprNode_createNew (exprNode_getType (e) );
1062
1063 checkArgumentList (t1, exprData_getArgs(data), sequencePoint);
616915dd 1064
9280addf 1065
1066 mergeResolve (e, t1, fcn);
1067
616915dd 1068 // e->constraints = constraintList_add (e->constraints, constraint_create (e,exprNode_undefined, GT, CALLSAFE ) );
1069 break;
1070
1071 case XPR_RETURN:
1072 exprNode_exprTraverse (exprData_getSingle (data), definatelv, definaterv, sequencePoint );
1073 break;
1074
1075 case XPR_NULLRETURN:
84c9ffbf 1076
616915dd 1077 break;
1078
1079
1080 case XPR_FACCESS:
1081 exprNode_exprTraverse (exprData_getFieldNode (data), definatelv, definaterv, sequencePoint );
616915dd 1082 break;
1083
1084 case XPR_ARROW:
1085 exprNode_exprTraverse (exprData_getFieldNode (data), definatelv, definaterv, sequencePoint );
616915dd 1086 break;
1087
1088 case XPR_STRINGLITERAL:
84c9ffbf 1089
616915dd 1090 break;
1091
1092 case XPR_NUMLIT:
84c9ffbf 1093
616915dd 1094 break;
1095
1096 case XPR_PREOP:
1097 t1 = exprData_getUopNode(data);
1098 tok = (exprData_getUopTok (data));
1099 //lltok_unparse (exprData_getUopTok (data));
1100 exprNode_exprTraverse (t1, definatelv, definaterv, sequencePoint );
1101 /*handle * pointer access */
1102 if (lltok_isInc_Op (tok) )
1103 {
1104 DPRINTF(("doing ++(var)"));
1105 t1 = exprData_getUopNode (data);
1106 cons = constraint_makeMaxSetSideEffectPostIncrement (t1, sequencePoint );
1107 e->ensuresConstraints = constraintList_add (e->ensuresConstraints, cons);
1108 }
1109 else if (lltok_isDec_Op (tok) )
1110 {
1111 DPRINTF(("doing --(var)"));
1112 t1 = exprData_getUopNode (data);
1113 cons = constraint_makeMaxSetSideEffectPostDecrement (t1, sequencePoint );
1114 e->ensuresConstraints = constraintList_add (e->ensuresConstraints, cons);
1115 }
84c9ffbf 1116 else if (lltok_isMult( tok ) )
616915dd 1117 {
1118 if (definatelv)
1119 {
1120 cons = constraint_makeWriteSafeInt (t1, 0);
1121 }
1122 else
1123 {
1124 cons = constraint_makeReadSafeInt (t1, 0);
1125 }
1126 e->requiresConstraints = constraintList_add(e->requiresConstraints, cons);
1127 }
84c9ffbf 1128 else if (lltok_isNot_Op (tok) )
1129 /* ! expr */
616915dd 1130 {
bb25bea6 1131 constraintList_free(e->trueEnsuresConstraints);
1132
616915dd 1133 e->trueEnsuresConstraints = constraintList_copy (t1->falseEnsuresConstraints);
bb25bea6 1134 constraintList_free(e->falseEnsuresConstraints);
616915dd 1135 e->falseEnsuresConstraints = constraintList_copy (t1->trueEnsuresConstraints);
1136 }
bb25bea6 1137
84c9ffbf 1138 else if (lltok_isAmpersand_Op (tok) )
1139 {
1140 break;
1141 }
bb25bea6 1142 else if (lltok_isMinus_Op (tok) )
1143 {
1144 break;
1145 }
4ab867d6 1146 else if ( lltok_isExcl_Op (tok) )
1147 {
1148 break;
1149 }
1150 else if (lltok_isTilde_Op (tok) )
1151 {
1152 break;
1153 }
84c9ffbf 1154 else
1155 {
1156 llcontbug((message("Unsupported preop in %s", exprNode_unparse(e) ) ));
1157 BADEXIT;
1158 }
616915dd 1159 break;
1160
1161 case XPR_POSTOP:
1162
1163 exprNode_exprTraverse (exprData_getUopNode (data), TRUE, definaterv, sequencePoint );
84c9ffbf 1164
616915dd 1165 if (lltok_isInc_Op (exprData_getUopTok (data) ) )
1166 {
1167 DPRINTF(("doing ++"));
1168 t1 = exprData_getUopNode (data);
1169 cons = constraint_makeMaxSetSideEffectPostIncrement (t1, sequencePoint );
1170 e->ensuresConstraints = constraintList_add (e->ensuresConstraints, cons);
1171 }
1172 if (lltok_isDec_Op (exprData_getUopTok (data) ) )
1173 {
1174 DPRINTF(("doing --"));
1175 t1 = exprData_getUopNode (data);
1176 cons = constraint_makeMaxSetSideEffectPostDecrement (t1, sequencePoint );
1177 e->ensuresConstraints = constraintList_add (e->ensuresConstraints, cons);
1178 }
1179 break;
470b7798 1180 case XPR_CAST:
1181 llassert(FALSE);
1182 exprNode_exprTraverse (exprData_getCastNode (data), definatelv, definaterv, sequencePoint );
1183 break;
1184 case XPR_COND:
1185 {
1186 exprNode pred, true, false;
1187 llassert(FALSE);
1188 pred = exprData_getTriplePred (data);
1189 true = exprData_getTripleTrue (data);
1190 false = exprData_getTripleFalse (data);
1191
1192 exprNode_exprTraverse (pred, FALSE, TRUE, sequencePoint );
bb25bea6 1193
1194 temp = pred->ensuresConstraints;
470b7798 1195 pred->ensuresConstraints = exprNode_traversEnsuresConstraints(pred);
bb25bea6 1196 constraintList_free(temp);
1197
1198 temp = pred->requiresConstraints;
470b7798 1199 pred->requiresConstraints = exprNode_traversRequiresConstraints(pred);
bb25bea6 1200 constraintList_free(temp);
470b7798 1201
bb25bea6 1202 temp = pred->trueEnsuresConstraints;
470b7798 1203 pred->trueEnsuresConstraints = exprNode_traversTrueEnsuresConstraints(pred);
bb25bea6 1204 constraintList_free(temp);
1205
1206 temp = pred->falseEnsuresConstraints;
470b7798 1207 pred->falseEnsuresConstraints = exprNode_traversFalseEnsuresConstraints(pred);
bb25bea6 1208 constraintList_free(temp);
1209
470b7798 1210
1211 exprNode_exprTraverse (true, FALSE, TRUE, sequencePoint );
bb25bea6 1212
1213 temp = true->ensuresConstraints;
470b7798 1214 true->ensuresConstraints = exprNode_traversEnsuresConstraints(true);
bb25bea6 1215 constraintList_free(temp);
1216
1217
1218 temp = true->requiresConstraints;
470b7798 1219 true->requiresConstraints = exprNode_traversRequiresConstraints(true);
bb25bea6 1220 constraintList_free(temp);
1221
470b7798 1222
bb25bea6 1223 temp = true->trueEnsuresConstraints;
470b7798 1224 true->trueEnsuresConstraints = exprNode_traversTrueEnsuresConstraints(true);
bb25bea6 1225 constraintList_free(temp);
1226
1227 temp = true->falseEnsuresConstraints;
470b7798 1228 true->falseEnsuresConstraints = exprNode_traversFalseEnsuresConstraints(true);
bb25bea6 1229 constraintList_free(temp);
470b7798 1230
bb25bea6 1231 //dfdf
470b7798 1232 exprNode_exprTraverse (false, FALSE, TRUE, sequencePoint );
bb25bea6 1233
1234 temp = false->ensuresConstraints;
470b7798 1235 false->ensuresConstraints = exprNode_traversEnsuresConstraints(false);
bb25bea6 1236 constraintList_free(temp);
1237
1238
1239 temp = false->requiresConstraints;
470b7798 1240 false->requiresConstraints = exprNode_traversRequiresConstraints(false);
bb25bea6 1241 constraintList_free(temp);
1242
470b7798 1243
bb25bea6 1244 temp = false->trueEnsuresConstraints;
470b7798 1245 false->trueEnsuresConstraints = exprNode_traversTrueEnsuresConstraints(false);
bb25bea6 1246 constraintList_free(temp);
470b7798 1247
bb25bea6 1248 temp = false->falseEnsuresConstraints;
1249 false->falseEnsuresConstraints = exprNode_traversFalseEnsuresConstraints(false);
1250 constraintList_free(temp);
470b7798 1251
1252 /* if pred is true e equals true otherwise pred equals false */
1253
1254 cons = constraint_makeEnsureEqual (e, true, sequencePoint);
1255 true->ensuresConstraints = constraintList_add(true->ensuresConstraints, cons);
1256
1257 cons = constraint_makeEnsureEqual (e, true, sequencePoint);
1258 false->ensuresConstraints = constraintList_add(false->ensuresConstraints, cons);
1259
1260 e = doIfElse (e, pred, true, false);
1261
1262 }
1263 break;
1264 case XPR_COMMA:
1265 llassert(FALSE);
1266 t1 = exprData_getPairA (data);
1267 t2 = exprData_getPairB (data);
1268 /* we essiantially treat this like expr1; expr2
1269 of course sequencePoint isn't adjusted so this isn't completely accurate
1270 problems../ */
1271 exprNode_exprTraverse (t1, FALSE, FALSE, sequencePoint );
1272 exprNode_exprTraverse (t2, definatelv, definaterv, sequencePoint );
1273 mergeResolve (e, t1, t2);
1274 break;
1275
616915dd 1276 default:
1277 handledExprNode = FALSE;
1278 }
1279
1280 e->requiresConstraints = constraintList_preserveOrig ( e->requiresConstraints);
1281 e->ensuresConstraints = constraintList_preserveOrig ( e->ensuresConstraints);
9280addf 1282 e->requiresConstraints = constraintList_addGeneratingExpr ( e->requiresConstraints, e);
1283
1284 e->ensuresConstraints = constraintList_addGeneratingExpr ( e->ensuresConstraints, e);
1285
d46ce6a4 1286 DPRINTF((message ("ensures constraints for %s are %s", exprNode_unparse(e), constraintList_printDetailed(e->ensuresConstraints) ) ));
1287
1288 DPRINTF((message ("Requires constraints for %s are %s", exprNode_unparse(e), constraintList_printDetailed(e->ensuresConstraints) ) ));
616915dd 1289
bb25bea6 1290 DPRINTF((message ("trueEnsures constraints for %s are %s", exprNode_unparse(e), constraintList_printDetailed(e->trueEnsuresConstraints) ) ));
1291
1292 DPRINTF((message ("falseEnsures constraints for %s are %s", exprNode_unparse(e), constraintList_printDetailed(e->falseEnsuresConstraints) ) ));
1293
84c9ffbf 1294 return; // handledExprNode;
616915dd 1295}
1296
1297
1298constraintList exprNode_traversTrueEnsuresConstraints (exprNode e)
1299{
470b7798 1300 exprNode t1;
616915dd 1301
1302 bool handledExprNode;
1303 // char * mes;
1304 exprData data;
1305 constraintList ret;
1306
1307 if (exprNode_handleError (e))
1308 {
c3e695ff 1309 ret = constraintList_makeNew();
616915dd 1310 return ret;
1311 }
1312 ret = constraintList_copy (e->trueEnsuresConstraints );
1313
1314 handledExprNode = TRUE;
1315
1316 data = e->edata;
1317
1318 switch (e->kind)
1319 {
9280addf 1320 case XPR_WHILEPRED:
1321 t1 = exprData_getSingle (data);
4ab867d6 1322 ret = constraintList_addListFree ( ret, exprNode_traversTrueEnsuresConstraints (t1) );
9280addf 1323 break;
616915dd 1324
1325 case XPR_FETCH:
1326
4ab867d6 1327 ret = constraintList_addListFree (ret,
616915dd 1328 exprNode_traversTrueEnsuresConstraints
1329 (exprData_getPairA (data) ) );
1330
4ab867d6 1331 ret = constraintList_addListFree (ret,
616915dd 1332 exprNode_traversTrueEnsuresConstraints
1333 (exprData_getPairB (data) ) );
1334 break;
1335 case XPR_PREOP:
1336
4ab867d6 1337 ret = constraintList_addListFree (ret,
616915dd 1338 exprNode_traversTrueEnsuresConstraints
1339 (exprData_getUopNode (data) ) );
1340 break;
1341
1342 case XPR_PARENS:
4ab867d6 1343 ret = constraintList_addListFree (ret, exprNode_traversTrueEnsuresConstraints
616915dd 1344 (exprData_getUopNode (data) ) );
1345 break;
1346 case XPR_ASSIGN:
4ab867d6 1347 ret = constraintList_addListFree (ret,
616915dd 1348 exprNode_traversTrueEnsuresConstraints
1349 (exprData_getOpA (data) ) );
1350
4ab867d6 1351 ret = constraintList_addListFree (ret,
616915dd 1352 exprNode_traversTrueEnsuresConstraints
1353 (exprData_getOpB (data) ) );
1354 break;
1355 case XPR_OP:
4ab867d6 1356 ret = constraintList_addListFree (ret,
616915dd 1357 exprNode_traversTrueEnsuresConstraints
1358 (exprData_getOpA (data) ) );
1359
4ab867d6 1360 ret = constraintList_addListFree (ret,
616915dd 1361 exprNode_traversTrueEnsuresConstraints
1362 (exprData_getOpB (data) ) );
1363 break;
1364 case XPR_SIZEOFT:
1365
1366 // ctype_unparse (qtype_getType (exprData_getType (data) ) );
1367
1368 break;
1369
1370 case XPR_SIZEOF:
1371
4ab867d6 1372 ret = constraintList_addListFree (ret,
1373 exprNode_traversTrueEnsuresConstraints
1374 (exprData_getSingle (data) ) );
616915dd 1375 break;
1376
1377 case XPR_CALL:
4ab867d6 1378 ret = constraintList_addListFree (ret,
616915dd 1379 exprNode_traversTrueEnsuresConstraints
1380 (exprData_getFcn (data) ) );
1381 /*@i11*/ // exprNodeList_unparse (exprData_getArgs (data) );
1382 break;
1383
1384 case XPR_RETURN:
4ab867d6 1385 ret = constraintList_addListFree (ret,
616915dd 1386 exprNode_traversTrueEnsuresConstraints
1387 (exprData_getSingle (data) ) );
1388 break;
1389
1390 case XPR_NULLRETURN:
1391 // cstring_makeLiteral ("return");;
1392 break;
1393
1394 case XPR_FACCESS:
4ab867d6 1395 ret = constraintList_addListFree (ret,
616915dd 1396 exprNode_traversTrueEnsuresConstraints
1397 (exprData_getFieldNode (data) ) );
1398 //exprData_getFieldName (data) ;
1399 break;
1400
1401 case XPR_ARROW:
4ab867d6 1402 ret = constraintList_addListFree (ret,
616915dd 1403 exprNode_traversTrueEnsuresConstraints
1404 (exprData_getFieldNode (data) ) );
1405 // exprData_getFieldName (data);
1406 break;
1407
1408 case XPR_STRINGLITERAL:
1409 // cstring_copy (exprData_getLiteral (data));
1410 break;
1411
1412 case XPR_NUMLIT:
1413 // cstring_copy (exprData_getLiteral (data));
1414 break;
1415 case XPR_POSTOP:
1416
4ab867d6 1417 ret = constraintList_addListFree (ret,
616915dd 1418 exprNode_traversTrueEnsuresConstraints
1419 (exprData_getUopNode (data) ) );
1420 break;
470b7798 1421
1422 case XPR_CAST:
1423
4ab867d6 1424 ret = constraintList_addListFree (ret,
470b7798 1425 exprNode_traversTrueEnsuresConstraints
1426 (exprData_getCastNode (data) ) );
470b7798 1427 break;
84c9ffbf 1428
616915dd 1429 default:
1430 break;
1431 }
1432
1433 return ret;
1434}
1435
9280addf 1436constraintList exprNode_traversFalseEnsuresConstraints (exprNode e)
1437{
470b7798 1438 exprNode t1;
9280addf 1439
1440 bool handledExprNode;
1441 // char * mes;
1442 exprData data;
1443 constraintList ret;
1444
1445 if (exprNode_handleError (e))
1446 {
c3e695ff 1447 ret = constraintList_makeNew();
9280addf 1448 return ret;
1449 }
1450 ret = constraintList_copy (e->falseEnsuresConstraints );
1451
1452 handledExprNode = TRUE;
1453
1454 data = e->edata;
1455
1456 switch (e->kind)
1457 {
1458 case XPR_WHILEPRED:
1459 t1 = exprData_getSingle (data);
4ab867d6 1460 ret = constraintList_addListFree ( ret,exprNode_traversFalseEnsuresConstraints (t1) );
9280addf 1461 break;
1462
1463 case XPR_FETCH:
1464
4ab867d6 1465 ret = constraintList_addListFree (ret,
9280addf 1466 exprNode_traversFalseEnsuresConstraints
1467 (exprData_getPairA (data) ) );
1468
4ab867d6 1469 ret = constraintList_addListFree (ret,
9280addf 1470 exprNode_traversFalseEnsuresConstraints
1471 (exprData_getPairB (data) ) );
1472 break;
1473 case XPR_PREOP:
1474
4ab867d6 1475 ret = constraintList_addListFree (ret,
9280addf 1476 exprNode_traversFalseEnsuresConstraints
1477 (exprData_getUopNode (data) ) );
1478 break;
1479
1480 case XPR_PARENS:
4ab867d6 1481 ret = constraintList_addListFree (ret, exprNode_traversFalseEnsuresConstraints
9280addf 1482 (exprData_getUopNode (data) ) );
1483 break;
1484 case XPR_ASSIGN:
4ab867d6 1485 ret = constraintList_addListFree (ret,
9280addf 1486 exprNode_traversFalseEnsuresConstraints
1487 (exprData_getOpA (data) ) );
1488
4ab867d6 1489 ret = constraintList_addListFree (ret,
9280addf 1490 exprNode_traversFalseEnsuresConstraints
1491 (exprData_getOpB (data) ) );
1492 break;
1493 case XPR_OP:
4ab867d6 1494 ret = constraintList_addListFree (ret,
9280addf 1495 exprNode_traversFalseEnsuresConstraints
1496 (exprData_getOpA (data) ) );
1497
4ab867d6 1498 ret = constraintList_addListFree (ret,
9280addf 1499 exprNode_traversFalseEnsuresConstraints
1500 (exprData_getOpB (data) ) );
1501 break;
1502 case XPR_SIZEOFT:
1503
1504 // ctype_unparse (qtype_getType (exprData_getType (data) ) );
1505
1506 break;
1507
1508 case XPR_SIZEOF:
1509
4ab867d6 1510 ret = constraintList_addListFree (ret,
9280addf 1511 exprNode_traversFalseEnsuresConstraints
1512 (exprData_getSingle (data) ) );
1513 break;
1514
1515 case XPR_CALL:
4ab867d6 1516 ret = constraintList_addListFree (ret,
9280addf 1517 exprNode_traversFalseEnsuresConstraints
1518 (exprData_getFcn (data) ) );
1519 /*@i11*/ // exprNodeList_unparse (exprData_getArgs (data) );
1520 break;
1521
1522 case XPR_RETURN:
4ab867d6 1523 ret = constraintList_addListFree (ret,
9280addf 1524 exprNode_traversFalseEnsuresConstraints
1525 (exprData_getSingle (data) ) );
1526 break;
1527
1528 case XPR_NULLRETURN:
1529 // cstring_makeLiteral ("return");;
1530 break;
1531
1532 case XPR_FACCESS:
4ab867d6 1533 ret = constraintList_addListFree (ret,
9280addf 1534 exprNode_traversFalseEnsuresConstraints
1535 (exprData_getFieldNode (data) ) );
1536 //exprData_getFieldName (data) ;
1537 break;
1538
1539 case XPR_ARROW:
4ab867d6 1540 ret = constraintList_addListFree (ret,
9280addf 1541 exprNode_traversFalseEnsuresConstraints
1542 (exprData_getFieldNode (data) ) );
1543 // exprData_getFieldName (data);
1544 break;
1545
1546 case XPR_STRINGLITERAL:
1547 // cstring_copy (exprData_getLiteral (data));
1548 break;
1549
1550 case XPR_NUMLIT:
1551 // cstring_copy (exprData_getLiteral (data));
1552 break;
1553 case XPR_POSTOP:
1554
4ab867d6 1555 ret = constraintList_addListFree (ret,
9280addf 1556 exprNode_traversFalseEnsuresConstraints
1557 (exprData_getUopNode (data) ) );
1558 break;
470b7798 1559
1560 case XPR_CAST:
1561
4ab867d6 1562 ret = constraintList_addListFree (ret,
470b7798 1563 exprNode_traversFalseEnsuresConstraints
1564 (exprData_getCastNode (data) ) );
1565 break;
1566
9280addf 1567 default:
1568 break;
1569 }
1570
1571 return ret;
1572}
1573
616915dd 1574
1575/* walk down the tree and get all requires Constraints in each subexpression*/
d46ce6a4 1576/*@only@*/ constraintList exprNode_traversRequiresConstraints (exprNode e)
616915dd 1577{
470b7798 1578 exprNode t1;
616915dd 1579
1580 bool handledExprNode;
1581 // char * mes;
1582 exprData data;
1583 constraintList ret;
1584
1585 if (exprNode_handleError (e))
1586 {
c3e695ff 1587 ret = constraintList_makeNew();
616915dd 1588 return ret;
1589 }
1590 ret = constraintList_copy (e->requiresConstraints );
1591
1592 handledExprNode = TRUE;
1593
1594 data = e->edata;
1595
1596 switch (e->kind)
1597 {
9280addf 1598 case XPR_WHILEPRED:
1599 t1 = exprData_getSingle (data);
4ab867d6 1600 ret = constraintList_addListFree ( ret, exprNode_traversRequiresConstraints (t1) );
9280addf 1601 break;
616915dd 1602
1603 case XPR_FETCH:
1604
4ab867d6 1605 ret = constraintList_addListFree (ret,
616915dd 1606 exprNode_traversRequiresConstraints
1607 (exprData_getPairA (data) ) );
1608
4ab867d6 1609 ret = constraintList_addListFree (ret,
616915dd 1610 exprNode_traversRequiresConstraints
1611 (exprData_getPairB (data) ) );
1612 break;
1613 case XPR_PREOP:
1614
4ab867d6 1615 ret = constraintList_addListFree (ret,
616915dd 1616 exprNode_traversRequiresConstraints
1617 (exprData_getUopNode (data) ) );
1618 break;
1619
1620 case XPR_PARENS:
4ab867d6 1621 ret = constraintList_addListFree (ret, exprNode_traversRequiresConstraints
616915dd 1622 (exprData_getUopNode (data) ) );
1623 break;
1624 case XPR_ASSIGN:
4ab867d6 1625 ret = constraintList_addListFree (ret,
616915dd 1626 exprNode_traversRequiresConstraints
1627 (exprData_getOpA (data) ) );
1628
4ab867d6 1629 ret = constraintList_addListFree (ret,
616915dd 1630 exprNode_traversRequiresConstraints
1631 (exprData_getOpB (data) ) );
1632 break;
1633 case XPR_OP:
4ab867d6 1634 ret = constraintList_addListFree (ret,
616915dd 1635 exprNode_traversRequiresConstraints
1636 (exprData_getOpA (data) ) );
1637
4ab867d6 1638 ret = constraintList_addListFree (ret,
616915dd 1639 exprNode_traversRequiresConstraints
1640 (exprData_getOpB (data) ) );
1641 break;
1642 case XPR_SIZEOFT:
1643
1644 // ctype_unparse (qtype_getType (exprData_getType (data) ) );
1645
1646 break;
1647
1648 case XPR_SIZEOF:
1649
4ab867d6 1650 ret = constraintList_addListFree (ret,
616915dd 1651 exprNode_traversRequiresConstraints
1652 (exprData_getSingle (data) ) );
1653 break;
1654
1655 case XPR_CALL:
4ab867d6 1656 ret = constraintList_addListFree (ret,
616915dd 1657 exprNode_traversRequiresConstraints
1658 (exprData_getFcn (data) ) );
1659 /*@i11*/ // exprNodeList_unparse (exprData_getArgs (data) );
1660 break;
1661
1662 case XPR_RETURN:
4ab867d6 1663 ret = constraintList_addListFree (ret,
616915dd 1664 exprNode_traversRequiresConstraints
1665 (exprData_getSingle (data) ) );
1666 break;
1667
1668 case XPR_NULLRETURN:
1669 // cstring_makeLiteral ("return");;
1670 break;
1671
1672 case XPR_FACCESS:
4ab867d6 1673 ret = constraintList_addListFree (ret,
616915dd 1674 exprNode_traversRequiresConstraints
1675 (exprData_getFieldNode (data) ) );
1676 //exprData_getFieldName (data) ;
1677 break;
1678
1679 case XPR_ARROW:
4ab867d6 1680 ret = constraintList_addListFree (ret,
616915dd 1681 exprNode_traversRequiresConstraints
1682 (exprData_getFieldNode (data) ) );
1683 // exprData_getFieldName (data);
1684 break;
1685
1686 case XPR_STRINGLITERAL:
1687 // cstring_copy (exprData_getLiteral (data));
1688 break;
1689
1690 case XPR_NUMLIT:
1691 // cstring_copy (exprData_getLiteral (data));
1692 break;
1693 case XPR_POSTOP:
1694
4ab867d6 1695 ret = constraintList_addListFree (ret,
616915dd 1696 exprNode_traversRequiresConstraints
1697 (exprData_getUopNode (data) ) );
1698 break;
470b7798 1699
1700 case XPR_CAST:
1701
4ab867d6 1702 ret = constraintList_addListFree (ret,
470b7798 1703 exprNode_traversRequiresConstraints
1704 (exprData_getCastNode (data) ) );
1705 break;
1706
616915dd 1707 default:
1708 break;
1709 }
1710
1711 return ret;
1712}
1713
1714
1715/* walk down the tree and get all Ensures Constraints in each subexpression*/
d46ce6a4 1716/*@only@*/ constraintList exprNode_traversEnsuresConstraints (exprNode e)
616915dd 1717{
470b7798 1718 exprNode t1;
616915dd 1719
1720 bool handledExprNode;
1721 // char * mes;
1722 exprData data;
1723 // constraintExpr tmp;
1724 // constraint cons;
1725 constraintList ret;
1726
1727
1728 if (exprNode_handleError (e))
1729 {
c3e695ff 1730 ret = constraintList_makeNew();
616915dd 1731 return ret;
1732 }
1733
1734 ret = constraintList_copy (e->ensuresConstraints );
1735 handledExprNode = TRUE;
1736
1737 data = e->edata;
1738
1739 DPRINTF( (message (
1740 "exprnode_traversEnsuresConstraints call for %s with constraintList of %s",
1741 exprNode_unparse (e),
1742 constraintList_print(e->ensuresConstraints)
1743 )
1744 ));
1745
1746
1747 switch (e->kind)
1748 {
9280addf 1749 case XPR_WHILEPRED:
1750 t1 = exprData_getSingle (data);
4ab867d6 1751 ret = constraintList_addListFree ( ret,exprNode_traversEnsuresConstraints (t1) );
9280addf 1752 break;
616915dd 1753
1754 case XPR_FETCH:
1755
4ab867d6 1756 ret = constraintList_addListFree (ret,
616915dd 1757 exprNode_traversEnsuresConstraints
1758 (exprData_getPairA (data) ) );
1759
4ab867d6 1760 ret = constraintList_addListFree (ret,
616915dd 1761 exprNode_traversEnsuresConstraints
1762 (exprData_getPairB (data) ) );
1763 break;
1764 case XPR_PREOP:
1765
4ab867d6 1766 ret = constraintList_addListFree (ret,
616915dd 1767 exprNode_traversEnsuresConstraints
1768 (exprData_getUopNode (data) ) );
1769 break;
1770
1771 case XPR_PARENS:
4ab867d6 1772 ret = constraintList_addListFree (ret, exprNode_traversEnsuresConstraints
616915dd 1773 (exprData_getUopNode (data) ) );
1774 break;
1775 case XPR_ASSIGN:
4ab867d6 1776 ret = constraintList_addListFree (ret,
616915dd 1777 exprNode_traversEnsuresConstraints
1778 (exprData_getOpA (data) ) );
1779
4ab867d6 1780 ret = constraintList_addListFree (ret,
616915dd 1781 exprNode_traversEnsuresConstraints
1782 (exprData_getOpB (data) ) );
1783 break;
1784 case XPR_OP:
4ab867d6 1785 ret = constraintList_addListFree (ret,
616915dd 1786 exprNode_traversEnsuresConstraints
1787 (exprData_getOpA (data) ) );
1788
4ab867d6 1789 ret = constraintList_addListFree (ret,
616915dd 1790 exprNode_traversEnsuresConstraints
1791 (exprData_getOpB (data) ) );
1792 break;
1793 case XPR_SIZEOFT:
1794
1795 // ctype_unparse (qtype_getType (exprData_getType (data) ) );
1796
1797 break;
1798
1799 case XPR_SIZEOF:
1800
4ab867d6 1801 ret = constraintList_addListFree (ret,
616915dd 1802 exprNode_traversEnsuresConstraints
1803 (exprData_getSingle (data) ) );
1804 break;
1805
1806 case XPR_CALL:
4ab867d6 1807 ret = constraintList_addListFree (ret,
616915dd 1808 exprNode_traversEnsuresConstraints
1809 (exprData_getFcn (data) ) );
1810 /*@i11*/ // exprNodeList_unparse (exprData_getArgs (data) );
1811 break;
1812
1813 case XPR_RETURN:
4ab867d6 1814 ret = constraintList_addListFree (ret,
616915dd 1815 exprNode_traversEnsuresConstraints
1816 (exprData_getSingle (data) ) );
1817 break;
1818
1819 case XPR_NULLRETURN:
1820 // cstring_makeLiteral ("return");;
1821 break;
1822
1823 case XPR_FACCESS:
4ab867d6 1824 ret = constraintList_addListFree (ret,
616915dd 1825 exprNode_traversEnsuresConstraints
1826 (exprData_getFieldNode (data) ) );
1827 //exprData_getFieldName (data) ;
1828 break;
1829
1830 case XPR_ARROW:
4ab867d6 1831 ret = constraintList_addListFree (ret,
616915dd 1832 exprNode_traversEnsuresConstraints
1833 (exprData_getFieldNode (data) ) );
1834 // exprData_getFieldName (data);
1835 break;
1836
1837 case XPR_STRINGLITERAL:
1838 // cstring_copy (exprData_getLiteral (data));
1839 break;
1840
1841 case XPR_NUMLIT:
1842 // cstring_copy (exprData_getLiteral (data));
1843 break;
1844 case XPR_POSTOP:
1845
4ab867d6 1846 ret = constraintList_addListFree (ret,
616915dd 1847 exprNode_traversEnsuresConstraints
1848 (exprData_getUopNode (data) ) );
1849 break;
470b7798 1850 case XPR_CAST:
1851
4ab867d6 1852 ret = constraintList_addListFree (ret,
470b7798 1853 exprNode_traversEnsuresConstraints
1854 (exprData_getCastNode (data) ) );
1855 break;
1856
616915dd 1857 default:
1858 break;
1859 }
1860DPRINTF( (message (
1861 "exprnode_traversEnsuresConstraints call for %s with constraintList of is returning %s",
1862 exprNode_unparse (e),
1863 // constraintList_print(e->ensuresConstraints),
1864 constraintList_print(ret)
1865 )
1866 ));
1867
1868
1869 return ret;
1870}
1871
This page took 0.647094 seconds and 5 git commands to generate.