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 # include "splintMacros.nf"
31 # include "cgrammar.h"
34 static ctype
constraintExpr_getOrigType (constraintExpr p_e
);
35 static bool constraintExpr_hasTypeChange(constraintExpr p_e
) /*@*/;
37 static /*@only@*/ constraintExpr
constraintExpr_makeBinaryOpConstraintExprIntLiteral (/*@only@*/constraintExpr p_expr
, int p_literal
);
41 /*@only@*/ static constraintExpr
42 doSRefFixInvarConstraintTerm (/*@only@*/ constraintExpr p_e
,
43 sRef p_s
, ctype p_ct
);
46 /*@only@*/ static constraintExpr
47 doSRefFixConstraintParamTerm (/*@only@*/ constraintExpr p_e
, /*@temp@*/ /*@observer@*/ exprNodeList p_arglist
) /*@modifies p_e@*/;
49 static /*@only@*/ constraintExpr
50 doFixResultTerm (/*@only@*/ constraintExpr p_e
, /*@exposed@*/ exprNode p_fcnCall
)
53 static bool constraintExpr_canGetCType (constraintExpr p_e
) /*@*/;
55 static ctype
constraintExpr_getCType (constraintExpr p_e
);
57 static /*@only@*/ constraintExpr
constraintExpr_adjustMaxSetForCast (/*@only@*/ constraintExpr p_e
,
58 ctype p_tfrom
, ctype p_tto
,
61 /*@special@*/ /*@notnull@*/ static constraintExpr
constraintExpr_makeBinaryOp (void)
62 /* @allocates result->data @ @sets result->kind @ */ ;
64 void constraintExpr_free (/*@only@*/ constraintExpr expr
)
66 if (constraintExpr_isDefined(expr
) )
71 constraintExprData_freeUnaryExpr(expr
->data
);
74 constraintExprData_freeBinaryExpr(expr
->data
);
77 constraintExprData_freeTerm(expr
->data
);
87 llcontbug(message("attempted to free null pointer in constraintExpr_free"));
91 bool constraintExpr_isLit (constraintExpr expr
)
93 llassert (expr
!= NULL
);
95 if (expr
->kind
== term
)
97 constraintTerm term
= constraintExprData_termGetTerm (expr
->data
);
98 if (constraintTerm_isIntLiteral (term
) )
107 static bool isZeroBinaryOp (constraintExpr expr
)
111 llassert (expr
!= NULL
); /* evans 2001-07-18 */
113 if (!constraintExpr_isBinaryExpr (expr
) )
119 e2
= constraintExprData_binaryExprGetExpr2(expr
->data
);
121 llassert (e2
!= NULL
); /* evans 2001-07-18 */
123 if (constraintExpr_isBinaryExpr (e2
) )
127 e1
= constraintExprData_binaryExprGetExpr1(e2
->data
);
129 if (constraintExpr_isLit(e1
) )
131 if (constraintExpr_getValue(e1
) == 0 )
140 /* change expr + (o - expr) to (expr -expr) */
142 /*@only@*/ /*@notnull@*/ static constraintExpr
removeZero (/*@only@*/ /*@returned@*/ constraintExpr expr
)
144 constraintExpr expr2
;
147 constraintExprBinaryOpKind op
;
148 constraintExprBinaryOpKind tempOp
;
150 llassert (expr
!= NULL
); /* evans 2001-07-18 */
152 if (!isZeroBinaryOp(expr
) )
155 expr2
= constraintExprData_binaryExprGetExpr2(expr
->data
);
156 op
= constraintExprData_binaryExprGetOp(expr
->data
);
158 llassert( constraintExpr_isBinaryExpr(expr2
) );
160 temp
= constraintExprData_binaryExprGetExpr2 (expr2
->data
);
161 temp
= constraintExpr_copy (temp
);
163 tempOp
= constraintExprData_binaryExprGetOp (expr2
->data
);
165 if (op
== BINARYOP_PLUS
)
167 else if (op
== BINARYOP_MINUS
)
169 if (tempOp
== BINARYOP_PLUS
)
171 else if (tempOp
== BINARYOP_MINUS
)
179 expr
->data
= constraintExprData_binaryExprSetExpr2(expr
->data
, temp
);
180 expr
->data
= constraintExprData_binaryExprSetOp(expr
->data
, op
);
186 /*@only@*//*@notnull@*/ constraintExpr
constraintExpr_propagateConstants (/*@only@*/ constraintExpr expr
,
187 /*@out@*/ bool * propagate
,
188 /*@out@*/ int *literal
)
190 constraintExpr expr1
;
191 constraintExpr expr2
;
192 bool propagate1
, propagate2
;
193 int literal1
, literal2
;
194 constraintExprBinaryOpKind op
;
206 llassert (expr
!= NULL
);
208 /* we simplify unaryExpr elsewhere */
209 if (expr
->kind
!= binaryexpr
)
212 op
= constraintExprData_binaryExprGetOp (expr
->data
);
214 DPRINTF((message("constraintExpr_propagateConstants: binaryexpr: %s", constraintExpr_unparse(expr
) ) ) );
216 expr
= removeZero(expr
);
218 expr1
= constraintExprData_binaryExprGetExpr1(expr
->data
);
219 expr2
= constraintExprData_binaryExprGetExpr2(expr
->data
);
221 expr1
= constraintExpr_copy(expr1
);
222 expr2
= constraintExpr_copy(expr2
);
224 expr1
= constraintExpr_propagateConstants (expr1
, &propagate1
, &literal1
);
225 expr2
= constraintExpr_propagateConstants (expr2
, &propagate2
, &literal2
);
227 expr1
= removeZero(expr1
);
228 expr2
= removeZero(expr2
);
231 *propagate
= propagate1
|| propagate2
;
233 if (op
== BINARYOP_PLUS
)
234 *literal
= literal1
+ literal2
;
235 else if (op
== BINARYOP_MINUS
)
236 *literal
= literal1
- literal2
;
240 if ( constraintExpr_isLit (expr1
) && constraintExpr_isLit (expr2
) )
243 t1
= constraintExpr_getValue (expr1
);
244 t2
= constraintExpr_getValue (expr2
);
245 llassert(*propagate
== FALSE
);
248 constraintExpr_free (expr
);
249 constraintExpr_free (expr1
);
250 constraintExpr_free (expr2
);
252 if (op
== BINARYOP_PLUS
)
253 return (constraintExpr_makeIntLiteral ((t1
+t2
) ));
254 else if (op
== BINARYOP_MINUS
)
255 return (constraintExpr_makeIntLiteral ((t1
-t2
) ));
261 if (constraintExpr_isLit (expr1
) )
265 *literal
+= constraintExpr_getValue (expr1
);
267 if (op
== BINARYOP_PLUS
)
269 constraintExpr_free(expr1
);
270 constraintExpr_free(expr
);
273 else if (op
== BINARYOP_MINUS
)
278 /* this is an ugly kludge to deal with not
279 having a unary minus operation...*/
281 temp
= constraintExpr_makeIntLiteral (0);
282 temp
= constraintExpr_makeSubtractExpr (temp
, expr2
);
284 constraintExpr_free(expr1
);
285 constraintExpr_free(expr
);
287 llassert (constraintExpr_isDefined(temp
) );
292 BADBRANCH
; /* evans 2001-07-18 */
296 if (constraintExpr_isLit (expr2
) )
300 if ( op
== BINARYOP_PLUS
)
301 *literal
+= constraintExpr_getValue (expr2
);
302 else if (op
== BINARYOP_MINUS
)
303 *literal
-= constraintExpr_getValue (expr2
);
307 constraintExpr_free(expr2
);
308 constraintExpr_free(expr
);
312 DPRINTF((message("constraintExpr_propagateConstants returning: %s", constraintExpr_unparse(expr
) ) ) );
314 expr
->data
= constraintExprData_binaryExprSetExpr1 (expr
->data
, expr1
);
315 expr
->data
= constraintExprData_binaryExprSetExpr2 (expr
->data
, expr2
);
317 expr
= removeZero(expr
);
321 /*@notnull@*/ /*@only@*/ static constraintExpr
constraintExpr_combineConstants (/*@only@*/ constraintExpr expr
) /*@modifies expr@*/
326 DPRINTF ((message ("Before combine %s", constraintExpr_unparse(expr
) ) ) );
327 expr
= constraintExpr_propagateConstants (expr
, &propagate
, &literal
);
336 ret
= constraintExpr_makeBinaryOpConstraintExprIntLiteral (expr
, literal
);
340 DPRINTF ((message ("After combine %s", constraintExpr_unparse(expr
) ) ) );
342 llassert(constraintExpr_isDefined(expr
) );
347 static /*@notnull@*/ constraintExpr
constraintExpr_alloc (void) /*@post:isnull result->data@*/
350 ret
= dmalloc (sizeof (*ret
) );
354 ret
->origType
= ctype_undefined
;
358 /*@only@*/ static constraintExprData
copyExprData (/*@observer@*/ constraintExprData data
, constraintExprKind kind
)
360 constraintExprData ret
;
361 llassert(constraintExprData_isDefined(data
));
366 ret
= constraintExprData_copyBinaryExpr(data
);
369 ret
= constraintExprData_copyUnaryExpr(data
);
372 ret
= constraintExprData_copyTerm(data
);
379 constraintExpr
constraintExpr_copy (constraintExpr expr
)
382 ret
= constraintExpr_alloc ();
385 /*drl 03/02/2003 this shouldn't be used to copy a null
386 expression but handle things cleanly if it is*/
387 llassert (!constraintExpr_isUndefined(expr
) );
389 if (constraintExpr_isUndefined(expr
) )
391 return constraintExpr_undefined
;
394 ret
->kind
= expr
->kind
;
396 ret
->data
= copyExprData (expr
->data
, expr
->kind
);
398 ret
->origType
= expr
->origType
;
403 /*@only@*/ static constraintExpr
oldconstraintExpr_makeTermExprNode ( /*@dependent@*/ exprNode e
)
407 ret
= constraintExpr_alloc();
409 ret
->data
= dmalloc (sizeof *(ret
->data
) );
410 t
= constraintTerm_makeExprNode (e
);
411 ret
->data
= constraintExprData_termSetTerm (ret
->data
, t
);
413 ret
->origType
= ctype_undefined
;
418 /*@access exprNode@*/
419 constraintExpr
constraintExpr_makeExprNode (exprNode e
)
422 constraintExpr ret
, ce1
, ce2
;
427 if (exprNode_isUndefined (e
))
429 return constraintExpr_undefined
;
437 t
= exprData_getSingle (data
);
438 while (exprNode_isInParens (t
) )
440 t
= exprData_getUopNode (t
->edata
);
442 s
= exprNode_getSref (t
);
443 if (sRef_isFixedArray(s
) )
447 size
= (int) sRef_getArraySize(s
);
448 ret
= constraintExpr_makeIntLiteral (size
);
450 else if (exprNode_isStringLiteral (t
))
452 cstring str
= multiVal_forceString (exprNode_getValue(t
));
453 ret
= constraintExpr_makeIntLiteral (size_toLong (cstring_length (str
) + 1));
457 DPRINTF ((message ("could not determine the size of %s", exprNode_unparse (e
) ) ) );
458 ret
= oldconstraintExpr_makeTermExprNode (e
);
463 DPRINTF ((message ("Examining operation %s", exprNode_unparse (e
) ) ) );
464 t1
= exprData_getOpA (data
);
465 t2
= exprData_getOpB (data
);
466 tok
= exprData_getOpTok (data
);
468 if (lltok_isPlus_Op (tok
) || lltok_isMinus_Op (tok
) )
470 ce1
= constraintExpr_makeExprNode (t1
);
471 ce2
= constraintExpr_makeExprNode (t2
);
472 ret
= constraintExpr_parseMakeBinaryOp (ce1
, tok
, ce2
);
476 /* define this block to activate the cheesy heuristic
477 for handling sizeof expressions*/
484 We handle expressions containing sizeof with the rule
485 (sizeof type ) * Expr = Expr
487 This is the total wronge way to do this but...
488 it may be better than nothing
493 else if (lltok_isMult(tok
) )
495 if ((t1
->kind
== XPR_SIZEOF
) || (t1
->kind
== XPR_SIZEOFT
) )
497 ret
= constraintExpr_makeExprNode(t2
);
499 else if ((t2
->kind
== XPR_SIZEOF
) || (t2
->kind
== XPR_SIZEOFT
) )
501 ret
= constraintExpr_makeExprNode(t1
);
505 ret
= oldconstraintExpr_makeTermExprNode (e
);
511 ret
= oldconstraintExpr_makeTermExprNode (e
);
515 t
= exprData_getUopNode (data
);
516 ret
= constraintExpr_makeExprNode (t
);
520 t
= exprData_getUopNode (data
);
521 tok
= exprData_getUopTok (data
);
522 if (lltok_isIncOp (tok
))
525 temp
= constraintExpr_makeExprNode(t
);
526 ret
= constraintExpr_makeIncConstraintExpr(temp
);
528 else if (lltok_isDecOp (tok
))
531 temp
= constraintExpr_makeExprNode(t
);
532 ret
= constraintExpr_makeDecConstraintExpr(temp
);
535 ret
= oldconstraintExpr_makeTermExprNode (e
);
539 t
= exprData_getUopNode (data
);
540 ret
= constraintExpr_makeExprNode (t
);
543 t
= exprData_getCastNode (data
);
544 ret
= constraintExpr_makeExprNode (t
);
547 t
= exprData_getPairA (data
);
548 ret
= constraintExpr_makeExprNode(t
);
551 ret
= oldconstraintExpr_makeTermExprNode (e
);
557 /*@noaccess exprNode@*/
563 static /*@only@*/ constraintExpr
constraintExpr_makeTermExprNode (/*@exposed@*/ exprNode e
)
565 return oldconstraintExpr_makeTermExprNode(e
);
569 static constraintExpr
constraintExpr_makeTerm (/*@only@*/ constraintTerm t
)
573 ret
= constraintExpr_alloc();
575 ret
->data
= dmalloc (sizeof *(ret
->data
) );
576 ret
->data
->term
= NULL
;
577 ret
->data
= constraintExprData_termSetTerm (ret
->data
, t
);
579 ret
->origType
= ctype_undefined
;
584 constraintExpr
constraintExpr_makeTermsRef (/*@temp@*/ sRef s
)
588 ret
= constraintExpr_alloc();
590 ret
->data
= dmalloc (sizeof *(ret
->data
) );
591 t
= constraintTerm_makesRef (s
);
592 ret
->data
= constraintExprData_termSetTerm (ret
->data
, t
);
595 ret
->origType
= ctype_undefined
;
600 /*@special@*/ /*@notnull@*/ static constraintExpr
makeUnaryOpGeneric (void) /*@allocates result->data@*/ /*@defines result->kind@*/
603 ret
= constraintExpr_alloc();
604 ret
->kind
= unaryExpr
;
605 ret
->data
= dmalloc (sizeof *(ret
->data
));
606 ret
->data
->unaryOp
.expr
= constraintExpr_undefined
;
610 /*@notnull@*/ /*@only@*/ static constraintExpr
constraintExpr_makeUnaryOpConstraintExpr (/*@only@*/ constraintExpr cexpr
)
613 ret
= makeUnaryOpGeneric();
617 ret
->data
= constraintExprData_unaryExprSetExpr (ret
->data
, cexpr
);
618 ret
->data
= constraintExprData_unaryExprSetOp (ret
->data
, UNARYOP_UNDEFINED
);
627 /*@only@*/ /*@notnull@*/ static constraintExpr
628 constraintExpr_makeUnaryOp (/*@only@*/ constraintExpr cexpr
, constraintExprUnaryOpKind Op
)
631 ret
= makeUnaryOpGeneric();
633 ret
->data
= constraintExprData_unaryExprSetExpr (ret
->data
, cexpr
);
634 ret
->data
= constraintExprData_unaryExprSetOp (ret
->data
, Op
);
637 ret
->origType
= ctype_undefined
;
642 /*@only@*/ /*@notnull@*/
643 static constraintExpr
constraintExpr_makeUnaryOpExprNode (/*@exposed@*/ exprNode expr
)
647 sub
= constraintExpr_makeExprNode (expr
);
648 ret
= constraintExpr_makeUnaryOpConstraintExpr(sub
);
653 /*@only@*/ /*@notnull@*/
654 static constraintExpr
constraintExpr_makeMaxSetConstraintExpr (/*@only@*/ constraintExpr c
)
657 ret
= constraintExpr_makeUnaryOp (c
, MAXSET
);
662 /*@only@*/ /*@notnull@*/
663 static constraintExpr
constraintExpr_makeSRefUnaryOp (/*@temp@*/ /*@observer@*/ sRef s
, constraintExprUnaryOpKind op
)
668 t
= constraintExpr_makeTermsRef (s
);
669 ret
= constraintExpr_makeUnaryOpConstraintExpr (t
);
670 ret
->data
= constraintExprData_unaryExprSetOp (ret
->data
, op
);
676 constraintExpr
constraintExpr_makeSRefMaxRead( sRef s
)
678 return (constraintExpr_makeSRefUnaryOp (s
, MAXREAD
) );
682 constraintExpr
constraintExpr_makeSRefMaxset ( sRef s
)
684 return (constraintExpr_makeSRefUnaryOp (s
, MAXSET
) );
688 constraintExpr
constraintExpr_parseMakeUnaryOp (lltok op
, constraintExpr cexpr
)
691 ret
= constraintExpr_makeUnaryOpConstraintExpr ( cexpr
);
693 switch (lltok_getTok (op
))
696 ret
->data
= constraintExprData_unaryExprSetOp (ret
->data
, MAXSET
);
699 ret
->data
= constraintExprData_unaryExprSetOp (ret
->data
, MAXREAD
);
702 llfatalbug (message ("Unhandled operation in constraint: %s", lltok_unparse (op
)));
708 constraintExpr
constraintExpr_makeMaxSetExpr (/*@exposed@*/ exprNode expr
)
711 ret
= constraintExpr_makeExprNode (expr
);
713 ret
= constraintExpr_makeMaxSetConstraintExpr (ret
);
715 llassert (ret
!= NULL
);
720 constraintExpr
constraintExpr_makeMaxReadExpr (exprNode expr
)
723 ret
= constraintExpr_makeUnaryOpExprNode(expr
);
724 ret
->data
= constraintExprData_unaryExprSetOp (ret
->data
, MAXREAD
);
730 /*@unused@*/ static constraintExpr
constraintExpr_makeMinSetExpr (/*@exposed@*/ exprNode expr
)
733 ret
= constraintExpr_makeUnaryOpExprNode(expr
);
734 ret
->data
= constraintExprData_unaryExprSetOp (ret
->data
, MINSET
);
739 /*@unused@*/ static constraintExpr
constraintExpr_makeMinReadExpr (/*@exposed@*/ exprNode expr
)
742 ret
= constraintExpr_makeUnaryOpExprNode(expr
);
743 ret
->data
= constraintExprData_unaryExprSetOp (ret
->data
, MINREAD
);
749 constraintExpr
constraintExpr_makeValueExpr (/*@exposed@*/ exprNode expr
)
752 ret
= constraintExpr_makeExprNode (expr
);
756 /*@only@*/ /*@notnull@*/
757 constraintExpr
constraintExpr_makeIntLiteral (long i
)
761 ret
= constraintExpr_alloc();
763 ret
->data
= dmalloc (sizeof *(ret
->data
) );
764 t
= constraintTerm_makeIntLiteral (i
);
765 ret
->data
= constraintExprData_termSetTerm (ret
->data
, t
);
768 ret
->origType
= ctype_undefined
;
774 constraintExpr constraintExpr_makeValueInt (int i)
776 return constraintExpr_makeIntLiteral (i);
780 /*@only@*/ /*@notnull@*/
781 /*@special@*/ static constraintExpr
constraintExpr_makeBinaryOp (void)
782 /*@allocates result->data @*/ /*@sets result->kind @*/
785 ret
= constraintExpr_alloc();
786 ret
->kind
= binaryexpr
;
787 ret
->data
= dmalloc ( sizeof *(ret
->data
) );
789 ret
->data
->binaryOp
.expr1
= constraintExpr_undefined
;
790 ret
->data
->binaryOp
.expr2
= constraintExpr_undefined
;
796 static /*@notnull@*/ /*@only@*/ constraintExpr
constraintExpr_makeBinaryOpConstraintExpr (/*@only@*/constraintExpr expr1
, /*@only@*/ constraintExpr expr2
)
801 ret
= constraintExpr_makeBinaryOp();
802 ret
->data
= constraintExprData_binaryExprSetExpr1 (ret
->data
, expr1
);
803 ret
->data
= constraintExprData_binaryExprSetExpr2 (ret
->data
, expr2
);
804 ret
->data
= constraintExprData_binaryExprSetOp (ret
->data
, BINARYOP_UNDEFINED
);
807 ret
->origType
= ctype_undefined
;
813 constraintExpr
constraintExpr_parseMakeBinaryOp (/*@only@*/ constraintExpr expr1
, lltok op
,/*@only@*/ constraintExpr expr2
)
816 ret
= constraintExpr_makeBinaryOpConstraintExpr (expr1
, expr2
);
818 if (lltok_getTok (op
) == TPLUS
)
820 ret
->data
= constraintExprData_binaryExprSetOp(ret
->data
, BINARYOP_PLUS
);
822 else if (lltok_getTok (op
) == TMINUS
)
824 ret
->data
= constraintExprData_binaryExprSetOp(ret
->data
, BINARYOP_MINUS
);
836 /*@unused@*/ static constraintExpr
constraintExpr_makeBinaryOpExprNode (/*@exposed@*/ exprNode expr1
, /*@exposed@*/ exprNode expr2
)
839 constraintExpr sub1
, sub2
;
840 sub1
= constraintExpr_makeTermExprNode (expr1
);
841 sub2
= constraintExpr_makeTermExprNode (expr2
);
842 ret
= constraintExpr_makeBinaryOpConstraintExpr(sub1
, sub2
);
847 static /*@notnull@*/ /*@only@*/
848 constraintExpr
constraintExpr_makeBinaryOpConstraintExprIntLiteral (/*@only@*/ constraintExpr expr
, int literal
)
851 constraintExpr constExpr
;
853 constExpr
= constraintExpr_makeIntLiteral (literal
);
854 ret
= constraintExpr_makeBinaryOpConstraintExpr (expr
, constExpr
);
855 ret
->data
= constraintExprData_binaryExprSetOp(ret
->data
, BINARYOP_PLUS
);
860 constraintExpr
constraintExpr_makeDecConstraintExpr (/*@only@*/constraintExpr expr
)
865 inc
= constraintExpr_makeIntLiteral (1);
866 ret
= constraintExpr_makeBinaryOpConstraintExpr (expr
, inc
);
867 ret
->data
= constraintExprData_binaryExprSetOp(ret
->data
, BINARYOP_MINUS
);
872 /*@only@*/ constraintExpr
constraintExpr_makeSubtractExpr (/*@only@*/ constraintExpr expr
, /*@only@*/ constraintExpr addent
)
876 DPRINTF ((message ("Making subtract expression") ) );
878 ret
= constraintExpr_makeBinaryOpConstraintExpr (expr
, addent
);
879 ret
->data
= constraintExprData_binaryExprSetOp (ret
->data
, BINARYOP_MINUS
);
884 constraintExpr
constraintExpr_makeAddExpr (/*@only@*/
885 constraintExpr expr
, /*@only@*/
886 constraintExpr addent
)
890 DPRINTF ((message ("Doing addTerm simplification") ) );
892 ret
= constraintExpr_makeBinaryOpConstraintExpr (expr
, addent
);
893 ret
->data
= constraintExprData_binaryExprSetOp (ret
->data
, BINARYOP_PLUS
);
899 constraintExpr
constraintExpr_makeIncConstraintExpr (/*@only@*/ constraintExpr expr
)
904 inc
= constraintExpr_makeIntLiteral (1);
905 ret
= constraintExpr_makeBinaryOpConstraintExpr (expr
, inc
);
906 ret
->data
= constraintExprData_binaryExprSetOp(ret
->data
, BINARYOP_PLUS
);
911 static cstring
constraintExprUnaryOpKind_print (constraintExprUnaryOpKind op
)
916 return message("maxSet");
918 return message("minSet");
920 return message("maxRead");
922 return message("minRead");
925 return message ("<(Unary OP OTHER>");
931 static cstring
constraintExprBinaryOpKind_print (constraintExprBinaryOpKind op
)
943 return message ("<binary OP Unknown>");
947 bool constraintExpr_similar (constraintExpr expr1
, constraintExpr expr2
)
949 constraintExprKind kind
;
951 llassert (expr1
!= NULL
);
952 llassert (expr2
!= NULL
);
953 if (expr1
->kind
!= expr2
->kind
)
961 return constraintTerm_similar (constraintExprData_termGetTerm(expr1
->data
),
962 constraintExprData_termGetTerm(expr2
->data
) );
963 /*@notreached@*/ break;
966 if (constraintExprData_unaryExprGetOp (expr1
->data
) != constraintExprData_unaryExprGetOp (expr2
->data
) )
969 return (constraintExpr_similar (
970 constraintExprData_unaryExprGetExpr (expr1
->data
),
971 constraintExprData_unaryExprGetExpr (expr2
->data
)
975 if (constraintExprData_binaryExprGetOp (expr1
->data
) != constraintExprData_binaryExprGetOp (expr2
->data
) )
978 if (! constraintExpr_similar (constraintExprData_binaryExprGetExpr1 (expr1
->data
),
979 constraintExprData_binaryExprGetExpr1 (expr2
->data
)) )
982 if (! constraintExpr_similar (constraintExprData_binaryExprGetExpr2 (expr1
->data
),
983 constraintExprData_binaryExprGetExpr2 (expr2
->data
)) )
998 bool constraintExpr_same (constraintExpr expr1
, constraintExpr expr2
)
1000 constraintExprKind kind
;
1002 llassert (expr1
!= NULL
);
1003 llassert (expr2
!= NULL
);
1004 if (expr1
->kind
!= expr2
->kind
)
1012 return constraintTerm_similar (constraintExprData_termGetTerm(expr1
->data
),
1013 constraintExprData_termGetTerm(expr2
->data
) );
1016 if (constraintExprData_unaryExprGetOp (expr1
->data
) != constraintExprData_unaryExprGetOp (expr2
->data
) )
1019 return (constraintExpr_same (
1020 constraintExprData_unaryExprGetExpr (expr1
->data
),
1021 constraintExprData_unaryExprGetExpr (expr2
->data
)
1025 if (constraintExprData_binaryExprGetOp (expr1
->data
) != constraintExprData_binaryExprGetOp (expr2
->data
) )
1028 if (! constraintExpr_same (constraintExprData_binaryExprGetExpr1 (expr1
->data
),
1029 constraintExprData_binaryExprGetExpr1 (expr2
->data
)) )
1032 if (! constraintExpr_same (constraintExprData_binaryExprGetExpr2 (expr1
->data
),
1033 constraintExprData_binaryExprGetExpr2 (expr2
->data
)) )
1043 constraintExpr_search (/*@observer@*/ constraintExpr c
,
1044 /*@observer@*/ constraintExpr old
)
1047 constraintExprKind kind
;
1048 constraintExpr temp
;
1050 if (constraintExpr_similar (c
, old
))
1052 DPRINTF (("Found %q", constraintExpr_unparse (old
)));
1056 llassert (constraintExpr_isDefined (c
) && constraintExpr_isDefined(old
) );
1058 if ( !(constraintExpr_isDefined (c
) && constraintExpr_isDefined(old
) ) )
1068 temp
= constraintExprData_unaryExprGetExpr (c
->data
);
1069 ret
= ret
|| constraintExpr_search (temp
, old
);
1073 temp
= constraintExprData_binaryExprGetExpr1 (c
->data
);
1074 ret
= ret
|| constraintExpr_search(temp
, old
);
1076 temp
= constraintExprData_binaryExprGetExpr2 (c
->data
);
1077 ret
= ret
|| constraintExpr_search(temp
, old
);
1087 /*@only@*/ constraintExpr
1088 constraintExpr_searchandreplace (/*@only@*/ /*@unique@*/ constraintExpr c
, /*@temp@*/ constraintExpr old
,
1089 /*@temp@*/ constraintExpr newExpr
)
1091 constraintExprKind kind
;
1092 constraintExpr temp
;
1095 llassert (constraintExpr_isDefined (newExpr
) && (constraintExpr_isDefined (old
) && constraintExpr_isDefined(c
) ) );
1097 if (constraintExpr_similar (c
, old
))
1099 ctype newType
= ctype_unknown
;
1100 ctype cType
= ctype_unknown
;
1102 ret
= constraintExpr_copy (newExpr
);
1103 llassert(constraintExpr_isDefined(ret
) );
1104 /*drl if newExpr != NULL then ret will != NULL*/
1106 DPRINTF (("Replacing %s with %s in %s",
1107 constraintExpr_unparse (old
), constraintExpr_unparse (newExpr
),
1108 constraintExpr_unparse (c
)));
1110 if (constraintExpr_canGetCType (c
) && constraintExpr_canGetCType (newExpr
))
1112 cType
= constraintExpr_getCType(c
);
1113 newType
= constraintExpr_getCType (newExpr
);
1115 if (ctype_match (cType
,newType
))
1117 DPRINTF (("constraintExpr_searchandreplace: replacing "
1118 " %s with type %s with %s with type %s",
1119 constraintExpr_unparse (c
), ctype_unparse(cType
),
1120 constraintExpr_unparse (newExpr
), ctype_unparse(newType
)));
1123 ret
->origType
= cType
;
1124 DPRINTF (("Type: %s", ctype_unparse (constraintExpr_getCType (ret
))));
1128 if (constraintExpr_hasMaxSet (c
))
1130 if (constraintExpr_hasTypeChange (c
))
1132 fileloc loc
= constraintExpr_loc (c
);
1133 DPRINTF (("constraintExpr_searchandreplace: encountered "
1134 "MaxSet with changed type %s ",
1135 constraintExpr_unparse (c
)));
1137 if (c
->kind
== unaryExpr
)
1139 constraintExpr ce
= constraintExprData_unaryExprGetExpr (c
->data
);
1140 DPRINTF (("Its a unary! %s / %s",
1141 ctype_unparse (constraintExpr_getCType (ce
)),
1142 ctype_unparse (constraintExpr_getOrigType (ce
))));
1143 ret
= constraintExpr_adjustMaxSetForCast (ret
, constraintExpr_getCType (ce
),
1144 constraintExpr_getOrigType (ce
),
1149 /* fix this with a conversation */
1150 DPRINTF (("Types: %s / %s", ctype_unparse (newType
), ctype_unparse (cType
)));
1151 ret
= constraintExpr_adjustMaxSetForCast (ret
, constraintExpr_getCType (c
),
1152 constraintExpr_getOrigType(c
),
1158 constraintExpr_free (c
);
1159 DPRINTF (("ret: %s", constraintExpr_unparse (ret
)));
1170 DPRINTF (("Making unary expression!"));
1171 temp
= constraintExprData_unaryExprGetExpr (c
->data
);
1172 temp
= constraintExpr_copy (temp
);
1173 temp
= constraintExpr_searchandreplace (temp
, old
, newExpr
);
1174 c
->data
= constraintExprData_unaryExprSetExpr (c
->data
, temp
);
1177 DPRINTF (("Making binary expression!"));
1178 temp
= constraintExprData_binaryExprGetExpr1 (c
->data
);
1179 temp
= constraintExpr_copy (temp
);
1180 temp
= constraintExpr_searchandreplace (temp
, old
, newExpr
);
1181 c
->data
= constraintExprData_binaryExprSetExpr1 (c
->data
, temp
);
1183 temp
= constraintExprData_binaryExprGetExpr2 (c
->data
);
1184 temp
= constraintExpr_copy (temp
);
1185 temp
= constraintExpr_searchandreplace (temp
, old
, newExpr
);
1186 c
->data
= constraintExprData_binaryExprSetExpr2 (c
->data
, temp
);
1192 DPRINTF (("ret: %s", constraintExpr_unparse (c
)));
1196 /*@notnull@*/ static constraintExpr
constraintExpr_simplifyChildren (/*@returned@*/ /*@notnull@*/ constraintExpr c
)
1198 constraintExprKind kind
;
1199 constraintExpr temp
;
1208 temp
= constraintExprData_unaryExprGetExpr (c
->data
);
1209 temp
= constraintExpr_copy(temp
);
1210 temp
= constraintExpr_simplify (temp
);
1211 c
->data
= constraintExprData_unaryExprSetExpr (c
->data
, temp
);
1214 DPRINTF((message("constraintExpr_simplfiyChildren: simplify binary expression: %s",constraintExpr_unparse(c
) ) ) );
1215 temp
= constraintExprData_binaryExprGetExpr1 (c
->data
);
1216 temp
= constraintExpr_copy(temp
);
1217 temp
= constraintExpr_simplify (temp
);
1219 c
->data
= constraintExprData_binaryExprSetExpr1 (c
->data
, temp
);
1221 temp
= constraintExprData_binaryExprGetExpr2 (c
->data
);
1222 temp
= constraintExpr_copy(temp
);
1223 temp
= constraintExpr_simplify (temp
);
1225 c
->data
= constraintExprData_binaryExprSetExpr2 (c
->data
, temp
);
1235 constraintExpr
constraintExpr_setFileloc (/*@returned@*/ constraintExpr c
, fileloc loc
) /*@modifies c @*/
1238 constraintExpr temp
;
1240 llassert(c
!= NULL
);
1245 t
= constraintExprData_termGetTerm (c
->data
);
1246 t
= constraintTerm_copy(t
);
1247 t
= constraintTerm_setFileloc (t
, loc
);
1248 c
->data
= constraintExprData_termSetTerm (c
->data
, t
);
1252 temp
= constraintExprData_binaryExprGetExpr1 (c
->data
);
1253 temp
= constraintExpr_copy(temp
);
1254 temp
= constraintExpr_setFileloc (temp
, loc
);
1255 c
->data
= constraintExprData_binaryExprSetExpr1 (c
->data
, temp
);
1257 temp
= constraintExprData_binaryExprGetExpr2 (c
->data
);
1258 temp
= constraintExpr_copy(temp
);
1259 temp
= constraintExpr_setFileloc (temp
, loc
);
1260 c
->data
= constraintExprData_binaryExprSetExpr2 (c
->data
, temp
);
1263 temp
= constraintExprData_unaryExprGetExpr (c
->data
);
1264 temp
= constraintExpr_copy(temp
);
1265 temp
= constraintExpr_setFileloc (temp
, loc
);
1266 c
->data
= constraintExprData_unaryExprSetExpr (c
->data
, temp
);
1272 static /*@only@*/ constraintExpr
constraintExpr_simplifybinaryExpr (/*@only@*/ /*@notnull@*/ constraintExpr c
)
1274 constraintExpr e1
, e2
;
1275 constraintExprBinaryOpKind op
;
1277 e1
= constraintExprData_binaryExprGetExpr1 (c
->data
);
1278 e2
= constraintExprData_binaryExprGetExpr2 (c
->data
);
1280 if (constraintExpr_canGetValue (e1
) && constraintExpr_canGetValue(e2
) )
1284 i
= constraintExpr_getValue(e1
) + constraintExpr_getValue (e2
);
1285 constraintExpr_free(c
);
1286 c
= constraintExpr_makeIntLiteral (i
);
1290 op
= constraintExprData_binaryExprGetOp (c
->data
);
1291 if (op
== BINARYOP_MINUS
)
1292 if (constraintExpr_similar(e1
, e2
) )
1294 constraintExpr_free(c
);
1295 c
= constraintExpr_makeIntLiteral (0);
1303 this thing takes the lexpr and expr of a constraint and modifies lexpr
1304 and returns a (possiblly new) value for expr
1306 /* 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 */
1308 /* the approach is a little Kludgy but seems to work. I should probably use something cleaner at some point ... */
1311 /*@only@*/ constraintExpr
constraintExpr_solveBinaryExpr (constraintExpr lexpr
, /*@only@*/ constraintExpr expr
)
1313 constraintExpr expr1
, expr2
;
1314 constraintExprBinaryOpKind op
;
1316 llassert(constraintExpr_isDefined (lexpr
) && constraintExpr_isDefined (expr
) );
1318 if (lexpr
->kind
!= binaryexpr
)
1321 expr2
= constraintExprData_binaryExprGetExpr2 (lexpr
->data
);
1322 expr1
= constraintExprData_binaryExprGetExpr1 (lexpr
->data
);
1324 op
= constraintExprData_binaryExprGetOp (lexpr
->data
);
1326 expr1
= constraintExpr_copy(expr1
);
1327 expr2
= constraintExpr_copy(expr2
);
1329 llassert(constraintExpr_isDefined (expr1
) && constraintExpr_isDefined (expr2
) );
1331 /* drl possible problem : warning make sure this works */
1333 lexpr
->kind
= expr1
->kind
;
1334 sfree (lexpr
->data
);
1336 lexpr
->data
= copyExprData (expr1
->data
, expr1
->kind
);
1337 constraintExpr_free(expr1
);
1339 if (op
== BINARYOP_PLUS
)
1340 expr
= constraintExpr_makeSubtractExpr (expr
, expr2
);
1341 else if (op
== BINARYOP_MINUS
)
1342 expr
= constraintExpr_makeAddExpr (expr
, expr2
);
1349 #warning this needs to be checked
1350 expr = constraintExpr_solveBinaryExpr (expr1, expr);
1352 expr = constraintExpr_solveBinaryExpr (expr2, expr);
1357 static /*@only@*/ constraintExpr
constraintExpr_simplifyunaryExpr (/*@only@*/ constraintExpr c
)
1361 llassert(constraintExpr_isDefined (c
) );
1362 llassert (c
->kind
== unaryExpr
);
1364 DPRINTF ((message ("Doing constraintExpr_simplifyunaryExpr:%s", constraintExpr_unparse (c
) ) ) );
1366 if ((constraintExprData_unaryExprGetOp (c
->data
) != MAXSET
) &&
1367 (constraintExprData_unaryExprGetOp (c
->data
) != MAXREAD
) )
1372 exp
= constraintExprData_unaryExprGetExpr (c
->data
);
1373 exp
= constraintExpr_copy(exp
);
1375 llassert(constraintExpr_isDefined (exp
) );
1377 if (exp
->kind
== term
)
1379 constraintTerm cterm
;
1381 cterm
= constraintExprData_termGetTerm (exp
->data
);
1383 if (constraintTerm_isStringLiteral(cterm
) )
1386 val
= constraintTerm_getStringLiteral (cterm
);
1387 if (constraintExprData_unaryExprGetOp (c
->data
) == MAXSET
)
1389 constraintExpr temp
;
1391 temp
= constraintExpr_makeIntLiteral ((int)strlen (cstring_toCharsSafe(val
) ) );
1393 constraintExpr_free(c
);
1394 constraintExpr_free(exp
);
1399 if (constraintExprData_unaryExprGetOp (c
->data
) == MAXREAD
)
1401 constraintExpr temp
;
1403 temp
= constraintExpr_makeIntLiteral ((int)strlen (cstring_toCharsSafe(val
) ) );
1405 constraintExpr_free(c
);
1406 constraintExpr_free(exp
);
1413 /* slight Kludge to handle var [] = { , , };
1414 ** type syntax I don't think this is sound but it should be good
1415 ** enough. The C standard is very confusing about initialization
1419 if (constraintTerm_isInitBlock(cterm
) )
1421 constraintExpr temp
;
1424 len
= constraintTerm_getInitBlockLength(cterm
);
1426 /* -- drl 12/08/2003 : decrementing to fix off by one error */
1430 temp
= constraintExpr_makeIntLiteral (len
);
1432 constraintExpr_free(c
);
1433 DPRINTF(( message("Changed to %q", constraintExpr_print(temp
)
1435 constraintExpr_free(exp
);
1439 constraintExpr_free(exp
);
1443 if (exp
->kind
!= binaryexpr
)
1445 constraintExpr_free(exp
);
1449 if (constraintExprData_binaryExprGetOp (exp
->data
) == BINARYOP_PLUS
)
1452 /* if (constraintExpr_canGetValue (constraintExprData_binaryExprGetExpr2 (exp->data) ) ) */
1455 constraintExpr temp
, temp2
;
1457 DPRINTF ((message ("Doing fancy simplification") ) );
1459 temp
= constraintExprData_binaryExprGetExpr2 (exp
->data
);
1461 temp2
= constraintExprData_binaryExprGetExpr1 (exp
->data
);
1463 temp2
= constraintExpr_copy(temp2
);
1464 c
->data
= constraintExprData_unaryExprSetExpr (c
->data
, temp2
);
1467 temp
= constraintExpr_copy (temp
);
1469 c
= constraintExpr_makeSubtractExpr (c
, temp
);
1471 DPRINTF ((message ("Done fancy simplification:%s", constraintExpr_unparse (c
) ) ) );
1475 DPRINTF ((message ("constraintExpr_simplifyUnaryExpr: Done simplification:%s", constraintExpr_unparse (c
) ) ) );
1477 constraintExpr_free(exp
);
1482 /*@only@*/ constraintExpr
constraintExpr_simplify (/*@only@*/ constraintExpr c
)
1484 constraintExprKind kind
;
1488 DPRINTF ((message ("Doing constraintExpr_simplify:%s", constraintExpr_unparse (c
) ) ) );
1492 llassert ( constraintExpr_isDefined (c
) );
1493 if (constraintExpr_isUndefined (c
) )
1495 return constraintExpr_undefined
;
1498 ret
= constraintExpr_copy(c
);
1499 llassert(constraintExpr_isDefined (ret
) );
1501 constraintExpr_free(c
);
1503 ret
= constraintExpr_simplifyChildren (ret
);
1505 ret
= constraintExpr_combineConstants (ret
);
1507 ret
= constraintExpr_simplifyChildren (ret
);
1515 t
= constraintExprData_termGetTerm (ret
->data
);
1516 t
= constraintTerm_copy(t
);
1517 t
= constraintTerm_simplify (t
);
1518 ret
->data
= constraintExprData_termSetTerm (ret
->data
, t
);
1521 ret
= constraintExpr_simplifyunaryExpr (ret
);
1524 ret
= constraintExpr_simplifybinaryExpr (ret
);
1530 DPRINTF ((message ("constraintExpr_simplify returning :%s", constraintExpr_unparse (ret
) ) ) );
1536 cstring
constraintExpr_unparse (/*@temp@*/ constraintExpr ex
) /*@*/
1539 constraintExprKind kind
;
1541 llassert (ex
!= NULL
);
1548 if (context_getFlag (FLG_PARENCONSTRAINT
) )
1550 st
= message ("(%q) ", constraintTerm_unparse (constraintExprData_termGetTerm (ex
->data
)));
1554 st
= message ("%q", constraintTerm_unparse (constraintExprData_termGetTerm (ex
->data
)));
1558 st
= message ("%q(%q)",
1559 constraintExprUnaryOpKind_print (constraintExprData_unaryExprGetOp (ex
->data
) ),
1560 constraintExpr_unparse (constraintExprData_unaryExprGetExpr (ex
->data
) )
1564 if (context_getFlag (FLG_PARENCONSTRAINT
) )
1566 st
= message ("(%q) %q (%q)",
1567 constraintExpr_unparse (constraintExprData_binaryExprGetExpr1 (ex
->data
) ),
1568 constraintExprBinaryOpKind_print (constraintExprData_binaryExprGetOp (ex
->data
)),
1569 constraintExpr_unparse (constraintExprData_binaryExprGetExpr2 (ex
->data
) )
1574 st
= message ("%q %q %q",
1575 constraintExpr_unparse (constraintExprData_binaryExprGetExpr1 (ex
->data
)),
1576 constraintExprBinaryOpKind_print (constraintExprData_binaryExprGetOp (ex
->data
)),
1577 constraintExpr_unparse (constraintExprData_binaryExprGetExpr2 (ex
->data
))
1584 st
= message ("error");
1588 DPRINTF((message ("constraintExpr_unparse: '%s'",st
) ) );
1593 constraintExpr
constraintExpr_doSRefFixBaseParam (/*@returned@*/ constraintExpr expr
, exprNodeList arglist
)
1595 constraintTerm Term
;
1596 constraintExprKind kind
;
1597 constraintExpr expr1
, expr2
;
1598 constraintExprData data
;
1599 llassert (expr
!= NULL
);
1608 Term
= constraintExprData_termGetTerm(data
);
1609 Term
= constraintTerm_copy(Term
);
1611 Term
= constraintTerm_doSRefFixBaseParam (Term
, arglist
);
1612 data
= constraintExprData_termSetTerm(data
, Term
);
1615 expr1
= constraintExprData_unaryExprGetExpr (data
);
1616 expr1
= constraintExpr_copy(expr1
);
1618 expr1
= constraintExpr_doSRefFixBaseParam (expr1
, arglist
);
1619 data
= constraintExprData_unaryExprSetExpr (data
, expr1
);
1622 expr1
= constraintExprData_binaryExprGetExpr1 (data
);
1623 expr2
= constraintExprData_binaryExprGetExpr2 (data
);
1625 expr1
= constraintExpr_copy(expr1
);
1626 expr2
= constraintExpr_copy(expr2
);
1628 expr1
= constraintExpr_doSRefFixBaseParam (expr1
, arglist
);
1629 data
= constraintExprData_binaryExprSetExpr1 (data
, expr1
);
1630 expr2
= constraintExpr_doSRefFixBaseParam (expr2
, arglist
);
1631 data
= constraintExprData_binaryExprSetExpr2 (data
, expr2
);
1640 # endif /* DEADCODE */
1643 /*@only@*/ constraintExpr
constraintExpr_doSRefFixInvarConstraint (/ *@only@
* / constraintExpr expr
, sRef s
, ctype ct
)
1645 constraintExprKind kind
;
1646 constraintExpr expr1
, expr2
;
1647 constraintExprData data
;
1648 llassert (expr
!= NULL
);
1657 expr
= doSRefFixInvarConstraintTerm (expr
, s
, ct
);
1660 expr1
= constraintExprData_unaryExprGetExpr (data
);
1661 expr1
= constraintExpr_copy(expr1
);
1662 expr1
= constraintExpr_doSRefFixInvarConstraint (expr1
, s
, ct
);
1663 data
= constraintExprData_unaryExprSetExpr (data
, expr1
);
1666 expr1
= constraintExprData_binaryExprGetExpr1 (data
);
1667 expr2
= constraintExprData_binaryExprGetExpr2 (data
);
1669 expr1
= constraintExpr_copy(expr1
);
1670 expr2
= constraintExpr_copy(expr2
);
1672 expr1
= constraintExpr_doSRefFixInvarConstraint (expr1
, s
, ct
);
1673 data
= constraintExprData_binaryExprSetExpr1 (data
, expr1
);
1674 expr2
= constraintExpr_doSRefFixInvarConstraint (expr2
, s
, ct
);
1675 data
= constraintExprData_binaryExprSetExpr2 (data
, expr2
);
1686 /*@only@*/ constraintExpr
constraintExpr_doSRefFixConstraintParam (/*@only@*/ constraintExpr expr
, exprNodeList arglist
) /*@modifies expr@*/
1688 constraintExprKind kind
;
1689 constraintExpr expr1
, expr2
;
1690 constraintExprData data
;
1691 llassert (expr
!= NULL
);
1700 expr
= doSRefFixConstraintParamTerm (expr
, arglist
);
1703 expr1
= constraintExprData_unaryExprGetExpr (data
);
1704 expr1
= constraintExpr_copy(expr1
);
1705 expr1
= constraintExpr_doSRefFixConstraintParam (expr1
, arglist
);
1706 data
= constraintExprData_unaryExprSetExpr (data
, expr1
);
1709 expr1
= constraintExprData_binaryExprGetExpr1 (data
);
1710 expr2
= constraintExprData_binaryExprGetExpr2 (data
);
1712 expr1
= constraintExpr_copy(expr1
);
1713 expr2
= constraintExpr_copy(expr2
);
1715 expr1
= constraintExpr_doSRefFixConstraintParam (expr1
, arglist
);
1716 data
= constraintExprData_binaryExprSetExpr1 (data
, expr1
);
1717 expr2
= constraintExpr_doSRefFixConstraintParam (expr2
, arglist
);
1718 data
= constraintExprData_binaryExprSetExpr2 (data
, expr2
);
1728 /*@only@*/ constraintExpr
constraintExpr_doFixResult (/*@only@*/ constraintExpr expr
, /*@observer@*/ exprNode fcnCall
)
1730 constraintExprKind kind
;
1731 constraintExpr expr1
, expr2
;
1732 constraintExprData data
;
1733 llassert (expr
!= NULL
);
1742 expr
= doFixResultTerm (expr
, fcnCall
);
1745 expr1
= constraintExprData_unaryExprGetExpr (data
);
1746 expr1
= constraintExpr_copy(expr1
);
1748 expr1
= constraintExpr_doFixResult (expr1
, fcnCall
);
1749 data
= constraintExprData_unaryExprSetExpr (data
, expr1
);
1752 expr1
= constraintExprData_binaryExprGetExpr1 (data
);
1753 expr2
= constraintExprData_binaryExprGetExpr2 (data
);
1755 expr1
= constraintExpr_copy(expr1
);
1756 expr2
= constraintExpr_copy(expr2
);
1758 expr1
= constraintExpr_doFixResult (expr1
, fcnCall
);
1759 data
= constraintExprData_binaryExprSetExpr1 (data
, expr1
);
1760 expr2
= constraintExpr_doFixResult (expr2
, fcnCall
);
1761 data
= constraintExprData_binaryExprSetExpr2 (data
, expr2
);
1770 cstring
constraintExpr_print (constraintExpr expr
) /*@*/
1772 return constraintExpr_unparse (expr
);
1775 bool constraintExpr_hasMaxSet (constraintExpr expr
) /*@*/
1780 t
= constraintExpr_unparse(expr
);
1782 ret
= cstring_containsLit(t
, "maxSet");
1790 /*returns 1 0 -1 like strcmp
1796 int constraintExpr_compare (constraintExpr expr1
, constraintExpr expr2
)
1798 long value1
, value2
;
1800 if (constraintExpr_similar (expr1
, expr2
) )
1805 value1
= constraintExpr_getValue(expr1
);
1806 value2
= constraintExpr_getValue(expr2
);
1808 if (value1
> value2
)
1811 if (value1
== value2
)
1818 long constraintExpr_getValue (constraintExpr expr
)
1820 llassert (constraintExpr_isDefined(expr
) );
1821 llassert (expr
->kind
== term
);
1823 return (constraintTerm_getValue (constraintExprData_termGetTerm (expr
->data
)));
1826 bool constraintExpr_canGetValue (constraintExpr expr
)
1828 llassert ( constraintExpr_isDefined (expr
));
1829 if (constraintExpr_isUndefined (expr
))
1837 return constraintTerm_canGetValue (constraintExprData_termGetTerm (expr
->data
) );
1843 fileloc
constraintExpr_loc (constraintExpr expr
)
1847 constraintExprKind kind
;
1849 llassert ( constraintExpr_isDefined (expr
) );
1850 if (constraintExpr_isUndefined (expr
) )
1852 return fileloc_undefined
;
1861 t
= constraintExprData_termGetTerm (expr
->data
);
1862 return (constraintTerm_getFileloc (t
) );
1866 e
= constraintExprData_unaryExprGetExpr (expr
->data
);
1867 return (constraintExpr_loc (e
) );
1871 e
= constraintExprData_binaryExprGetExpr1 (expr
->data
);
1872 return (constraintExpr_loc (e
) );
1877 return (fileloc_undefined
);
1880 /*drl moved from constriantTerm.c 5/20/001*/
1881 static /*@only@*/ constraintExpr
1882 doFixResultTerm (/*@only@*/ constraintExpr e
, /*@exposed@*/ exprNode fcnCall
)
1886 constraintExprData data
;
1887 constraintExprKind kind
;
1890 llassert (constraintExpr_isDefined (e
) );
1895 llassert (kind
== term
);
1897 t
= constraintExprData_termGetTerm (data
);
1898 llassert (constraintTerm_isDefined (t
));
1902 switch (constraintTerm_getKind (t
))
1905 case CTT_INTLITERAL
:
1909 s
= constraintTerm_getSRef(t
);
1910 if (sRef_isResult (s
))
1912 ret
= constraintExpr_makeExprNode(fcnCall
);
1913 constraintExpr_free(e
);
1926 /*to be used for structure checking */
1928 / *@only@
* / static constraintExpr
1929 doSRefFixInvarConstraintTerm (/ *@only@
* / constraintExpr e
, sRef s
, ctype ct
)
1933 constraintExprData data
= e
->data
;
1935 constraintExprKind kind
= e
->kind
;
1939 llassert(kind
== term
);
1941 t
= constraintExprData_termGetTerm (data
);
1942 llassert (constraintTerm_isDefined(t
) );
1946 DPRINTF (("Fixing: %s", constraintExpr_print (e
)));
1948 switch (constraintTerm_getKind(t
))
1951 DPRINTF((message ("%q @ %q ", constraintTerm_unparse(t
),
1952 fileloc_unparse (constraintTerm_getFileloc(t
) ) ) ));
1954 case CTT_INTLITERAL
:
1955 DPRINTF((message (" %q ", constraintTerm_unparse (t
)) ));
1959 / * evans
2001-07-24: constants should use the original term
* /
1960 if (!constraintTerm_canGetValue (t
))
1963 DPRINTF ((message("Doing sRef_fixInvarConstraint for %q ",
1964 constraintTerm_unparse (t
) ) ));
1966 snew
= fixSref (ct
, s
, constraintTerm_getSRef(t
));
1968 ret
= constraintExpr_makeTermsRef(snew
);
1970 constraintExpr_free (e
);
1972 DPRINTF (( message("After Doing sRef_fixConstraintParam constraintExpr is %q ",
1973 constraintExpr_print (ret
) ) ));
1974 / *@
-branchstate@
* /
1975 } / *@
=branchstate@
* /
1986 /*drl moved from constriantTerm.c 5/20/001*/
1987 /*@only@*/ static constraintExpr
1988 doSRefFixConstraintParamTerm (/*@only@*/ constraintExpr e
, /*@observer@*/ /*@temp@*/ exprNodeList arglist
)
1992 constraintExprData data
;
1994 constraintExprKind kind
;
1999 llassert(constraintExpr_isDefined (e
) );
2007 llassert(kind
== term
);
2009 t
= constraintExprData_termGetTerm (data
);
2010 llassert (constraintTerm_isDefined(t
) );
2014 DPRINTF (("Fixing: %s", constraintExpr_print (e
)));
2016 switch (constraintTerm_getKind(t
))
2019 DPRINTF((message ("%q @ %q ", constraintTerm_unparse(t
),
2020 fileloc_unparse (constraintTerm_getFileloc(t
) ) ) ));
2022 case CTT_INTLITERAL
:
2023 DPRINTF((message (" %q ", constraintTerm_unparse (t
)) ));
2026 /* evans 2001-07-24: constants should use the original term */
2027 if (!constraintTerm_canGetValue (t
))
2029 DPRINTF ((message("Doing sRef_fixConstraintParam for %q ",
2030 constraintTerm_unparse (t
) ) ));
2031 ret
= sRef_fixConstraintParam (constraintTerm_getSRef(t
), arglist
);
2033 constraintExpr_free (e
);
2035 DPRINTF (( message("After Doing sRef_fixConstraintParam constraintExpr is %q ",
2036 constraintExpr_print (ret
) ) ));
2038 } /*@=branchstate@*/
2050 bool constraintExpr_includesTerm (constraintExpr expr
, constraintTerm term
)
2052 if (constraintTerm_hasTerm (expr
->term
, term
) )
2055 if ((expr
->expr
) != NULL
)
2057 return ( constraintExpr_includesTerm (expr
->expr
, term
) );
2064 /*drl added 6/11/01 */
2065 bool constraintExpr_isBinaryExpr (/*@observer@*/ constraintExpr c
)
2068 llassert(constraintExpr_isDefined (c
) );
2070 if ( ! (constraintExpr_isDefined (c
) ) )
2073 if (c
->kind
== binaryexpr
)
2080 /*drl added 8/08/001 */
2081 bool constraintExpr_isTerm (/*@observer@*/ constraintExpr c
) /*@*/
2083 llassert(constraintExpr_isDefined (c
) );
2085 if (c
->kind
== term
)
2092 /*@observer@*/ /*@temp@*/ constraintTerm
constraintExpr_getTerm ( /*@temp@*/ /*@observer@*/ constraintExpr c
) /*@*/
2094 constraintTerm term
;
2096 llassert(constraintExpr_isDefined (c
) );
2098 llassert(constraintExpr_isTerm(c
) );
2100 term
= constraintExprData_termGetTerm(c
->data
);
2105 static void binaryExpr_dump (/*@observer@*/ constraintExprData data
, FILE *f
)
2107 constraintExpr expr1
;
2108 constraintExprBinaryOpKind binaryOp
;
2109 constraintExpr expr2
;
2112 binaryOp
= constraintExprData_binaryExprGetOp (data
);
2114 fprintf(f
, "%d\n", (int) binaryOp
);
2116 expr1
= constraintExprData_binaryExprGetExpr1 (data
);
2117 expr2
= constraintExprData_binaryExprGetExpr2 (data
);
2121 constraintExpr_dump(expr1
, f
);
2124 constraintExpr_dump(expr2
, f
);
2128 static constraintExpr
binaryExpr_undump (FILE *f
)
2130 constraintExpr expr1
;
2131 constraintExprBinaryOpKind binaryOp
;
2132 constraintExpr expr2
;
2141 os
= mstring_create (MAX_DUMP_LINE_LENGTH
);
2143 str
= fgets(os
, MAX_DUMP_LINE_LENGTH
, f
);
2145 if (! mstring_isDefined(str
) )
2147 llfatalbug(message("Library file is corrupted") );
2150 binaryOp
= (constraintExprBinaryOpKind
) reader_getInt(&str
);
2152 str
= fgets(os
, MAX_DUMP_LINE_LENGTH
, f
);
2154 if (! mstring_isDefined(str
) )
2156 llfatalbug(message("Library file is corrupted") );
2159 reader_checkChar (&str
, 'e');
2160 reader_checkChar (&str
, '1');
2162 expr1
= constraintExpr_undump (f
);
2164 str
= fgets(os
, MAX_DUMP_LINE_LENGTH
, f
);
2166 reader_checkChar (&str
, 'e');
2167 reader_checkChar (&str
, '2');
2169 expr2
= constraintExpr_undump (f
);
2171 ret
= constraintExpr_makeBinaryOpConstraintExpr (expr1
, expr2
);
2172 ret
->data
= constraintExprData_binaryExprSetOp(ret
->data
, binaryOp
);
2180 static void unaryExpr_dump (/*@observer@*/ constraintExprData data
, FILE *f
)
2183 constraintExpr expr
;
2184 constraintExprUnaryOpKind unaryOp
;
2186 unaryOp
= constraintExprData_unaryExprGetOp (data
);
2188 fprintf(f
, "%d\n", (int) unaryOp
);
2190 expr
= constraintExprData_unaryExprGetExpr (data
);
2192 constraintExpr_dump(expr
, f
);
2195 static constraintExpr
unaryExpr_undump ( FILE *f
)
2198 constraintExpr expr
;
2199 constraintExprUnaryOpKind unaryOp
;
2205 str
= mstring_create (MAX_DUMP_LINE_LENGTH
);
2207 str
= fgets(os
, MAX_DUMP_LINE_LENGTH
, f
);
2209 if (! mstring_isDefined(str
) )
2211 llfatalbug(message("Library file is corrupted") );
2214 unaryOp
= (constraintExprUnaryOpKind
) reader_getInt(&str
);
2216 expr
= constraintExpr_undump (f
);
2218 ret
= constraintExpr_makeUnaryOp (expr
, unaryOp
);
2225 void constraintExpr_dump (/*@observer@*/ constraintExpr expr
, FILE *f
)
2227 constraintExprKind kind
;
2231 llassert(constraintExpr_isDefined(expr
) );
2233 DPRINTF((message("constraintExpr_dump:: dumping constraintExpr %s",
2234 constraintExpr_unparse(expr
)
2239 fprintf(f
,"%d\n", (int) kind
);
2244 t
= constraintExprData_termGetTerm (expr
->data
);
2245 constraintTerm_dump (t
, f
);
2248 unaryExpr_dump (expr
->data
, f
);
2251 binaryExpr_dump (expr
->data
, f
);
2256 /*@only@*/ constraintExpr
constraintExpr_undump (FILE *f
)
2258 constraintExprKind kind
;
2265 os
= mstring_create (MAX_DUMP_LINE_LENGTH
);
2266 s
= fgets(os
, MAX_DUMP_LINE_LENGTH
, f
);
2267 if (! mstring_isDefined(s
))
2269 llfatalbug(message("Library file is corrupted") );
2272 kind
= (constraintExprKind
) reader_getInt(&s
);
2279 t
= constraintTerm_undump (f
);
2280 ret
= constraintExpr_makeTerm(t
);
2283 ret
= unaryExpr_undump (f
);
2286 ret
= binaryExpr_undump (f
);
2294 int constraintExpr_getDepth (constraintExpr ex
)
2298 constraintExprKind kind
;
2300 llassert (ex
!= NULL
);
2310 ret
= constraintExpr_getDepth (constraintExprData_unaryExprGetExpr (ex
->data
) );
2314 ret
= constraintExpr_getDepth (constraintExprData_binaryExprGetExpr1 (ex
->data
) );
2316 ret
+= constraintExpr_getDepth (constraintExprData_binaryExprGetExpr2 (ex
->data
) );
2325 bool constraintExpr_canGetCType (constraintExpr e
) /*@*/
2327 if (constraintExpr_isUndefined(e
))
2330 if (e
->kind
== term
)
2336 DPRINTF (("constraintExpr_canGetCType: can't get type for %s", constraintExpr_unparse (e
)));
2341 ctype
constraintExpr_getCType (constraintExpr e
) /*@*/
2345 llassert (constraintExpr_isDefined (e
));
2346 llassert (constraintExpr_canGetCType (e
));
2351 t
= constraintExprData_termGetTerm (e
->data
);
2352 return (constraintTerm_getCType(t
) );
2353 /* assume that a unary expression will be an int ... */
2355 return ctype_unknown
; /* was ctype_signedintegral; */
2356 /* drl for just return type of first operand */
2358 return (constraintExpr_getCType (constraintExprData_binaryExprGetExpr1 (e
->data
)));
2363 /* drl add 10-5-001 */
2365 static bool constraintExpr_hasTypeChange (constraintExpr e
)
2367 llassert(constraintExpr_isDefined(e
));
2369 if (constraintExpr_isDefined((e
)) && (e
->ct
== TRUE
))
2374 if (e
->kind
== unaryExpr
)
2376 if (constraintExprData_unaryExprGetOp (e
->data
) == MAXSET
)
2378 constraintExpr ce
= constraintExprData_unaryExprGetExpr(e
->data
);
2379 DPRINTF (("Unary type change: [%x] %s", ce
, constraintExpr_unparse (ce
)));
2380 DPRINTF (("Types: %s / %s", ctype_unparse (constraintExpr_getCType (ce
)),
2381 ctype_unparse (constraintExpr_getOrigType (ce
))));
2382 return (constraintExpr_hasTypeChange(ce
));
2389 /* drl add 10-5-001 */
2391 static ctype
constraintExpr_getOrigType (constraintExpr e
)
2393 llassert (constraintExpr_isDefined (e
));
2394 llassert (constraintExpr_hasTypeChange (e
));
2401 if (e
->kind
== unaryExpr
)
2403 if (constraintExprData_unaryExprGetOp (e
->data
) == MAXSET
)
2405 constraintExpr ce
= constraintExprData_unaryExprGetExpr (e
->data
);
2406 return (constraintExpr_getOrigType(ce
));
2414 /*drl added these around 10/18/001*/
2416 static /*@only@*/ constraintExpr
2417 constraintExpr_div (/*@only@*/ constraintExpr e
, ctype tfrom
, ctype tto
, fileloc loc
)
2419 int sizefrom
= ctype_getSize (tfrom
);
2420 int sizeto
= ctype_getSize (tto
);
2422 DPRINTF (("%s: %s", __func__
, constraintExpr_unparse (e
)));
2423 DPRINTF (("Types: %s / %s",
2424 ctype_unparse (tfrom
),
2425 ctype_unparse (tto
)));
2427 if (sizefrom
== -1) {
2428 llbug (message ("constraintExpr_div: type size unknown: %s", ctype_unparse (tfrom
)));
2432 llbug (message ("constraintExpr_div: type size unknown: %s", ctype_unparse (tto
)));
2435 if (sizeto
== sizefrom
)
2437 DPRINTF (("Sizes match: %d / %d", sizeto
, sizefrom
));
2438 ; /* Sizes match, a-ok */
2444 llassert (e
!= NULL
);
2445 llassert (e
->kind
== term
);
2446 ct
= constraintExprData_termGetTerm (e
->data
);
2447 if (!constraintTerm_canGetValue (ct
))
2449 DPRINTF (("%s: can't get constraint term value: %s", __func__
,
2450 constraintTerm_unparse (ct
)));
2456 DPRINTF (("constraint: %s / %s", constraintExpr_unparse (e
),
2457 constraintTerm_unparse (ct
)));
2459 val
= constraintTerm_getValue (ct
);
2460 if ((val
* sizefrom
) % sizeto
!= 0)
2462 voptgenerror (FLG_ALLOCMISMATCH
,
2463 message ("Allocated memory is converted to type %s of (size %d), "
2464 "which is not divisible into original allocation of space "
2465 "for %d elements of type %s (size %d)",
2466 ctype_unparse (tto
), sizeto
,
2467 long_toInt (val
), ctype_unparse (tfrom
), sizefrom
),
2470 constraintTerm_setValue (ct
, (val
* sizefrom
) / sizeto
);
2474 DPRINTF (("After div: %s", constraintExpr_unparse (e
)));
2479 /*@access exprNode@*/
2480 static /*@only@*/ constraintExpr
2481 constraintTerm_simpleDivTypeExprNode (/*@only@*/ constraintExpr e
, ctype tfrom
, ctype tto
, fileloc loc
)
2484 exprNode t1
, t2
, expr
;
2488 llassert (constraintExpr_isDefined(e
) );
2490 DPRINTF (("constraintTerm_simpleDivTypeExprNode e=%s [%s => %s]", constraintExpr_print(e
),
2491 ctype_unparse(tfrom
), ctype_unparse (tto
)));
2493 t
= constraintExprData_termGetTerm (e
->data
);
2495 expr
= constraintTerm_getExprNode (t
);
2497 llassert (constraintExpr_isDefined(e
));
2498 llassert (exprNode_isDefined(expr
));
2500 if (expr
->kind
== XPR_OP
)
2504 t1
= exprData_getOpA (data
);
2505 t2
= exprData_getOpB (data
);
2506 tok
= exprData_getOpTok (data
);
2508 if (lltok_isMult (tok
))
2511 ** If the sizeof is first, flip them.
2514 llassert (exprNode_isDefined(t1
) && exprNode_isDefined(t2
));
2516 if (t2
->kind
== XPR_SIZEOF
|| t2
->kind
== XPR_SIZEOFT
)
2523 /*drl 3/2/2003 we know this from the fact that it's a
2524 multiplication operation...*/
2526 if (t1
->kind
== XPR_SIZEOF
|| t1
->kind
== XPR_SIZEOFT
)
2530 if (t1
->kind
== XPR_SIZEOFT
)
2532 multype
= qtype_getType (exprData_getType (t1
->edata
));
2536 exprNode tempE
= exprData_getSingle (t1
->edata
);
2537 multype
= exprNode_getType (tempE
);
2540 DPRINTF (("Here we go sizeof: %s / %s / %s",
2541 ctype_unparse (multype
), ctype_unparse (tfrom
), ctype_unparse (tto
)));
2542 llassert (ctype_isPointer (tfrom
));
2544 if (ctype_almostEqual (ctype_makePointer (multype
), tto
))
2546 /* this is a bit sloopy but ... */
2547 constraintExpr_free (e
);
2548 DPRINTF (("Sizeof types match okay!"));
2549 return constraintExpr_makeExprNode (t2
);
2553 int sizemul
= ctype_getSize (multype
);
2554 ctype tobase
= ctype_baseArrayPtr (tto
);
2555 int sizeto
= ctype_getSize (tobase
);
2557 DPRINTF (("Types: %s / %s / %s",
2558 ctype_unparse (tfrom
), ctype_unparse (tto
), ctype_unparse (multype
)));
2560 voptgenerror (FLG_ALLOCMISMATCH
,
2561 message ("Allocated memory is used as a different type (%s) from the sizeof type (%s)",
2562 ctype_unparse (tobase
), ctype_unparse (multype
)),
2565 if (sizemul
== sizeto
)
2567 constraintExpr_free (e
);
2568 DPRINTF (("Sizeof types match okay!"));
2569 return constraintExpr_makeExprNode (t2
);
2573 /* nothing was here */
2574 DPRINTF (("MISMATCHING TYPES!"));
2575 return (constraintExpr_div (constraintExpr_makeExprNode (t2
), multype
, tto
, loc
));
2581 DPRINTF (("NOT A SIZEOF!"));
2587 DPRINTF (("Not a mult: %s", constraintExpr_unparse (e
)));
2591 return (constraintExpr_div (e
, tfrom
, tto
, loc
));
2593 /*@noaccess exprNode@*/
2595 static /*@only@*/ constraintExpr
simpleDivType (/*@only@*/ constraintExpr e
, ctype tfrom
, ctype tto
, fileloc loc
)
2597 DPRINTF (("simpleDiv got %s", constraintExpr_unparse(e
)));
2598 DPRINTF (("Types: %s / %s",
2599 ctype_unparse (tfrom
),
2600 ctype_unparse (tto
)));
2602 llassert (constraintExpr_isDefined(e
));
2608 constraintTerm t
= constraintExprData_termGetTerm (e
->data
);
2610 DPRINTF (("Term: %s", constraintTerm_unparse (t
)));
2612 if (constraintTerm_isExprNode (t
))
2614 return constraintTerm_simpleDivTypeExprNode (e
, tfrom
, tto
, loc
);
2616 /* search for * size of ct and remove */
2618 DPRINTF (("Here: %s / %s -> %s", constraintExpr_unparse (e
), ctype_unparse (tfrom
), ctype_unparse (tto
)));
2619 return constraintExpr_div (e
, tfrom
, tto
, loc
);
2624 constraintExpr temp
;
2626 temp
= constraintExprData_binaryExprGetExpr1 (e
->data
);
2627 temp
= constraintExpr_copy(temp
);
2628 temp
= simpleDivType (temp
, tfrom
, tto
, loc
);
2630 e
->data
= constraintExprData_binaryExprSetExpr1 (e
->data
, temp
);
2632 temp
= constraintExprData_binaryExprGetExpr2 (e
->data
);
2633 temp
= constraintExpr_copy(temp
);
2634 temp
= simpleDivType (temp
, tfrom
, tto
, loc
);
2635 e
->data
= constraintExprData_binaryExprSetExpr2 (e
->data
, temp
);
2637 DPRINTF (("simpleDiv binaryexpr returning %s ", constraintExpr_unparse(e
)));
2642 return constraintExpr_div (e
, tfrom
, tto
, loc
);
2649 static /*@only@*/ constraintExpr
constraintExpr_adjustMaxSetForCast (/*@only@*/ constraintExpr e
, ctype tfrom
,
2650 ctype tto
, fileloc loc
)
2652 DPRINTF (("constraintExpr_adjustMaxSetForCast got %s [%s => %s]", constraintExpr_unparse(e
),
2653 ctype_unparse (tfrom
), ctype_unparse (tto
)));
2655 e
= constraintExpr_makeIncConstraintExpr (e
);
2656 e
= constraintExpr_simplify (e
);
2657 e
= simpleDivType (e
, tfrom
, tto
, loc
);
2658 e
= constraintExpr_makeDecConstraintExpr (e
);
2659 e
= constraintExpr_simplify (e
);
2661 DPRINTF (("constraintExpr_adjustMaxSetForCast returning %s ", constraintExpr_unparse(e
)));
2666 bool constraintExpr_isConstantOnly (constraintExpr e
)
2668 DPRINTF (("constraintExpr_isConstantOnly %s ", constraintExpr_unparse(e
)));
2669 llassert (constraintExpr_isDefined(e
));
2675 constraintTerm t
= constraintExprData_termGetTerm(e
->data
);
2677 if (constraintTerm_isConstantOnly (t
))
2689 constraintExpr temp1
= constraintExprData_binaryExprGetExpr1 (e
->data
);
2690 constraintExpr temp2
= constraintExprData_binaryExprGetExpr2 (e
->data
);
2692 if (constraintExpr_isConstantOnly(temp1
) &&
2693 constraintExpr_isConstantOnly(temp2
) )
2705 constraintExpr temp
;
2707 temp
= constraintExprData_unaryExprGetExpr (e
->data
);
2709 if (constraintExpr_isConstantOnly(temp
) )