2 ** Splint - annotation-assisted static program checker
3 ** Copyright (C) 1994-2002 University of Virginia,
4 ** Massachusetts Institute of Technology
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.
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.
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.
20 ** For information on splint: info@splint.org
21 ** To report a bug: splint-bug@splint.org
22 ** For more information: http://www.splint.org
29 /* #define DEBUGPRINT 1 */
31 # include "splintMacros.nf"
33 # include "cgrammar.h"
34 # include "cgrammar_tokens.h"
36 # include "exprChecks.h"
37 # include "exprNodeSList.h"
43 /*@access exprNode constraintExpr@*/
45 static ctype constraintExpr_getOrigType (constraintExpr p_e);
46 static bool constraintExpr_hasTypeChange(constraintExpr p_e) /*@*/;
48 static /*@only@*/ constraintExpr constraintExpr_makeBinaryOpConstraintExprIntLiteral (/*@only@*/constraintExpr p_expr, int p_literal);
51 /*@only@*/ static constraintExpr
52 doSRefFixInvarConstraintTerm (/*@only@*/ constraintExpr p_e,
53 sRef p_s, ctype p_ct);
55 /*@only@*/ static constraintExpr
56 doSRefFixConstraintParamTerm (/*@only@*/ constraintExpr p_e, /*@temp@*/ /*@observer@*/ exprNodeList p_arglist) /*@modifies p_e@*/;
58 static /*@only@*/ constraintExpr
59 doFixResultTerm (/*@only@*/ constraintExpr p_e, /*@exposed@*/ exprNode p_fcnCall)
62 static bool constraintExpr_canGetCType (constraintExpr p_e) /*@*/;
64 static ctype constraintExpr_getCType (constraintExpr p_e);
66 static /*@only@*/ constraintExpr constraintExpr_adjustMaxSetForCast(/*@only@*/ constraintExpr p_e, ctype p_ct);
68 /*@special@*/ static constraintExpr constraintExpr_makeBinaryOp (void)
69 /* @allocates result->data @ @sets result->kind @ */ ;
71 void constraintExpr_free (/*@only@*/ constraintExpr expr)
73 if (constraintExpr_isDefined(expr) )
78 constraintExprData_freeUnaryExpr(expr->data);
81 constraintExprData_freeBinaryExpr(expr->data);
84 constraintExprData_freeTerm(expr->data);
95 llcontbug(message("attempted to free null pointer in constraintExpr_free"));
99 bool constraintExpr_isLit (constraintExpr expr)
101 llassert (expr != NULL);
103 if (expr->kind == term)
105 constraintTerm term = constraintExprData_termGetTerm (expr->data);
106 if (constraintTerm_isIntLiteral (term) )
115 static bool isZeroBinaryOp (constraintExpr expr)
119 llassert (expr != NULL); /* evans 2001-07-18 */
121 if (!constraintExpr_isBinaryExpr (expr) )
127 e2 = constraintExprData_binaryExprGetExpr2(expr->data);
129 llassert (e2 != NULL); /* evans 2001-07-18 */
131 if (constraintExpr_isBinaryExpr (e2) )
134 constraintExprBinaryOpKind op;
136 op = constraintExprData_binaryExprGetOp (e2->data);
138 e1 = constraintExprData_binaryExprGetExpr1(e2->data);
140 if (constraintExpr_isLit(e1) )
142 if (constraintExpr_getValue(e1) == 0 )
151 /* change expr + (o - expr) to (expr -expr) */
153 /*@only@*/ static constraintExpr removeZero (/*@only@*/ /*@returned@*/ constraintExpr expr)
155 constraintExpr expr1, expr2;
159 constraintExprBinaryOpKind op;
161 constraintExprBinaryOpKind tempOp;
163 if (!isZeroBinaryOp(expr) )
166 llassert (expr != NULL); /* evans 2001-07-18 */
168 expr1 = constraintExprData_binaryExprGetExpr1(expr->data);
169 expr2 = constraintExprData_binaryExprGetExpr2(expr->data);
170 op = constraintExprData_binaryExprGetOp(expr->data);
172 llassert( constraintExpr_isBinaryExpr(expr2) );
174 temp = constraintExprData_binaryExprGetExpr2 (expr2->data);
175 temp = constraintExpr_copy (temp);
177 tempOp = constraintExprData_binaryExprGetOp (expr2->data);
179 if (op == BINARYOP_PLUS)
181 else if (op == BINARYOP_MINUS)
183 if (tempOp == BINARYOP_PLUS)
185 else if (tempOp == BINARYOP_MINUS)
193 expr->data = constraintExprData_binaryExprSetExpr2(expr->data, temp);
194 expr->data = constraintExprData_binaryExprSetOp(expr->data, op);
200 /*@only@*/ constraintExpr constraintExpr_propagateConstants (/*@only@*/ constraintExpr expr,
201 /*@out@*/ bool * propagate,
202 /*@out@*/ int *literal)
204 constraintExpr expr1;
205 constraintExpr expr2;
206 bool propagate1, propagate2;
207 int literal1, literal2;
208 constraintExprBinaryOpKind op;
220 llassert (expr != NULL);
222 /* we simplify unaryExpr elsewhere */
223 if (expr->kind != binaryexpr)
226 op = constraintExprData_binaryExprGetOp (expr->data);
228 DPRINTF((message("constraintExpr_propagateConstants: binaryexpr: %s", constraintExpr_unparse(expr) ) ) );
230 expr = removeZero(expr);
232 expr1 = constraintExprData_binaryExprGetExpr1(expr->data);
233 expr2 = constraintExprData_binaryExprGetExpr2(expr->data);
235 expr1 = constraintExpr_copy(expr1);
236 expr2 = constraintExpr_copy(expr2);
238 expr1 = constraintExpr_propagateConstants (expr1, &propagate1, &literal1);
239 expr2 = constraintExpr_propagateConstants (expr2, &propagate2, &literal2);
241 expr1 = removeZero(expr1);
242 expr2 = removeZero(expr2);
245 *propagate = propagate1 || propagate2;
247 if (op == BINARYOP_PLUS)
248 *literal = literal1 + literal2;
249 else if (op == BINARYOP_MINUS)
250 *literal = literal1 - literal2;
254 if ( constraintExpr_isLit (expr1) && constraintExpr_isLit (expr2) )
257 t1 = constraintExpr_getValue (expr1);
258 t2 = constraintExpr_getValue (expr2);
259 llassert(*propagate == FALSE);
262 constraintExpr_free (expr);
263 constraintExpr_free (expr1);
264 constraintExpr_free (expr2);
266 if (op == BINARYOP_PLUS )
267 return (constraintExpr_makeIntLiteral ((t1+t2) ));
268 else if (op == BINARYOP_MINUS)
269 return (constraintExpr_makeIntLiteral ((t1-t2) ));
275 if (constraintExpr_isLit (expr1) )
279 *literal += constraintExpr_getValue (expr1);
281 if (op == BINARYOP_PLUS)
283 constraintExpr_free(expr1);
284 constraintExpr_free(expr);
287 else if (op == BINARYOP_MINUS)
292 /* this is an ugly kludge to deal with not
293 having a unary minus operation...*/
295 temp = constraintExpr_makeIntLiteral (0);
296 temp = constraintExpr_makeSubtractExpr (temp, expr2);
298 constraintExpr_free(expr1);
299 constraintExpr_free(expr);
305 BADBRANCH; /* evans 2001-07-18 */
309 if (constraintExpr_isLit (expr2) )
313 if ( op == BINARYOP_PLUS )
314 *literal += constraintExpr_getValue (expr2);
315 else if (op == BINARYOP_MINUS)
316 *literal -= constraintExpr_getValue (expr2);
321 constraintExpr_free(expr2);
322 constraintExpr_free(expr);
326 DPRINTF((message("constraintExpr_propagateConstants returning: %s", constraintExpr_unparse(expr) ) ) );
328 expr->data = constraintExprData_binaryExprSetExpr1 (expr->data, expr1);
329 expr->data = constraintExprData_binaryExprSetExpr2 (expr->data, expr2);
331 expr = removeZero(expr);
335 /*@only@*/ static constraintExpr constraintExpr_combineConstants (/*@only@*/ constraintExpr expr ) /*@modifies expr@*/
340 DPRINTF ((message ("Before combine %s", constraintExpr_unparse(expr) ) ) );
341 expr = constraintExpr_propagateConstants (expr, &propagate, &literal);
350 ret = constraintExpr_makeBinaryOpConstraintExprIntLiteral (expr, literal);
354 DPRINTF ((message ("After combine %s", constraintExpr_unparse(expr) ) ) );
359 static constraintExpr constraintExpr_alloc (void) /*@post:isnull result->data@*/
362 ret = dmalloc (sizeof (*ret) );
366 ret->origType = ctype_undefined;
370 /*@only@*/ static constraintExprData copyExprData (/*@observer@*/ constraintExprData data, constraintExprKind kind)
372 constraintExprData ret;
373 llassert(constraintExprData_isDefined(data));
378 ret = constraintExprData_copyBinaryExpr(data);
381 ret = constraintExprData_copyUnaryExpr(data);
384 ret = constraintExprData_copyTerm(data);
392 constraintExpr constraintExpr_copy (constraintExpr expr)
395 ret = constraintExpr_alloc();
396 ret->kind = expr->kind;
398 ret->data = copyExprData (expr->data, expr->kind);
400 ret->origType = expr->origType;
405 /*@only@*/ static constraintExpr oldconstraintExpr_makeTermExprNode ( /*@dependent@*/ exprNode e)
409 ret = constraintExpr_alloc();
411 ret->data = dmalloc (sizeof *(ret->data) );
412 t = constraintTerm_makeExprNode (e);
413 ret->data = constraintExprData_termSetTerm (ret->data, t);
415 ret->origType = ctype_undefined;
420 constraintExpr constraintExpr_makeExprNode (exprNode e)
423 constraintExpr ret, ce1, ce2;
429 llassert (e != NULL);
436 t = exprData_getSingle (data);
437 s = exprNode_getSref (t);
438 if (sRef_isFixedArray(s) )
442 size = (int) sRef_getArraySize(s);
443 ret = constraintExpr_makeIntLiteral (size);
447 DPRINTF ((message ("could not determine the size of %s", exprNode_unparse (e) ) ) );
448 ret = oldconstraintExpr_makeTermExprNode (e);
453 DPRINTF ((message ("Examining operation %s", exprNode_unparse (e) ) ) );
454 t1 = exprData_getOpA (data);
455 t2 = exprData_getOpB (data);
456 tok = exprData_getOpTok (data);
458 if (lltok_isPlus_Op (tok) || lltok_isMinus_Op (tok) )
460 ce1 = constraintExpr_makeExprNode (t1);
461 ce2 = constraintExpr_makeExprNode (t2);
462 ret = constraintExpr_parseMakeBinaryOp (ce1, tok, ce2);
467 /* uncomment this block to activate the cheesy heuristic
468 for handling sizeof expressions
473 We handle expressions containing sizeof with the rule
474 (sizeof type ) * Expr = Expr
476 This is the total wronge way to do this but...
477 it may be better than nothing
482 else if (lltok_isMult(tok) )
484 if ((t1->kind == XPR_SIZEOF) || (t1->kind == XPR_SIZEOFT) )
486 ret = constraintExpr_makeExprNode(t2);
488 else if ((t2->kind == XPR_SIZEOF) || (t2->kind == XPR_SIZEOFT) )
490 ret = constraintExpr_makeExprNode(t1);
494 ret = oldconstraintExpr_makeTermExprNode (e);
499 ret = oldconstraintExpr_makeTermExprNode (e);
503 t = exprData_getUopNode (data);
504 ret = constraintExpr_makeExprNode (t);
508 t = exprData_getUopNode (data);
509 tok = exprData_getUopTok (data);
510 if (lltok_isInc_Op (tok) )
513 temp = constraintExpr_makeExprNode(t);
514 ret = constraintExpr_makeIncConstraintExpr(temp);
516 else if (lltok_isDec_Op (tok) )
519 temp = constraintExpr_makeExprNode(t);
520 ret = constraintExpr_makeDecConstraintExpr(temp);
523 ret = oldconstraintExpr_makeTermExprNode (e);
527 t = exprData_getUopNode (data);
528 ret = constraintExpr_makeExprNode (t);
531 t = exprData_getCastNode (data);
532 ret = constraintExpr_makeExprNode (t);
535 t = exprData_getPairA(data);
536 ret = constraintExpr_makeExprNode(t);
537 /*@i3434*/ /* drl: I'm not sure if this is right. I'm adding a break to quiet Splint */
540 ret = oldconstraintExpr_makeTermExprNode (e);
546 /*@only@*/ constraintExpr constraintExpr_makeTermExprNode (/*@exposed@*/ exprNode e)
548 return oldconstraintExpr_makeTermExprNode(e);
551 static constraintExpr constraintExpr_makeTerm (/*@only@*/ constraintTerm t)
555 ret = constraintExpr_alloc();
557 ret->data = dmalloc (sizeof *(ret->data) );
558 ret->data->term = NULL;
559 ret->data = constraintExprData_termSetTerm (ret->data, t);
561 ret->origType = ctype_undefined;
566 constraintExpr constraintExpr_makeTermsRef (/*@temp@*/ sRef s)
570 ret = constraintExpr_alloc();
572 ret->data = dmalloc (sizeof *(ret->data) );
573 t = constraintTerm_makesRef (s);
574 ret->data = constraintExprData_termSetTerm (ret->data, t);
577 ret->origType = ctype_undefined;
582 /*@special@*/ static constraintExpr makeUnaryOpGeneric (void) /*@allocates result->data@*/ /*@defines result->kind@*/
585 ret = constraintExpr_alloc();
586 ret->kind = unaryExpr;
587 ret->data = dmalloc ( sizeof *(ret->data) );
588 ret->data->unaryOp.expr = constraintExpr_undefined;
592 /*@only@*/ static constraintExpr constraintExpr_makeUnaryOpConstraintExpr (/*@only@*/ constraintExpr cexpr)
595 ret = makeUnaryOpGeneric();
599 ret->data = constraintExprData_unaryExprSetExpr (ret->data, cexpr);
600 ret->data = constraintExprData_unaryExprSetOp (ret->data, UNARYOP_UNDEFINED);
609 /*@only@*/ static constraintExpr constraintExpr_makeUnaryOp (/*@only@*/ constraintExpr cexpr, constraintExprUnaryOpKind Op )
612 ret = makeUnaryOpGeneric();
614 ret->data = constraintExprData_unaryExprSetExpr (ret->data, cexpr);
615 ret->data = constraintExprData_unaryExprSetOp (ret->data, Op);
618 ret->origType = ctype_undefined;
624 static constraintExpr constraintExpr_makeMaxSetConstraintExpr (/*@only@*/ constraintExpr c)
627 ret = constraintExpr_makeUnaryOp (c, MAXSET);
632 static constraintExpr constraintExpr_makeUnaryOpExprNode (/*@exposed@*/ exprNode expr)
636 sub = constraintExpr_makeExprNode (expr);
637 ret = constraintExpr_makeUnaryOpConstraintExpr(sub);
645 static constraintExpr constraintExpr_makeSRefUnaryOp (/*@temp@*/ /*@observer@*/ sRef s, constraintExprUnaryOpKind op)
650 t = constraintExpr_makeTermsRef (s);
651 ret = constraintExpr_makeUnaryOpConstraintExpr (t);
652 ret->data = constraintExprData_unaryExprSetOp (ret->data, op);
658 constraintExpr constraintExpr_makeSRefMaxRead( sRef s)
660 return (constraintExpr_makeSRefUnaryOp (s, MAXREAD) );
664 constraintExpr constraintExpr_makeSRefMaxset ( sRef s)
666 return (constraintExpr_makeSRefUnaryOp (s, MAXSET) );
670 constraintExpr constraintExpr_parseMakeUnaryOp (lltok op, constraintExpr cexpr)
673 ret = constraintExpr_makeUnaryOpConstraintExpr ( cexpr);
678 ret->data = constraintExprData_unaryExprSetOp (ret->data, MAXSET);
681 ret->data = constraintExprData_unaryExprSetOp (ret->data, MAXREAD);
684 llfatalbug(message("Unhandled Operation in Constraint") );
690 constraintExpr constraintExpr_makeMaxSetExpr (/*@exposed@*/ exprNode expr)
693 ret = constraintExpr_makeExprNode (expr);
695 ret = constraintExpr_makeMaxSetConstraintExpr (ret);
697 llassert (ret != NULL);
702 constraintExpr constraintExpr_makeMaxReadExpr (exprNode expr)
705 ret = constraintExpr_makeUnaryOpExprNode(expr);
706 ret->data = constraintExprData_unaryExprSetOp (ret->data, MAXREAD);
712 /*@unused@*/ static constraintExpr constraintExpr_makeMinSetExpr (/*@exposed@*/ exprNode expr)
715 ret = constraintExpr_makeUnaryOpExprNode(expr);
716 ret->data = constraintExprData_unaryExprSetOp (ret->data, MINSET);
721 /*@unused@*/ static constraintExpr constraintExpr_makeMinReadExpr (/*@exposed@*/ exprNode expr)
724 ret = constraintExpr_makeUnaryOpExprNode(expr);
725 ret->data = constraintExprData_unaryExprSetOp (ret->data, MINREAD);
731 constraintExpr constraintExpr_makeValueExpr (/*@exposed@*/ exprNode expr)
734 ret = constraintExpr_makeExprNode (expr);
739 constraintExpr constraintExpr_makeIntLiteral (long i)
743 ret = constraintExpr_alloc();
745 ret->data = dmalloc (sizeof *(ret->data) );
746 t = constraintTerm_makeIntLiteral (i);
747 ret->data = constraintExprData_termSetTerm (ret->data, t);
750 ret->origType = ctype_undefined;
756 constraintExpr constraintExpr_makeValueInt (int i)
758 return constraintExpr_makeIntLiteral (i);
763 /*@special@*/ static constraintExpr constraintExpr_makeBinaryOp (void)
764 /*@allocates result->data @*/ /*@sets result->kind @*/
767 ret = constraintExpr_alloc();
768 ret->kind = binaryexpr;
769 ret->data = dmalloc ( sizeof *(ret->data) );
771 ret->data->binaryOp.expr1 = constraintExpr_undefined;
772 ret->data->binaryOp.expr2 = constraintExpr_undefined;
778 static /*@only@*/ constraintExpr constraintExpr_makeBinaryOpConstraintExpr (/*@only@*/constraintExpr expr1, /*@only@*/ constraintExpr expr2)
783 ret = constraintExpr_makeBinaryOp();
784 ret->data = constraintExprData_binaryExprSetExpr1 (ret->data, expr1);
785 ret->data = constraintExprData_binaryExprSetExpr2 (ret->data, expr2);
786 ret->data = constraintExprData_binaryExprSetOp (ret->data, BINARYOP_UNDEFINED);
789 ret->origType = ctype_undefined;
795 constraintExpr constraintExpr_parseMakeBinaryOp (/*@only@*/ constraintExpr expr1, lltok op,/*@only@*/ constraintExpr expr2)
798 ret = constraintExpr_makeBinaryOpConstraintExpr (expr1, expr2);
800 ret->data = constraintExprData_binaryExprSetOp(ret->data, BINARYOP_PLUS);
801 else if (op.tok == TMINUS)
802 ret->data = constraintExprData_binaryExprSetOp(ret->data, BINARYOP_MINUS);
812 /*@unused@*/ static constraintExpr constraintExpr_makeBinaryOpExprNode (/*@exposed@*/ exprNode expr1, /*@exposed@*/ exprNode expr2)
815 constraintExpr sub1, sub2;
816 sub1 = constraintExpr_makeTermExprNode (expr1);
817 sub2 = constraintExpr_makeTermExprNode (expr2);
818 ret = constraintExpr_makeBinaryOpConstraintExpr(sub1, sub2);
824 constraintExpr constraintExpr_makeBinaryOpConstraintExprIntLiteral (/*@only@*/ constraintExpr expr, int literal)
827 constraintExpr constExpr;
829 constExpr = constraintExpr_makeIntLiteral (literal);
830 ret = constraintExpr_makeBinaryOpConstraintExpr (expr, constExpr);
831 ret->data = constraintExprData_binaryExprSetOp(ret->data, BINARYOP_PLUS);
836 constraintExpr constraintExpr_makeDecConstraintExpr (/*@only@*/constraintExpr expr)
841 inc = constraintExpr_makeIntLiteral (1);
842 ret = constraintExpr_makeBinaryOpConstraintExpr (expr, inc);
843 ret->data = constraintExprData_binaryExprSetOp(ret->data, BINARYOP_MINUS);
848 /*@only@*/ constraintExpr constraintExpr_makeSubtractExpr (/*@only@*/ constraintExpr expr, /*@only@*/ constraintExpr addent)
852 DPRINTF ((message ("Making subtract expression") ) );
854 ret = constraintExpr_makeBinaryOpConstraintExpr (expr, addent);
855 ret->data = constraintExprData_binaryExprSetOp (ret->data, BINARYOP_MINUS);
860 constraintExpr constraintExpr_makeAddExpr (/*@only@*/
861 constraintExpr expr, /*@only@*/
862 constraintExpr addent)
866 DPRINTF ((message ("Doing addTerm simplification") ) );
868 ret = constraintExpr_makeBinaryOpConstraintExpr (expr, addent);
869 ret->data = constraintExprData_binaryExprSetOp (ret->data, BINARYOP_PLUS);
875 constraintExpr constraintExpr_makeIncConstraintExpr (/*@only@*/ constraintExpr expr)
880 inc = constraintExpr_makeIntLiteral (1);
881 ret = constraintExpr_makeBinaryOpConstraintExpr (expr, inc);
882 ret->data = constraintExprData_binaryExprSetOp(ret->data, BINARYOP_PLUS);
887 static cstring constraintExprUnaryOpKind_print (constraintExprUnaryOpKind op)
892 return message("maxSet");
894 return message("minSet");
896 return message("maxRead");
898 return message("minRead");
901 return message ("<(Unary OP OTHER>");
907 static cstring constraintExprBinaryOpKind_print (constraintExprBinaryOpKind op)
919 return message ("<binary OP Unknown>");
923 bool constraintExpr_similar (constraintExpr expr1, constraintExpr expr2)
925 constraintExprKind kind;
927 llassert (expr1 != NULL);
928 llassert (expr2 != NULL);
929 if (expr1->kind != expr2->kind)
937 return constraintTerm_similar (constraintExprData_termGetTerm(expr1->data),
938 constraintExprData_termGetTerm(expr2->data) );
939 /*@notreached@*/ break;
942 if (constraintExprData_unaryExprGetOp (expr1->data) != constraintExprData_unaryExprGetOp (expr2->data) )
945 return (constraintExpr_similar (
946 constraintExprData_unaryExprGetExpr (expr1->data),
947 constraintExprData_unaryExprGetExpr (expr2->data)
951 if (constraintExprData_binaryExprGetOp (expr1->data) != constraintExprData_binaryExprGetOp (expr2->data) )
954 if (! constraintExpr_similar (constraintExprData_binaryExprGetExpr1 (expr1->data),
955 constraintExprData_binaryExprGetExpr1 (expr2->data)) )
958 if (! constraintExpr_similar (constraintExprData_binaryExprGetExpr2 (expr1->data),
959 constraintExprData_binaryExprGetExpr2 (expr2->data)) )
974 bool constraintExpr_same (constraintExpr expr1, constraintExpr expr2)
976 constraintExprKind kind;
978 llassert (expr1 != NULL);
979 llassert (expr2 != NULL);
980 if (expr1->kind != expr2->kind)
988 return constraintTerm_similar (constraintExprData_termGetTerm(expr1->data),
989 constraintExprData_termGetTerm(expr2->data) );
990 /*@notreached@*/ break;
993 if (constraintExprData_unaryExprGetOp (expr1->data) != constraintExprData_unaryExprGetOp (expr2->data) )
996 return (constraintExpr_same (
997 constraintExprData_unaryExprGetExpr (expr1->data),
998 constraintExprData_unaryExprGetExpr (expr2->data)
1003 if (constraintExprData_binaryExprGetOp (expr1->data) != constraintExprData_binaryExprGetOp (expr2->data) )
1006 if (! constraintExpr_same (constraintExprData_binaryExprGetExpr1 (expr1->data),
1007 constraintExprData_binaryExprGetExpr1 (expr2->data)) )
1010 if (! constraintExpr_same (constraintExprData_binaryExprGetExpr2 (expr1->data),
1011 constraintExprData_binaryExprGetExpr2 (expr2->data)) )
1015 /*@notreached@*/ break;
1026 bool constraintExpr_search (/*@observer@*/ constraintExpr c, /*@observer@*/ constraintExpr old)
1029 constraintExprKind kind;
1030 constraintExpr temp;
1032 if ( constraintExpr_similar (c, old) )
1034 DPRINTF((message ("Found %q",
1035 constraintExpr_unparse(old)
1047 temp = constraintExprData_unaryExprGetExpr (c->data);
1048 ret = ret || constraintExpr_search (temp, old);
1052 temp = constraintExprData_binaryExprGetExpr1 (c->data);
1053 ret = ret || constraintExpr_search(temp, old);
1055 temp = constraintExprData_binaryExprGetExpr2 (c->data);
1056 ret = ret || constraintExpr_search(temp, old);
1066 /*@only@*/ constraintExpr constraintExpr_searchandreplace (/*@only@*/ /*@unique@*/ constraintExpr c, /*@temp@*/ constraintExpr old, /*@temp@*/ constraintExpr newExpr )
1068 constraintExprKind kind;
1069 constraintExpr temp;
1072 if ( constraintExpr_similar (c, old) )
1075 ctype newType, cType;
1078 ret = constraintExpr_copy (newExpr);
1080 DPRINTF((message ("Replacing %s with %s",
1081 constraintExpr_unparse(old), constraintExpr_unparse(newExpr)
1084 if (constraintExpr_canGetCType(c) && constraintExpr_canGetCType(newExpr) )
1086 cType = constraintExpr_getCType(c);
1087 newType = constraintExpr_getCType(newExpr);
1089 if (ctype_match(cType,newType) )
1091 DPRINTF(( message("constraintExpr_searchandreplace: replacing "
1092 " %s with type %s with %s with type %s",
1093 constraintExpr_print(c), ctype_unparse(cType),
1094 constraintExpr_print(newExpr), ctype_unparse(newType)
1099 ret->origType = cType;
1103 if (constraintExpr_hasMaxSet(c) )
1105 if (constraintExpr_hasTypeChange(c))
1107 DPRINTF(( message("constraintExpr_searchandreplace: encountered "
1108 "MaxSet with changed type %s ",
1109 constraintExpr_print(c) )
1112 /*fix this with a conversation */
1113 ret = constraintExpr_adjustMaxSetForCast(ret, constraintExpr_getOrigType(c));
1116 constraintExpr_free(c);
1128 temp = constraintExprData_unaryExprGetExpr (c->data);
1129 temp = constraintExpr_copy(temp);
1130 temp = constraintExpr_searchandreplace (temp, old, newExpr);
1131 c->data = constraintExprData_unaryExprSetExpr (c->data, temp);
1135 temp = constraintExprData_binaryExprGetExpr1 (c->data);
1136 temp = constraintExpr_copy(temp);
1137 temp = constraintExpr_searchandreplace (temp, old, newExpr);
1138 c->data = constraintExprData_binaryExprSetExpr1 (c->data, temp);
1140 temp = constraintExprData_binaryExprGetExpr2 (c->data);
1141 temp = constraintExpr_copy(temp);
1142 temp = constraintExpr_searchandreplace (temp, old, newExpr);
1143 c->data = constraintExprData_binaryExprSetExpr2 (c->data, temp);
1151 static constraintExpr constraintExpr_simplifyChildren (/*@returned@*/ constraintExpr c)
1153 constraintExprKind kind;
1154 constraintExpr temp;
1163 temp = constraintExprData_unaryExprGetExpr (c->data);
1164 temp = constraintExpr_copy(temp);
1165 temp = constraintExpr_simplify (temp);
1166 c->data = constraintExprData_unaryExprSetExpr (c->data, temp);
1169 DPRINTF((message("constraintExpr_simplfiyChildren: simplify binary expression: %s",constraintExpr_unparse(c) ) ) );
1170 temp = constraintExprData_binaryExprGetExpr1 (c->data);
1171 temp = constraintExpr_copy(temp);
1172 temp = constraintExpr_simplify (temp);
1174 c->data = constraintExprData_binaryExprSetExpr1 (c->data, temp);
1176 temp = constraintExprData_binaryExprGetExpr2 (c->data);
1177 temp = constraintExpr_copy(temp);
1178 temp = constraintExpr_simplify (temp);
1180 c->data = constraintExprData_binaryExprSetExpr2 (c->data, temp);
1190 constraintExpr constraintExpr_setFileloc (/*@returned@*/ constraintExpr c, fileloc loc) /*@modifies c @*/
1193 constraintExpr temp;
1195 llassert(c != NULL);
1200 t = constraintExprData_termGetTerm (c->data);
1201 t = constraintTerm_copy(t);
1202 t = constraintTerm_setFileloc (t, loc);
1203 c->data = constraintExprData_termSetTerm (c->data, t);
1207 temp = constraintExprData_binaryExprGetExpr1 (c->data);
1208 temp = constraintExpr_copy(temp);
1209 temp = constraintExpr_setFileloc (temp, loc);
1210 c->data = constraintExprData_binaryExprSetExpr1 (c->data, temp);
1212 temp = constraintExprData_binaryExprGetExpr2 (c->data);
1213 temp = constraintExpr_copy(temp);
1214 temp = constraintExpr_setFileloc (temp, loc);
1215 c->data = constraintExprData_binaryExprSetExpr2 (c->data, temp);
1218 temp = constraintExprData_unaryExprGetExpr (c->data);
1219 temp = constraintExpr_copy(temp);
1220 temp = constraintExpr_setFileloc (temp, loc);
1221 c->data = constraintExprData_unaryExprSetExpr (c->data, temp);
1227 static /*@only@*/ constraintExpr constraintExpr_simplifybinaryExpr (/*@only@*/constraintExpr c)
1229 constraintExpr e1, e2;
1230 constraintExprBinaryOpKind op;
1232 e1 = constraintExprData_binaryExprGetExpr1 (c->data);
1233 e2 = constraintExprData_binaryExprGetExpr2 (c->data);
1235 if (constraintExpr_canGetValue (e1) && constraintExpr_canGetValue(e2) )
1239 i = constraintExpr_getValue(e1) + constraintExpr_getValue (e2);
1240 constraintExpr_free(c);
1241 c = constraintExpr_makeIntLiteral (i);
1245 op = constraintExprData_binaryExprGetOp (c->data);
1246 if (op == BINARYOP_MINUS)
1247 if (constraintExpr_similar(e1, e2) )
1249 constraintExpr_free(c);
1250 c = constraintExpr_makeIntLiteral (0);
1258 this thing takes the lexpr and expr of a constraint and modifies lexpr
1259 and returns a (possiblly new) value for expr
1261 /* if lexpr is a binary express say x + y, we set lexpr to x and return a value for expr such as expr_old - y */
1263 /* the approach is a little Kludgy but seems to work. I should probably use something cleaner at some point ... */
1266 /*@only@*/ constraintExpr constraintExpr_solveBinaryExpr (constraintExpr lexpr, /*@only@*/ constraintExpr expr)
1268 constraintExpr expr1, expr2;
1269 constraintExprBinaryOpKind op;
1271 if (lexpr->kind != binaryexpr)
1274 expr2 = constraintExprData_binaryExprGetExpr2 (lexpr->data);
1275 expr1 = constraintExprData_binaryExprGetExpr1 (lexpr->data);
1277 op = constraintExprData_binaryExprGetOp (lexpr->data);
1279 expr1 = constraintExpr_copy(expr1);
1280 expr2 = constraintExpr_copy(expr2);
1282 /* drl possible problem : warning make sure this works */
1284 lexpr->kind = expr1->kind;
1285 sfree (lexpr->data);
1287 lexpr->data = copyExprData (expr1->data, expr1->kind);
1288 constraintExpr_free(expr1);
1290 if (op == BINARYOP_PLUS)
1291 expr = constraintExpr_makeSubtractExpr (expr, expr2);
1292 else if (op == BINARYOP_MINUS)
1293 expr = constraintExpr_makeAddExpr (expr, expr2);
1301 #warning this needs to be checked
1302 expr = constraintExpr_solveBinaryExpr (expr1, expr);
1304 expr = constraintExpr_solveBinaryExpr (expr2, expr);
1309 static /*@only@*/ constraintExpr constraintExpr_simplifyunaryExpr (/*@only@*/ constraintExpr c)
1313 llassert (c->kind == unaryExpr);
1315 DPRINTF ((message ("Doing constraintExpr_simplifyunaryExpr:%s", constraintExpr_unparse (c) ) ) );
1317 if ((constraintExprData_unaryExprGetOp (c->data) != MAXSET) &&
1318 (constraintExprData_unaryExprGetOp (c->data) != MAXREAD) )
1323 exp = constraintExprData_unaryExprGetExpr (c->data);
1324 exp = constraintExpr_copy(exp);
1326 if (exp->kind == term)
1328 constraintTerm cterm;
1330 cterm = constraintExprData_termGetTerm (exp->data);
1332 if (constraintTerm_isStringLiteral(cterm) )
1335 val = constraintTerm_getStringLiteral (cterm);
1336 if (constraintExprData_unaryExprGetOp (c->data) == MAXSET)
1338 constraintExpr temp;
1340 temp = constraintExpr_makeIntLiteral ((int)strlen (cstring_toCharsSafe(val) ) );
1342 constraintExpr_free(c);
1343 constraintExpr_free(exp);
1348 if (constraintExprData_unaryExprGetOp (c->data) == MAXREAD)
1350 constraintExpr temp;
1352 temp = constraintExpr_makeIntLiteral ((int)strlen (cstring_toCharsSafe(val) ) );
1354 constraintExpr_free(c);
1355 constraintExpr_free(exp);
1362 /* slight Kludge to hanlde var [] = { , , };
1363 ** type syntax I don't think this is sounds but it should be good
1364 ** enough. The C stanrad is very confusing about initialization
1368 if (constraintTerm_isInitBlock(cterm) )
1370 constraintExpr temp;
1373 len = constraintTerm_getInitBlockLength(cterm);
1375 temp = constraintExpr_makeIntLiteral (len );
1377 constraintExpr_free(c);
1378 DPRINTF(( message("Changed too %q", constraintExpr_print(temp)
1380 constraintExpr_free(exp);
1384 constraintExpr_free(exp);
1388 if (exp->kind != binaryexpr)
1390 constraintExpr_free(exp);
1394 if (constraintExprData_binaryExprGetOp (exp->data) == BINARYOP_PLUS )
1397 /* if (constraintExpr_canGetValue (constraintExprData_binaryExprGetExpr2 (exp->data) ) ) */
1400 constraintExpr temp, temp2;
1402 DPRINTF ((message ("Doing fancy simplification") ) );
1404 temp = constraintExprData_binaryExprGetExpr2 (exp->data);
1406 temp2 = constraintExprData_binaryExprGetExpr1 (exp->data);
1408 temp2 = constraintExpr_copy(temp2);
1409 c->data = constraintExprData_unaryExprSetExpr (c->data, temp2);
1412 temp = constraintExpr_copy (temp);
1414 c = constraintExpr_makeSubtractExpr (c, temp);
1416 DPRINTF ((message ("Done fancy simplification:%s", constraintExpr_unparse (c) ) ) );
1420 DPRINTF ((message ("constraintExpr_simplifyUnaryExpr: Done simplification:%s", constraintExpr_unparse (c) ) ) );
1422 constraintExpr_free(exp);
1427 /*@only@*/ constraintExpr constraintExpr_simplify (/*@only@*/ constraintExpr c)
1429 constraintExprKind kind;
1433 DPRINTF ((message ("Doing constraintExpr_simplify:%s", constraintExpr_unparse (c) ) ) );
1438 /* drl: I think this is an Splint bug */
1440 ret = constraintExpr_copy(c);
1442 constraintExpr_free(c);
1444 ret = constraintExpr_simplifyChildren (ret);
1446 ret = constraintExpr_combineConstants (ret);
1448 ret = constraintExpr_simplifyChildren (ret);
1456 t = constraintExprData_termGetTerm (ret->data);
1457 t = constraintTerm_copy(t);
1458 t = constraintTerm_simplify (t);
1459 ret->data = constraintExprData_termSetTerm (ret->data, t);
1462 ret = constraintExpr_simplifyunaryExpr (ret);
1465 ret = constraintExpr_simplifybinaryExpr (ret);
1471 DPRINTF ((message ("constraintExpr_simplify returning :%s", constraintExpr_unparse (ret) ) ) );
1477 cstring constraintExpr_unparse (/*@temp@*/ /*@observer@*/ constraintExpr ex) /*@*/
1480 constraintExprKind kind;
1482 llassert (ex != NULL);
1490 if (context_getFlag (FLG_PARENCONSTRAINT) )
1492 st = message ("(%q) ", constraintTerm_print (constraintExprData_termGetTerm (ex->data)));
1496 st = message ("%q", constraintTerm_print (constraintExprData_termGetTerm (ex->data)));
1500 st = message ("%q(%q)",
1501 constraintExprUnaryOpKind_print (constraintExprData_unaryExprGetOp (ex->data) ),
1502 constraintExpr_unparse (constraintExprData_unaryExprGetExpr (ex->data) )
1506 if (context_getFlag (FLG_PARENCONSTRAINT) )
1508 st = message ("(%q) %q (%q)",
1509 constraintExpr_unparse (constraintExprData_binaryExprGetExpr1 (ex->data) ),
1510 constraintExprBinaryOpKind_print (constraintExprData_binaryExprGetOp (ex->data)
1512 constraintExpr_unparse (constraintExprData_binaryExprGetExpr2 (ex->data) )
1517 st = message ("%q %q %q",
1518 constraintExpr_unparse (constraintExprData_binaryExprGetExpr1 (ex->data) ),
1519 constraintExprBinaryOpKind_print (constraintExprData_binaryExprGetOp (ex->data)
1521 constraintExpr_unparse (constraintExprData_binaryExprGetExpr2 (ex->data) )
1528 st = message ("error");
1532 DPRINTF((message ("constraintExpr_unparse: '%s'",st) ) );
1536 constraintExpr constraintExpr_doSRefFixBaseParam (/*@returned@*/ constraintExpr expr, exprNodeList arglist)
1538 constraintTerm Term;
1539 constraintExprKind kind;
1540 constraintExpr expr1, expr2;
1541 constraintExprData data;
1542 llassert (expr != NULL);
1551 Term = constraintExprData_termGetTerm(data);
1552 Term = constraintTerm_copy(Term);
1554 Term = constraintTerm_doSRefFixBaseParam (Term, arglist);
1555 data = constraintExprData_termSetTerm(data, Term);
1558 expr1 = constraintExprData_unaryExprGetExpr (data);
1559 expr1 = constraintExpr_copy(expr1);
1561 expr1 = constraintExpr_doSRefFixBaseParam (expr1, arglist);
1562 data = constraintExprData_unaryExprSetExpr (data, expr1);
1565 expr1 = constraintExprData_binaryExprGetExpr1 (data);
1566 expr2 = constraintExprData_binaryExprGetExpr2 (data);
1568 expr1 = constraintExpr_copy(expr1);
1569 expr2 = constraintExpr_copy(expr2);
1571 expr1 = constraintExpr_doSRefFixBaseParam (expr1, arglist);
1572 data = constraintExprData_binaryExprSetExpr1 (data, expr1);
1573 expr2 = constraintExpr_doSRefFixBaseParam (expr2, arglist);
1574 data = constraintExprData_binaryExprSetExpr2 (data, expr2);
1585 / *@only@* / constraintExpr constraintExpr_doSRefFixInvarConstraint (/ *@only@* / constraintExpr expr, sRef s, ctype ct)
1587 constraintExprKind kind;
1588 constraintExpr expr1, expr2;
1589 constraintExprData data;
1590 llassert (expr != NULL);
1599 expr = doSRefFixInvarConstraintTerm (expr, s, ct);
1602 expr1 = constraintExprData_unaryExprGetExpr (data);
1603 expr1 = constraintExpr_copy(expr1);
1604 expr1 = constraintExpr_doSRefFixInvarConstraint (expr1, s, ct);
1605 data = constraintExprData_unaryExprSetExpr (data, expr1);
1608 expr1 = constraintExprData_binaryExprGetExpr1 (data);
1609 expr2 = constraintExprData_binaryExprGetExpr2 (data);
1611 expr1 = constraintExpr_copy(expr1);
1612 expr2 = constraintExpr_copy(expr2);
1614 expr1 = constraintExpr_doSRefFixInvarConstraint (expr1, s, ct);
1615 data = constraintExprData_binaryExprSetExpr1 (data, expr1);
1616 expr2 = constraintExpr_doSRefFixInvarConstraint (expr2, s, ct);
1617 data = constraintExprData_binaryExprSetExpr2 (data, expr2);
1628 /*@only@*/ constraintExpr constraintExpr_doSRefFixConstraintParam (/*@only@*/ constraintExpr expr, exprNodeList arglist) /*@modifies expr@*/
1630 constraintExprKind kind;
1631 constraintExpr expr1, expr2;
1632 constraintExprData data;
1633 llassert (expr != NULL);
1642 expr = doSRefFixConstraintParamTerm (expr, arglist);
1645 expr1 = constraintExprData_unaryExprGetExpr (data);
1646 expr1 = constraintExpr_copy(expr1);
1647 expr1 = constraintExpr_doSRefFixConstraintParam (expr1, arglist);
1648 data = constraintExprData_unaryExprSetExpr (data, expr1);
1651 expr1 = constraintExprData_binaryExprGetExpr1 (data);
1652 expr2 = constraintExprData_binaryExprGetExpr2 (data);
1654 expr1 = constraintExpr_copy(expr1);
1655 expr2 = constraintExpr_copy(expr2);
1657 expr1 = constraintExpr_doSRefFixConstraintParam (expr1, arglist);
1658 data = constraintExprData_binaryExprSetExpr1 (data, expr1);
1659 expr2 = constraintExpr_doSRefFixConstraintParam (expr2, arglist);
1660 data = constraintExprData_binaryExprSetExpr2 (data, expr2);
1670 /*@only@*/ constraintExpr constraintExpr_doFixResult (/*@only@*/ constraintExpr expr, /*@observer@*/ exprNode fcnCall)
1672 constraintExprKind kind;
1673 constraintExpr expr1, expr2;
1674 constraintExprData data;
1675 llassert (expr != NULL);
1684 expr = doFixResultTerm (expr, fcnCall);
1687 expr1 = constraintExprData_unaryExprGetExpr (data);
1688 expr1 = constraintExpr_copy(expr1);
1690 expr1 = constraintExpr_doFixResult (expr1, fcnCall);
1691 data = constraintExprData_unaryExprSetExpr (data, expr1);
1694 expr1 = constraintExprData_binaryExprGetExpr1 (data);
1695 expr2 = constraintExprData_binaryExprGetExpr2 (data);
1697 expr1 = constraintExpr_copy(expr1);
1698 expr2 = constraintExpr_copy(expr2);
1700 expr1 = constraintExpr_doFixResult (expr1, fcnCall);
1701 data = constraintExprData_binaryExprSetExpr1 (data, expr1);
1702 expr2 = constraintExpr_doFixResult (expr2, fcnCall);
1703 data = constraintExprData_binaryExprSetExpr2 (data, expr2);
1713 cstring constraintExpr_print (constraintExpr expr) /*@*/
1715 return constraintExpr_unparse (expr);
1718 bool constraintExpr_hasMaxSet (constraintExpr expr) /*@*/
1722 t = constraintExpr_unparse(expr);
1724 if (cstring_containsLit(t, "maxSet") != NULL )
1738 /*returns 1 0 -1 like strcmp
1744 int constraintExpr_compare (constraintExpr expr1, constraintExpr expr2)
1746 long value1, value2;
1748 if (constraintExpr_similar (expr1, expr2) )
1753 value1 = constraintExpr_getValue(expr1);
1754 value2 = constraintExpr_getValue(expr2);
1756 if (value1 > value2)
1759 if (value1 == value2)
1766 long constraintExpr_getValue (constraintExpr expr)
1768 llassert (expr->kind == term);
1769 return (constraintTerm_getValue (constraintExprData_termGetTerm (expr->data)));
1772 bool constraintExpr_canGetValue (constraintExpr expr)
1777 return constraintTerm_canGetValue (constraintExprData_termGetTerm (expr->data) );
1786 fileloc constraintExpr_getFileloc (constraintExpr expr)
1790 constraintExprKind kind;
1797 t = constraintExprData_termGetTerm (expr->data);
1798 return (constraintTerm_getFileloc (t) );
1802 e = constraintExprData_unaryExprGetExpr (expr->data);
1803 return (constraintExpr_getFileloc (e) );
1807 e = constraintExprData_binaryExprGetExpr1 (expr->data);
1808 return (constraintExpr_getFileloc (e) );
1813 return (fileloc_undefined);
1816 /*drl moved from constriantTerm.c 5/20/001*/
1817 static /*@only@*/ constraintExpr
1818 doFixResultTerm (/*@only@*/ constraintExpr e, /*@exposed@*/ exprNode fcnCall)
1822 /*maybe this should move to cosntraintExpr.c -drl7x 5/18/01*/
1825 constraintExprData data = e->data;
1826 constraintExprKind kind = e->kind;
1830 llassert(kind == term);
1832 t = constraintExprData_termGetTerm (data);
1833 llassert (constraintTerm_isDefined(t) );
1836 switch (constraintTerm_getKind(t) )
1844 s = constraintTerm_getSRef(t);
1845 if (sRef_isResult (s))
1847 ret = constraintExpr_makeExprNode(fcnCall);
1848 constraintExpr_free(e);
1864 / *@only@* / static constraintExpr
1865 doSRefFixInvarConstraintTerm (/ *@only@* / constraintExpr e,
1870 constraintExprData data = e->data;
1872 constraintExprKind kind = e->kind;
1876 llassert(kind == term);
1878 t = constraintExprData_termGetTerm (data);
1879 llassert (constraintTerm_isDefined(t) );
1883 DPRINTF (("Fixing: %s", constraintExpr_print (e)));
1885 switch (constraintTerm_getKind(t))
1888 DPRINTF((message ("%q @ %q ", constraintTerm_print(t),
1889 fileloc_unparse (constraintTerm_getFileloc(t) ) ) ));
1892 DPRINTF((message (" %q ", constraintTerm_print (t)) ));
1896 / * evans 2001-07-24: constants should use the original term * /
1897 if (!constraintTerm_canGetValue (t))
1900 DPRINTF ((message("Doing sRef_fixInvarConstraint for %q ",
1901 constraintTerm_print (t) ) ));
1903 snew = fixSref (ct, s, constraintTerm_getSRef(t));
1905 ret = constraintExpr_makeTermsRef(snew);
1907 constraintExpr_free (e);
1909 DPRINTF (( message("After Doing sRef_fixConstraintParam constraintExpr is %q ",
1910 constraintExpr_print (ret) ) ));
1911 / *@-branchstate@* /
1912 } / *@=branchstate@* /
1924 /*drl moved from constriantTerm.c 5/20/001*/
1925 /*@only@*/ static constraintExpr
1926 doSRefFixConstraintParamTerm (/*@only@*/ constraintExpr e, /*@observer@*/ /*@temp@*/ exprNodeList arglist)
1930 constraintExprData data = e->data;
1932 constraintExprKind kind = e->kind;
1936 llassert(kind == term);
1938 t = constraintExprData_termGetTerm (data);
1939 llassert (constraintTerm_isDefined(t) );
1943 DPRINTF (("Fixing: %s", constraintExpr_print (e)));
1945 switch (constraintTerm_getKind(t))
1948 DPRINTF((message ("%q @ %q ", constraintTerm_print(t),
1949 fileloc_unparse (constraintTerm_getFileloc(t) ) ) ));
1952 DPRINTF((message (" %q ", constraintTerm_print (t)) ));
1956 /* evans 2001-07-24: constants should use the original term */
1957 if (!constraintTerm_canGetValue (t))
1959 DPRINTF ((message("Doing sRef_fixConstraintParam for %q ",
1960 constraintTerm_print (t) ) ));
1961 ret = sRef_fixConstraintParam (constraintTerm_getSRef(t), arglist);
1963 constraintExpr_free (e);
1965 DPRINTF (( message("After Doing sRef_fixConstraintParam constraintExpr is %q ",
1966 constraintExpr_print (ret) ) ));
1968 } /*@=branchstate@*/
1980 /* bool constraintExpr_includesTerm (constraintExpr expr, constraintTerm term) */
1982 /* if (constraintTerm_hasTerm (expr->term, term) ) */
1985 /* if ((expr->expr) != NULL) */
1987 /* return ( constraintExpr_includesTerm (expr->expr, term) ); */
1993 /*drl added 6/11/01 */
1994 bool constraintExpr_isBinaryExpr (/*@observer@*/ constraintExpr c)
1996 if (c->kind == binaryexpr)
2003 /*drl added 8/08/001 */
2004 bool constraintExpr_isTerm (/*@observer@*/ constraintExpr c) /*@*/
2006 if (c->kind == term)
2013 /*@observer@*/ /*@temp@*/ constraintTerm constraintExpr_getTerm ( /*@temp@*/ /*@observer@*/ constraintExpr c) /*@*/
2015 constraintTerm term;
2017 llassert(constraintExpr_isTerm(c) );
2019 term = constraintExprData_termGetTerm(c->data);
2024 static void binaryExpr_dump (/*@observer@*/ constraintExprData data, FILE *f)
2026 constraintExpr expr1;
2027 constraintExprBinaryOpKind binaryOp;
2028 constraintExpr expr2;
2031 binaryOp = constraintExprData_binaryExprGetOp (data);
2033 fprintf(f, "%d\n", (int) binaryOp);
2035 expr1 = constraintExprData_binaryExprGetExpr1 (data);
2036 expr2 = constraintExprData_binaryExprGetExpr2 (data);
2040 constraintExpr_dump(expr1, f);
2043 constraintExpr_dump(expr2, f);
2047 static constraintExpr binaryExpr_undump (FILE *f)
2049 constraintExpr expr1;
2050 constraintExprBinaryOpKind binaryOp;
2051 constraintExpr expr2;
2060 os = mstring_create (MAX_DUMP_LINE_LENGTH);
2062 str = fgets(os, MAX_DUMP_LINE_LENGTH, f);
2065 binaryOp = (constraintExprBinaryOpKind) reader_getInt(&str);
2067 str = fgets(os, MAX_DUMP_LINE_LENGTH, f);
2069 reader_checkChar (&str, 'e');
2070 reader_checkChar (&str, '1');
2072 expr1 = constraintExpr_undump (f);
2074 str = fgets(os, MAX_DUMP_LINE_LENGTH, f);
2076 reader_checkChar (&str, 'e');
2077 reader_checkChar (&str, '2');
2079 expr2 = constraintExpr_undump (f);
2081 ret = constraintExpr_makeBinaryOpConstraintExpr (expr1, expr2);
2082 ret->data = constraintExprData_binaryExprSetOp(ret->data, binaryOp);
2090 static void unaryExpr_dump (/*@observer@*/ constraintExprData data, FILE *f)
2093 constraintExpr expr;
2094 constraintExprUnaryOpKind unaryOp;
2096 unaryOp = constraintExprData_unaryExprGetOp (data);
2098 fprintf(f, "%d\n", (int) unaryOp);
2100 expr = constraintExprData_unaryExprGetExpr (data);
2102 constraintExpr_dump(expr, f);
2105 static constraintExpr unaryExpr_undump ( FILE *f)
2108 constraintExpr expr;
2109 constraintExprUnaryOpKind unaryOp;
2115 str = mstring_create (MAX_DUMP_LINE_LENGTH);
2117 str = fgets(os, MAX_DUMP_LINE_LENGTH, f);
2119 unaryOp = (constraintExprUnaryOpKind) reader_getInt(&str);
2121 expr = constraintExpr_undump (f);
2123 ret = constraintExpr_makeUnaryOp (expr, unaryOp);
2130 void constraintExpr_dump (/*@observer@*/ constraintExpr expr, FILE *f)
2132 constraintExprKind kind;
2138 fprintf(f,"%d\n", (int) kind);
2143 t = constraintExprData_termGetTerm (expr->data);
2144 constraintTerm_dump (t, f);
2147 unaryExpr_dump (expr->data, f);
2150 binaryExpr_dump (expr->data, f);
2155 /*@only@*/ constraintExpr constraintExpr_undump (FILE *f)
2157 constraintExprKind kind;
2164 s = mstring_create (MAX_DUMP_LINE_LENGTH);
2168 s = fgets(os, MAX_DUMP_LINE_LENGTH, f);
2170 kind = (constraintExprKind) reader_getInt(&s);
2177 t = constraintTerm_undump (f);
2178 ret = constraintExpr_makeTerm(t);
2181 ret = unaryExpr_undump (f);
2184 ret = binaryExpr_undump (f);
2192 int constraintExpr_getDepth (constraintExpr ex)
2196 constraintExprKind kind;
2198 llassert (ex != NULL);
2208 ret = constraintExpr_getDepth (constraintExprData_unaryExprGetExpr (ex->data) );
2214 ret = constraintExpr_getDepth (constraintExprData_binaryExprGetExpr1 (ex->data) );
2218 ret += constraintExpr_getDepth (constraintExprData_binaryExprGetExpr2 (ex->data) );
2229 bool constraintExpr_canGetCType (constraintExpr e) /*@*/
2231 if (e->kind == term)
2237 DPRINTF(( message("constraintExpr_canGetCType: can't get type for %s ",
2238 constraintExpr_print(e) ) ));
2243 ctype constraintExpr_getCType (constraintExpr e) /*@*/
2247 llassert(constraintExpr_canGetCType(e) );
2252 t = constraintExprData_termGetTerm (e->data);
2253 return (constraintTerm_getCType(t) );
2254 /* assume that a unary expression will be an int ... */
2256 return ctype_signedintegral;
2258 /* drl for just return type of first operand */
2261 constraintExpr_getCType
2262 (constraintExprData_binaryExprGetExpr1 (e->data) )
2270 /* drl add 10-5-001 */
2272 static bool constraintExpr_hasTypeChange(constraintExpr e)
2274 if (constraintExpr_isDefined((e)) && (e->ct == TRUE) )
2279 if (e->kind == unaryExpr)
2281 if (constraintExprData_unaryExprGetOp (e->data) == MAXSET)
2285 ce = constraintExprData_unaryExprGetExpr(e->data);
2287 return (constraintExpr_hasTypeChange(ce) );
2294 /* drl add 10-5-001 */
2296 static ctype constraintExpr_getOrigType (constraintExpr e)
2299 llassert(constraintExpr_hasTypeChange(e) );
2307 if (e->kind == unaryExpr)
2309 if (constraintExprData_unaryExprGetOp (e->data) == MAXSET)
2313 ce = constraintExprData_unaryExprGetExpr(e->data);
2315 return (constraintExpr_getOrigType(ce) );
2323 /*drl added these around 10/18/001*/
2325 static /*@only@*/ constraintExpr constraintExpr_div (/*@only@*/ constraintExpr e, /*@unused@*/ ctype ct)
2330 static /*@only@*/ constraintExpr constraintTerm_simpleDivTypeExprNode(/*@only@*/ constraintExpr e, ctype ct)
2333 exprNode t1, t2, expr;
2338 message("constraintTerm_simpleDivTypeExprNode e=%s, ct=%s",
2339 constraintExpr_print(e), ctype_unparse(ct)
2343 t = constraintExprData_termGetTerm(e->data);
2345 expr = constraintTerm_getExprNode(t);
2347 if (expr->kind == XPR_OP)
2351 t1 = exprData_getOpA (data);
2352 t2 = exprData_getOpB (data);
2353 tok = exprData_getOpTok (data);
2354 if (lltok_isMult(tok) )
2357 if ((t1->kind == XPR_SIZEOF) || (t1->kind == XPR_SIZEOFT) )
2361 if (t1->kind == XPR_SIZEOFT)
2363 ct2 = qtype_getType (exprData_getType (t1->edata));
2367 ct2 = qtype_getType (exprData_getType(exprData_getSingle (t1->edata)->edata ) );
2369 if (ctype_match (ctype_makePointer(ct2), ct) )
2371 /* this is a bit sloopy but ... */
2372 constraintExpr_free(e);
2373 return constraintExpr_makeExprNode(t2);
2378 else if ((t2->kind == XPR_SIZEOF) || (t2->kind == XPR_SIZEOFT) )
2382 if (t2->kind == XPR_SIZEOFT)
2384 ct2 = qtype_getType (exprData_getType (t2->edata));
2388 ct2 = qtype_getType (exprData_getType(exprData_getSingle (t2->edata)->edata ) );
2390 if (ctype_match (ctype_makePointer(ct2),ct) )
2392 /* sloopy way to do this... */ /*@i22*/
2393 constraintExpr_free(e);
2394 return constraintExpr_makeExprNode(t1);
2404 return (constraintExpr_div (e, ct) );
2407 static /*@only@*/ constraintExpr simpleDivType (/*@only@*/ constraintExpr e, ctype ct)
2410 DPRINTF(( (message("simpleDiv got %s ", constraintExpr_unparse(e) ) )
2420 t = constraintExprData_termGetTerm(e->data);
2423 if (constraintTerm_isExprNode (t) )
2425 return constraintTerm_simpleDivTypeExprNode(e, ct);
2427 /* search for * size of ct and remove */
2429 return constraintExpr_div (e, ct);
2434 constraintExpr temp;
2436 temp = constraintExprData_binaryExprGetExpr1 (e->data);
2437 temp = constraintExpr_copy(temp);
2438 temp = simpleDivType (temp, ct);
2440 e->data = constraintExprData_binaryExprSetExpr1 (e->data, temp);
2442 temp = constraintExprData_binaryExprGetExpr2 (e->data);
2443 temp = constraintExpr_copy(temp);
2444 temp = simpleDivType (temp, ct);
2445 e->data = constraintExprData_binaryExprSetExpr2 (e->data, temp);
2447 DPRINTF(( (message("simpleDiv binaryexpr returning %s ", constraintExpr_unparse(e) ) )
2453 return constraintExpr_div (e, ct);
2460 static /*@only@*/ constraintExpr constraintExpr_adjustMaxSetForCast(/*@only@*/ constraintExpr e, ctype ct)
2463 DPRINTF(( (message("constraintExpr_adjustMaxSetForCast got %s ", constraintExpr_unparse(e) ) )
2466 e = constraintExpr_makeIncConstraintExpr(e);
2468 e = constraintExpr_simplify(e);
2471 e = simpleDivType (e, ct);
2473 e = constraintExpr_makeDecConstraintExpr(e);
2475 e = constraintExpr_simplify(e);
2477 DPRINTF(( (message("constraintExpr_adjustMaxSetForCast returning %s ", constraintExpr_unparse(e) ) )