2 ** Splint - annotation-assisted static program checker
3 ** Copyright (C) 1994-2003 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 */
33 # include "splintMacros.nf"
35 # include "cgrammar.h"
38 static ctype
constraintExpr_getOrigType (constraintExpr p_e
);
39 static bool constraintExpr_hasTypeChange(constraintExpr p_e
) /*@*/;
41 static /*@only@*/ constraintExpr
constraintExpr_makeBinaryOpConstraintExprIntLiteral (/*@only@*/constraintExpr p_expr
, int p_literal
);
45 /*@only@*/ static constraintExpr
46 doSRefFixInvarConstraintTerm (/*@only@*/ constraintExpr p_e
,
47 sRef p_s
, ctype p_ct
);
50 /*@only@*/ static constraintExpr
51 doSRefFixConstraintParamTerm (/*@only@*/ constraintExpr p_e
, /*@temp@*/ /*@observer@*/ exprNodeList p_arglist
) /*@modifies p_e@*/;
53 static /*@only@*/ constraintExpr
54 doFixResultTerm (/*@only@*/ constraintExpr p_e
, /*@exposed@*/ exprNode p_fcnCall
)
57 static bool constraintExpr_canGetCType (constraintExpr p_e
) /*@*/;
59 static ctype
constraintExpr_getCType (constraintExpr p_e
);
61 static /*@only@*/ constraintExpr
constraintExpr_adjustMaxSetForCast (/*@only@*/ constraintExpr p_e
,
62 ctype p_tfrom
, ctype p_tto
,
65 /*@special@*/ /*@notnull@*/ static constraintExpr
constraintExpr_makeBinaryOp (void)
66 /* @allocates result->data @ @sets result->kind @ */ ;
68 void constraintExpr_free (/*@only@*/ constraintExpr expr
)
70 if (constraintExpr_isDefined(expr
) )
75 constraintExprData_freeUnaryExpr(expr
->data
);
78 constraintExprData_freeBinaryExpr(expr
->data
);
81 constraintExprData_freeTerm(expr
->data
);
91 llcontbug(message("attempted to free null pointer in constraintExpr_free"));
95 bool constraintExpr_isLit (constraintExpr expr
)
97 llassert (expr
!= NULL
);
99 if (expr
->kind
== term
)
101 constraintTerm term
= constraintExprData_termGetTerm (expr
->data
);
102 if (constraintTerm_isIntLiteral (term
) )
111 static bool isZeroBinaryOp (constraintExpr expr
)
115 llassert (expr
!= NULL
); /* evans 2001-07-18 */
117 if (!constraintExpr_isBinaryExpr (expr
) )
123 e2
= constraintExprData_binaryExprGetExpr2(expr
->data
);
125 llassert (e2
!= NULL
); /* evans 2001-07-18 */
127 if (constraintExpr_isBinaryExpr (e2
) )
131 e1
= constraintExprData_binaryExprGetExpr1(e2
->data
);
133 if (constraintExpr_isLit(e1
) )
135 if (constraintExpr_getValue(e1
) == 0 )
144 /* change expr + (o - expr) to (expr -expr) */
146 /*@only@*/ /*@notnull@*/ static constraintExpr
removeZero (/*@only@*/ /*@returned@*/ constraintExpr expr
)
148 constraintExpr expr2
;
151 constraintExprBinaryOpKind op
;
152 constraintExprBinaryOpKind tempOp
;
154 llassert (expr
!= NULL
); /* evans 2001-07-18 */
156 if (!isZeroBinaryOp(expr
) )
159 expr2
= constraintExprData_binaryExprGetExpr2(expr
->data
);
160 op
= constraintExprData_binaryExprGetOp(expr
->data
);
162 llassert( constraintExpr_isBinaryExpr(expr2
) );
164 temp
= constraintExprData_binaryExprGetExpr2 (expr2
->data
);
165 temp
= constraintExpr_copy (temp
);
167 tempOp
= constraintExprData_binaryExprGetOp (expr2
->data
);
169 if (op
== BINARYOP_PLUS
)
171 else if (op
== BINARYOP_MINUS
)
173 if (tempOp
== BINARYOP_PLUS
)
175 else if (tempOp
== BINARYOP_MINUS
)
183 expr
->data
= constraintExprData_binaryExprSetExpr2(expr
->data
, temp
);
184 expr
->data
= constraintExprData_binaryExprSetOp(expr
->data
, op
);
190 /*@only@*//*@notnull@*/ constraintExpr
constraintExpr_propagateConstants (/*@only@*/ constraintExpr expr
,
191 /*@out@*/ bool * propagate
,
192 /*@out@*/ int *literal
)
194 constraintExpr expr1
;
195 constraintExpr expr2
;
196 bool propagate1
, propagate2
;
197 int literal1
, literal2
;
198 constraintExprBinaryOpKind op
;
210 llassert (expr
!= NULL
);
212 /* we simplify unaryExpr elsewhere */
213 if (expr
->kind
!= binaryexpr
)
216 op
= constraintExprData_binaryExprGetOp (expr
->data
);
218 DPRINTF((message("constraintExpr_propagateConstants: binaryexpr: %s", constraintExpr_unparse(expr
) ) ) );
220 expr
= removeZero(expr
);
222 expr1
= constraintExprData_binaryExprGetExpr1(expr
->data
);
223 expr2
= constraintExprData_binaryExprGetExpr2(expr
->data
);
225 expr1
= constraintExpr_copy(expr1
);
226 expr2
= constraintExpr_copy(expr2
);
228 expr1
= constraintExpr_propagateConstants (expr1
, &propagate1
, &literal1
);
229 expr2
= constraintExpr_propagateConstants (expr2
, &propagate2
, &literal2
);
231 expr1
= removeZero(expr1
);
232 expr2
= removeZero(expr2
);
235 *propagate
= propagate1
|| propagate2
;
237 if (op
== BINARYOP_PLUS
)
238 *literal
= literal1
+ literal2
;
239 else if (op
== BINARYOP_MINUS
)
240 *literal
= literal1
- literal2
;
244 if ( constraintExpr_isLit (expr1
) && constraintExpr_isLit (expr2
) )
247 t1
= constraintExpr_getValue (expr1
);
248 t2
= constraintExpr_getValue (expr2
);
249 llassert(*propagate
== FALSE
);
252 constraintExpr_free (expr
);
253 constraintExpr_free (expr1
);
254 constraintExpr_free (expr2
);
256 if (op
== BINARYOP_PLUS
)
257 return (constraintExpr_makeIntLiteral ((t1
+t2
) ));
258 else if (op
== BINARYOP_MINUS
)
259 return (constraintExpr_makeIntLiteral ((t1
-t2
) ));
265 if (constraintExpr_isLit (expr1
) )
269 *literal
+= constraintExpr_getValue (expr1
);
271 if (op
== BINARYOP_PLUS
)
273 constraintExpr_free(expr1
);
274 constraintExpr_free(expr
);
277 else if (op
== BINARYOP_MINUS
)
282 /* this is an ugly kludge to deal with not
283 having a unary minus operation...*/
285 temp
= constraintExpr_makeIntLiteral (0);
286 temp
= constraintExpr_makeSubtractExpr (temp
, expr2
);
288 constraintExpr_free(expr1
);
289 constraintExpr_free(expr
);
291 llassert (constraintExpr_isDefined(temp
) );
296 BADBRANCH
; /* evans 2001-07-18 */
300 if (constraintExpr_isLit (expr2
) )
304 if ( op
== BINARYOP_PLUS
)
305 *literal
+= constraintExpr_getValue (expr2
);
306 else if (op
== BINARYOP_MINUS
)
307 *literal
-= constraintExpr_getValue (expr2
);
311 constraintExpr_free(expr2
);
312 constraintExpr_free(expr
);
316 DPRINTF((message("constraintExpr_propagateConstants returning: %s", constraintExpr_unparse(expr
) ) ) );
318 expr
->data
= constraintExprData_binaryExprSetExpr1 (expr
->data
, expr1
);
319 expr
->data
= constraintExprData_binaryExprSetExpr2 (expr
->data
, expr2
);
321 expr
= removeZero(expr
);
325 /*@notnull@*/ /*@only@*/ static constraintExpr
constraintExpr_combineConstants (/*@only@*/ constraintExpr expr
) /*@modifies expr@*/
330 DPRINTF ((message ("Before combine %s", constraintExpr_unparse(expr
) ) ) );
331 expr
= constraintExpr_propagateConstants (expr
, &propagate
, &literal
);
340 ret
= constraintExpr_makeBinaryOpConstraintExprIntLiteral (expr
, literal
);
344 DPRINTF ((message ("After combine %s", constraintExpr_unparse(expr
) ) ) );
346 llassert(constraintExpr_isDefined(expr
) );
351 static /*@notnull@*/ constraintExpr
constraintExpr_alloc (void) /*@post:isnull result->data@*/
354 ret
= dmalloc (sizeof (*ret
) );
358 ret
->origType
= ctype_undefined
;
362 /*@only@*/ static constraintExprData
copyExprData (/*@observer@*/ constraintExprData data
, constraintExprKind kind
)
364 constraintExprData ret
;
365 llassert(constraintExprData_isDefined(data
));
370 ret
= constraintExprData_copyBinaryExpr(data
);
373 ret
= constraintExprData_copyUnaryExpr(data
);
376 ret
= constraintExprData_copyTerm(data
);
383 constraintExpr
constraintExpr_copy (constraintExpr expr
)
386 ret
= constraintExpr_alloc ();
389 /*drl 03/02/2003 this shouldn't be used to copy a null
390 expression but handle things cleanly if it is*/
391 llassert (!constraintExpr_isUndefined(expr
) );
393 if (constraintExpr_isUndefined(expr
) )
395 return constraintExpr_undefined
;
398 ret
->kind
= expr
->kind
;
400 ret
->data
= copyExprData (expr
->data
, expr
->kind
);
402 ret
->origType
= expr
->origType
;
407 /*@only@*/ static constraintExpr
oldconstraintExpr_makeTermExprNode ( /*@dependent@*/ exprNode e
)
411 ret
= constraintExpr_alloc();
413 ret
->data
= dmalloc (sizeof *(ret
->data
) );
414 t
= constraintTerm_makeExprNode (e
);
415 ret
->data
= constraintExprData_termSetTerm (ret
->data
, t
);
417 ret
->origType
= ctype_undefined
;
422 /*@access exprNode@*/
423 constraintExpr
constraintExpr_makeExprNode (exprNode e
)
426 constraintExpr ret
, ce1
, ce2
;
431 if (exprNode_isUndefined (e
))
433 return constraintExpr_undefined
;
441 t
= exprData_getSingle (data
);
442 while (exprNode_isInParens (t
) )
444 t
= exprData_getUopNode (t
->edata
);
446 s
= exprNode_getSref (t
);
447 if (sRef_isFixedArray(s
) )
451 size
= (int) sRef_getArraySize(s
);
452 ret
= constraintExpr_makeIntLiteral (size
);
454 else if (exprNode_isStringLiteral (t
))
456 cstring str
= multiVal_forceString (exprNode_getValue(t
));
457 ret
= constraintExpr_makeIntLiteral (size_toLong (cstring_length (str
) + 1));
461 DPRINTF ((message ("could not determine the size of %s", exprNode_unparse (e
) ) ) );
462 ret
= oldconstraintExpr_makeTermExprNode (e
);
467 DPRINTF ((message ("Examining operation %s", exprNode_unparse (e
) ) ) );
468 t1
= exprData_getOpA (data
);
469 t2
= exprData_getOpB (data
);
470 tok
= exprData_getOpTok (data
);
472 if (lltok_isPlus_Op (tok
) || lltok_isMinus_Op (tok
) )
474 ce1
= constraintExpr_makeExprNode (t1
);
475 ce2
= constraintExpr_makeExprNode (t2
);
476 ret
= constraintExpr_parseMakeBinaryOp (ce1
, tok
, ce2
);
480 /* define this block to activate the cheesy heuristic
481 for handling sizeof expressions*/
488 We handle expressions containing sizeof with the rule
489 (sizeof type ) * Expr = Expr
491 This is the total wronge way to do this but...
492 it may be better than nothing
497 else if (lltok_isMult(tok
) )
499 if ((t1
->kind
== XPR_SIZEOF
) || (t1
->kind
== XPR_SIZEOFT
) )
501 ret
= constraintExpr_makeExprNode(t2
);
503 else if ((t2
->kind
== XPR_SIZEOF
) || (t2
->kind
== XPR_SIZEOFT
) )
505 ret
= constraintExpr_makeExprNode(t1
);
509 ret
= oldconstraintExpr_makeTermExprNode (e
);
515 ret
= oldconstraintExpr_makeTermExprNode (e
);
519 t
= exprData_getUopNode (data
);
520 ret
= constraintExpr_makeExprNode (t
);
524 t
= exprData_getUopNode (data
);
525 tok
= exprData_getUopTok (data
);
526 if (lltok_isIncOp (tok
))
529 temp
= constraintExpr_makeExprNode(t
);
530 ret
= constraintExpr_makeIncConstraintExpr(temp
);
532 else if (lltok_isDecOp (tok
))
535 temp
= constraintExpr_makeExprNode(t
);
536 ret
= constraintExpr_makeDecConstraintExpr(temp
);
539 ret
= oldconstraintExpr_makeTermExprNode (e
);
543 t
= exprData_getUopNode (data
);
544 ret
= constraintExpr_makeExprNode (t
);
547 t
= exprData_getCastNode (data
);
548 ret
= constraintExpr_makeExprNode (t
);
551 t
= exprData_getPairA (data
);
552 ret
= constraintExpr_makeExprNode(t
);
555 ret
= oldconstraintExpr_makeTermExprNode (e
);
561 /*@noaccess exprNode@*/
567 static /*@only@*/ constraintExpr
constraintExpr_makeTermExprNode (/*@exposed@*/ exprNode e
)
569 return oldconstraintExpr_makeTermExprNode(e
);
573 static constraintExpr
constraintExpr_makeTerm (/*@only@*/ constraintTerm t
)
577 ret
= constraintExpr_alloc();
579 ret
->data
= dmalloc (sizeof *(ret
->data
) );
580 ret
->data
->term
= NULL
;
581 ret
->data
= constraintExprData_termSetTerm (ret
->data
, t
);
583 ret
->origType
= ctype_undefined
;
588 constraintExpr
constraintExpr_makeTermsRef (/*@temp@*/ sRef s
)
592 ret
= constraintExpr_alloc();
594 ret
->data
= dmalloc (sizeof *(ret
->data
) );
595 t
= constraintTerm_makesRef (s
);
596 ret
->data
= constraintExprData_termSetTerm (ret
->data
, t
);
599 ret
->origType
= ctype_undefined
;
604 /*@special@*/ /*@notnull@*/ static constraintExpr
makeUnaryOpGeneric (void) /*@allocates result->data@*/ /*@defines result->kind@*/
607 ret
= constraintExpr_alloc();
608 ret
->kind
= unaryExpr
;
609 ret
->data
= dmalloc (sizeof *(ret
->data
));
610 ret
->data
->unaryOp
.expr
= constraintExpr_undefined
;
614 /*@notnull@*/ /*@only@*/ static constraintExpr
constraintExpr_makeUnaryOpConstraintExpr (/*@only@*/ constraintExpr cexpr
)
617 ret
= makeUnaryOpGeneric();
621 ret
->data
= constraintExprData_unaryExprSetExpr (ret
->data
, cexpr
);
622 ret
->data
= constraintExprData_unaryExprSetOp (ret
->data
, UNARYOP_UNDEFINED
);
631 /*@only@*/ /*@notnull@*/ static constraintExpr
632 constraintExpr_makeUnaryOp (/*@only@*/ constraintExpr cexpr
, constraintExprUnaryOpKind Op
)
635 ret
= makeUnaryOpGeneric();
637 ret
->data
= constraintExprData_unaryExprSetExpr (ret
->data
, cexpr
);
638 ret
->data
= constraintExprData_unaryExprSetOp (ret
->data
, Op
);
641 ret
->origType
= ctype_undefined
;
646 /*@only@*/ /*@notnull@*/
647 static constraintExpr
constraintExpr_makeUnaryOpExprNode (/*@exposed@*/ exprNode expr
)
651 sub
= constraintExpr_makeExprNode (expr
);
652 ret
= constraintExpr_makeUnaryOpConstraintExpr(sub
);
657 /*@only@*/ /*@notnull@*/
658 static constraintExpr
constraintExpr_makeMaxSetConstraintExpr (/*@only@*/ constraintExpr c
)
661 ret
= constraintExpr_makeUnaryOp (c
, MAXSET
);
666 /*@only@*/ /*@notnull@*/
667 static constraintExpr
constraintExpr_makeSRefUnaryOp (/*@temp@*/ /*@observer@*/ sRef s
, constraintExprUnaryOpKind op
)
672 t
= constraintExpr_makeTermsRef (s
);
673 ret
= constraintExpr_makeUnaryOpConstraintExpr (t
);
674 ret
->data
= constraintExprData_unaryExprSetOp (ret
->data
, op
);
680 constraintExpr
constraintExpr_makeSRefMaxRead( sRef s
)
682 return (constraintExpr_makeSRefUnaryOp (s
, MAXREAD
) );
686 constraintExpr
constraintExpr_makeSRefMaxset ( sRef s
)
688 return (constraintExpr_makeSRefUnaryOp (s
, MAXSET
) );
692 constraintExpr
constraintExpr_parseMakeUnaryOp (lltok op
, constraintExpr cexpr
)
695 ret
= constraintExpr_makeUnaryOpConstraintExpr ( cexpr
);
697 switch (lltok_getTok (op
))
700 ret
->data
= constraintExprData_unaryExprSetOp (ret
->data
, MAXSET
);
703 ret
->data
= constraintExprData_unaryExprSetOp (ret
->data
, MAXREAD
);
706 llfatalbug (message ("Unhandled operation in constraint: %s", lltok_unparse (op
)));
712 constraintExpr
constraintExpr_makeMaxSetExpr (/*@exposed@*/ exprNode expr
)
715 ret
= constraintExpr_makeExprNode (expr
);
717 ret
= constraintExpr_makeMaxSetConstraintExpr (ret
);
719 llassert (ret
!= NULL
);
724 constraintExpr
constraintExpr_makeMaxReadExpr (exprNode expr
)
727 ret
= constraintExpr_makeUnaryOpExprNode(expr
);
728 ret
->data
= constraintExprData_unaryExprSetOp (ret
->data
, MAXREAD
);
734 /*@unused@*/ static constraintExpr
constraintExpr_makeMinSetExpr (/*@exposed@*/ exprNode expr
)
737 ret
= constraintExpr_makeUnaryOpExprNode(expr
);
738 ret
->data
= constraintExprData_unaryExprSetOp (ret
->data
, MINSET
);
743 /*@unused@*/ static constraintExpr
constraintExpr_makeMinReadExpr (/*@exposed@*/ exprNode expr
)
746 ret
= constraintExpr_makeUnaryOpExprNode(expr
);
747 ret
->data
= constraintExprData_unaryExprSetOp (ret
->data
, MINREAD
);
753 constraintExpr
constraintExpr_makeValueExpr (/*@exposed@*/ exprNode expr
)
756 ret
= constraintExpr_makeExprNode (expr
);
760 /*@only@*/ /*@notnull@*/
761 constraintExpr
constraintExpr_makeIntLiteral (long i
)
765 ret
= constraintExpr_alloc();
767 ret
->data
= dmalloc (sizeof *(ret
->data
) );
768 t
= constraintTerm_makeIntLiteral (i
);
769 ret
->data
= constraintExprData_termSetTerm (ret
->data
, t
);
772 ret
->origType
= ctype_undefined
;
778 constraintExpr constraintExpr_makeValueInt (int i)
780 return constraintExpr_makeIntLiteral (i);
784 /*@only@*/ /*@notnull@*/
785 /*@special@*/ static constraintExpr
constraintExpr_makeBinaryOp (void)
786 /*@allocates result->data @*/ /*@sets result->kind @*/
789 ret
= constraintExpr_alloc();
790 ret
->kind
= binaryexpr
;
791 ret
->data
= dmalloc ( sizeof *(ret
->data
) );
793 ret
->data
->binaryOp
.expr1
= constraintExpr_undefined
;
794 ret
->data
->binaryOp
.expr2
= constraintExpr_undefined
;
800 static /*@notnull@*/ /*@only@*/ constraintExpr
constraintExpr_makeBinaryOpConstraintExpr (/*@only@*/constraintExpr expr1
, /*@only@*/ constraintExpr expr2
)
805 ret
= constraintExpr_makeBinaryOp();
806 ret
->data
= constraintExprData_binaryExprSetExpr1 (ret
->data
, expr1
);
807 ret
->data
= constraintExprData_binaryExprSetExpr2 (ret
->data
, expr2
);
808 ret
->data
= constraintExprData_binaryExprSetOp (ret
->data
, BINARYOP_UNDEFINED
);
811 ret
->origType
= ctype_undefined
;
817 constraintExpr
constraintExpr_parseMakeBinaryOp (/*@only@*/ constraintExpr expr1
, lltok op
,/*@only@*/ constraintExpr expr2
)
820 ret
= constraintExpr_makeBinaryOpConstraintExpr (expr1
, expr2
);
822 if (lltok_getTok (op
) == TPLUS
)
824 ret
->data
= constraintExprData_binaryExprSetOp(ret
->data
, BINARYOP_PLUS
);
826 else if (lltok_getTok (op
) == TMINUS
)
828 ret
->data
= constraintExprData_binaryExprSetOp(ret
->data
, BINARYOP_MINUS
);
840 /*@unused@*/ static constraintExpr
constraintExpr_makeBinaryOpExprNode (/*@exposed@*/ exprNode expr1
, /*@exposed@*/ exprNode expr2
)
843 constraintExpr sub1
, sub2
;
844 sub1
= constraintExpr_makeTermExprNode (expr1
);
845 sub2
= constraintExpr_makeTermExprNode (expr2
);
846 ret
= constraintExpr_makeBinaryOpConstraintExpr(sub1
, sub2
);
851 static /*@notnull@*/ /*@only@*/
852 constraintExpr
constraintExpr_makeBinaryOpConstraintExprIntLiteral (/*@only@*/ constraintExpr expr
, int literal
)
855 constraintExpr constExpr
;
857 constExpr
= constraintExpr_makeIntLiteral (literal
);
858 ret
= constraintExpr_makeBinaryOpConstraintExpr (expr
, constExpr
);
859 ret
->data
= constraintExprData_binaryExprSetOp(ret
->data
, BINARYOP_PLUS
);
864 constraintExpr
constraintExpr_makeDecConstraintExpr (/*@only@*/constraintExpr expr
)
869 inc
= constraintExpr_makeIntLiteral (1);
870 ret
= constraintExpr_makeBinaryOpConstraintExpr (expr
, inc
);
871 ret
->data
= constraintExprData_binaryExprSetOp(ret
->data
, BINARYOP_MINUS
);
876 /*@only@*/ constraintExpr
constraintExpr_makeSubtractExpr (/*@only@*/ constraintExpr expr
, /*@only@*/ constraintExpr addent
)
880 DPRINTF ((message ("Making subtract expression") ) );
882 ret
= constraintExpr_makeBinaryOpConstraintExpr (expr
, addent
);
883 ret
->data
= constraintExprData_binaryExprSetOp (ret
->data
, BINARYOP_MINUS
);
888 constraintExpr
constraintExpr_makeAddExpr (/*@only@*/
889 constraintExpr expr
, /*@only@*/
890 constraintExpr addent
)
894 DPRINTF ((message ("Doing addTerm simplification") ) );
896 ret
= constraintExpr_makeBinaryOpConstraintExpr (expr
, addent
);
897 ret
->data
= constraintExprData_binaryExprSetOp (ret
->data
, BINARYOP_PLUS
);
903 constraintExpr
constraintExpr_makeIncConstraintExpr (/*@only@*/ constraintExpr expr
)
908 inc
= constraintExpr_makeIntLiteral (1);
909 ret
= constraintExpr_makeBinaryOpConstraintExpr (expr
, inc
);
910 ret
->data
= constraintExprData_binaryExprSetOp(ret
->data
, BINARYOP_PLUS
);
915 static cstring
constraintExprUnaryOpKind_print (constraintExprUnaryOpKind op
)
920 return message("maxSet");
922 return message("minSet");
924 return message("maxRead");
926 return message("minRead");
929 return message ("<(Unary OP OTHER>");
935 static cstring
constraintExprBinaryOpKind_print (constraintExprBinaryOpKind op
)
947 return message ("<binary OP Unknown>");
951 bool constraintExpr_similar (constraintExpr expr1
, constraintExpr expr2
)
953 constraintExprKind kind
;
955 llassert (expr1
!= NULL
);
956 llassert (expr2
!= NULL
);
957 if (expr1
->kind
!= expr2
->kind
)
965 return constraintTerm_similar (constraintExprData_termGetTerm(expr1
->data
),
966 constraintExprData_termGetTerm(expr2
->data
) );
967 /*@notreached@*/ break;
970 if (constraintExprData_unaryExprGetOp (expr1
->data
) != constraintExprData_unaryExprGetOp (expr2
->data
) )
973 return (constraintExpr_similar (
974 constraintExprData_unaryExprGetExpr (expr1
->data
),
975 constraintExprData_unaryExprGetExpr (expr2
->data
)
979 if (constraintExprData_binaryExprGetOp (expr1
->data
) != constraintExprData_binaryExprGetOp (expr2
->data
) )
982 if (! constraintExpr_similar (constraintExprData_binaryExprGetExpr1 (expr1
->data
),
983 constraintExprData_binaryExprGetExpr1 (expr2
->data
)) )
986 if (! constraintExpr_similar (constraintExprData_binaryExprGetExpr2 (expr1
->data
),
987 constraintExprData_binaryExprGetExpr2 (expr2
->data
)) )
1002 bool constraintExpr_same (constraintExpr expr1
, constraintExpr expr2
)
1004 constraintExprKind kind
;
1006 llassert (expr1
!= NULL
);
1007 llassert (expr2
!= NULL
);
1008 if (expr1
->kind
!= expr2
->kind
)
1016 return constraintTerm_similar (constraintExprData_termGetTerm(expr1
->data
),
1017 constraintExprData_termGetTerm(expr2
->data
) );
1020 if (constraintExprData_unaryExprGetOp (expr1
->data
) != constraintExprData_unaryExprGetOp (expr2
->data
) )
1023 return (constraintExpr_same (
1024 constraintExprData_unaryExprGetExpr (expr1
->data
),
1025 constraintExprData_unaryExprGetExpr (expr2
->data
)
1029 if (constraintExprData_binaryExprGetOp (expr1
->data
) != constraintExprData_binaryExprGetOp (expr2
->data
) )
1032 if (! constraintExpr_same (constraintExprData_binaryExprGetExpr1 (expr1
->data
),
1033 constraintExprData_binaryExprGetExpr1 (expr2
->data
)) )
1036 if (! constraintExpr_same (constraintExprData_binaryExprGetExpr2 (expr1
->data
),
1037 constraintExprData_binaryExprGetExpr2 (expr2
->data
)) )
1047 constraintExpr_search (/*@observer@*/ constraintExpr c
,
1048 /*@observer@*/ constraintExpr old
)
1051 constraintExprKind kind
;
1052 constraintExpr temp
;
1054 if (constraintExpr_similar (c
, old
))
1056 DPRINTF (("Found %q", constraintExpr_unparse (old
)));
1060 llassert (constraintExpr_isDefined (c
) && constraintExpr_isDefined(old
) );
1062 if ( !(constraintExpr_isDefined (c
) && constraintExpr_isDefined(old
) ) )
1072 temp
= constraintExprData_unaryExprGetExpr (c
->data
);
1073 ret
= ret
|| constraintExpr_search (temp
, old
);
1077 temp
= constraintExprData_binaryExprGetExpr1 (c
->data
);
1078 ret
= ret
|| constraintExpr_search(temp
, old
);
1080 temp
= constraintExprData_binaryExprGetExpr2 (c
->data
);
1081 ret
= ret
|| constraintExpr_search(temp
, old
);
1091 /*@only@*/ constraintExpr
1092 constraintExpr_searchandreplace (/*@only@*/ /*@unique@*/ constraintExpr c
, /*@temp@*/ constraintExpr old
,
1093 /*@temp@*/ constraintExpr newExpr
)
1095 constraintExprKind kind
;
1096 constraintExpr temp
;
1099 llassert (constraintExpr_isDefined (newExpr
) && (constraintExpr_isDefined (old
) && constraintExpr_isDefined(c
) ) );
1101 if (constraintExpr_similar (c
, old
))
1103 ctype newType
= ctype_unknown
;
1104 ctype cType
= ctype_unknown
;
1106 ret
= constraintExpr_copy (newExpr
);
1107 llassert(constraintExpr_isDefined(ret
) );
1108 /*drl if newExpr != NULL then ret will != NULL*/
1110 DPRINTF (("Replacing %s with %s in %s",
1111 constraintExpr_unparse (old
), constraintExpr_unparse (newExpr
),
1112 constraintExpr_unparse (c
)));
1114 if (constraintExpr_canGetCType (c
) && constraintExpr_canGetCType (newExpr
))
1116 cType
= constraintExpr_getCType(c
);
1117 newType
= constraintExpr_getCType (newExpr
);
1119 if (ctype_match (cType
,newType
))
1121 DPRINTF (("constraintExpr_searchandreplace: replacing "
1122 " %s with type %s with %s with type %s",
1123 constraintExpr_unparse (c
), ctype_unparse(cType
),
1124 constraintExpr_unparse (newExpr
), ctype_unparse(newType
)));
1127 ret
->origType
= cType
;
1128 DPRINTF (("Type: %s", ctype_unparse (constraintExpr_getCType (ret
))));
1132 if (constraintExpr_hasMaxSet (c
))
1134 if (constraintExpr_hasTypeChange (c
))
1136 fileloc loc
= constraintExpr_loc (c
);
1137 DPRINTF (("constraintExpr_searchandreplace: encountered "
1138 "MaxSet with changed type %s ",
1139 constraintExpr_unparse (c
)));
1141 if (c
->kind
== unaryExpr
)
1143 constraintExpr ce
= constraintExprData_unaryExprGetExpr (c
->data
);
1144 DPRINTF (("Its a unary! %s / %s",
1145 ctype_unparse (constraintExpr_getCType (ce
)),
1146 ctype_unparse (constraintExpr_getOrigType (ce
))));
1147 ret
= constraintExpr_adjustMaxSetForCast (ret
, constraintExpr_getCType (ce
),
1148 constraintExpr_getOrigType (ce
),
1153 /* fix this with a conversation */
1154 DPRINTF (("Types: %s / %s", ctype_unparse (newType
), ctype_unparse (cType
)));
1155 ret
= constraintExpr_adjustMaxSetForCast (ret
, constraintExpr_getCType (c
),
1156 constraintExpr_getOrigType(c
),
1162 constraintExpr_free (c
);
1163 DPRINTF (("ret: %s", constraintExpr_unparse (ret
)));
1174 DPRINTF (("Making unary expression!"));
1175 temp
= constraintExprData_unaryExprGetExpr (c
->data
);
1176 temp
= constraintExpr_copy (temp
);
1177 temp
= constraintExpr_searchandreplace (temp
, old
, newExpr
);
1178 c
->data
= constraintExprData_unaryExprSetExpr (c
->data
, temp
);
1181 DPRINTF (("Making binary expression!"));
1182 temp
= constraintExprData_binaryExprGetExpr1 (c
->data
);
1183 temp
= constraintExpr_copy (temp
);
1184 temp
= constraintExpr_searchandreplace (temp
, old
, newExpr
);
1185 c
->data
= constraintExprData_binaryExprSetExpr1 (c
->data
, temp
);
1187 temp
= constraintExprData_binaryExprGetExpr2 (c
->data
);
1188 temp
= constraintExpr_copy (temp
);
1189 temp
= constraintExpr_searchandreplace (temp
, old
, newExpr
);
1190 c
->data
= constraintExprData_binaryExprSetExpr2 (c
->data
, temp
);
1196 DPRINTF (("ret: %s", constraintExpr_unparse (c
)));
1200 /*@notnull@*/ static constraintExpr
constraintExpr_simplifyChildren (/*@returned@*/ /*@notnull@*/ constraintExpr c
)
1202 constraintExprKind kind
;
1203 constraintExpr temp
;
1212 temp
= constraintExprData_unaryExprGetExpr (c
->data
);
1213 temp
= constraintExpr_copy(temp
);
1214 temp
= constraintExpr_simplify (temp
);
1215 c
->data
= constraintExprData_unaryExprSetExpr (c
->data
, temp
);
1218 DPRINTF((message("constraintExpr_simplfiyChildren: simplify binary expression: %s",constraintExpr_unparse(c
) ) ) );
1219 temp
= constraintExprData_binaryExprGetExpr1 (c
->data
);
1220 temp
= constraintExpr_copy(temp
);
1221 temp
= constraintExpr_simplify (temp
);
1223 c
->data
= constraintExprData_binaryExprSetExpr1 (c
->data
, temp
);
1225 temp
= constraintExprData_binaryExprGetExpr2 (c
->data
);
1226 temp
= constraintExpr_copy(temp
);
1227 temp
= constraintExpr_simplify (temp
);
1229 c
->data
= constraintExprData_binaryExprSetExpr2 (c
->data
, temp
);
1239 constraintExpr
constraintExpr_setFileloc (/*@returned@*/ constraintExpr c
, fileloc loc
) /*@modifies c @*/
1242 constraintExpr temp
;
1244 llassert(c
!= NULL
);
1249 t
= constraintExprData_termGetTerm (c
->data
);
1250 t
= constraintTerm_copy(t
);
1251 t
= constraintTerm_setFileloc (t
, loc
);
1252 c
->data
= constraintExprData_termSetTerm (c
->data
, t
);
1256 temp
= constraintExprData_binaryExprGetExpr1 (c
->data
);
1257 temp
= constraintExpr_copy(temp
);
1258 temp
= constraintExpr_setFileloc (temp
, loc
);
1259 c
->data
= constraintExprData_binaryExprSetExpr1 (c
->data
, temp
);
1261 temp
= constraintExprData_binaryExprGetExpr2 (c
->data
);
1262 temp
= constraintExpr_copy(temp
);
1263 temp
= constraintExpr_setFileloc (temp
, loc
);
1264 c
->data
= constraintExprData_binaryExprSetExpr2 (c
->data
, temp
);
1267 temp
= constraintExprData_unaryExprGetExpr (c
->data
);
1268 temp
= constraintExpr_copy(temp
);
1269 temp
= constraintExpr_setFileloc (temp
, loc
);
1270 c
->data
= constraintExprData_unaryExprSetExpr (c
->data
, temp
);
1276 static /*@only@*/ constraintExpr
constraintExpr_simplifybinaryExpr (/*@only@*/ /*@notnull@*/ constraintExpr c
)
1278 constraintExpr e1
, e2
;
1279 constraintExprBinaryOpKind op
;
1281 e1
= constraintExprData_binaryExprGetExpr1 (c
->data
);
1282 e2
= constraintExprData_binaryExprGetExpr2 (c
->data
);
1284 if (constraintExpr_canGetValue (e1
) && constraintExpr_canGetValue(e2
) )
1288 i
= constraintExpr_getValue(e1
) + constraintExpr_getValue (e2
);
1289 constraintExpr_free(c
);
1290 c
= constraintExpr_makeIntLiteral (i
);
1294 op
= constraintExprData_binaryExprGetOp (c
->data
);
1295 if (op
== BINARYOP_MINUS
)
1296 if (constraintExpr_similar(e1
, e2
) )
1298 constraintExpr_free(c
);
1299 c
= constraintExpr_makeIntLiteral (0);
1307 this thing takes the lexpr and expr of a constraint and modifies lexpr
1308 and returns a (possiblly new) value for expr
1310 /* 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 */
1312 /* the approach is a little Kludgy but seems to work. I should probably use something cleaner at some point ... */
1315 /*@only@*/ constraintExpr
constraintExpr_solveBinaryExpr (constraintExpr lexpr
, /*@only@*/ constraintExpr expr
)
1317 constraintExpr expr1
, expr2
;
1318 constraintExprBinaryOpKind op
;
1320 llassert(constraintExpr_isDefined (lexpr
) && constraintExpr_isDefined (expr
) );
1322 if (lexpr
->kind
!= binaryexpr
)
1325 expr2
= constraintExprData_binaryExprGetExpr2 (lexpr
->data
);
1326 expr1
= constraintExprData_binaryExprGetExpr1 (lexpr
->data
);
1328 op
= constraintExprData_binaryExprGetOp (lexpr
->data
);
1330 expr1
= constraintExpr_copy(expr1
);
1331 expr2
= constraintExpr_copy(expr2
);
1333 llassert(constraintExpr_isDefined (expr1
) && constraintExpr_isDefined (expr2
) );
1335 /* drl possible problem : warning make sure this works */
1337 lexpr
->kind
= expr1
->kind
;
1338 sfree (lexpr
->data
);
1340 lexpr
->data
= copyExprData (expr1
->data
, expr1
->kind
);
1341 constraintExpr_free(expr1
);
1343 if (op
== BINARYOP_PLUS
)
1344 expr
= constraintExpr_makeSubtractExpr (expr
, expr2
);
1345 else if (op
== BINARYOP_MINUS
)
1346 expr
= constraintExpr_makeAddExpr (expr
, expr2
);
1353 #warning this needs to be checked
1354 expr = constraintExpr_solveBinaryExpr (expr1, expr);
1356 expr = constraintExpr_solveBinaryExpr (expr2, expr);
1361 static /*@only@*/ constraintExpr
constraintExpr_simplifyunaryExpr (/*@only@*/ constraintExpr c
)
1365 llassert(constraintExpr_isDefined (c
) );
1366 llassert (c
->kind
== unaryExpr
);
1368 DPRINTF ((message ("Doing constraintExpr_simplifyunaryExpr:%s", constraintExpr_unparse (c
) ) ) );
1370 if ((constraintExprData_unaryExprGetOp (c
->data
) != MAXSET
) &&
1371 (constraintExprData_unaryExprGetOp (c
->data
) != MAXREAD
) )
1376 exp
= constraintExprData_unaryExprGetExpr (c
->data
);
1377 exp
= constraintExpr_copy(exp
);
1379 llassert(constraintExpr_isDefined (exp
) );
1381 if (exp
->kind
== term
)
1383 constraintTerm cterm
;
1385 cterm
= constraintExprData_termGetTerm (exp
->data
);
1387 if (constraintTerm_isStringLiteral(cterm
) )
1390 val
= constraintTerm_getStringLiteral (cterm
);
1391 if (constraintExprData_unaryExprGetOp (c
->data
) == MAXSET
)
1393 constraintExpr temp
;
1395 temp
= constraintExpr_makeIntLiteral ((int)strlen (cstring_toCharsSafe(val
) ) );
1397 constraintExpr_free(c
);
1398 constraintExpr_free(exp
);
1403 if (constraintExprData_unaryExprGetOp (c
->data
) == MAXREAD
)
1405 constraintExpr temp
;
1407 temp
= constraintExpr_makeIntLiteral ((int)strlen (cstring_toCharsSafe(val
) ) );
1409 constraintExpr_free(c
);
1410 constraintExpr_free(exp
);
1417 /* slight Kludge to handle var [] = { , , };
1418 ** type syntax I don't think this is sound but it should be good
1419 ** enough. The C standard is very confusing about initialization
1423 if (constraintTerm_isInitBlock(cterm
) )
1425 constraintExpr temp
;
1428 len
= constraintTerm_getInitBlockLength(cterm
);
1430 /* -- drl 12/08/2003 : decrementing to fix off by one error */
1434 temp
= constraintExpr_makeIntLiteral (len
);
1436 constraintExpr_free(c
);
1437 DPRINTF(( message("Changed to %q", constraintExpr_print(temp
)
1439 constraintExpr_free(exp
);
1443 constraintExpr_free(exp
);
1447 if (exp
->kind
!= binaryexpr
)
1449 constraintExpr_free(exp
);
1453 if (constraintExprData_binaryExprGetOp (exp
->data
) == BINARYOP_PLUS
)
1456 /* if (constraintExpr_canGetValue (constraintExprData_binaryExprGetExpr2 (exp->data) ) ) */
1459 constraintExpr temp
, temp2
;
1461 DPRINTF ((message ("Doing fancy simplification") ) );
1463 temp
= constraintExprData_binaryExprGetExpr2 (exp
->data
);
1465 temp2
= constraintExprData_binaryExprGetExpr1 (exp
->data
);
1467 temp2
= constraintExpr_copy(temp2
);
1468 c
->data
= constraintExprData_unaryExprSetExpr (c
->data
, temp2
);
1471 temp
= constraintExpr_copy (temp
);
1473 c
= constraintExpr_makeSubtractExpr (c
, temp
);
1475 DPRINTF ((message ("Done fancy simplification:%s", constraintExpr_unparse (c
) ) ) );
1479 DPRINTF ((message ("constraintExpr_simplifyUnaryExpr: Done simplification:%s", constraintExpr_unparse (c
) ) ) );
1481 constraintExpr_free(exp
);
1486 /*@only@*/ constraintExpr
constraintExpr_simplify (/*@only@*/ constraintExpr c
)
1488 constraintExprKind kind
;
1492 DPRINTF ((message ("Doing constraintExpr_simplify:%s", constraintExpr_unparse (c
) ) ) );
1496 llassert ( constraintExpr_isDefined (c
) );
1497 if (constraintExpr_isUndefined (c
) )
1499 return constraintExpr_undefined
;
1502 ret
= constraintExpr_copy(c
);
1503 llassert(constraintExpr_isDefined (ret
) );
1505 constraintExpr_free(c
);
1507 ret
= constraintExpr_simplifyChildren (ret
);
1509 ret
= constraintExpr_combineConstants (ret
);
1511 ret
= constraintExpr_simplifyChildren (ret
);
1519 t
= constraintExprData_termGetTerm (ret
->data
);
1520 t
= constraintTerm_copy(t
);
1521 t
= constraintTerm_simplify (t
);
1522 ret
->data
= constraintExprData_termSetTerm (ret
->data
, t
);
1525 ret
= constraintExpr_simplifyunaryExpr (ret
);
1528 ret
= constraintExpr_simplifybinaryExpr (ret
);
1534 DPRINTF ((message ("constraintExpr_simplify returning :%s", constraintExpr_unparse (ret
) ) ) );
1540 cstring
constraintExpr_unparse (/*@temp@*/ constraintExpr ex
) /*@*/
1543 constraintExprKind kind
;
1545 llassert (ex
!= NULL
);
1552 if (context_getFlag (FLG_PARENCONSTRAINT
) )
1554 st
= message ("(%q) ", constraintTerm_unparse (constraintExprData_termGetTerm (ex
->data
)));
1558 st
= message ("%q", constraintTerm_unparse (constraintExprData_termGetTerm (ex
->data
)));
1562 st
= message ("%q(%q)",
1563 constraintExprUnaryOpKind_print (constraintExprData_unaryExprGetOp (ex
->data
) ),
1564 constraintExpr_unparse (constraintExprData_unaryExprGetExpr (ex
->data
) )
1568 if (context_getFlag (FLG_PARENCONSTRAINT
) )
1570 st
= message ("(%q) %q (%q)",
1571 constraintExpr_unparse (constraintExprData_binaryExprGetExpr1 (ex
->data
) ),
1572 constraintExprBinaryOpKind_print (constraintExprData_binaryExprGetOp (ex
->data
)),
1573 constraintExpr_unparse (constraintExprData_binaryExprGetExpr2 (ex
->data
) )
1578 st
= message ("%q %q %q",
1579 constraintExpr_unparse (constraintExprData_binaryExprGetExpr1 (ex
->data
)),
1580 constraintExprBinaryOpKind_print (constraintExprData_binaryExprGetOp (ex
->data
)),
1581 constraintExpr_unparse (constraintExprData_binaryExprGetExpr2 (ex
->data
))
1588 st
= message ("error");
1592 DPRINTF((message ("constraintExpr_unparse: '%s'",st
) ) );
1597 constraintExpr
constraintExpr_doSRefFixBaseParam (/*@returned@*/ constraintExpr expr
, exprNodeList arglist
)
1599 constraintTerm Term
;
1600 constraintExprKind kind
;
1601 constraintExpr expr1
, expr2
;
1602 constraintExprData data
;
1603 llassert (expr
!= NULL
);
1612 Term
= constraintExprData_termGetTerm(data
);
1613 Term
= constraintTerm_copy(Term
);
1615 Term
= constraintTerm_doSRefFixBaseParam (Term
, arglist
);
1616 data
= constraintExprData_termSetTerm(data
, Term
);
1619 expr1
= constraintExprData_unaryExprGetExpr (data
);
1620 expr1
= constraintExpr_copy(expr1
);
1622 expr1
= constraintExpr_doSRefFixBaseParam (expr1
, arglist
);
1623 data
= constraintExprData_unaryExprSetExpr (data
, expr1
);
1626 expr1
= constraintExprData_binaryExprGetExpr1 (data
);
1627 expr2
= constraintExprData_binaryExprGetExpr2 (data
);
1629 expr1
= constraintExpr_copy(expr1
);
1630 expr2
= constraintExpr_copy(expr2
);
1632 expr1
= constraintExpr_doSRefFixBaseParam (expr1
, arglist
);
1633 data
= constraintExprData_binaryExprSetExpr1 (data
, expr1
);
1634 expr2
= constraintExpr_doSRefFixBaseParam (expr2
, arglist
);
1635 data
= constraintExprData_binaryExprSetExpr2 (data
, expr2
);
1644 # endif /* DEADCODE */
1647 /*@only@*/ constraintExpr
constraintExpr_doSRefFixInvarConstraint (/ *@only@
* / constraintExpr expr
, sRef s
, ctype ct
)
1649 constraintExprKind kind
;
1650 constraintExpr expr1
, expr2
;
1651 constraintExprData data
;
1652 llassert (expr
!= NULL
);
1661 expr
= doSRefFixInvarConstraintTerm (expr
, s
, ct
);
1664 expr1
= constraintExprData_unaryExprGetExpr (data
);
1665 expr1
= constraintExpr_copy(expr1
);
1666 expr1
= constraintExpr_doSRefFixInvarConstraint (expr1
, s
, ct
);
1667 data
= constraintExprData_unaryExprSetExpr (data
, expr1
);
1670 expr1
= constraintExprData_binaryExprGetExpr1 (data
);
1671 expr2
= constraintExprData_binaryExprGetExpr2 (data
);
1673 expr1
= constraintExpr_copy(expr1
);
1674 expr2
= constraintExpr_copy(expr2
);
1676 expr1
= constraintExpr_doSRefFixInvarConstraint (expr1
, s
, ct
);
1677 data
= constraintExprData_binaryExprSetExpr1 (data
, expr1
);
1678 expr2
= constraintExpr_doSRefFixInvarConstraint (expr2
, s
, ct
);
1679 data
= constraintExprData_binaryExprSetExpr2 (data
, expr2
);
1690 /*@only@*/ constraintExpr
constraintExpr_doSRefFixConstraintParam (/*@only@*/ constraintExpr expr
, exprNodeList arglist
) /*@modifies expr@*/
1692 constraintExprKind kind
;
1693 constraintExpr expr1
, expr2
;
1694 constraintExprData data
;
1695 llassert (expr
!= NULL
);
1704 expr
= doSRefFixConstraintParamTerm (expr
, arglist
);
1707 expr1
= constraintExprData_unaryExprGetExpr (data
);
1708 expr1
= constraintExpr_copy(expr1
);
1709 expr1
= constraintExpr_doSRefFixConstraintParam (expr1
, arglist
);
1710 data
= constraintExprData_unaryExprSetExpr (data
, expr1
);
1713 expr1
= constraintExprData_binaryExprGetExpr1 (data
);
1714 expr2
= constraintExprData_binaryExprGetExpr2 (data
);
1716 expr1
= constraintExpr_copy(expr1
);
1717 expr2
= constraintExpr_copy(expr2
);
1719 expr1
= constraintExpr_doSRefFixConstraintParam (expr1
, arglist
);
1720 data
= constraintExprData_binaryExprSetExpr1 (data
, expr1
);
1721 expr2
= constraintExpr_doSRefFixConstraintParam (expr2
, arglist
);
1722 data
= constraintExprData_binaryExprSetExpr2 (data
, expr2
);
1732 /*@only@*/ constraintExpr
constraintExpr_doFixResult (/*@only@*/ constraintExpr expr
, /*@observer@*/ exprNode fcnCall
)
1734 constraintExprKind kind
;
1735 constraintExpr expr1
, expr2
;
1736 constraintExprData data
;
1737 llassert (expr
!= NULL
);
1746 expr
= doFixResultTerm (expr
, fcnCall
);
1749 expr1
= constraintExprData_unaryExprGetExpr (data
);
1750 expr1
= constraintExpr_copy(expr1
);
1752 expr1
= constraintExpr_doFixResult (expr1
, fcnCall
);
1753 data
= constraintExprData_unaryExprSetExpr (data
, expr1
);
1756 expr1
= constraintExprData_binaryExprGetExpr1 (data
);
1757 expr2
= constraintExprData_binaryExprGetExpr2 (data
);
1759 expr1
= constraintExpr_copy(expr1
);
1760 expr2
= constraintExpr_copy(expr2
);
1762 expr1
= constraintExpr_doFixResult (expr1
, fcnCall
);
1763 data
= constraintExprData_binaryExprSetExpr1 (data
, expr1
);
1764 expr2
= constraintExpr_doFixResult (expr2
, fcnCall
);
1765 data
= constraintExprData_binaryExprSetExpr2 (data
, expr2
);
1774 cstring
constraintExpr_print (constraintExpr expr
) /*@*/
1776 return constraintExpr_unparse (expr
);
1779 bool constraintExpr_hasMaxSet (constraintExpr expr
) /*@*/
1784 t
= constraintExpr_unparse(expr
);
1786 ret
= cstring_containsLit(t
, "maxSet");
1794 /*returns 1 0 -1 like strcmp
1800 int constraintExpr_compare (constraintExpr expr1
, constraintExpr expr2
)
1802 long value1
, value2
;
1804 if (constraintExpr_similar (expr1
, expr2
) )
1809 value1
= constraintExpr_getValue(expr1
);
1810 value2
= constraintExpr_getValue(expr2
);
1812 if (value1
> value2
)
1815 if (value1
== value2
)
1822 long constraintExpr_getValue (constraintExpr expr
)
1824 llassert (constraintExpr_isDefined(expr
) );
1825 llassert (expr
->kind
== term
);
1827 return (constraintTerm_getValue (constraintExprData_termGetTerm (expr
->data
)));
1830 bool constraintExpr_canGetValue (constraintExpr expr
)
1832 llassert ( constraintExpr_isDefined (expr
));
1833 if (constraintExpr_isUndefined (expr
))
1841 return constraintTerm_canGetValue (constraintExprData_termGetTerm (expr
->data
) );
1847 fileloc
constraintExpr_loc (constraintExpr expr
)
1851 constraintExprKind kind
;
1853 llassert ( constraintExpr_isDefined (expr
) );
1854 if (constraintExpr_isUndefined (expr
) )
1856 return fileloc_undefined
;
1865 t
= constraintExprData_termGetTerm (expr
->data
);
1866 return (constraintTerm_getFileloc (t
) );
1870 e
= constraintExprData_unaryExprGetExpr (expr
->data
);
1871 return (constraintExpr_loc (e
) );
1875 e
= constraintExprData_binaryExprGetExpr1 (expr
->data
);
1876 return (constraintExpr_loc (e
) );
1881 return (fileloc_undefined
);
1884 /*drl moved from constriantTerm.c 5/20/001*/
1885 static /*@only@*/ constraintExpr
1886 doFixResultTerm (/*@only@*/ constraintExpr e
, /*@exposed@*/ exprNode fcnCall
)
1890 constraintExprData data
;
1891 constraintExprKind kind
;
1894 llassert (constraintExpr_isDefined (e
) );
1899 llassert (kind
== term
);
1901 t
= constraintExprData_termGetTerm (data
);
1902 llassert (constraintTerm_isDefined (t
));
1906 switch (constraintTerm_getKind (t
))
1909 case CTT_INTLITERAL
:
1913 s
= constraintTerm_getSRef(t
);
1914 if (sRef_isResult (s
))
1916 ret
= constraintExpr_makeExprNode(fcnCall
);
1917 constraintExpr_free(e
);
1930 /*to be used for structure checking */
1932 / *@only@
* / static constraintExpr
1933 doSRefFixInvarConstraintTerm (/ *@only@
* / constraintExpr e
, sRef s
, ctype ct
)
1937 constraintExprData data
= e
->data
;
1939 constraintExprKind kind
= e
->kind
;
1943 llassert(kind
== term
);
1945 t
= constraintExprData_termGetTerm (data
);
1946 llassert (constraintTerm_isDefined(t
) );
1950 DPRINTF (("Fixing: %s", constraintExpr_print (e
)));
1952 switch (constraintTerm_getKind(t
))
1955 DPRINTF((message ("%q @ %q ", constraintTerm_unparse(t
),
1956 fileloc_unparse (constraintTerm_getFileloc(t
) ) ) ));
1958 case CTT_INTLITERAL
:
1959 DPRINTF((message (" %q ", constraintTerm_unparse (t
)) ));
1963 / * evans
2001-07-24: constants should use the original term
* /
1964 if (!constraintTerm_canGetValue (t
))
1967 DPRINTF ((message("Doing sRef_fixInvarConstraint for %q ",
1968 constraintTerm_unparse (t
) ) ));
1970 snew
= fixSref (ct
, s
, constraintTerm_getSRef(t
));
1972 ret
= constraintExpr_makeTermsRef(snew
);
1974 constraintExpr_free (e
);
1976 DPRINTF (( message("After Doing sRef_fixConstraintParam constraintExpr is %q ",
1977 constraintExpr_print (ret
) ) ));
1978 / *@
-branchstate@
* /
1979 } / *@
=branchstate@
* /
1990 /*drl moved from constriantTerm.c 5/20/001*/
1991 /*@only@*/ static constraintExpr
1992 doSRefFixConstraintParamTerm (/*@only@*/ constraintExpr e
, /*@observer@*/ /*@temp@*/ exprNodeList arglist
)
1996 constraintExprData data
;
1998 constraintExprKind kind
;
2003 llassert(constraintExpr_isDefined (e
) );
2011 llassert(kind
== term
);
2013 t
= constraintExprData_termGetTerm (data
);
2014 llassert (constraintTerm_isDefined(t
) );
2018 DPRINTF (("Fixing: %s", constraintExpr_print (e
)));
2020 switch (constraintTerm_getKind(t
))
2023 DPRINTF((message ("%q @ %q ", constraintTerm_unparse(t
),
2024 fileloc_unparse (constraintTerm_getFileloc(t
) ) ) ));
2026 case CTT_INTLITERAL
:
2027 DPRINTF((message (" %q ", constraintTerm_unparse (t
)) ));
2030 /* evans 2001-07-24: constants should use the original term */
2031 if (!constraintTerm_canGetValue (t
))
2033 DPRINTF ((message("Doing sRef_fixConstraintParam for %q ",
2034 constraintTerm_unparse (t
) ) ));
2035 ret
= sRef_fixConstraintParam (constraintTerm_getSRef(t
), arglist
);
2037 constraintExpr_free (e
);
2039 DPRINTF (( message("After Doing sRef_fixConstraintParam constraintExpr is %q ",
2040 constraintExpr_print (ret
) ) ));
2042 } /*@=branchstate@*/
2054 bool constraintExpr_includesTerm (constraintExpr expr
, constraintTerm term
)
2056 if (constraintTerm_hasTerm (expr
->term
, term
) )
2059 if ((expr
->expr
) != NULL
)
2061 return ( constraintExpr_includesTerm (expr
->expr
, term
) );
2068 /*drl added 6/11/01 */
2069 bool constraintExpr_isBinaryExpr (/*@observer@*/ constraintExpr c
)
2072 llassert(constraintExpr_isDefined (c
) );
2074 if ( ! (constraintExpr_isDefined (c
) ) )
2077 if (c
->kind
== binaryexpr
)
2084 /*drl added 8/08/001 */
2085 bool constraintExpr_isTerm (/*@observer@*/ constraintExpr c
) /*@*/
2087 llassert(constraintExpr_isDefined (c
) );
2089 if (c
->kind
== term
)
2096 /*@observer@*/ /*@temp@*/ constraintTerm
constraintExpr_getTerm ( /*@temp@*/ /*@observer@*/ constraintExpr c
) /*@*/
2098 constraintTerm term
;
2100 llassert(constraintExpr_isDefined (c
) );
2102 llassert(constraintExpr_isTerm(c
) );
2104 term
= constraintExprData_termGetTerm(c
->data
);
2109 static void binaryExpr_dump (/*@observer@*/ constraintExprData data
, FILE *f
)
2111 constraintExpr expr1
;
2112 constraintExprBinaryOpKind binaryOp
;
2113 constraintExpr expr2
;
2116 binaryOp
= constraintExprData_binaryExprGetOp (data
);
2118 fprintf(f
, "%d\n", (int) binaryOp
);
2120 expr1
= constraintExprData_binaryExprGetExpr1 (data
);
2121 expr2
= constraintExprData_binaryExprGetExpr2 (data
);
2125 constraintExpr_dump(expr1
, f
);
2128 constraintExpr_dump(expr2
, f
);
2132 static constraintExpr
binaryExpr_undump (FILE *f
)
2134 constraintExpr expr1
;
2135 constraintExprBinaryOpKind binaryOp
;
2136 constraintExpr expr2
;
2145 os
= mstring_create (MAX_DUMP_LINE_LENGTH
);
2147 str
= fgets(os
, MAX_DUMP_LINE_LENGTH
, f
);
2149 if (! mstring_isDefined(str
) )
2151 llfatalbug(message("Library file is corrupted") );
2154 binaryOp
= (constraintExprBinaryOpKind
) reader_getInt(&str
);
2156 str
= fgets(os
, MAX_DUMP_LINE_LENGTH
, f
);
2158 if (! mstring_isDefined(str
) )
2160 llfatalbug(message("Library file is corrupted") );
2163 reader_checkChar (&str
, 'e');
2164 reader_checkChar (&str
, '1');
2166 expr1
= constraintExpr_undump (f
);
2168 str
= fgets(os
, MAX_DUMP_LINE_LENGTH
, f
);
2170 reader_checkChar (&str
, 'e');
2171 reader_checkChar (&str
, '2');
2173 expr2
= constraintExpr_undump (f
);
2175 ret
= constraintExpr_makeBinaryOpConstraintExpr (expr1
, expr2
);
2176 ret
->data
= constraintExprData_binaryExprSetOp(ret
->data
, binaryOp
);
2184 static void unaryExpr_dump (/*@observer@*/ constraintExprData data
, FILE *f
)
2187 constraintExpr expr
;
2188 constraintExprUnaryOpKind unaryOp
;
2190 unaryOp
= constraintExprData_unaryExprGetOp (data
);
2192 fprintf(f
, "%d\n", (int) unaryOp
);
2194 expr
= constraintExprData_unaryExprGetExpr (data
);
2196 constraintExpr_dump(expr
, f
);
2199 static constraintExpr
unaryExpr_undump ( FILE *f
)
2202 constraintExpr expr
;
2203 constraintExprUnaryOpKind unaryOp
;
2209 str
= mstring_create (MAX_DUMP_LINE_LENGTH
);
2211 str
= fgets(os
, MAX_DUMP_LINE_LENGTH
, f
);
2213 if (! mstring_isDefined(str
) )
2215 llfatalbug(message("Library file is corrupted") );
2218 unaryOp
= (constraintExprUnaryOpKind
) reader_getInt(&str
);
2220 expr
= constraintExpr_undump (f
);
2222 ret
= constraintExpr_makeUnaryOp (expr
, unaryOp
);
2229 void constraintExpr_dump (/*@observer@*/ constraintExpr expr
, FILE *f
)
2231 constraintExprKind kind
;
2235 llassert(constraintExpr_isDefined(expr
) );
2237 DPRINTF((message("constraintExpr_dump:: dumping constraintExpr %s",
2238 constraintExpr_unparse(expr
)
2243 fprintf(f
,"%d\n", (int) kind
);
2248 t
= constraintExprData_termGetTerm (expr
->data
);
2249 constraintTerm_dump (t
, f
);
2252 unaryExpr_dump (expr
->data
, f
);
2255 binaryExpr_dump (expr
->data
, f
);
2260 /*@only@*/ constraintExpr
constraintExpr_undump (FILE *f
)
2262 constraintExprKind kind
;
2269 os
= mstring_create (MAX_DUMP_LINE_LENGTH
);
2270 s
= fgets(os
, MAX_DUMP_LINE_LENGTH
, f
);
2271 if (! mstring_isDefined(s
))
2273 llfatalbug(message("Library file is corrupted") );
2276 kind
= (constraintExprKind
) reader_getInt(&s
);
2283 t
= constraintTerm_undump (f
);
2284 ret
= constraintExpr_makeTerm(t
);
2287 ret
= unaryExpr_undump (f
);
2290 ret
= binaryExpr_undump (f
);
2298 int constraintExpr_getDepth (constraintExpr ex
)
2302 constraintExprKind kind
;
2304 llassert (ex
!= NULL
);
2314 ret
= constraintExpr_getDepth (constraintExprData_unaryExprGetExpr (ex
->data
) );
2318 ret
= constraintExpr_getDepth (constraintExprData_binaryExprGetExpr1 (ex
->data
) );
2320 ret
+= constraintExpr_getDepth (constraintExprData_binaryExprGetExpr2 (ex
->data
) );
2329 bool constraintExpr_canGetCType (constraintExpr e
) /*@*/
2331 if (constraintExpr_isUndefined(e
))
2334 if (e
->kind
== term
)
2340 DPRINTF (("constraintExpr_canGetCType: can't get type for %s", constraintExpr_unparse (e
)));
2345 ctype
constraintExpr_getCType (constraintExpr e
) /*@*/
2349 llassert (constraintExpr_isDefined (e
));
2350 llassert (constraintExpr_canGetCType (e
));
2355 t
= constraintExprData_termGetTerm (e
->data
);
2356 return (constraintTerm_getCType(t
) );
2357 /* assume that a unary expression will be an int ... */
2359 return ctype_unknown
; /* was ctype_signedintegral; */
2360 /* drl for just return type of first operand */
2362 return (constraintExpr_getCType (constraintExprData_binaryExprGetExpr1 (e
->data
)));
2367 /* drl add 10-5-001 */
2369 static bool constraintExpr_hasTypeChange (constraintExpr e
)
2371 llassert(constraintExpr_isDefined(e
));
2373 if (constraintExpr_isDefined((e
)) && (e
->ct
== TRUE
))
2378 if (e
->kind
== unaryExpr
)
2380 if (constraintExprData_unaryExprGetOp (e
->data
) == MAXSET
)
2382 constraintExpr ce
= constraintExprData_unaryExprGetExpr(e
->data
);
2383 DPRINTF (("Unary type change: [%x] %s", ce
, constraintExpr_unparse (ce
)));
2384 DPRINTF (("Types: %s / %s", ctype_unparse (constraintExpr_getCType (ce
)),
2385 ctype_unparse (constraintExpr_getOrigType (ce
))));
2386 return (constraintExpr_hasTypeChange(ce
));
2393 /* drl add 10-5-001 */
2395 static ctype
constraintExpr_getOrigType (constraintExpr e
)
2397 llassert (constraintExpr_isDefined (e
));
2398 llassert (constraintExpr_hasTypeChange (e
));
2405 if (e
->kind
== unaryExpr
)
2407 if (constraintExprData_unaryExprGetOp (e
->data
) == MAXSET
)
2409 constraintExpr ce
= constraintExprData_unaryExprGetExpr (e
->data
);
2410 return (constraintExpr_getOrigType(ce
));
2418 /*drl added these around 10/18/001*/
2420 static /*@only@*/ constraintExpr
2421 constraintExpr_div (/*@only@*/ constraintExpr e
, ctype tfrom
, ctype tto
, fileloc loc
)
2423 int sizefrom
= ctype_getSize (tfrom
);
2424 int sizeto
= ctype_getSize (tto
);
2426 DPRINTF (("constraintExpr_div: %s", constraintExpr_unparse (e
)));
2427 DPRINTF (("Types: %s / %s",
2428 ctype_unparse (tfrom
),
2429 ctype_unparse (tto
)));
2431 if (sizefrom
== -1) {
2432 llbug (message ("constraintExpr_div: type size unknown: %s", ctype_unparse (tfrom
)));
2436 llbug (message ("constraintExpr_div: type size unknown: %s", ctype_unparse (tto
)));
2439 if (sizeto
== sizefrom
)
2441 DPRINTF (("Sizes match: %d / %d", sizeto
, sizefrom
));
2442 ; /* Sizes match, a-ok */
2446 float scale
= (float) sizefrom
/ (float) sizeto
;
2452 llassert (e
!= NULL
);
2453 llassert (e
->kind
== term
);
2454 ct
= constraintExprData_termGetTerm (e
->data
);
2455 DPRINTF (("constraint: %s / %s", constraintExpr_unparse (e
), constraintTerm_unparse (ct
)));
2456 llassert (constraintTerm_canGetValue (ct
));
2457 val
= constraintTerm_getValue (ct
);
2459 DPRINTF (("Scaling constraints by: %ld * %f", val
, scale
));
2461 fnewval
= ((float) val
) * scale
;
2462 newval
= (long) fnewval
;
2464 DPRINTF (("Values: %f / %ld", fnewval
, newval
));
2466 if ((fnewval
- (float) newval
) > FLT_EPSILON
)
2468 voptgenerror (FLG_ALLOCMISMATCH
,
2469 message ("Allocated memory is converted to type %s of (size %d), "
2470 "which is not divisible into original allocation of space "
2471 "for %d elements of type %s (size %d)",
2472 ctype_unparse (tto
), sizeto
,
2473 long_toInt (val
), ctype_unparse (tfrom
), sizefrom
),
2477 constraintTerm_setValue (ct
, newval
);
2480 DPRINTF (("After div: %s", constraintExpr_unparse (e
)));
2485 /*@access exprNode@*/
2486 static /*@only@*/ constraintExpr
2487 constraintTerm_simpleDivTypeExprNode (/*@only@*/ constraintExpr e
, ctype tfrom
, ctype tto
, fileloc loc
)
2490 exprNode t1
, t2
, expr
;
2494 llassert (constraintExpr_isDefined(e
) );
2496 DPRINTF (("constraintTerm_simpleDivTypeExprNode e=%s [%s => %s]", constraintExpr_print(e
),
2497 ctype_unparse(tfrom
), ctype_unparse (tto
)));
2499 t
= constraintExprData_termGetTerm (e
->data
);
2501 expr
= constraintTerm_getExprNode (t
);
2503 llassert (constraintExpr_isDefined(e
));
2504 llassert (exprNode_isDefined(expr
));
2506 if (expr
->kind
== XPR_OP
)
2510 t1
= exprData_getOpA (data
);
2511 t2
= exprData_getOpB (data
);
2512 tok
= exprData_getOpTok (data
);
2514 if (lltok_isMult (tok
))
2517 ** If the sizeof is first, flip them.
2520 llassert (exprNode_isDefined(t1
) && exprNode_isDefined(t2
));
2522 if (t2
->kind
== XPR_SIZEOF
|| t2
->kind
== XPR_SIZEOFT
)
2529 /*drl 3/2/2003 we know this from the fact that it's a
2530 multiplication operation...*/
2532 if (t1
->kind
== XPR_SIZEOF
|| t1
->kind
== XPR_SIZEOFT
)
2536 if (t1
->kind
== XPR_SIZEOFT
)
2538 multype
= qtype_getType (exprData_getType (t1
->edata
));
2542 exprNode tempE
= exprData_getSingle (t1
->edata
);
2543 multype
= exprNode_getType (tempE
);
2546 DPRINTF (("Here we go sizeof: %s / %s / %s",
2547 ctype_unparse (multype
), ctype_unparse (tfrom
), ctype_unparse (tto
)));
2548 llassert (ctype_isPointer (tfrom
));
2550 if (ctype_almostEqual (ctype_makePointer (multype
), tto
))
2552 /* this is a bit sloopy but ... */
2553 constraintExpr_free (e
);
2554 DPRINTF (("Sizeof types match okay!"));
2555 return constraintExpr_makeExprNode (t2
);
2559 int sizemul
= ctype_getSize (multype
);
2560 ctype tobase
= ctype_baseArrayPtr (tto
);
2561 int sizeto
= ctype_getSize (tobase
);
2563 DPRINTF (("Types: %s / %s / %s",
2564 ctype_unparse (tfrom
), ctype_unparse (tto
), ctype_unparse (multype
)));
2566 voptgenerror (FLG_ALLOCMISMATCH
,
2567 message ("Allocated memory is used as a different type (%s) from the sizeof type (%s)",
2568 ctype_unparse (tobase
), ctype_unparse (multype
)),
2571 if (sizemul
== sizeto
)
2573 constraintExpr_free (e
);
2574 DPRINTF (("Sizeof types match okay!"));
2575 return constraintExpr_makeExprNode (t2
);
2579 /* nothing was here */
2580 DPRINTF (("MISMATCHING TYPES!"));
2581 return (constraintExpr_div (constraintExpr_makeExprNode (t2
), multype
, tto
, loc
));
2587 DPRINTF (("NOT A SIZEOF!"));
2593 DPRINTF (("Not a mult: %s", constraintExpr_unparse (e
)));
2597 return (constraintExpr_div (e
, tfrom
, tto
, loc
));
2599 /*@noaccess exprNode@*/
2601 static /*@only@*/ constraintExpr
simpleDivType (/*@only@*/ constraintExpr e
, ctype tfrom
, ctype tto
, fileloc loc
)
2603 DPRINTF (("simpleDiv got %s", constraintExpr_unparse(e
)));
2604 DPRINTF (("Types: %s / %s",
2605 ctype_unparse (tfrom
),
2606 ctype_unparse (tto
)));
2608 llassert (constraintExpr_isDefined(e
));
2614 constraintTerm t
= constraintExprData_termGetTerm (e
->data
);
2616 DPRINTF (("Term: %s", constraintTerm_unparse (t
)));
2618 if (constraintTerm_isExprNode (t
))
2620 return constraintTerm_simpleDivTypeExprNode (e
, tfrom
, tto
, loc
);
2622 /* search for * size of ct and remove */
2624 DPRINTF (("Here: %s / %s -> %s", constraintExpr_unparse (e
), ctype_unparse (tfrom
), ctype_unparse (tto
)));
2625 return constraintExpr_div (e
, tfrom
, tto
, loc
);
2630 constraintExpr temp
;
2632 temp
= constraintExprData_binaryExprGetExpr1 (e
->data
);
2633 temp
= constraintExpr_copy(temp
);
2634 temp
= simpleDivType (temp
, tfrom
, tto
, loc
);
2636 e
->data
= constraintExprData_binaryExprSetExpr1 (e
->data
, temp
);
2638 temp
= constraintExprData_binaryExprGetExpr2 (e
->data
);
2639 temp
= constraintExpr_copy(temp
);
2640 temp
= simpleDivType (temp
, tfrom
, tto
, loc
);
2641 e
->data
= constraintExprData_binaryExprSetExpr2 (e
->data
, temp
);
2643 DPRINTF (("simpleDiv binaryexpr returning %s ", constraintExpr_unparse(e
)));
2648 return constraintExpr_div (e
, tfrom
, tto
, loc
);
2655 static /*@only@*/ constraintExpr
constraintExpr_adjustMaxSetForCast (/*@only@*/ constraintExpr e
, ctype tfrom
,
2656 ctype tto
, fileloc loc
)
2658 DPRINTF (("constraintExpr_adjustMaxSetForCast got %s [%s => %s]", constraintExpr_unparse(e
),
2659 ctype_unparse (tfrom
), ctype_unparse (tto
)));
2661 e
= constraintExpr_makeIncConstraintExpr (e
);
2662 e
= constraintExpr_simplify (e
);
2663 e
= simpleDivType (e
, tfrom
, tto
, loc
);
2664 e
= constraintExpr_makeDecConstraintExpr (e
);
2665 e
= constraintExpr_simplify (e
);
2667 DPRINTF (("constraintExpr_adjustMaxSetForCast returning %s ", constraintExpr_unparse(e
)));
2672 bool constraintExpr_isConstantOnly (constraintExpr e
)
2674 DPRINTF (("constraintExpr_isConstantOnly %s ", constraintExpr_unparse(e
)));
2675 llassert (constraintExpr_isDefined(e
));
2681 constraintTerm t
= constraintExprData_termGetTerm(e
->data
);
2683 if (constraintTerm_isConstantOnly (t
))
2695 constraintExpr temp1
= constraintExprData_binaryExprGetExpr1 (e
->data
);
2696 constraintExpr temp2
= constraintExprData_binaryExprGetExpr2 (e
->data
);
2698 if (constraintExpr_isConstantOnly(temp1
) &&
2699 constraintExpr_isConstantOnly(temp2
) )
2711 constraintExpr temp
;
2713 temp
= constraintExprData_unaryExprGetExpr (e
->data
);
2715 if (constraintExpr_isConstantOnly(temp
) )