6 # include <ctype.h> /* for isdigit */
7 # include "lclintMacros.nf"
10 # include "cgrammar_tokens.h"
12 # include "exprChecks.h"
13 # include "aliasChecks.h"
14 # include "exprNodeSList.h"
15 # include "exprData.i"
17 void /*@alt bool@*/ exprNode_generateConstraints (/*@temp@*/ exprNode e);
18 static bool exprNode_handleError( exprNode p_e);
20 //static cstring exprNode_findConstraints ( exprNode p_e);
21 static bool exprNode_isMultiStatement(exprNode p_e);
22 static bool exprNode_multiStatement (exprNode p_e);
23 bool exprNode_exprTraverse (exprNode e, bool definatelv, bool definaterv, fileloc sequencePoint);
24 //static void exprNode_constraintPropagateUp (exprNode p_e);
25 constraintList exprNode_traversRequiresConstraints (exprNode e);
26 constraintList exprNode_traversEnsuresConstraints (exprNode e);
27 void mergeResolve (exprNode parent, exprNode child1, exprNode child2);
31 bool exprNode_isUnhandled (exprNode e)
33 llassert( exprNode_isDefined(e) );
62 DPRINTF((message ("Warning current constraint generation does not handle expression %s", exprNode_unparse(e)) ) );
74 bool exprNode_handleError( exprNode e)
76 if (exprNode_isError (e) || !exprNode_isUnhandled(e) )
78 static /*@only@*/ cstring error = cstring_undefined;
80 if (!cstring_isDefined (error))
82 error = cstring_makeLiteral ("<error>");
85 /*@-unqualifiedtrans*/ return TRUE; /*@=unqualifiedtrans*/
90 void /*@alt bool@*/ exprNode_generateConstraints (/*@temp@*/ exprNode e)
92 DPRINTF((message ("exprNode_gnerateConstraints Analysising %s %s at", exprNode_unparse( e),
93 fileloc_unparse(exprNode_getfileloc(e) ) ) ) );
95 if (exprNode_isMultiStatement ( e) )
97 exprNode_multiStatement(e);
103 printf ("%s", (message ("%s", constraintList_printDetailed (e->requiresConstraints) ) ) );
104 printf ("%s", (message ("%s", constraintList_printDetailed (e->ensuresConstraints) ) ) );
109 /* handles multiple statements */
111 bool exprNode_isMultiStatement(exprNode e)
113 if (exprNode_handleError (e) != NULL)
135 bool exprNode_stmt (exprNode e)
141 if (exprNode_isError(e) )
145 e->requiresConstraints = constraintList_new();
146 e->ensuresConstraints = constraintList_new();
149 DPRINTF(( "STMT:") );
150 DPRINTF ( ( cstring_toCharsSafe ( exprNode_unparse(e)) )
152 if (e->kind != XPR_STMT)
155 DPRINTF (("Not Stmt") );
156 DPRINTF ( (message ("%s ", exprNode_unparse (e)) ) );
157 if (exprNode_isMultiStatement (e) )
159 return exprNode_multiStatement (e );
165 DPRINTF ( (message ("%s ", exprNode_unparse (e)) ) );
167 snode = exprData_getUopNode (e->edata);
169 /* could be stmt involving multiple statements:
170 i.e. if, while for ect.
173 if (exprNode_isMultiStatement (snode))
176 return exprNode_multiStatement (snode);
179 loc = exprNode_getNextSequencePoint(e); /* reduces to an expression */
180 notError = exprNode_exprTraverse (snode, FALSE, FALSE, loc);
181 e->requiresConstraints = exprNode_traversRequiresConstraints(snode);
182 // printf ("%s\n", constraintList_print(e->requiresConstraints) );
183 e->ensuresConstraints = exprNode_traversEnsuresConstraints(snode);
184 // printf ("Ensures that:\n %s\n", constraintList_print(e->ensuresConstraints) );
191 bool exprNode_stmtList (exprNode e)
193 exprNode stmt1, stmt2;
194 if (exprNode_isError (e) )
199 e->requiresConstraints = constraintList_new();
200 e->ensuresConstraints = constraintList_new();
202 /*Handle case of stmtList with only one statement:
203 The parse tree stores this as stmt instead of stmtList*/
204 if (e->kind != XPR_STMTLIST)
206 return exprNode_stmt(e);
208 llassert (e->kind == XPR_STMTLIST);
209 DPRINTF(( "STMTLIST:") );
210 DPRINTF ((cstring_toCharsSafe (exprNode_unparse(e)) ) );
211 stmt1 = exprData_getPairA (e->edata);
212 stmt2 = exprData_getPairB (e->edata);
215 DPRINTF(("XW stmtlist ") );
216 DPRINTF ((message("XW%s | %s", exprNode_unparse(stmt1), exprNode_unparse(stmt2) ) ) );
218 exprNode_stmt (stmt1);
219 DPRINTF(("\nstmt after stmtList call " ));
221 exprNode_stmt (stmt2);
222 mergeResolve (e, stmt1, stmt2 );
223 DPRINTF ( (message ("smtlist constraints are: pre: %s \n and \t post %s\n",
224 constraintList_print(e->requiresConstraints),
225 constraintList_print(e->ensuresConstraints) ) ) );
230 bool exprNode_multiStatement (exprNode e)
237 DPRINTF((message ("exprNode_multistatement Analysising %s %s at", exprNode_unparse( e),
238 fileloc_unparse(exprNode_getfileloc(e) ) ) ) );
240 if (exprNode_handleError (e))
253 // ret = message ("%s %s",
254 exprNode_generateConstraints (exprData_getPairA (data));
255 exprNode_generateConstraints (exprData_getPairB (data));
259 // ret = message ("for (%s; %s; %s)",
260 exprNode_generateConstraints (exprData_getTripleInit (data));
261 exprNode_generateConstraints (exprData_getTripleTest (data));
262 exprNode_generateConstraints (exprData_getTripleInc (data));
266 DPRINTF ((exprNode_unparse(e) ) );
267 // ret = message ("if (%s) %s",
268 exprNode_generateConstraints (exprData_getPairA (data));
269 exprNode_generateConstraints (exprData_getPairB (data));
270 // e->constraints = constraintList_exprNodemerge (exprData_getPairA (data),exprData_getPairB(data));
274 // ret = message ("if (%s) %s else %s",
275 exprNode_generateConstraints (exprData_getTriplePred (data));
276 exprNode_generateConstraints (exprData_getTripleTrue (data));
277 exprNode_generateConstraints (exprData_getTripleFalse (data));
280 // ret = message ("while (%s) %s",
281 exprNode_generateConstraints (exprData_getPairA (data));
282 exprNode_generateConstraints (exprData_getPairB (data));
283 // e->constraints = constraintList_exprNodemerge (exprData_getPairA (data), exprData_getPairB (data) );
289 exprNode_generateConstraints (exprData_getSingle (data));
293 // ret = message ("do { %s } while (%s)",
294 exprNode_generateConstraints (exprData_getPairB (data));
295 exprNode_generateConstraints (exprData_getPairA (data));
299 // ret = message ("{ %s }",
300 exprNode_generateConstraints (exprData_getSingle (data));
301 e->requiresConstraints = constraintList_copy ( (exprData_getSingle (data))->requiresConstraints );
302 e->ensuresConstraints = constraintList_copy ( (exprData_getSingle (data))->ensuresConstraints );
303 // e->constraints = (exprData_getSingle (data))->constraints;
308 return exprNode_stmtList (e);
318 bool exprNode_exprTraverse (exprNode e, bool definatelv, bool definaterv, fileloc sequencePoint)
322 bool handledExprNode;
326 DPRINTF((message ("exprNode_exprTraverset Analysising %s %s at", exprNode_unparse( e),
327 fileloc_unparse(exprNode_getfileloc(e) ) ) ) );
329 e->requiresConstraints = constraintList_new();
330 e->ensuresConstraints = constraintList_new();
332 if (exprNode_handleError (e))
337 handledExprNode = TRUE;
348 t1 = (exprData_getPairA (data) );
349 t2 = (exprData_getPairB (data) );
350 cons = constraint_makeWriteSafeExprNode (t1, t2);
354 t1 = (exprData_getPairA (data) );
355 t2 = (exprData_getPairB (data) );
356 cons = constraint_makeReadSafeExprNode (t1, t2 );
359 e->requiresConstraints = constraintList_add(e->requiresConstraints, cons);
360 cons = constraint_makeEnsureMaxReadAtLeast (t1, t2, sequencePoint);
361 e->ensuresConstraints = constraintList_add(e->ensuresConstraints, cons);
362 // cons = constraint_makeEnsureMinReadAtMost (t1, t2, sequencePoint);
363 // e->ensuresConstraints = constraintList_add(e->ensuresConstraints, cons);
365 exprNode_exprTraverse (exprData_getPairA (data), FALSE, TRUE, sequencePoint);
366 exprNode_exprTraverse (exprData_getPairB (data), FALSE, TRUE, sequencePoint);
368 /*@i325 Should check which is array/index. */
371 t1 = exprData_getUopNode(data);
372 lltok_unparse (exprData_getUopTok (data));
373 exprNode_exprTraverse (exprData_getUopNode (data), definatelv, definaterv, sequencePoint );
374 /*handle * pointer access */
376 /*@ i 325 do ++ and -- */
377 if (lltok_isMult( exprData_getUopTok (data) ) )
381 cons = constraint_makeWriteSafeInt (t1, 0);
385 cons = constraint_makeReadSafeInt (t1, 0);
387 e->requiresConstraints = constraintList_add(e->requiresConstraints, cons);
389 if (lltok_isInc_Op (exprData_getUopTok (data) ) )
391 // cons = constraint_makeSideEffectPostIncrement (t1, sequencePoint);
392 // e->ensuresConstraints = constraintList_add(e->requiresConstraints, cons);
397 exprNode_exprTraverse (exprData_getUopNode (e->edata), definatelv, definaterv, sequencePoint);
398 // e->constraints = constraintList_exprNodemerge (exprData_getUopNode (e->edata), exprNode_undefined);
401 exprNode_exprTraverse (exprData_getOpA (data), TRUE, definaterv, sequencePoint );
402 lltok_unparse (exprData_getOpTok (data));
403 exprNode_exprTraverse (exprData_getOpB (data), definatelv, TRUE, sequencePoint );
404 // e->constraints = constraintList_exprNodemerge (exprData_getOpA (data), exprData_getOpB (data) );
407 exprNode_exprTraverse (exprData_getOpA (data), definatelv, definaterv, sequencePoint );
408 lltok_unparse (exprData_getOpTok (data));
409 exprNode_exprTraverse (exprData_getOpB (data), definatelv, definaterv, sequencePoint );
411 // e->constraints = constraintList_exprNodemerge (exprData_getOpA (data), exprData_getOpB (data));
414 ctype_unparse (qtype_getType (exprData_getType (data) ) );
419 exprNode_exprTraverse (exprData_getSingle (data), definatelv, definaterv, sequencePoint );
420 // e->constraints = constraintList_exprNodemerge (exprData_getSingle (e->edata), exprNode_undefined);
424 exprNode_exprTraverse (exprData_getFcn (data), definatelv, definaterv, sequencePoint );
425 exprNodeList_unparse (exprData_getArgs (data) );
426 // e->constraints = constraintList_add (e->constraints, constraint_create (e,exprNode_undefined, GT, CALLSAFE ) );
430 exprNode_exprTraverse (exprData_getSingle (data), definatelv, definaterv, sequencePoint );
434 cstring_makeLiteral ("return");;
439 exprNode_exprTraverse (exprData_getFieldNode (data), definatelv, definaterv, sequencePoint );
440 exprData_getFieldName (data) ;
444 exprNode_exprTraverse (exprData_getFieldNode (data), definatelv, definaterv, sequencePoint );
445 exprData_getFieldName (data);
448 case XPR_STRINGLITERAL:
449 cstring_copy (exprData_getLiteral (data));
453 cstring_copy (exprData_getLiteral (data));
457 exprNode_exprTraverse (exprData_getUopNode (data), TRUE, definaterv, sequencePoint );
458 lltok_unparse (exprData_getUopTok (data));
459 if (lltok_isInc_Op (exprData_getUopTok (data) ) )
461 DPRINTF(("doing ++"));
462 t1 = exprData_getUopNode (data);
463 cons = constraint_makeMaxSetSideEffectPostIncrement (t1, sequencePoint );
464 e->ensuresConstraints = constraintList_add (e->ensuresConstraints, cons);
465 // cons = constraint_makeMaxReadSideEffectPostIncrement (t1, sequencePoint );
466 //e->ensuresConstraints = constraintList_add (e->ensuresConstraints, cons);
470 handledExprNode = FALSE;
473 e->requiresConstraints = constraintList_preserveOrig ( e->requiresConstraints);
474 e->ensuresConstraints = constraintList_preserveOrig ( e->ensuresConstraints);
476 return handledExprNode;
479 /* walk down the tree and get all requires Constraints in each subexpression*/
480 constraintList exprNode_traversRequiresConstraints (exprNode e)
484 bool handledExprNode;
488 ret = constraintList_copy (e->requiresConstraints );
489 if (exprNode_handleError (e))
494 handledExprNode = TRUE;
503 ret = constraintList_addList (ret,
504 exprNode_traversRequiresConstraints
505 (exprData_getPairA (data) ) );
507 ret = constraintList_addList (ret,
508 exprNode_traversRequiresConstraints
509 (exprData_getPairB (data) ) );
513 ret = constraintList_addList (ret,
514 exprNode_traversRequiresConstraints
515 (exprData_getUopNode (data) ) );
519 ret = constraintList_addList (ret, exprNode_traversRequiresConstraints
520 (exprData_getUopNode (data) ) );
523 ret = constraintList_addList (ret,
524 exprNode_traversRequiresConstraints
525 (exprData_getOpA (data) ) );
527 ret = constraintList_addList (ret,
528 exprNode_traversRequiresConstraints
529 (exprData_getOpB (data) ) );
532 ret = constraintList_addList (ret,
533 exprNode_traversRequiresConstraints
534 (exprData_getOpA (data) ) );
536 ret = constraintList_addList (ret,
537 exprNode_traversRequiresConstraints
538 (exprData_getOpB (data) ) );
542 // ctype_unparse (qtype_getType (exprData_getType (data) ) );
548 ret = constraintList_addList (ret,
549 exprNode_traversRequiresConstraints
550 (exprData_getSingle (data) ) );
554 ret = constraintList_addList (ret,
555 exprNode_traversRequiresConstraints
556 (exprData_getFcn (data) ) );
557 /*@i11*/ // exprNodeList_unparse (exprData_getArgs (data) );
561 ret = constraintList_addList (ret,
562 exprNode_traversRequiresConstraints
563 (exprData_getSingle (data) ) );
567 // cstring_makeLiteral ("return");;
571 ret = constraintList_addList (ret,
572 exprNode_traversRequiresConstraints
573 (exprData_getFieldNode (data) ) );
574 //exprData_getFieldName (data) ;
578 ret = constraintList_addList (ret,
579 exprNode_traversRequiresConstraints
580 (exprData_getFieldNode (data) ) );
581 // exprData_getFieldName (data);
584 case XPR_STRINGLITERAL:
585 // cstring_copy (exprData_getLiteral (data));
589 // cstring_copy (exprData_getLiteral (data));
593 ret = constraintList_addList (ret,
594 exprNode_traversRequiresConstraints
595 (exprData_getUopNode (data) ) );
605 /* walk down the tree and get all Ensures Constraints in each subexpression*/
606 constraintList exprNode_traversEnsuresConstraints (exprNode e)
610 bool handledExprNode;
613 // constraintExpr tmp;
616 ret = constraintList_copy (e->ensuresConstraints );
617 if (exprNode_handleError (e))
622 handledExprNode = TRUE;
627 "exprnode_traversEnsuresConstraints call for %s with constraintList of %s",
628 exprNode_unparse (e),
629 constraintList_print(e->ensuresConstraints)
639 ret = constraintList_addList (ret,
640 exprNode_traversEnsuresConstraints
641 (exprData_getPairA (data) ) );
643 ret = constraintList_addList (ret,
644 exprNode_traversEnsuresConstraints
645 (exprData_getPairB (data) ) );
649 ret = constraintList_addList (ret,
650 exprNode_traversEnsuresConstraints
651 (exprData_getUopNode (data) ) );
655 ret = constraintList_addList (ret, exprNode_traversEnsuresConstraints
656 (exprData_getUopNode (data) ) );
659 ret = constraintList_addList (ret,
660 exprNode_traversEnsuresConstraints
661 (exprData_getOpA (data) ) );
663 ret = constraintList_addList (ret,
664 exprNode_traversEnsuresConstraints
665 (exprData_getOpB (data) ) );
668 ret = constraintList_addList (ret,
669 exprNode_traversEnsuresConstraints
670 (exprData_getOpA (data) ) );
672 ret = constraintList_addList (ret,
673 exprNode_traversEnsuresConstraints
674 (exprData_getOpB (data) ) );
678 // ctype_unparse (qtype_getType (exprData_getType (data) ) );
684 ret = constraintList_addList (ret,
685 exprNode_traversEnsuresConstraints
686 (exprData_getSingle (data) ) );
690 ret = constraintList_addList (ret,
691 exprNode_traversEnsuresConstraints
692 (exprData_getFcn (data) ) );
693 /*@i11*/ // exprNodeList_unparse (exprData_getArgs (data) );
697 ret = constraintList_addList (ret,
698 exprNode_traversEnsuresConstraints
699 (exprData_getSingle (data) ) );
703 // cstring_makeLiteral ("return");;
707 ret = constraintList_addList (ret,
708 exprNode_traversEnsuresConstraints
709 (exprData_getFieldNode (data) ) );
710 //exprData_getFieldName (data) ;
714 ret = constraintList_addList (ret,
715 exprNode_traversEnsuresConstraints
716 (exprData_getFieldNode (data) ) );
717 // exprData_getFieldName (data);
720 case XPR_STRINGLITERAL:
721 // cstring_copy (exprData_getLiteral (data));
725 // cstring_copy (exprData_getLiteral (data));
729 ret = constraintList_addList (ret,
730 exprNode_traversEnsuresConstraints
731 (exprData_getUopNode (data) ) );
737 "exprnode_traversEnsuresConstraints call for %s with constraintList of is returning %s",
738 exprNode_unparse (e),
739 // constraintList_print(e->ensuresConstraints),
740 constraintList_print(ret)