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 ("For: %s \n", exprNode_unparse (e) );
183 printf ("%s\n", constraintList_print(e->requiresConstraints) );
184 e->ensuresConstraints = exprNode_traversEnsuresConstraints(snode);
185 printf ("Ensures that:\n %s\n", constraintList_print(e->ensuresConstraints) );
192 bool exprNode_stmtList (exprNode e)
194 exprNode stmt1, stmt2;
195 if (exprNode_isError (e) )
200 e->requiresConstraints = constraintList_new();
201 e->ensuresConstraints = constraintList_new();
203 /*Handle case of stmtList with only one statement:
204 The parse tree stores this as stmt instead of stmtList*/
205 if (e->kind != XPR_STMTLIST)
207 return exprNode_stmt(e);
209 llassert (e->kind == XPR_STMTLIST);
210 DPRINTF(( "STMTLIST:") );
211 DPRINTF ((cstring_toCharsSafe (exprNode_unparse(e)) ) );
212 stmt1 = exprData_getPairA (e->edata);
213 stmt2 = exprData_getPairB (e->edata);
216 DPRINTF(("XW stmtlist ") );
217 DPRINTF ((message("XW%s | %s", exprNode_unparse(stmt1), exprNode_unparse(stmt2) ) ) );
219 exprNode_stmt (stmt1);
220 DPRINTF(("\nstmt after stmtList call " ));
222 exprNode_stmt (stmt2);
223 mergeResolve (e, stmt1, stmt2 );
225 DPRINTF ( (message ("smtlist constraints are: pre: %s \n and \t post %s\n",
226 constraintList_print(e->requiresConstraints),
227 constraintList_print(e->ensuresConstraints) ) ) );
232 bool exprNode_multiStatement (exprNode e)
239 DPRINTF((message ("exprNode_multistatement Analysising %s %s at", exprNode_unparse( e),
240 fileloc_unparse(exprNode_getfileloc(e) ) ) ) );
242 if (exprNode_handleError (e))
255 // ret = message ("%s %s",
256 exprNode_generateConstraints (exprData_getPairA (data));
257 exprNode_generateConstraints (exprData_getPairB (data));
261 // ret = message ("for (%s; %s; %s)",
262 exprNode_generateConstraints (exprData_getTripleInit (data));
263 exprNode_generateConstraints (exprData_getTripleTest (data));
264 exprNode_generateConstraints (exprData_getTripleInc (data));
268 DPRINTF ((exprNode_unparse(e) ) );
269 // ret = message ("if (%s) %s",
270 exprNode_generateConstraints (exprData_getPairA (data));
271 exprNode_generateConstraints (exprData_getPairB (data));
272 // e->constraints = constraintList_exprNodemerge (exprData_getPairA (data),exprData_getPairB(data));
276 // ret = message ("if (%s) %s else %s",
277 exprNode_generateConstraints (exprData_getTriplePred (data));
278 exprNode_generateConstraints (exprData_getTripleTrue (data));
279 exprNode_generateConstraints (exprData_getTripleFalse (data));
282 // ret = message ("while (%s) %s",
283 exprNode_generateConstraints (exprData_getPairA (data));
284 exprNode_generateConstraints (exprData_getPairB (data));
285 // e->constraints = constraintList_exprNodemerge (exprData_getPairA (data), exprData_getPairB (data) );
291 exprNode_generateConstraints (exprData_getSingle (data));
295 // ret = message ("do { %s } while (%s)",
296 exprNode_generateConstraints (exprData_getPairB (data));
297 exprNode_generateConstraints (exprData_getPairA (data));
301 // ret = message ("{ %s }",
302 exprNode_generateConstraints (exprData_getSingle (data));
303 e->requiresConstraints = constraintList_copy ( (exprData_getSingle (data))->requiresConstraints );
304 e->ensuresConstraints = constraintList_copy ( (exprData_getSingle (data))->ensuresConstraints );
305 // e->constraints = (exprData_getSingle (data))->constraints;
310 return exprNode_stmtList (e);
320 bool exprNode_exprTraverse (exprNode e, bool definatelv, bool definaterv, fileloc sequencePoint)
324 bool handledExprNode;
328 DPRINTF((message ("exprNode_exprTraverset Analysising %s %s at", exprNode_unparse( e),
329 fileloc_unparse(exprNode_getfileloc(e) ) ) ) );
331 e->requiresConstraints = constraintList_new();
332 e->ensuresConstraints = constraintList_new();
334 if (exprNode_handleError (e))
339 handledExprNode = TRUE;
350 t1 = (exprData_getPairA (data) );
351 t2 = (exprData_getPairB (data) );
352 cons = constraint_makeWriteSafeExprNode (t1, t2);
356 t1 = (exprData_getPairA (data) );
357 t2 = (exprData_getPairB (data) );
358 cons = constraint_makeReadSafeExprNode (t1, t2 );
361 e->requiresConstraints = constraintList_add(e->requiresConstraints, cons);
362 cons = constraint_makeEnsureMaxReadAtLeast (t1, t2, sequencePoint);
363 e->ensuresConstraints = constraintList_add(e->ensuresConstraints, cons);
364 // cons = constraint_makeEnsureMinReadAtMost (t1, t2, sequencePoint);
365 // e->ensuresConstraints = constraintList_add(e->ensuresConstraints, cons);
367 exprNode_exprTraverse (exprData_getPairA (data), FALSE, TRUE, sequencePoint);
368 exprNode_exprTraverse (exprData_getPairB (data), FALSE, TRUE, sequencePoint);
370 /*@i325 Should check which is array/index. */
373 t1 = exprData_getUopNode(data);
374 lltok_unparse (exprData_getUopTok (data));
375 exprNode_exprTraverse (exprData_getUopNode (data), definatelv, definaterv, sequencePoint );
376 /*handle * pointer access */
378 /*@ i 325 do ++ and -- */
379 if (lltok_isMult( exprData_getUopTok (data) ) )
383 cons = constraint_makeWriteSafeInt (t1, 0);
387 cons = constraint_makeReadSafeInt (t1, 0);
389 e->requiresConstraints = constraintList_add(e->requiresConstraints, cons);
391 if (lltok_isInc_Op (exprData_getUopTok (data) ) )
393 // cons = constraint_makeSideEffectPostIncrement (t1, sequencePoint);
394 // e->ensuresConstraints = constraintList_add(e->requiresConstraints, cons);
399 exprNode_exprTraverse (exprData_getUopNode (e->edata), definatelv, definaterv, sequencePoint);
400 // e->constraints = constraintList_exprNodemerge (exprData_getUopNode (e->edata), exprNode_undefined);
403 exprNode_exprTraverse (exprData_getOpA (data), TRUE, definaterv, sequencePoint );
404 lltok_unparse (exprData_getOpTok (data));
405 exprNode_exprTraverse (exprData_getOpB (data), definatelv, TRUE, sequencePoint );
406 // e->constraints = constraintList_exprNodemerge (exprData_getOpA (data), exprData_getOpB (data) );
409 exprNode_exprTraverse (exprData_getOpA (data), definatelv, definaterv, sequencePoint );
410 lltok_unparse (exprData_getOpTok (data));
411 exprNode_exprTraverse (exprData_getOpB (data), definatelv, definaterv, sequencePoint );
413 // e->constraints = constraintList_exprNodemerge (exprData_getOpA (data), exprData_getOpB (data));
416 ctype_unparse (qtype_getType (exprData_getType (data) ) );
421 exprNode_exprTraverse (exprData_getSingle (data), definatelv, definaterv, sequencePoint );
422 // e->constraints = constraintList_exprNodemerge (exprData_getSingle (e->edata), exprNode_undefined);
426 exprNode_exprTraverse (exprData_getFcn (data), definatelv, definaterv, sequencePoint );
427 exprNodeList_unparse (exprData_getArgs (data) );
428 // e->constraints = constraintList_add (e->constraints, constraint_create (e,exprNode_undefined, GT, CALLSAFE ) );
432 exprNode_exprTraverse (exprData_getSingle (data), definatelv, definaterv, sequencePoint );
436 cstring_makeLiteral ("return");;
441 exprNode_exprTraverse (exprData_getFieldNode (data), definatelv, definaterv, sequencePoint );
442 exprData_getFieldName (data) ;
446 exprNode_exprTraverse (exprData_getFieldNode (data), definatelv, definaterv, sequencePoint );
447 exprData_getFieldName (data);
450 case XPR_STRINGLITERAL:
451 cstring_copy (exprData_getLiteral (data));
455 cstring_copy (exprData_getLiteral (data));
459 exprNode_exprTraverse (exprData_getUopNode (data), TRUE, definaterv, sequencePoint );
460 lltok_unparse (exprData_getUopTok (data));
461 if (lltok_isInc_Op (exprData_getUopTok (data) ) )
463 DPRINTF(("doing ++"));
464 t1 = exprData_getUopNode (data);
465 cons = constraint_makeMaxSetSideEffectPostIncrement (t1, sequencePoint );
466 e->ensuresConstraints = constraintList_add (e->ensuresConstraints, cons);
467 // cons = constraint_makeMaxReadSideEffectPostIncrement (t1, sequencePoint );
468 //e->ensuresConstraints = constraintList_add (e->ensuresConstraints, cons);
472 handledExprNode = FALSE;
475 e->requiresConstraints = constraintList_preserveOrig ( e->requiresConstraints);
476 e->ensuresConstraints = constraintList_preserveOrig ( e->ensuresConstraints);
478 return handledExprNode;
481 /* walk down the tree and get all requires Constraints in each subexpression*/
482 constraintList exprNode_traversRequiresConstraints (exprNode e)
486 bool handledExprNode;
490 ret = constraintList_copy (e->requiresConstraints );
491 if (exprNode_handleError (e))
496 handledExprNode = TRUE;
505 ret = constraintList_addList (ret,
506 exprNode_traversRequiresConstraints
507 (exprData_getPairA (data) ) );
509 ret = constraintList_addList (ret,
510 exprNode_traversRequiresConstraints
511 (exprData_getPairB (data) ) );
515 ret = constraintList_addList (ret,
516 exprNode_traversRequiresConstraints
517 (exprData_getUopNode (data) ) );
521 ret = constraintList_addList (ret, exprNode_traversRequiresConstraints
522 (exprData_getUopNode (data) ) );
525 ret = constraintList_addList (ret,
526 exprNode_traversRequiresConstraints
527 (exprData_getOpA (data) ) );
529 ret = constraintList_addList (ret,
530 exprNode_traversRequiresConstraints
531 (exprData_getOpB (data) ) );
534 ret = constraintList_addList (ret,
535 exprNode_traversRequiresConstraints
536 (exprData_getOpA (data) ) );
538 ret = constraintList_addList (ret,
539 exprNode_traversRequiresConstraints
540 (exprData_getOpB (data) ) );
544 // ctype_unparse (qtype_getType (exprData_getType (data) ) );
550 ret = constraintList_addList (ret,
551 exprNode_traversRequiresConstraints
552 (exprData_getSingle (data) ) );
556 ret = constraintList_addList (ret,
557 exprNode_traversRequiresConstraints
558 (exprData_getFcn (data) ) );
559 /*@i11*/ // exprNodeList_unparse (exprData_getArgs (data) );
563 ret = constraintList_addList (ret,
564 exprNode_traversRequiresConstraints
565 (exprData_getSingle (data) ) );
569 // cstring_makeLiteral ("return");;
573 ret = constraintList_addList (ret,
574 exprNode_traversRequiresConstraints
575 (exprData_getFieldNode (data) ) );
576 //exprData_getFieldName (data) ;
580 ret = constraintList_addList (ret,
581 exprNode_traversRequiresConstraints
582 (exprData_getFieldNode (data) ) );
583 // exprData_getFieldName (data);
586 case XPR_STRINGLITERAL:
587 // cstring_copy (exprData_getLiteral (data));
591 // cstring_copy (exprData_getLiteral (data));
595 ret = constraintList_addList (ret,
596 exprNode_traversRequiresConstraints
597 (exprData_getUopNode (data) ) );
607 /* walk down the tree and get all Ensures Constraints in each subexpression*/
608 constraintList exprNode_traversEnsuresConstraints (exprNode e)
612 bool handledExprNode;
615 // constraintExpr tmp;
618 ret = constraintList_copy (e->ensuresConstraints );
619 if (exprNode_handleError (e))
624 handledExprNode = TRUE;
629 "exprnode_traversEnsuresConstraints call for %s with constraintList of %s",
630 exprNode_unparse (e),
631 constraintList_print(e->ensuresConstraints)
641 ret = constraintList_addList (ret,
642 exprNode_traversEnsuresConstraints
643 (exprData_getPairA (data) ) );
645 ret = constraintList_addList (ret,
646 exprNode_traversEnsuresConstraints
647 (exprData_getPairB (data) ) );
651 ret = constraintList_addList (ret,
652 exprNode_traversEnsuresConstraints
653 (exprData_getUopNode (data) ) );
657 ret = constraintList_addList (ret, exprNode_traversEnsuresConstraints
658 (exprData_getUopNode (data) ) );
661 ret = constraintList_addList (ret,
662 exprNode_traversEnsuresConstraints
663 (exprData_getOpA (data) ) );
665 ret = constraintList_addList (ret,
666 exprNode_traversEnsuresConstraints
667 (exprData_getOpB (data) ) );
670 ret = constraintList_addList (ret,
671 exprNode_traversEnsuresConstraints
672 (exprData_getOpA (data) ) );
674 ret = constraintList_addList (ret,
675 exprNode_traversEnsuresConstraints
676 (exprData_getOpB (data) ) );
680 // ctype_unparse (qtype_getType (exprData_getType (data) ) );
686 ret = constraintList_addList (ret,
687 exprNode_traversEnsuresConstraints
688 (exprData_getSingle (data) ) );
692 ret = constraintList_addList (ret,
693 exprNode_traversEnsuresConstraints
694 (exprData_getFcn (data) ) );
695 /*@i11*/ // exprNodeList_unparse (exprData_getArgs (data) );
699 ret = constraintList_addList (ret,
700 exprNode_traversEnsuresConstraints
701 (exprData_getSingle (data) ) );
705 // cstring_makeLiteral ("return");;
709 ret = constraintList_addList (ret,
710 exprNode_traversEnsuresConstraints
711 (exprData_getFieldNode (data) ) );
712 //exprData_getFieldName (data) ;
716 ret = constraintList_addList (ret,
717 exprNode_traversEnsuresConstraints
718 (exprData_getFieldNode (data) ) );
719 // exprData_getFieldName (data);
722 case XPR_STRINGLITERAL:
723 // cstring_copy (exprData_getLiteral (data));
727 // cstring_copy (exprData_getLiteral (data));
731 ret = constraintList_addList (ret,
732 exprNode_traversEnsuresConstraints
733 (exprData_getUopNode (data) ) );
739 "exprnode_traversEnsuresConstraints call for %s with constraintList of is returning %s",
740 exprNode_unparse (e),
741 // constraintList_print(e->ensuresConstraints),
742 constraintList_print(ret)