Some consistency changes to library & headers flags.
[splint-patched.git] / src / constraintExpr.c
blob55b3d8105b7b3f713e16bf955cb8bbf893a1470d
1 /*
2 ** Splint - annotation-assisted static program checker
3 ** Copyright (C) 1994-2003 University of Virginia,
4 ** Massachusetts Institute of Technology
5 **
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.
10 **
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.
15 **
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
26 ** constraintExpr.c
29 # include "splintMacros.nf"
30 # include "basic.h"
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);
40 #if 0
41 /*@only@*/ static constraintExpr
42 doSRefFixInvarConstraintTerm (/*@only@*/ constraintExpr p_e,
43 sRef p_s, ctype p_ct);
44 #endif
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)
51 /*@modifies p_e@*/;
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,
59 fileloc p_loc);
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) )
68 switch (expr->kind)
70 case unaryExpr:
71 constraintExprData_freeUnaryExpr(expr->data);
72 break;
73 case binaryexpr:
74 constraintExprData_freeBinaryExpr(expr->data);
75 break;
76 case term:
77 constraintExprData_freeTerm(expr->data);
78 break;
79 BADDEFAULT;
82 expr->data = NULL;
83 free (expr);
85 else
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) )
100 return TRUE;
104 return FALSE;
107 static bool isZeroBinaryOp (constraintExpr expr)
109 constraintExpr e2;
111 llassert (expr != NULL); /* evans 2001-07-18 */
113 if (!constraintExpr_isBinaryExpr (expr) )
115 return FALSE;
119 e2 = constraintExprData_binaryExprGetExpr2(expr->data);
121 llassert (e2 != NULL); /* evans 2001-07-18 */
123 if (constraintExpr_isBinaryExpr (e2) )
125 constraintExpr e1;
127 e1 = constraintExprData_binaryExprGetExpr1(e2->data);
129 if (constraintExpr_isLit(e1) )
131 if (constraintExpr_getValue(e1) == 0 )
133 return TRUE;
137 return FALSE;
140 /* change expr + (o - expr) to (expr -expr) */
142 /*@only@*/ /*@notnull@*/ static constraintExpr removeZero (/*@only@*/ /*@returned@*/ constraintExpr expr)
144 constraintExpr expr2;
145 constraintExpr temp;
147 constraintExprBinaryOpKind op;
148 constraintExprBinaryOpKind tempOp;
150 llassert (expr != NULL); /* evans 2001-07-18 */
152 if (!isZeroBinaryOp(expr) )
153 return 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)
166 op = tempOp;
167 else if (op == BINARYOP_MINUS)
169 if (tempOp == BINARYOP_PLUS)
170 op = BINARYOP_MINUS;
171 else if (tempOp == BINARYOP_MINUS)
172 op = BINARYOP_PLUS;
173 else
174 BADEXIT;
176 else
177 BADEXIT;
179 expr->data = constraintExprData_binaryExprSetExpr2(expr->data, temp);
180 expr->data = constraintExprData_binaryExprSetOp(expr->data, op);
182 return expr;
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;
196 propagate1 = FALSE;
197 propagate2 = FALSE;
199 literal1 = 0;
200 literal2 = 0;
202 *propagate = FALSE;
203 *literal = 0;
206 llassert (expr != NULL);
208 /* we simplify unaryExpr elsewhere */
209 if (expr->kind != binaryexpr)
210 return expr;
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;
237 else
238 BADEXIT;
240 if ( constraintExpr_isLit (expr1) && constraintExpr_isLit (expr2) )
242 long t1, t2;
243 t1 = constraintExpr_getValue (expr1);
244 t2 = constraintExpr_getValue (expr2);
245 llassert(*propagate == FALSE);
246 *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) ));
256 else
257 BADEXIT;
261 if (constraintExpr_isLit (expr1) )
263 *propagate = TRUE;
265 *literal += constraintExpr_getValue (expr1);
267 if (op == BINARYOP_PLUS)
269 constraintExpr_free(expr1);
270 constraintExpr_free(expr);
271 return expr2;
273 else if (op == BINARYOP_MINUS)
276 constraintExpr temp;
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) );
288 return temp;
290 else
292 BADBRANCH; /* evans 2001-07-18 */
296 if (constraintExpr_isLit (expr2) )
298 *propagate = TRUE;
300 if ( op == BINARYOP_PLUS )
301 *literal += constraintExpr_getValue (expr2);
302 else if (op == BINARYOP_MINUS)
303 *literal -= constraintExpr_getValue (expr2);
304 else
305 BADEXIT;
307 constraintExpr_free(expr2);
308 constraintExpr_free(expr);
309 return expr1;
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);
318 return expr;
321 /*@notnull@*/ /*@only@*/ static constraintExpr constraintExpr_combineConstants (/*@only@*/ constraintExpr expr ) /*@modifies expr@*/
323 bool propagate;
324 int literal;
326 DPRINTF ((message ("Before combine %s", constraintExpr_unparse(expr) ) ) );
327 expr = constraintExpr_propagateConstants (expr, &propagate, &literal);
330 if (propagate)
332 constraintExpr ret;
334 if (literal != 0)
336 ret = constraintExpr_makeBinaryOpConstraintExprIntLiteral (expr, literal);
337 expr = ret;
340 DPRINTF ((message ("After combine %s", constraintExpr_unparse(expr) ) ) );
342 llassert(constraintExpr_isDefined(expr) );
343 return expr;
346 /*@special@*/
347 static /*@notnull@*/ constraintExpr constraintExpr_alloc (void) /*@post:isnull result->data@*/
349 constraintExpr ret;
350 ret = dmalloc (sizeof (*ret) );
351 ret->kind = term;
352 ret->data = NULL;
353 ret->ct = FALSE;
354 ret->origType = ctype_undefined;
355 return ret;
358 /*@only@*/ static constraintExprData copyExprData (/*@observer@*/ constraintExprData data, constraintExprKind kind)
360 constraintExprData ret;
361 llassert(constraintExprData_isDefined(data));
363 switch (kind)
365 case binaryexpr:
366 ret = constraintExprData_copyBinaryExpr(data);
367 break;
368 case unaryExpr:
369 ret = constraintExprData_copyUnaryExpr(data);
370 break;
371 case term:
372 ret = constraintExprData_copyTerm(data);
373 break;
374 BADDEFAULT;
376 return ret;
379 constraintExpr constraintExpr_copy (constraintExpr expr)
381 constraintExpr ret;
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);
397 ret->ct = expr->ct;
398 ret->origType = expr->origType;
399 return ret;
403 /*@only@*/ static constraintExpr oldconstraintExpr_makeTermExprNode ( /*@dependent@*/ exprNode e)
405 constraintExpr ret;
406 constraintTerm t;
407 ret = constraintExpr_alloc();
408 ret->kind = term;
409 ret->data = dmalloc (sizeof *(ret->data) );
410 t = constraintTerm_makeExprNode (e);
411 ret->data = constraintExprData_termSetTerm (ret->data, t);
412 ret->ct = FALSE;
413 ret->origType = ctype_undefined;
415 return ret;
418 /*@access exprNode@*/
419 constraintExpr constraintExpr_makeExprNode (exprNode e)
421 sRef s;
422 constraintExpr ret, ce1, ce2;
423 exprData data;
424 exprNode t, t1, t2;
425 lltok tok;
427 if (exprNode_isUndefined (e))
429 return constraintExpr_undefined;
432 data = e->edata;
434 switch (e->kind)
436 case XPR_SIZEOF:
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) )
445 int size;
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));
455 else
457 DPRINTF ((message ("could not determine the size of %s", exprNode_unparse (e) ) ) );
458 ret = oldconstraintExpr_makeTermExprNode (e);
460 break;
462 case XPR_OP:
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*/
478 #if 0
482 drl 8-11-001
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);
503 else
505 ret = oldconstraintExpr_makeTermExprNode (e);
508 #endif
510 else
511 ret = oldconstraintExpr_makeTermExprNode (e);
513 break;
514 case XPR_PARENS:
515 t = exprData_getUopNode (data);
516 ret = constraintExpr_makeExprNode (t);
517 break;
519 case XPR_PREOP:
520 t = exprData_getUopNode (data);
521 tok = exprData_getUopTok (data);
522 if (lltok_isIncOp (tok))
524 constraintExpr temp;
525 temp = constraintExpr_makeExprNode(t);
526 ret = constraintExpr_makeIncConstraintExpr(temp);
528 else if (lltok_isDecOp (tok))
530 constraintExpr temp;
531 temp = constraintExpr_makeExprNode(t);
532 ret = constraintExpr_makeDecConstraintExpr(temp);
534 else
535 ret = oldconstraintExpr_makeTermExprNode (e);
536 break;
538 case XPR_POSTOP:
539 t = exprData_getUopNode (data);
540 ret = constraintExpr_makeExprNode (t);
541 break;
542 case XPR_CAST:
543 t = exprData_getCastNode (data);
544 ret = constraintExpr_makeExprNode (t);
545 break;
546 case XPR_COMMA:
547 t = exprData_getPairA (data);
548 ret = constraintExpr_makeExprNode(t);
549 break;
550 default:
551 ret = oldconstraintExpr_makeTermExprNode (e);
554 return ret;
557 /*@noaccess exprNode@*/
562 #if 0
563 static /*@only@*/ constraintExpr constraintExpr_makeTermExprNode (/*@exposed@*/ exprNode e)
565 return oldconstraintExpr_makeTermExprNode(e);
567 #endif
569 static constraintExpr constraintExpr_makeTerm (/*@only@*/ constraintTerm t)
571 constraintExpr ret;
573 ret = constraintExpr_alloc();
574 ret->kind = term;
575 ret->data = dmalloc (sizeof *(ret->data) );
576 ret->data->term = NULL;
577 ret->data = constraintExprData_termSetTerm (ret->data, t);
578 ret->ct = FALSE;
579 ret->origType = ctype_undefined;
581 return ret;
584 constraintExpr constraintExpr_makeTermsRef (/*@temp@*/ sRef s)
586 constraintExpr ret;
587 constraintTerm t;
588 ret = constraintExpr_alloc();
589 ret->kind = term;
590 ret->data = dmalloc (sizeof *(ret->data) );
591 t = constraintTerm_makesRef (s);
592 ret->data = constraintExprData_termSetTerm (ret->data, t);
594 ret->ct = FALSE;
595 ret->origType = ctype_undefined;
597 return ret;
600 /*@special@*/ /*@notnull@*/ static constraintExpr makeUnaryOpGeneric (void) /*@allocates result->data@*/ /*@defines result->kind@*/
602 constraintExpr ret;
603 ret = constraintExpr_alloc();
604 ret->kind = unaryExpr;
605 ret->data = dmalloc (sizeof *(ret->data));
606 ret->data->unaryOp.expr = constraintExpr_undefined;
607 return ret;
610 /*@notnull@*/ /*@only@*/ static constraintExpr constraintExpr_makeUnaryOpConstraintExpr (/*@only@*/ constraintExpr cexpr)
612 constraintExpr ret;
613 ret = makeUnaryOpGeneric();
615 /*@-uniondef@*/
616 /*@-compdef@*/
617 ret->data = constraintExprData_unaryExprSetExpr (ret->data, cexpr);
618 ret->data = constraintExprData_unaryExprSetOp (ret->data, UNARYOP_UNDEFINED);
620 return ret;
622 /*@=compdef@*/
623 /*@=uniondef@*/
627 /*@only@*/ /*@notnull@*/ static constraintExpr
628 constraintExpr_makeUnaryOp (/*@only@*/ constraintExpr cexpr, constraintExprUnaryOpKind Op)
630 constraintExpr ret;
631 ret = makeUnaryOpGeneric();
633 ret->data = constraintExprData_unaryExprSetExpr (ret->data, cexpr);
634 ret->data = constraintExprData_unaryExprSetOp (ret->data, Op);
636 ret->ct = FALSE;
637 ret->origType = ctype_undefined;
639 return ret;
642 /*@only@*/ /*@notnull@*/
643 static constraintExpr constraintExpr_makeUnaryOpExprNode (/*@exposed@*/ exprNode expr)
645 constraintExpr ret;
646 constraintExpr sub;
647 sub = constraintExpr_makeExprNode (expr);
648 ret = constraintExpr_makeUnaryOpConstraintExpr(sub);
650 return ret;
653 /*@only@*/ /*@notnull@*/
654 static constraintExpr constraintExpr_makeMaxSetConstraintExpr (/*@only@*/ constraintExpr c)
656 constraintExpr ret;
657 ret = constraintExpr_makeUnaryOp (c, MAXSET);
658 return ret;
662 /*@only@*/ /*@notnull@*/
663 static constraintExpr constraintExpr_makeSRefUnaryOp (/*@temp@*/ /*@observer@*/ sRef s, constraintExprUnaryOpKind op)
665 constraintExpr ret;
666 constraintExpr t;
668 t = constraintExpr_makeTermsRef (s);
669 ret = constraintExpr_makeUnaryOpConstraintExpr (t);
670 ret->data = constraintExprData_unaryExprSetOp (ret->data, op);
672 return ret;
675 /*@only@*/
676 constraintExpr constraintExpr_makeSRefMaxRead( sRef s)
678 return (constraintExpr_makeSRefUnaryOp (s, MAXREAD) );
681 /*@only@*/
682 constraintExpr constraintExpr_makeSRefMaxset ( sRef s)
684 return (constraintExpr_makeSRefUnaryOp (s, MAXSET) );
687 /*@only@*/
688 constraintExpr constraintExpr_parseMakeUnaryOp (lltok op, constraintExpr cexpr)
690 constraintExpr ret;
691 ret = constraintExpr_makeUnaryOpConstraintExpr ( cexpr);
693 switch (lltok_getTok (op))
695 case QMAXSET:
696 ret->data = constraintExprData_unaryExprSetOp (ret->data, MAXSET);
697 break;
698 case QMAXREAD:
699 ret->data = constraintExprData_unaryExprSetOp (ret->data, MAXREAD);
700 break;
701 default:
702 llfatalbug (message ("Unhandled operation in constraint: %s", lltok_unparse (op)));
704 return ret;
707 /*@only@*/
708 constraintExpr constraintExpr_makeMaxSetExpr (/*@exposed@*/ exprNode expr)
710 constraintExpr ret;
711 ret = constraintExpr_makeExprNode (expr);
713 ret = constraintExpr_makeMaxSetConstraintExpr (ret);
715 llassert (ret != NULL);
716 return ret;
719 /*@only@*/
720 constraintExpr constraintExpr_makeMaxReadExpr (exprNode expr)
722 constraintExpr ret;
723 ret = constraintExpr_makeUnaryOpExprNode(expr);
724 ret->data = constraintExprData_unaryExprSetOp (ret->data, MAXREAD);
725 return ret;
728 # if 0
729 /*@only@*/
730 /*@unused@*/ static constraintExpr constraintExpr_makeMinSetExpr (/*@exposed@*/ exprNode expr)
732 constraintExpr ret;
733 ret = constraintExpr_makeUnaryOpExprNode(expr);
734 ret->data = constraintExprData_unaryExprSetOp (ret->data, MINSET);
735 return ret;
738 /*@only@*/
739 /*@unused@*/ static constraintExpr constraintExpr_makeMinReadExpr (/*@exposed@*/ exprNode expr)
741 constraintExpr ret;
742 ret = constraintExpr_makeUnaryOpExprNode(expr);
743 ret->data = constraintExprData_unaryExprSetOp (ret->data, MINREAD);
744 return ret;
746 # endif
748 /*@only@*/
749 constraintExpr constraintExpr_makeValueExpr (/*@exposed@*/ exprNode expr)
751 constraintExpr ret;
752 ret = constraintExpr_makeExprNode (expr);
753 return ret;
756 /*@only@*/ /*@notnull@*/
757 constraintExpr constraintExpr_makeIntLiteral (long i)
759 constraintExpr ret;
760 constraintTerm t;
761 ret = constraintExpr_alloc();
762 ret->kind = term;
763 ret->data = dmalloc (sizeof *(ret->data) );
764 t = constraintTerm_makeIntLiteral (i);
765 ret->data = constraintExprData_termSetTerm (ret->data, t);
767 ret->ct = FALSE;
768 ret->origType = ctype_undefined;
770 return ret;
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 @*/
784 constraintExpr ret;
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;
792 return ret;
796 static /*@notnull@*/ /*@only@*/ constraintExpr constraintExpr_makeBinaryOpConstraintExpr (/*@only@*/constraintExpr expr1, /*@only@*/ constraintExpr expr2)
799 constraintExpr ret;
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);
806 ret->ct = FALSE;
807 ret->origType = ctype_undefined;
809 return ret;
812 /*@only@*/
813 constraintExpr constraintExpr_parseMakeBinaryOp (/*@only@*/ constraintExpr expr1, lltok op,/*@only@*/ constraintExpr expr2)
815 constraintExpr ret;
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);
826 else
828 llassert (FALSE);
831 return ret;
834 # if 0
835 /*@only@*/
836 /*@unused@*/ static constraintExpr constraintExpr_makeBinaryOpExprNode (/*@exposed@*/ exprNode expr1, /*@exposed@*/ exprNode expr2)
838 constraintExpr ret;
839 constraintExpr sub1, sub2;
840 sub1 = constraintExpr_makeTermExprNode (expr1);
841 sub2 = constraintExpr_makeTermExprNode (expr2);
842 ret = constraintExpr_makeBinaryOpConstraintExpr(sub1, sub2);
843 return ret;
845 # endif
847 static /*@notnull@*/ /*@only@*/
848 constraintExpr constraintExpr_makeBinaryOpConstraintExprIntLiteral (/*@only@*/ constraintExpr expr, int literal)
850 constraintExpr ret;
851 constraintExpr constExpr;
853 constExpr = constraintExpr_makeIntLiteral (literal);
854 ret = constraintExpr_makeBinaryOpConstraintExpr (expr, constExpr);
855 ret->data = constraintExprData_binaryExprSetOp(ret->data, BINARYOP_PLUS);
856 return ret;
859 /*@only@*/
860 constraintExpr constraintExpr_makeDecConstraintExpr (/*@only@*/constraintExpr expr)
862 constraintExpr ret;
863 constraintExpr inc;
865 inc = constraintExpr_makeIntLiteral (1);
866 ret = constraintExpr_makeBinaryOpConstraintExpr (expr, inc);
867 ret->data = constraintExprData_binaryExprSetOp(ret->data, BINARYOP_MINUS);
868 return ret;
872 /*@only@*/ constraintExpr constraintExpr_makeSubtractExpr (/*@only@*/ constraintExpr expr, /*@only@*/ constraintExpr addent)
874 constraintExpr ret;
876 DPRINTF ((message ("Making subtract expression") ) );
878 ret = constraintExpr_makeBinaryOpConstraintExpr (expr, addent);
879 ret->data = constraintExprData_binaryExprSetOp (ret->data, BINARYOP_MINUS);
880 return ret;
883 /*@only@*/
884 constraintExpr constraintExpr_makeAddExpr (/*@only@*/
885 constraintExpr expr, /*@only@*/
886 constraintExpr addent)
888 constraintExpr ret;
890 DPRINTF ((message ("Doing addTerm simplification") ) );
892 ret = constraintExpr_makeBinaryOpConstraintExpr (expr, addent);
893 ret->data = constraintExprData_binaryExprSetOp (ret->data, BINARYOP_PLUS);
894 return ret;
898 /*@only@*/
899 constraintExpr constraintExpr_makeIncConstraintExpr (/*@only@*/ constraintExpr expr)
901 constraintExpr ret;
902 constraintExpr inc;
904 inc = constraintExpr_makeIntLiteral (1);
905 ret = constraintExpr_makeBinaryOpConstraintExpr (expr, inc);
906 ret->data = constraintExprData_binaryExprSetOp(ret->data, BINARYOP_PLUS);
907 return ret;
910 /*@only@*/
911 static cstring constraintExprUnaryOpKind_print (constraintExprUnaryOpKind op)
913 switch (op)
915 case MAXSET:
916 return message("maxSet");
917 case MINSET:
918 return message("minSet");
919 case MAXREAD:
920 return message("maxRead");
921 case MINREAD:
922 return message("minRead");
923 default:
924 llassert(FALSE);
925 return message ("<(Unary OP OTHER>");
930 /*@only@*/
931 static cstring constraintExprBinaryOpKind_print (constraintExprBinaryOpKind op)
934 switch (op)
936 case BINARYOP_PLUS:
937 return message("+");
938 case BINARYOP_MINUS:
939 return message("-");
941 default:
942 llassert(FALSE);
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)
954 return FALSE;
956 kind = expr1->kind;
958 switch (kind)
960 case term:
961 return constraintTerm_similar (constraintExprData_termGetTerm(expr1->data),
962 constraintExprData_termGetTerm(expr2->data) );
963 /*@notreached@*/ break;
965 case unaryExpr:
966 if (constraintExprData_unaryExprGetOp (expr1->data) != constraintExprData_unaryExprGetOp (expr2->data) )
967 return FALSE;
969 return (constraintExpr_similar (
970 constraintExprData_unaryExprGetExpr (expr1->data),
971 constraintExprData_unaryExprGetExpr (expr2->data)
974 case binaryexpr:
975 if (constraintExprData_binaryExprGetOp (expr1->data) != constraintExprData_binaryExprGetOp (expr2->data) )
976 return FALSE;
978 if (! constraintExpr_similar (constraintExprData_binaryExprGetExpr1 (expr1->data),
979 constraintExprData_binaryExprGetExpr1 (expr2->data)) )
980 return FALSE;
982 if (! constraintExpr_similar (constraintExprData_binaryExprGetExpr2 (expr1->data),
983 constraintExprData_binaryExprGetExpr2 (expr2->data)) )
984 return FALSE;
985 else
986 return TRUE;
987 /*@notreached@*/
988 break;
990 default:
991 llassert(FALSE);
992 return FALSE;
994 /*@notreached@*/
995 return FALSE;
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)
1005 return FALSE;
1007 kind = expr1->kind;
1009 switch (kind)
1011 case term:
1012 return constraintTerm_similar (constraintExprData_termGetTerm(expr1->data),
1013 constraintExprData_termGetTerm(expr2->data) );
1015 case unaryExpr:
1016 if (constraintExprData_unaryExprGetOp (expr1->data) != constraintExprData_unaryExprGetOp (expr2->data) )
1017 return FALSE;
1019 return (constraintExpr_same (
1020 constraintExprData_unaryExprGetExpr (expr1->data),
1021 constraintExprData_unaryExprGetExpr (expr2->data)
1024 case binaryexpr:
1025 if (constraintExprData_binaryExprGetOp (expr1->data) != constraintExprData_binaryExprGetOp (expr2->data) )
1026 return FALSE;
1028 if (! constraintExpr_same (constraintExprData_binaryExprGetExpr1 (expr1->data),
1029 constraintExprData_binaryExprGetExpr1 (expr2->data)) )
1030 return FALSE;
1032 if (! constraintExpr_same (constraintExprData_binaryExprGetExpr2 (expr1->data),
1033 constraintExprData_binaryExprGetExpr2 (expr2->data)) )
1034 return FALSE;
1035 else
1036 return TRUE;
1038 BADDEFAULT;
1042 bool
1043 constraintExpr_search (/*@observer@*/ constraintExpr c,
1044 /*@observer@*/ constraintExpr old)
1046 bool ret = FALSE;
1047 constraintExprKind kind;
1048 constraintExpr temp;
1050 if (constraintExpr_similar (c, old))
1052 DPRINTF (("Found %q", constraintExpr_unparse (old)));
1053 return TRUE;
1056 llassert (constraintExpr_isDefined (c) && constraintExpr_isDefined(old) );
1058 if ( !(constraintExpr_isDefined (c) && constraintExpr_isDefined(old) ) )
1059 return FALSE;
1061 kind = c->kind;
1063 switch (kind)
1065 case term:
1066 break;
1067 case unaryExpr:
1068 temp = constraintExprData_unaryExprGetExpr (c->data);
1069 ret = ret || constraintExpr_search (temp, old);
1070 break;
1071 case binaryexpr:
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);
1078 break;
1079 default:
1080 llassert(FALSE);
1082 return ret;
1087 /*@only@*/ constraintExpr
1088 constraintExpr_searchandreplace (/*@only@*/ /*@unique@*/ constraintExpr c, /*@temp@*/ constraintExpr old,
1089 /*@temp@*/ constraintExpr newExpr )
1091 constraintExprKind kind;
1092 constraintExpr temp;
1093 constraintExpr ret;
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)));
1122 ret->ct = TRUE;
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),
1145 loc);
1147 else
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),
1153 loc);
1158 constraintExpr_free (c);
1159 DPRINTF (("ret: %s", constraintExpr_unparse (ret)));
1160 return ret;
1163 kind = c->kind;
1165 switch (kind)
1167 case term:
1168 break;
1169 case unaryExpr:
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);
1175 break;
1176 case binaryexpr:
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);
1187 break;
1188 default:
1189 llassert (FALSE);
1192 DPRINTF (("ret: %s", constraintExpr_unparse (c)));
1193 return c;
1196 /*@notnull@*/ static constraintExpr constraintExpr_simplifyChildren (/*@returned@*/ /*@notnull@*/ constraintExpr c)
1198 constraintExprKind kind;
1199 constraintExpr temp;
1201 kind = c->kind;
1203 switch (kind)
1205 case term:
1206 break;
1207 case unaryExpr:
1208 temp = constraintExprData_unaryExprGetExpr (c->data);
1209 temp = constraintExpr_copy(temp);
1210 temp = constraintExpr_simplify (temp);
1211 c->data = constraintExprData_unaryExprSetExpr (c->data, temp);
1212 break;
1213 case binaryexpr:
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);
1226 break;
1227 default:
1228 llassert(FALSE);
1230 return c;
1235 constraintExpr constraintExpr_setFileloc (/*@returned@*/ constraintExpr c, fileloc loc) /*@modifies c @*/
1237 constraintTerm t;
1238 constraintExpr temp;
1240 llassert(c != NULL);
1242 switch (c->kind)
1244 case term:
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);
1249 break;
1250 case binaryexpr:
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);
1261 break;
1262 case unaryExpr:
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);
1267 break;
1269 return c;
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) )
1282 long i;
1284 i = constraintExpr_getValue(e1) + constraintExpr_getValue (e2);
1285 constraintExpr_free(c);
1286 c = constraintExpr_makeIntLiteral (i);
1288 else
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);
1299 return c;
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)
1319 return expr;
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);
1343 else
1344 BADEXIT;
1346 return expr;
1349 #warning this needs to be checked
1350 expr = constraintExpr_solveBinaryExpr (expr1, expr);
1352 expr = constraintExpr_solveBinaryExpr (expr2, expr);
1353 return expr;
1357 static /*@only@*/ constraintExpr constraintExpr_simplifyunaryExpr (/*@only@*/ constraintExpr c)
1359 constraintExpr exp;
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) )
1369 return c;
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) )
1385 cstring val;
1386 val = constraintTerm_getStringLiteral (cterm);
1387 if (constraintExprData_unaryExprGetOp (c->data) == MAXSET)
1389 constraintExpr temp;
1391 temp = constraintExpr_makeIntLiteral ((int)strlen (cstring_toCharsSafe(val) ) );
1392 cstring_free(val);
1393 constraintExpr_free(c);
1394 constraintExpr_free(exp);
1396 return temp;
1399 if (constraintExprData_unaryExprGetOp (c->data) == MAXREAD)
1401 constraintExpr temp;
1403 temp = constraintExpr_makeIntLiteral ((int)strlen (cstring_toCharsSafe(val) ) );
1404 cstring_free(val);
1405 constraintExpr_free(c);
1406 constraintExpr_free(exp);
1408 return temp;
1410 BADEXIT;
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
1416 ** -- DRL 7/25/01
1419 if (constraintTerm_isInitBlock(cterm) )
1421 constraintExpr temp;
1422 int len;
1424 len = constraintTerm_getInitBlockLength(cterm);
1426 /* -- drl 12/08/2003 : decrementing to fix off by one error */
1428 len--;
1430 temp = constraintExpr_makeIntLiteral (len );
1432 constraintExpr_free(c);
1433 DPRINTF(( message("Changed to %q", constraintExpr_print(temp)
1434 ) ));
1435 constraintExpr_free(exp);
1436 return temp;
1439 constraintExpr_free(exp);
1440 return c;
1443 if (exp->kind != binaryexpr)
1445 constraintExpr_free(exp);
1446 return c;
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);
1478 return c;
1482 /*@only@*/ constraintExpr constraintExpr_simplify (/*@only@*/ constraintExpr c)
1484 constraintExprKind kind;
1485 constraintExpr ret;
1486 constraintTerm t;
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);
1510 kind = ret->kind;
1512 switch (kind)
1514 case term:
1515 t = constraintExprData_termGetTerm (ret->data);
1516 t = constraintTerm_copy(t);
1517 t = constraintTerm_simplify (t);
1518 ret->data = constraintExprData_termSetTerm (ret->data, t);
1519 break;
1520 case unaryExpr:
1521 ret = constraintExpr_simplifyunaryExpr (ret);
1522 break;
1523 case binaryexpr:
1524 ret = constraintExpr_simplifybinaryExpr (ret);
1525 break;
1526 default:
1527 llassert(FALSE);
1530 DPRINTF ((message ("constraintExpr_simplify returning :%s", constraintExpr_unparse (ret) ) ) );
1531 return ret;
1535 /*@only@*/
1536 cstring constraintExpr_unparse (/*@temp@*/ constraintExpr ex) /*@*/
1538 cstring st;
1539 constraintExprKind kind;
1541 llassert (ex != NULL);
1543 kind = ex->kind;
1545 switch (kind)
1547 case term:
1548 if (context_getFlag (FLG_PARENCONSTRAINT) )
1550 st = message ("(%q) ", constraintTerm_unparse (constraintExprData_termGetTerm (ex->data)));
1552 else
1554 st = message ("%q", constraintTerm_unparse (constraintExprData_termGetTerm (ex->data)));
1556 break;
1557 case unaryExpr:
1558 st = message ("%q(%q)",
1559 constraintExprUnaryOpKind_print (constraintExprData_unaryExprGetOp (ex->data) ),
1560 constraintExpr_unparse (constraintExprData_unaryExprGetExpr (ex->data) )
1562 break;
1563 case binaryexpr:
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) )
1572 else
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))
1581 break;
1582 default:
1583 llassert(FALSE);
1584 st = message ("error");
1588 DPRINTF((message ("constraintExpr_unparse: '%s'",st) ) );
1589 return st;
1592 # ifdef DEADCODE
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);
1601 data = expr->data;
1603 kind = expr->kind;
1605 switch (kind)
1607 case term:
1608 Term = constraintExprData_termGetTerm(data);
1609 Term = constraintTerm_copy(Term);
1611 Term = constraintTerm_doSRefFixBaseParam (Term, arglist);
1612 data = constraintExprData_termSetTerm(data, Term);
1613 break;
1614 case unaryExpr:
1615 expr1 = constraintExprData_unaryExprGetExpr (data);
1616 expr1 = constraintExpr_copy(expr1);
1618 expr1 = constraintExpr_doSRefFixBaseParam (expr1, arglist);
1619 data = constraintExprData_unaryExprSetExpr (data, expr1);
1620 break;
1621 case binaryexpr:
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);
1633 break;
1634 default:
1635 llassert(FALSE);
1636 data = NULL;
1638 return expr;
1640 # endif /* DEADCODE */
1642 #if 0
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);
1650 data = expr->data;
1652 kind = expr->kind;
1654 switch (kind)
1656 case term:
1657 expr = doSRefFixInvarConstraintTerm (expr, s, ct);
1658 break;
1659 case unaryExpr:
1660 expr1 = constraintExprData_unaryExprGetExpr (data);
1661 expr1 = constraintExpr_copy(expr1);
1662 expr1 = constraintExpr_doSRefFixInvarConstraint (expr1, s, ct);
1663 data = constraintExprData_unaryExprSetExpr (data, expr1);
1664 break;
1665 case binaryexpr:
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);
1677 break;
1678 default:
1679 llassert(FALSE);
1680 data = NULL;
1682 return expr;
1684 #endif
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);
1693 data = expr->data;
1695 kind = expr->kind;
1697 switch (kind)
1699 case term:
1700 expr = doSRefFixConstraintParamTerm (expr, arglist);
1701 break;
1702 case unaryExpr:
1703 expr1 = constraintExprData_unaryExprGetExpr (data);
1704 expr1 = constraintExpr_copy(expr1);
1705 expr1 = constraintExpr_doSRefFixConstraintParam (expr1, arglist);
1706 data = constraintExprData_unaryExprSetExpr (data, expr1);
1707 break;
1708 case binaryexpr:
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);
1720 break;
1721 default:
1722 llassert(FALSE);
1723 data = NULL;
1725 return expr;
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);
1735 data = expr->data;
1737 kind = expr->kind;
1739 switch (kind)
1741 case term:
1742 expr = doFixResultTerm (expr, fcnCall);
1743 break;
1744 case unaryExpr:
1745 expr1 = constraintExprData_unaryExprGetExpr (data);
1746 expr1 = constraintExpr_copy(expr1);
1748 expr1 = constraintExpr_doFixResult (expr1, fcnCall);
1749 data = constraintExprData_unaryExprSetExpr (data, expr1);
1750 break;
1751 case binaryexpr:
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);
1762 break;
1763 default:
1764 llassert(FALSE);
1765 data = NULL;
1767 return expr;
1770 cstring constraintExpr_print (constraintExpr expr) /*@*/
1772 return constraintExpr_unparse (expr);
1775 bool constraintExpr_hasMaxSet (constraintExpr expr) /*@*/
1777 cstring t;
1778 bool ret;
1780 t = constraintExpr_unparse(expr);
1782 ret = cstring_containsLit(t, "maxSet");
1783 cstring_free(t);
1785 return ret;
1790 /*returns 1 0 -1 like strcmp
1791 1 => expr1 > expr2
1792 0 => expr1 == expr2
1793 -1 => expr1 < expr2
1796 int constraintExpr_compare (constraintExpr expr1, constraintExpr expr2)
1798 long value1, value2;
1800 if (constraintExpr_similar (expr1, expr2) )
1802 return 0;
1805 value1 = constraintExpr_getValue(expr1);
1806 value2 = constraintExpr_getValue(expr2);
1808 if (value1 > value2)
1809 return 1;
1811 if (value1 == value2)
1812 return 0;
1814 else
1815 return -1;
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))
1831 return FALSE;
1834 switch (expr->kind)
1836 case term:
1837 return constraintTerm_canGetValue (constraintExprData_termGetTerm (expr->data) );
1838 default:
1839 return FALSE;
1843 fileloc constraintExpr_loc (constraintExpr expr)
1845 constraintExpr e;
1846 constraintTerm t;
1847 constraintExprKind kind;
1849 llassert ( constraintExpr_isDefined (expr) );
1850 if (constraintExpr_isUndefined (expr) )
1852 return fileloc_undefined;
1856 kind = expr->kind;
1858 switch (kind)
1860 case term:
1861 t = constraintExprData_termGetTerm (expr->data);
1862 return (constraintTerm_getFileloc (t) );
1863 /*@notreached@*/
1864 break;
1865 case unaryExpr:
1866 e = constraintExprData_unaryExprGetExpr (expr->data);
1867 return (constraintExpr_loc (e) );
1868 /*@notreached@*/
1869 break;
1870 case binaryexpr:
1871 e = constraintExprData_binaryExprGetExpr1 (expr->data);
1872 return (constraintExpr_loc (e) );
1873 /*@notreached@*/
1874 break;
1876 llassert (FALSE);
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)
1884 constraintTerm t;
1885 sRef s;
1886 constraintExprData data;
1887 constraintExprKind kind;
1888 constraintExpr ret;
1890 llassert (constraintExpr_isDefined (e) );
1892 data = e->data;
1893 kind = e->kind;
1895 llassert (kind == term);
1897 t = constraintExprData_termGetTerm (data);
1898 llassert (constraintTerm_isDefined (t));
1900 ret = e;
1902 switch (constraintTerm_getKind (t))
1904 case CTT_EXPR:
1905 case CTT_INTLITERAL:
1906 break;
1908 case CTT_SREF:
1909 s = constraintTerm_getSRef(t);
1910 if (sRef_isResult (s))
1912 ret = constraintExpr_makeExprNode(fcnCall);
1913 constraintExpr_free(e);
1915 break;
1917 BADDEFAULT;
1920 return ret;
1924 #if 0
1926 /*to be used for structure checking */
1928 / *@only@* / static constraintExpr
1929 doSRefFixInvarConstraintTerm (/ *@only@* / constraintExpr e, sRef s, ctype ct)
1931 constraintTerm t;
1933 constraintExprData data = e->data;
1935 constraintExprKind kind = e->kind;
1937 constraintExpr ret;
1939 llassert(kind == term);
1941 t = constraintExprData_termGetTerm (data);
1942 llassert (constraintTerm_isDefined(t) );
1944 ret = e;
1946 DPRINTF (("Fixing: %s", constraintExpr_print (e)));
1948 switch (constraintTerm_getKind(t))
1950 case CTT_EXPR:
1951 DPRINTF((message ("%q @ %q ", constraintTerm_unparse(t),
1952 fileloc_unparse (constraintTerm_getFileloc(t) ) ) ));
1953 break;
1954 case CTT_INTLITERAL:
1955 DPRINTF((message (" %q ", constraintTerm_unparse (t)) ));
1956 break;
1958 case CTT_SREF:
1959 / * evans 2001-07-24: constants should use the original term * /
1960 if (!constraintTerm_canGetValue (t))
1962 sRef snew;
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@* /
1977 break;
1978 BADDEFAULT;
1981 return ret;
1984 #endif
1986 /*drl moved from constriantTerm.c 5/20/001*/
1987 /*@only@*/ static constraintExpr
1988 doSRefFixConstraintParamTerm (/*@only@*/ constraintExpr e, /*@observer@*/ /*@temp@*/ exprNodeList arglist)
1990 constraintTerm t;
1992 constraintExprData data;
1994 constraintExprKind kind;
1996 constraintExpr ret;
1999 llassert(constraintExpr_isDefined (e) );
2001 data = e->data;
2003 kind = e->kind;
2007 llassert(kind == term);
2009 t = constraintExprData_termGetTerm (data);
2010 llassert (constraintTerm_isDefined(t) );
2012 ret = e;
2014 DPRINTF (("Fixing: %s", constraintExpr_print (e)));
2016 switch (constraintTerm_getKind(t))
2018 case CTT_EXPR:
2019 DPRINTF((message ("%q @ %q ", constraintTerm_unparse(t),
2020 fileloc_unparse (constraintTerm_getFileloc(t) ) ) ));
2021 break;
2022 case CTT_INTLITERAL:
2023 DPRINTF((message (" %q ", constraintTerm_unparse (t)) ));
2024 break;
2025 case CTT_SREF:
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) ) ));
2037 /*@-branchstate@*/
2038 } /*@=branchstate@*/
2040 break;
2041 BADDEFAULT;
2044 return ret;
2049 #if 0
2050 bool constraintExpr_includesTerm (constraintExpr expr, constraintTerm term)
2052 if (constraintTerm_hasTerm (expr->term, term) )
2053 return TRUE;
2055 if ((expr->expr) != NULL)
2057 return ( constraintExpr_includesTerm (expr->expr, term) );
2059 return FALSE;
2062 #endif
2064 /*drl added 6/11/01 */
2065 bool constraintExpr_isBinaryExpr (/*@observer@*/ constraintExpr c)
2068 llassert(constraintExpr_isDefined (c) );
2070 if ( ! (constraintExpr_isDefined (c) ) )
2071 return FALSE;
2073 if (c->kind == binaryexpr)
2074 return TRUE;
2076 else
2077 return FALSE;
2080 /*drl added 8/08/001 */
2081 bool constraintExpr_isTerm (/*@observer@*/ constraintExpr c) /*@*/
2083 llassert(constraintExpr_isDefined (c) );
2085 if (c->kind == term)
2086 return TRUE;
2088 else
2089 return FALSE;
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);
2102 return term;
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);
2119 fprintf(f, "e1\n");
2121 constraintExpr_dump(expr1, f);
2123 fprintf(f, "e2\n");
2124 constraintExpr_dump(expr2, f);
2128 static constraintExpr binaryExpr_undump (FILE *f)
2130 constraintExpr expr1;
2131 constraintExprBinaryOpKind binaryOp;
2132 constraintExpr expr2;
2134 constraintExpr ret;
2138 char * str;
2139 char * os;
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);
2174 free(os);
2175 return ret;
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;
2200 constraintExpr ret;
2202 char * str;
2203 char * os;
2205 str = mstring_create (MAX_DUMP_LINE_LENGTH);
2206 os = str;
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);
2220 free(os);
2222 return ret;
2225 void constraintExpr_dump (/*@observer@*/ constraintExpr expr, FILE *f)
2227 constraintExprKind kind;
2228 constraintTerm t;
2231 llassert(constraintExpr_isDefined(expr) );
2233 DPRINTF((message("constraintExpr_dump:: dumping constraintExpr %s",
2234 constraintExpr_unparse(expr)
2235 ) ));
2237 kind = expr->kind;
2239 fprintf(f,"%d\n", (int) kind);
2241 switch (kind)
2243 case term:
2244 t = constraintExprData_termGetTerm (expr->data);
2245 constraintTerm_dump (t, f);
2246 break;
2247 case unaryExpr:
2248 unaryExpr_dump (expr->data, f);
2249 break;
2250 case binaryexpr:
2251 binaryExpr_dump (expr->data, f);
2252 break;
2256 /*@only@*/ constraintExpr constraintExpr_undump (FILE *f)
2258 constraintExprKind kind;
2259 constraintTerm t;
2260 constraintExpr ret;
2262 char * s;
2263 char * os;
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);
2274 free (os);
2276 switch (kind)
2278 case term:
2279 t = constraintTerm_undump (f);
2280 ret = constraintExpr_makeTerm(t);
2281 break;
2282 case unaryExpr:
2283 ret = unaryExpr_undump (f);
2284 break;
2285 case binaryexpr:
2286 ret = binaryExpr_undump (f);
2287 break;
2288 BADDEFAULT;
2291 return ret;
2294 int constraintExpr_getDepth (constraintExpr ex)
2296 int ret;
2298 constraintExprKind kind;
2300 llassert (ex != NULL);
2302 kind = ex->kind;
2304 switch (kind)
2306 case term:
2307 ret = 1;
2308 break;
2309 case unaryExpr:
2310 ret = constraintExpr_getDepth (constraintExprData_unaryExprGetExpr (ex->data) );
2311 ret++;
2312 break;
2313 case binaryexpr:
2314 ret = constraintExpr_getDepth (constraintExprData_binaryExprGetExpr1 (ex->data) );
2315 ret++;
2316 ret += constraintExpr_getDepth (constraintExprData_binaryExprGetExpr2 (ex->data) );
2317 break;
2318 BADDEFAULT;
2321 return ret;
2325 bool constraintExpr_canGetCType (constraintExpr e) /*@*/
2327 if (constraintExpr_isUndefined(e))
2328 return FALSE;
2330 if (e->kind == term)
2332 return TRUE;
2334 else
2336 DPRINTF (("constraintExpr_canGetCType: can't get type for %s", constraintExpr_unparse (e)));
2337 return FALSE;
2341 ctype constraintExpr_getCType (constraintExpr e) /*@*/
2343 constraintTerm t;
2345 llassert (constraintExpr_isDefined (e));
2346 llassert (constraintExpr_canGetCType (e));
2348 switch (e->kind)
2350 case term:
2351 t = constraintExprData_termGetTerm (e->data);
2352 return (constraintTerm_getCType(t) );
2353 /* assume that a unary expression will be an int ... */
2354 case unaryExpr:
2355 return ctype_unknown; /* was ctype_signedintegral; */
2356 /* drl for just return type of first operand */
2357 case binaryexpr:
2358 return (constraintExpr_getCType (constraintExprData_binaryExprGetExpr1 (e->data)));
2359 BADDEFAULT;
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))
2371 return 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));
2386 return FALSE;
2389 /* drl add 10-5-001 */
2391 static ctype constraintExpr_getOrigType (constraintExpr e)
2393 llassert (constraintExpr_isDefined (e));
2394 llassert (constraintExpr_hasTypeChange (e));
2396 if (e->ct == TRUE)
2398 return e->origType;
2401 if (e->kind == unaryExpr)
2403 if (constraintExprData_unaryExprGetOp (e->data) == MAXSET)
2405 constraintExpr ce = constraintExprData_unaryExprGetExpr (e->data);
2406 return (constraintExpr_getOrigType(ce));
2411 BADEXIT;
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)));
2431 if (sizeto == -1) {
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 */
2440 else
2442 constraintTerm ct;
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)));
2452 else
2454 long val;
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),
2468 loc);
2470 constraintTerm_setValue (ct, (val * sizefrom) / sizeto);
2474 DPRINTF (("After div: %s", constraintExpr_unparse (e)));
2475 return e;
2479 /*@access exprNode@*/
2480 static /*@only@*/ constraintExpr
2481 constraintTerm_simpleDivTypeExprNode (/*@only@*/ constraintExpr e, ctype tfrom, ctype tto, fileloc loc)
2483 exprData data;
2484 exprNode t1, t2, expr;
2485 lltok tok;
2486 constraintTerm t;
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)
2502 data = expr->edata;
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)
2518 exprNode tmp = t1;
2519 t1 = t2;
2520 t2 = tmp;
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)
2528 ctype multype;
2530 if (t1->kind == XPR_SIZEOFT)
2532 multype = qtype_getType (exprData_getType (t1->edata));
2534 else
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);
2551 else
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)),
2563 loc);
2565 if (sizemul == sizeto)
2567 constraintExpr_free (e);
2568 DPRINTF (("Sizeof types match okay!"));
2569 return constraintExpr_makeExprNode (t2);
2571 else
2573 /* nothing was here */
2574 DPRINTF (("MISMATCHING TYPES!"));
2575 return (constraintExpr_div (constraintExpr_makeExprNode (t2), multype, tto, loc));
2579 else
2581 DPRINTF (("NOT A SIZEOF!"));
2582 /* empty */
2585 else
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));
2604 switch (e->kind)
2606 case term:
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);
2622 case binaryexpr:
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)));
2638 return e;
2640 case unaryExpr:
2642 return constraintExpr_div (e, tfrom, tto, loc);
2645 BADDEFAULT;
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)));
2662 return e;
2666 bool constraintExpr_isConstantOnly (constraintExpr e)
2668 DPRINTF (("constraintExpr_isConstantOnly %s ", constraintExpr_unparse(e)));
2669 llassert (constraintExpr_isDefined(e));
2671 switch (e->kind)
2673 case term:
2675 constraintTerm t = constraintExprData_termGetTerm(e->data);
2677 if (constraintTerm_isConstantOnly (t))
2679 return TRUE;
2681 else
2683 return FALSE;
2687 case binaryexpr:
2689 constraintExpr temp1 = constraintExprData_binaryExprGetExpr1 (e->data);
2690 constraintExpr temp2 = constraintExprData_binaryExprGetExpr2 (e->data);
2692 if (constraintExpr_isConstantOnly(temp1) &&
2693 constraintExpr_isConstantOnly(temp2) )
2695 return TRUE;
2697 else
2699 return FALSE;
2703 case unaryExpr:
2705 constraintExpr temp;
2707 temp = constraintExprData_unaryExprGetExpr (e->data );
2709 if (constraintExpr_isConstantOnly(temp) )
2711 return TRUE;
2713 else
2715 return FALSE;
2719 BADDEFAULT;