]> andersk Git - splint.git/blob - src/constraintExpr.c
Changes to fix malloc size problem.
[splint.git] / src / constraintExpr.c
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.
19 **
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
23 */
24
25 /*
26 ** constraintExpr.c
27 */
28
29 /* #define DEBUGPRINT 1 */
30
31 # include "splintMacros.nf"
32 # include "basic.h"
33 # include "cgrammar.h"
34 # include "cgrammar_tokens.h"
35
36 # include "exprChecks.h"
37 # include "exprNodeSList.h"
38
39
40 static ctype constraintExpr_getOrigType (constraintExpr p_e);
41 static bool constraintExpr_hasTypeChange(constraintExpr p_e) /*@*/;
42
43 static /*@only@*/ constraintExpr constraintExpr_makeBinaryOpConstraintExprIntLiteral (/*@only@*/constraintExpr p_expr, int p_literal);
44
45
46 /*@only@*/ static constraintExpr
47 doSRefFixInvarConstraintTerm (/*@only@*/ constraintExpr p_e,
48                               sRef p_s, ctype p_ct);
49
50 /*@only@*/ static constraintExpr 
51 doSRefFixConstraintParamTerm (/*@only@*/ constraintExpr p_e, /*@temp@*/ /*@observer@*/ exprNodeList p_arglist) /*@modifies p_e@*/;
52
53 static /*@only@*/ constraintExpr 
54 doFixResultTerm (/*@only@*/ constraintExpr p_e, /*@exposed@*/ exprNode p_fcnCall)
55      /*@modifies p_e@*/;
56
57 static bool constraintExpr_canGetCType (constraintExpr p_e) /*@*/;
58
59 static ctype constraintExpr_getCType (constraintExpr p_e);
60
61 static /*@only@*/ constraintExpr constraintExpr_adjustMaxSetForCast (/*@only@*/ constraintExpr p_e,
62                                                                      ctype p_tfrom, ctype p_tto,
63                                                                      fileloc loc);
64
65 /*@special@*/ /*@notnull@*/ static constraintExpr constraintExpr_makeBinaryOp (void) 
66      /* @allocates result->data @ @sets result->kind @ */ ;
67
68 void constraintExpr_free (/*@only@*/ constraintExpr expr)
69 {
70   if (constraintExpr_isDefined(expr) )
71     {
72       switch (expr->kind)
73         {
74         case unaryExpr:
75           constraintExprData_freeUnaryExpr(expr->data);
76           break;
77         case binaryexpr:
78           constraintExprData_freeBinaryExpr(expr->data);
79           break;
80         case term:
81           constraintExprData_freeTerm(expr->data);
82           break;
83         default:
84           BADEXIT;
85         }
86
87       expr->data = NULL;
88       free (expr);
89     }
90   else
91     {
92       llcontbug(message("attempted to free null pointer in constraintExpr_free"));
93     }
94 }
95
96 bool constraintExpr_isLit (constraintExpr expr)
97 {
98   llassert (expr != NULL);
99   
100   if (expr->kind == term)
101     {
102       constraintTerm term = constraintExprData_termGetTerm (expr->data);
103       if (constraintTerm_isIntLiteral (term) )
104         {
105           return TRUE;
106         }
107
108     }
109   return FALSE;
110 }
111
112 static bool isZeroBinaryOp (constraintExpr expr)
113 {
114   constraintExpr e2;
115   
116   llassert (expr != NULL); /* evans 2001-07-18 */
117
118   if (!constraintExpr_isBinaryExpr (expr) )
119     {
120       return FALSE;
121     }
122
123   
124   e2 = constraintExprData_binaryExprGetExpr2(expr->data);
125
126   llassert (e2 != NULL); /* evans 2001-07-18 */
127
128   if (constraintExpr_isBinaryExpr (e2) )
129     {
130       constraintExpr e1;
131       constraintExprBinaryOpKind  op;
132
133       op = constraintExprData_binaryExprGetOp (e2->data);
134
135       e1 = constraintExprData_binaryExprGetExpr1(e2->data);
136
137         if (constraintExpr_isLit(e1) )
138           {
139             if (constraintExpr_getValue(e1) == 0 )
140               {
141                 return TRUE;
142               }
143           }
144     }
145   return FALSE;
146 }
147
148 /* change expr + (o - expr) to (expr -expr) */
149
150 /*@only@*/ /*@notnull@*/ static constraintExpr removeZero (/*@only@*/ /*@returned@*/ constraintExpr expr)
151 {
152   constraintExpr expr1, expr2;
153   
154   constraintExpr temp;
155
156   constraintExprBinaryOpKind  op;
157   
158   constraintExprBinaryOpKind  tempOp;
159
160   llassert (expr != NULL); /* evans 2001-07-18 */
161
162   if (!isZeroBinaryOp(expr) )
163     return expr;
164
165   
166   expr1 = constraintExprData_binaryExprGetExpr1(expr->data);
167   expr2 = constraintExprData_binaryExprGetExpr2(expr->data);
168   op = constraintExprData_binaryExprGetOp(expr->data);
169
170   llassert( constraintExpr_isBinaryExpr(expr2) );           
171
172   temp = constraintExprData_binaryExprGetExpr2 (expr2->data);
173   temp = constraintExpr_copy (temp);
174
175   tempOp = constraintExprData_binaryExprGetOp (expr2->data);
176
177   if (op == BINARYOP_PLUS)
178     op = tempOp;
179   else if (op == BINARYOP_MINUS)
180     {
181       if (tempOp == BINARYOP_PLUS)
182         op = BINARYOP_MINUS;
183       else if (tempOp == BINARYOP_MINUS)
184         op = BINARYOP_PLUS;
185       else
186         BADEXIT;
187     }
188   else
189     BADEXIT;
190
191   expr->data = constraintExprData_binaryExprSetExpr2(expr->data, temp);
192   expr->data = constraintExprData_binaryExprSetOp(expr->data, op);
193
194   return expr;
195 }
196
197
198 /*@only@*//*@notnull@*/  constraintExpr constraintExpr_propagateConstants (/*@only@*/ constraintExpr expr,
199                                                 /*@out@*/ bool * propagate,
200                                                   /*@out@*/ int *literal)
201 {
202   constraintExpr expr1;
203   constraintExpr expr2;
204   bool propagate1, propagate2;
205   int literal1, literal2;
206   constraintExprBinaryOpKind  op;
207   
208   propagate1 = FALSE;
209   propagate2 = FALSE;
210  
211   literal1 = 0;
212   literal2 = 0;
213   
214   *propagate = FALSE;
215   *literal = 0;
216
217   
218   llassert (expr != NULL);
219   
220   /* we simplify unaryExpr elsewhere */
221   if (expr->kind != binaryexpr)
222     return expr;
223
224   op = constraintExprData_binaryExprGetOp (expr->data);
225
226   DPRINTF((message("constraintExpr_propagateConstants: binaryexpr: %s", constraintExpr_unparse(expr) ) ) );
227
228   expr = removeZero(expr);
229   
230   expr1 = constraintExprData_binaryExprGetExpr1(expr->data);
231   expr2 = constraintExprData_binaryExprGetExpr2(expr->data);
232
233   expr1 = constraintExpr_copy(expr1);
234   expr2 = constraintExpr_copy(expr2);
235
236   expr1 = constraintExpr_propagateConstants (expr1, &propagate1, &literal1);
237   expr2 = constraintExpr_propagateConstants (expr2, &propagate2, &literal2);
238
239   expr1 = removeZero(expr1);
240   expr2 = removeZero(expr2);
241
242   
243   *propagate = propagate1 || propagate2;
244
245   if (op == BINARYOP_PLUS)
246     *literal    = literal1 +  literal2;
247   else   if (op == BINARYOP_MINUS)
248     *literal    = literal1 -  literal2;
249   else
250     BADEXIT;
251     
252   if ( constraintExpr_isLit (expr1) && constraintExpr_isLit (expr2) )
253     {
254       long t1, t2;
255       t1 = constraintExpr_getValue (expr1);
256       t2 = constraintExpr_getValue (expr2);
257       llassert(*propagate == FALSE);
258       *propagate = FALSE;
259
260       constraintExpr_free (expr);
261       constraintExpr_free (expr1);
262       constraintExpr_free (expr2);
263
264       if (op == BINARYOP_PLUS )
265         return (constraintExpr_makeIntLiteral ((t1+t2) ));
266       else if (op ==  BINARYOP_MINUS)
267         return (constraintExpr_makeIntLiteral ((t1-t2) ));
268       else
269         BADEXIT;
270     }
271
272   
273   if (constraintExpr_isLit (expr1) )
274     {
275       *propagate = TRUE;
276
277       *literal += constraintExpr_getValue (expr1);
278
279       if (op == BINARYOP_PLUS)
280         {
281           constraintExpr_free(expr1);
282           constraintExpr_free(expr);
283           return expr2;
284         }
285       else if (op == BINARYOP_MINUS)
286         {
287           
288           constraintExpr temp;
289
290           /* this is an ugly kludge to deal with not
291              having a unary minus operation...*/
292
293           temp = constraintExpr_makeIntLiteral (0);
294           temp = constraintExpr_makeSubtractExpr (temp, expr2);
295           
296           constraintExpr_free(expr1);
297           constraintExpr_free(expr);
298
299           llassert (constraintExpr_isDefined(temp) );
300           return temp;
301         }
302       else
303         {
304           BADBRANCH; /* evans 2001-07-18 */
305         }
306     }
307   
308   if (constraintExpr_isLit (expr2) )
309     {
310       *propagate = TRUE;
311           
312       if ( op == BINARYOP_PLUS )
313         *literal += constraintExpr_getValue (expr2);
314       else if (op ==  BINARYOP_MINUS)
315         *literal -= constraintExpr_getValue (expr2);
316       else
317         BADEXIT;
318
319
320       constraintExpr_free(expr2);
321       constraintExpr_free(expr);
322       return expr1;
323     }
324   
325   DPRINTF((message("constraintExpr_propagateConstants returning: %s", constraintExpr_unparse(expr) ) ) );
326
327   expr->data = constraintExprData_binaryExprSetExpr1 (expr->data, expr1);
328   expr->data = constraintExprData_binaryExprSetExpr2 (expr->data, expr2);
329
330   expr = removeZero(expr);
331   return expr;
332 }
333
334 /*@notnull@*/ /*@only@*/ static constraintExpr constraintExpr_combineConstants (/*@only@*/ constraintExpr expr ) /*@modifies expr@*/
335 {
336   bool propagate;
337   int literal;
338
339   DPRINTF ((message ("Before combine %s", constraintExpr_unparse(expr) ) ) );
340   expr = constraintExpr_propagateConstants (expr, &propagate, &literal);
341  
342
343   if (propagate)
344     {
345       constraintExpr ret;
346
347       if (literal != 0)
348         {
349           ret = constraintExpr_makeBinaryOpConstraintExprIntLiteral (expr, literal);
350           expr = ret;
351         }
352     }
353    DPRINTF ((message ("After combine %s", constraintExpr_unparse(expr) ) ) );
354
355    llassert(constraintExpr_isDefined(expr) );
356    return expr;
357 }
358
359 /*@special@*/
360 static /*@notnull@*/ constraintExpr constraintExpr_alloc (void) /*@post:isnull result->data@*/
361 {
362   constraintExpr ret;
363   ret = dmalloc (sizeof (*ret) );
364   ret->kind = term;
365   ret->data = NULL;
366   ret->ct = FALSE;
367   ret->origType = ctype_undefined; 
368   return ret;
369 }
370
371 /*@only@*/ static constraintExprData copyExprData (/*@observer@*/ constraintExprData data, constraintExprKind kind)
372 {
373   constraintExprData ret;
374   llassert(constraintExprData_isDefined(data));
375
376   switch (kind)
377     {
378     case binaryexpr:
379       ret = constraintExprData_copyBinaryExpr(data);
380       break;
381     case unaryExpr:
382       ret = constraintExprData_copyUnaryExpr(data);
383       break;
384     case term:
385       ret = constraintExprData_copyTerm(data);
386       break;
387     default:
388       BADEXIT;
389     }
390   return ret;
391 }
392
393 constraintExpr constraintExpr_copy (constraintExpr expr)
394 {
395   constraintExpr ret;
396   ret = constraintExpr_alloc ();
397
398
399   /*drl 03/02/2003 this shouldn't be used to copy a null
400     expression but handle things cleanly if it is*/
401   llassert (!constraintExpr_isUndefined(expr) );
402
403   if (constraintExpr_isUndefined(expr) )
404     {
405       return constraintExpr_undefined;
406     }
407   
408   ret->kind = expr->kind;
409   
410   ret->data = copyExprData (expr->data, expr->kind);
411   ret->ct = expr->ct;
412   ret->origType = expr->origType;
413   return ret;
414 }
415
416
417 /*@only@*/ static constraintExpr oldconstraintExpr_makeTermExprNode ( /*@dependent@*/ exprNode e)
418 {
419   constraintExpr ret;
420   constraintTerm t;
421   ret = constraintExpr_alloc();
422   ret->kind = term;
423   ret->data = dmalloc (sizeof *(ret->data) );
424   t = constraintTerm_makeExprNode (e);
425   ret->data = constraintExprData_termSetTerm (ret->data, t);
426   ret->ct = FALSE;
427   ret->origType = ctype_undefined;
428
429   return ret;
430 }
431
432 /*@access exprNode@*/
433 constraintExpr constraintExpr_makeExprNode (exprNode e)
434 {
435  sRef s;
436  constraintExpr ret, ce1, ce2;
437  exprData data;
438  exprNode t, t1, t2;
439  lltok tok;
440  
441  llassert (e != NULL);
442  
443  data = e->edata;
444
445  switch (e->kind)
446    {
447    case XPR_SIZEOF:
448      t = exprData_getSingle (data);
449      while (exprNode_isInParens (t) )
450        {
451          t = exprData_getUopNode (t->edata);
452        }
453      s = exprNode_getSref (t);
454      if (sRef_isFixedArray(s) )
455       {
456         int size;
457
458         size = (int) sRef_getArraySize(s);
459         ret = constraintExpr_makeIntLiteral (size);
460       }
461      else if (exprNode_isStringLiteral (t))
462       {
463         cstring str = multiVal_forceString (exprNode_getValue(t));
464         ret = constraintExpr_makeIntLiteral (size_toLong (cstring_length (str) + 1));
465       } 
466      else
467        {
468          DPRINTF ((message ("could not determine the size of %s", exprNode_unparse (e) ) ) );
469          ret = oldconstraintExpr_makeTermExprNode (e);
470        }
471      break;
472      
473    case XPR_OP:
474       DPRINTF ((message ("Examining operation %s", exprNode_unparse (e) ) ) );
475      t1 = exprData_getOpA (data);
476      t2 = exprData_getOpB (data);
477      tok = exprData_getOpTok (data);
478      
479      if (lltok_isPlus_Op (tok) || lltok_isMinus_Op (tok) )
480        {
481          ce1 = constraintExpr_makeExprNode (t1);
482          ce2 = constraintExpr_makeExprNode (t2);
483          ret = constraintExpr_parseMakeBinaryOp (ce1, tok, ce2);         
484        }
485
486
487         /* define this block to activate the cheesy heuristic
488         for handling sizeof expressions*/
489 #if 0     
490
491         
492      /*
493        drl 8-11-001
494        
495        We handle expressions containing sizeof with the rule
496        (sizeof type ) * Expr = Expr
497
498        This is the total wronge way to do this but...
499        it may be better than nothing
500      */
501
502      
503       
504      else if (lltok_isMult(tok) )
505        {
506          if  ((t1->kind == XPR_SIZEOF) || (t1->kind == XPR_SIZEOFT) )
507            {
508              ret = constraintExpr_makeExprNode(t2);
509            }
510          else if  ((t2->kind == XPR_SIZEOF) || (t2->kind == XPR_SIZEOFT) )
511            {
512              ret = constraintExpr_makeExprNode(t1);
513              } 
514          else
515            {
516            ret =  oldconstraintExpr_makeTermExprNode (e);
517            }
518        }
519 #endif
520      
521      else
522         ret = oldconstraintExpr_makeTermExprNode (e);
523    
524      break;
525    case XPR_PARENS: 
526      t = exprData_getUopNode (data);
527      ret = constraintExpr_makeExprNode (t);
528      break;
529      
530    case XPR_PREOP:
531       t = exprData_getUopNode (data);
532       tok =  exprData_getUopTok (data);
533       if (lltok_isIncOp (tok))
534         {
535           constraintExpr temp;
536           temp = constraintExpr_makeExprNode(t);
537           ret = constraintExpr_makeIncConstraintExpr(temp);
538         }
539       else if (lltok_isDecOp (tok))
540         {
541           constraintExpr temp;
542           temp = constraintExpr_makeExprNode(t);
543           ret = constraintExpr_makeDecConstraintExpr(temp);
544         }
545       else
546         ret =  oldconstraintExpr_makeTermExprNode (e);
547       break;
548       
549    case XPR_POSTOP:
550      t = exprData_getUopNode (data);
551           ret = constraintExpr_makeExprNode (t);
552      break;
553    case XPR_CAST:
554      t = exprData_getCastNode (data);
555      ret = constraintExpr_makeExprNode (t);
556      break;
557    case XPR_COMMA:
558      t = exprData_getPairA(data);
559      ret = constraintExpr_makeExprNode(t);
560      break;
561    default:
562      ret = oldconstraintExpr_makeTermExprNode (e);
563      
564    }
565   return ret;
566 }
567
568 /*@noaccess exprNode@*/
569
570
571
572
573 /*@only@*/ constraintExpr constraintExpr_makeTermExprNode (/*@exposed@*/ exprNode e)
574 {
575   return  oldconstraintExpr_makeTermExprNode(e);
576 }
577
578 static constraintExpr constraintExpr_makeTerm (/*@only@*/  constraintTerm t)
579 {
580   constraintExpr ret;
581
582   ret = constraintExpr_alloc();
583   ret->kind = term;
584   ret->data = dmalloc (sizeof *(ret->data) );
585   ret->data->term = NULL;
586   ret->data = constraintExprData_termSetTerm (ret->data, t);
587   ret->ct = FALSE;
588   ret->origType = ctype_undefined; 
589
590   return ret;
591 }
592
593 constraintExpr constraintExpr_makeTermsRef (/*@temp@*/ sRef s)
594 {
595   constraintExpr ret;
596   constraintTerm t;
597   ret = constraintExpr_alloc();
598   ret->kind = term;
599   ret->data = dmalloc (sizeof *(ret->data) );
600   t = constraintTerm_makesRef (s);
601   ret->data = constraintExprData_termSetTerm (ret->data, t);
602
603   ret->ct = FALSE;
604   ret->origType = ctype_undefined; 
605
606   return ret;
607 }
608
609 /*@special@*/ /*@notnull@*/ static constraintExpr makeUnaryOpGeneric (void) /*@allocates result->data@*/ /*@defines result->kind@*/
610 {
611   constraintExpr ret;
612   ret = constraintExpr_alloc();
613   ret->kind = unaryExpr;
614   ret->data = dmalloc (sizeof *(ret->data));
615   ret->data->unaryOp.expr = constraintExpr_undefined;
616   return ret;
617 }
618
619 /*@notnull@*/ /*@only@*/ static constraintExpr constraintExpr_makeUnaryOpConstraintExpr (/*@only@*/ constraintExpr cexpr)
620 {
621   constraintExpr ret;
622   ret = makeUnaryOpGeneric();
623
624   /*@-uniondef@*/ 
625   /*@-compdef@*/
626   ret->data = constraintExprData_unaryExprSetExpr (ret->data, cexpr);
627   ret->data = constraintExprData_unaryExprSetOp (ret->data, UNARYOP_UNDEFINED);
628   
629   return ret;
630   
631   /*@=compdef@*/
632   /*@=uniondef@*/
633 }
634
635
636 /*@only@*/ /*@notnull@*/ static constraintExpr 
637 constraintExpr_makeUnaryOp (/*@only@*/ constraintExpr cexpr, constraintExprUnaryOpKind Op)
638 {
639   constraintExpr ret;
640   ret = makeUnaryOpGeneric();
641
642   ret->data = constraintExprData_unaryExprSetExpr (ret->data, cexpr);
643   ret->data = constraintExprData_unaryExprSetOp (ret->data, Op);
644
645   ret->ct = FALSE;
646   ret->origType = ctype_undefined; 
647
648   return ret;
649 }
650
651 /*@only@*/ /*@notnull@*/
652 static constraintExpr constraintExpr_makeUnaryOpExprNode (/*@exposed@*/ exprNode expr)
653 {
654   constraintExpr ret;
655   constraintExpr sub;
656   sub = constraintExpr_makeExprNode (expr);
657   ret = constraintExpr_makeUnaryOpConstraintExpr(sub);
658
659   return ret;
660 }
661
662 /*@only@*/ /*@notnull@*/
663 static constraintExpr constraintExpr_makeMaxSetConstraintExpr (/*@only@*/ constraintExpr c)
664 {
665   constraintExpr ret;
666   ret = constraintExpr_makeUnaryOp (c, MAXSET);
667   return ret;
668 }
669
670
671 /*@only@*/ /*@notnull@*/
672 static constraintExpr constraintExpr_makeSRefUnaryOp (/*@temp@*/ /*@observer@*/ sRef s,  constraintExprUnaryOpKind op)
673 {
674   constraintExpr ret;
675   constraintExpr t;
676
677   t = constraintExpr_makeTermsRef (s);
678   ret = constraintExpr_makeUnaryOpConstraintExpr (t);
679   ret->data = constraintExprData_unaryExprSetOp (ret->data, op);
680
681   return ret;
682 }
683
684 /*@only@*/
685 constraintExpr constraintExpr_makeSRefMaxRead( sRef s)
686 {
687   return (constraintExpr_makeSRefUnaryOp (s, MAXREAD) );
688 }     
689
690 /*@only@*/
691 constraintExpr constraintExpr_makeSRefMaxset ( sRef s)
692 {
693   return (constraintExpr_makeSRefUnaryOp (s, MAXSET) );
694 }
695
696 /*@only@*/
697 constraintExpr constraintExpr_parseMakeUnaryOp (lltok op, constraintExpr cexpr)
698 {
699   constraintExpr ret;
700   ret = constraintExpr_makeUnaryOpConstraintExpr ( cexpr);
701
702   switch (lltok_getTok (op))
703     {
704     case QMAXSET:
705       ret->data = constraintExprData_unaryExprSetOp (ret->data, MAXSET);
706       break;
707     case QMAXREAD:
708       ret->data = constraintExprData_unaryExprSetOp (ret->data, MAXREAD);
709       break;
710     default:
711       llfatalbug (message ("Unhandled operation in constraint: %s", lltok_unparse (op)));
712     }
713   return ret;
714 }
715
716 /*@only@*/
717 constraintExpr constraintExpr_makeMaxSetExpr (/*@exposed@*/ exprNode expr)
718 {
719   constraintExpr ret;
720   ret = constraintExpr_makeExprNode (expr);
721
722   ret = constraintExpr_makeMaxSetConstraintExpr (ret);
723
724   llassert (ret != NULL);
725   return ret;
726 }
727
728 /*@only@*/
729 constraintExpr  constraintExpr_makeMaxReadExpr (exprNode expr)
730 {
731   constraintExpr ret;
732   ret = constraintExpr_makeUnaryOpExprNode(expr);
733   ret->data      = constraintExprData_unaryExprSetOp (ret->data, MAXREAD);
734   return ret; 
735 }
736
737 # if 0
738 /*@only@*/
739 /*@unused@*/ static constraintExpr  constraintExpr_makeMinSetExpr (/*@exposed@*/ exprNode expr)
740 {
741   constraintExpr ret;
742   ret = constraintExpr_makeUnaryOpExprNode(expr);
743   ret->data      = constraintExprData_unaryExprSetOp (ret->data, MINSET);
744   return ret;
745 }
746
747 /*@only@*/
748 /*@unused@*/ static constraintExpr constraintExpr_makeMinReadExpr (/*@exposed@*/ exprNode expr)
749 {
750   constraintExpr ret;
751   ret = constraintExpr_makeUnaryOpExprNode(expr);
752   ret->data      = constraintExprData_unaryExprSetOp (ret->data, MINREAD);
753   return ret;
754 }
755 # endif
756
757 /*@only@*/
758 constraintExpr constraintExpr_makeValueExpr (/*@exposed@*/ exprNode expr)
759 {
760   constraintExpr ret;
761   ret = constraintExpr_makeExprNode (expr);
762   return ret;
763 }
764
765 /*@only@*/ /*@notnull@*/
766 constraintExpr constraintExpr_makeIntLiteral (long i)
767 {
768   constraintExpr ret;
769   constraintTerm t;
770   ret = constraintExpr_alloc();
771   ret->kind = term;
772   ret->data = dmalloc (sizeof *(ret->data) );
773   t = constraintTerm_makeIntLiteral (i);
774   ret->data = constraintExprData_termSetTerm (ret->data, t);
775
776   ret->ct = FALSE;
777   ret->origType = ctype_undefined; 
778
779   return ret;
780 }
781
782 /*
783 constraintExpr constraintExpr_makeValueInt (int i)
784 {
785   return constraintExpr_makeIntLiteral (i);
786 }
787 */
788
789 /*@only@*/ /*@notnull@*/
790  /*@special@*/ static constraintExpr constraintExpr_makeBinaryOp (void)
791       /*@allocates result->data @*/ /*@sets result->kind @*/
792 {
793   constraintExpr ret;
794   ret = constraintExpr_alloc();
795   ret->kind = binaryexpr;
796   ret->data = dmalloc ( sizeof *(ret->data) );
797
798   ret->data->binaryOp.expr1 = constraintExpr_undefined;
799   ret->data->binaryOp.expr2 = constraintExpr_undefined;
800   
801   return ret;
802 }
803
804
805 static /*@notnull@*/ /*@only@*/ constraintExpr constraintExpr_makeBinaryOpConstraintExpr (/*@only@*/constraintExpr expr1, /*@only@*/ constraintExpr expr2)
806      
807 {
808   constraintExpr ret;
809
810   ret = constraintExpr_makeBinaryOp();
811   ret->data = constraintExprData_binaryExprSetExpr1 (ret->data, expr1);
812   ret->data = constraintExprData_binaryExprSetExpr2 (ret->data, expr2);
813   ret->data = constraintExprData_binaryExprSetOp (ret->data, BINARYOP_UNDEFINED);
814
815   ret->ct = FALSE;
816   ret->origType = ctype_undefined; 
817
818   return ret;
819 }
820
821 /*@only@*/
822 constraintExpr constraintExpr_parseMakeBinaryOp (/*@only@*/ constraintExpr expr1, lltok op,/*@only@*/ constraintExpr expr2)
823 {
824   constraintExpr ret;
825   ret = constraintExpr_makeBinaryOpConstraintExpr (expr1, expr2);
826
827   if (lltok_getTok (op) == TPLUS)
828     {
829       ret->data = constraintExprData_binaryExprSetOp(ret->data, BINARYOP_PLUS);
830     }
831   else if (lltok_getTok (op) == TMINUS)
832     {
833       ret->data = constraintExprData_binaryExprSetOp(ret->data, BINARYOP_MINUS);
834     }
835   else
836     {
837       llassert (FALSE);
838     }
839
840   return ret;
841 }
842
843 # if 0
844 /*@only@*/
845 /*@unused@*/ static constraintExpr constraintExpr_makeBinaryOpExprNode (/*@exposed@*/ exprNode expr1, /*@exposed@*/ exprNode expr2)
846 {
847   constraintExpr ret;
848   constraintExpr sub1, sub2;
849   sub1 = constraintExpr_makeTermExprNode (expr1);
850   sub2 = constraintExpr_makeTermExprNode (expr2);
851   ret = constraintExpr_makeBinaryOpConstraintExpr(sub1, sub2);
852   return ret;
853 }
854 # endif
855
856 static /*@notnull@*/ /*@only@*/
857 constraintExpr constraintExpr_makeBinaryOpConstraintExprIntLiteral (/*@only@*/ constraintExpr expr, int literal)
858 {
859   constraintExpr ret;
860   constraintExpr constExpr;
861
862   constExpr = constraintExpr_makeIntLiteral (literal);
863   ret = constraintExpr_makeBinaryOpConstraintExpr (expr, constExpr);
864   ret->data = constraintExprData_binaryExprSetOp(ret->data, BINARYOP_PLUS);
865   return ret;
866 }
867
868 /*@only@*/
869 constraintExpr constraintExpr_makeDecConstraintExpr (/*@only@*/constraintExpr expr)
870 {
871   constraintExpr ret;
872   constraintExpr inc;
873
874   inc = constraintExpr_makeIntLiteral (1);
875   ret = constraintExpr_makeBinaryOpConstraintExpr (expr, inc);
876   ret->data = constraintExprData_binaryExprSetOp(ret->data, BINARYOP_MINUS);
877   return ret;
878 }
879
880
881 /*@only@*/  constraintExpr constraintExpr_makeSubtractExpr (/*@only@*/ constraintExpr expr, /*@only@*/ constraintExpr addent)
882 {
883   constraintExpr  ret;
884   
885   DPRINTF ((message ("Making  subtract expression") ) );
886
887   ret = constraintExpr_makeBinaryOpConstraintExpr (expr, addent);
888   ret->data = constraintExprData_binaryExprSetOp (ret->data, BINARYOP_MINUS);
889   return ret;
890 }
891
892 /*@only@*/
893 constraintExpr constraintExpr_makeAddExpr (/*@only@*/
894 constraintExpr expr, /*@only@*/
895 constraintExpr addent)
896 {
897   constraintExpr  ret;
898   
899   DPRINTF ((message ("Doing addTerm simplification") ) );
900
901   ret = constraintExpr_makeBinaryOpConstraintExpr (expr, addent);
902   ret->data = constraintExprData_binaryExprSetOp (ret->data, BINARYOP_PLUS);
903   return ret;
904 }
905
906
907 /*@only@*/
908 constraintExpr constraintExpr_makeIncConstraintExpr (/*@only@*/ constraintExpr expr)
909 {
910   constraintExpr ret;
911   constraintExpr inc;
912
913   inc = constraintExpr_makeIntLiteral (1);
914   ret = constraintExpr_makeBinaryOpConstraintExpr (expr, inc);
915   ret->data = constraintExprData_binaryExprSetOp(ret->data, BINARYOP_PLUS);
916   return ret;
917 }
918
919 /*@only@*/
920 static cstring constraintExprUnaryOpKind_print (constraintExprUnaryOpKind op)
921 {
922   switch (op)
923     {
924     case MAXSET:
925       return message("maxSet");
926     case MINSET:
927       return message("minSet");
928     case MAXREAD:
929       return message("maxRead");
930     case MINREAD:
931       return message("minRead");
932     default:
933       llassert(FALSE);
934       return message ("<(Unary OP OTHER>");
935     }
936 }
937
938
939 /*@only@*/
940 static cstring constraintExprBinaryOpKind_print (constraintExprBinaryOpKind op)
941 {
942   
943   switch (op)
944     {
945     case BINARYOP_PLUS:
946       return message("+");
947     case BINARYOP_MINUS:
948       return message("-");
949
950     default:
951       llassert(FALSE);
952       return message ("<binary OP Unknown>");
953     }
954 }
955
956 bool constraintExpr_similar (constraintExpr expr1, constraintExpr expr2)
957 {
958   constraintExprKind kind;
959   
960   llassert (expr1 != NULL);
961   llassert (expr2 != NULL);
962   if (expr1->kind != expr2->kind)
963     return FALSE;
964   
965   kind = expr1->kind;
966   
967   switch (kind)
968     {
969     case term:
970       return constraintTerm_similar (constraintExprData_termGetTerm(expr1->data),
971                                   constraintExprData_termGetTerm(expr2->data) );
972       /*@notreached@*/ break;
973       
974     case unaryExpr:
975       if (constraintExprData_unaryExprGetOp (expr1->data) != constraintExprData_unaryExprGetOp (expr2->data) )
976         return FALSE;
977       
978       return (constraintExpr_similar (
979               constraintExprData_unaryExprGetExpr (expr1->data),
980               constraintExprData_unaryExprGetExpr (expr2->data)
981               ));
982       
983     case binaryexpr:
984       if (constraintExprData_binaryExprGetOp (expr1->data) != constraintExprData_binaryExprGetOp (expr2->data) )
985         return FALSE;
986       
987       if (! constraintExpr_similar (constraintExprData_binaryExprGetExpr1 (expr1->data),
988                                  constraintExprData_binaryExprGetExpr1 (expr2->data)) )
989         return FALSE;
990       
991       if (! constraintExpr_similar (constraintExprData_binaryExprGetExpr2 (expr1->data),
992                                  constraintExprData_binaryExprGetExpr2 (expr2->data)) )
993         return FALSE;
994       else
995         return TRUE;
996       /*@notreached@*/
997       break;
998       
999     default:
1000       llassert(FALSE);
1001       return FALSE;
1002     }
1003   /*@notreached@*/
1004   return FALSE;
1005 }
1006
1007 bool constraintExpr_same (constraintExpr expr1, constraintExpr expr2)
1008 {
1009   constraintExprKind kind;
1010   
1011   llassert (expr1 != NULL);
1012   llassert (expr2 != NULL);
1013   if (expr1->kind != expr2->kind)
1014     return FALSE;
1015   
1016   kind = expr1->kind;
1017   
1018   switch (kind)
1019     {
1020     case term:
1021       return constraintTerm_similar (constraintExprData_termGetTerm(expr1->data),
1022                                   constraintExprData_termGetTerm(expr2->data) );
1023       /*@notreached@*/ break;
1024       
1025     case unaryExpr:
1026       if (constraintExprData_unaryExprGetOp (expr1->data) != constraintExprData_unaryExprGetOp (expr2->data) )
1027         return FALSE;
1028
1029       return (constraintExpr_same (
1030               constraintExprData_unaryExprGetExpr (expr1->data),
1031               constraintExprData_unaryExprGetExpr (expr2->data)
1032               ));
1033       
1034             
1035     case binaryexpr:
1036       if (constraintExprData_binaryExprGetOp (expr1->data) != constraintExprData_binaryExprGetOp (expr2->data) )
1037         return FALSE;
1038       
1039       if (! constraintExpr_same (constraintExprData_binaryExprGetExpr1 (expr1->data),
1040                                  constraintExprData_binaryExprGetExpr1 (expr2->data)) )
1041         return FALSE;
1042       
1043       if (! constraintExpr_same (constraintExprData_binaryExprGetExpr2 (expr1->data),
1044                                  constraintExprData_binaryExprGetExpr2 (expr2->data)) )
1045         return FALSE;
1046       else
1047         return TRUE;
1048       /*@notreached@*/ break;
1049       
1050     default:
1051       llassert(FALSE);
1052       return FALSE;
1053     }
1054
1055   /*@notreached@*/
1056   BADEXIT;
1057 }
1058
1059 bool 
1060 constraintExpr_search (/*@observer@*/ constraintExpr c, 
1061                        /*@observer@*/ constraintExpr old)
1062 {
1063   bool ret = FALSE;
1064   constraintExprKind kind;
1065   constraintExpr temp;
1066   
1067   if (constraintExpr_similar (c, old))
1068     {
1069       DPRINTF (("Found  %q", constraintExpr_unparse (old)));
1070       return TRUE;
1071     }
1072
1073   llassert (constraintExpr_isDefined (c) && constraintExpr_isDefined(old) );
1074
1075   if ( !(constraintExpr_isDefined (c) && constraintExpr_isDefined(old) ) )
1076     return FALSE;
1077
1078   kind = c->kind;
1079   
1080   switch (kind)
1081     {
1082     case term:
1083       break;      
1084     case unaryExpr:
1085       temp = constraintExprData_unaryExprGetExpr (c->data);
1086       ret = ret || constraintExpr_search (temp, old);
1087       break;           
1088     case binaryexpr:
1089       
1090       temp = constraintExprData_binaryExprGetExpr1 (c->data);
1091       ret = ret || constraintExpr_search(temp, old);
1092            
1093       temp = constraintExprData_binaryExprGetExpr2 (c->data);
1094       ret = ret || constraintExpr_search(temp, old);
1095       break;
1096     default:
1097       llassert(FALSE);
1098     }
1099   return ret;
1100   
1101 }
1102
1103
1104 /*@only@*/ constraintExpr 
1105 constraintExpr_searchandreplace (/*@only@*/ /*@unique@*/ constraintExpr c, /*@temp@*/ constraintExpr old, 
1106                                  /*@temp@*/ constraintExpr newExpr )
1107 {
1108   constraintExprKind kind;
1109   constraintExpr temp;
1110   constraintExpr ret;
1111
1112   llassert (constraintExpr_isDefined (newExpr) && (constraintExpr_isDefined (old) && constraintExpr_isDefined(c) ) );
1113   
1114   if (constraintExpr_similar (c, old))
1115     {
1116       ctype newType = ctype_unknown;
1117       ctype cType = ctype_unknown;
1118       
1119       ret = constraintExpr_copy (newExpr);
1120       llassert(constraintExpr_isDefined(ret) );
1121       /*drl if newExpr != NULL then ret will != NULL*/
1122       
1123       DPRINTF (("Replacing %s with %s in %s", 
1124                 constraintExpr_unparse (old), constraintExpr_unparse (newExpr),
1125                 constraintExpr_unparse (c)));
1126
1127       if (constraintExpr_canGetCType (c) && constraintExpr_canGetCType (newExpr))
1128         {
1129           cType = constraintExpr_getCType(c);
1130           newType =  constraintExpr_getCType (newExpr);
1131           
1132           if (ctype_match (cType,newType))
1133             {
1134               DPRINTF (("constraintExpr_searchandreplace: replacing "
1135                         " %s with type %s with %s with type %s",
1136                         constraintExpr_unparse (c), ctype_unparse(cType),
1137                         constraintExpr_unparse (newExpr), ctype_unparse(newType)));
1138               
1139               ret->ct = TRUE;
1140               ret->origType = cType;
1141               DPRINTF (("Type: %s", ctype_unparse (constraintExpr_getCType (ret))));
1142             }
1143         }
1144       
1145       if (constraintExpr_hasMaxSet (c))
1146         {
1147           if (constraintExpr_hasTypeChange (c))
1148             {
1149               fileloc loc = constraintExpr_loc (c);
1150               DPRINTF (("constraintExpr_searchandreplace: encountered "
1151                         "MaxSet with changed type %s ",
1152                         constraintExpr_unparse (c)));
1153               
1154               if (c->kind == unaryExpr) 
1155                 {
1156                   constraintExpr ce = constraintExprData_unaryExprGetExpr (c->data);
1157                   DPRINTF (("Its a unary! %s / %s",
1158                             ctype_unparse (constraintExpr_getCType (ce)),
1159                             ctype_unparse (constraintExpr_getOrigType (ce))));
1160                   ret = constraintExpr_adjustMaxSetForCast (ret, constraintExpr_getCType (ce),
1161                                                             constraintExpr_getOrigType (ce),
1162                                                             loc);
1163                 }
1164               else
1165                 {
1166                   /* fix this with a conversation */
1167                   DPRINTF (("Types: %s / %s", ctype_unparse (newType), ctype_unparse (cType)));
1168                   ret = constraintExpr_adjustMaxSetForCast (ret, constraintExpr_getCType (c), 
1169                                                             constraintExpr_getOrigType(c),
1170                                                             loc);
1171                 }
1172             }
1173         }
1174
1175       constraintExpr_free (c);
1176       DPRINTF (("ret: %s", constraintExpr_unparse (ret)));
1177       return ret;
1178     }
1179
1180   kind = c->kind;
1181   
1182   switch (kind)
1183     {
1184     case term:
1185       break;      
1186     case unaryExpr:
1187       DPRINTF (("Making unary expression!"));
1188       temp = constraintExprData_unaryExprGetExpr (c->data);
1189       temp = constraintExpr_copy (temp);
1190       temp = constraintExpr_searchandreplace (temp, old, newExpr);
1191       c->data = constraintExprData_unaryExprSetExpr (c->data, temp);
1192       break;           
1193     case binaryexpr:
1194       DPRINTF (("Making binary expression!"));
1195       temp = constraintExprData_binaryExprGetExpr1 (c->data);
1196       temp = constraintExpr_copy (temp);
1197       temp = constraintExpr_searchandreplace (temp, old, newExpr);
1198       c->data = constraintExprData_binaryExprSetExpr1 (c->data, temp);
1199        
1200       temp = constraintExprData_binaryExprGetExpr2 (c->data);
1201       temp = constraintExpr_copy (temp);
1202       temp = constraintExpr_searchandreplace (temp, old, newExpr);
1203       c->data = constraintExprData_binaryExprSetExpr2 (c->data, temp);
1204       break;
1205     default:
1206       llassert (FALSE);
1207     }
1208   
1209   DPRINTF (("ret: %s", constraintExpr_unparse (c)));
1210   return c;
1211 }
1212
1213 /*@notnull@*/ static constraintExpr constraintExpr_simplifyChildren (/*@returned@*/ /*@notnull@*/ constraintExpr c)
1214 {
1215   constraintExprKind kind;
1216   constraintExpr temp;
1217
1218   kind = c->kind;
1219   
1220   switch (kind)
1221     {
1222     case term:
1223       break;      
1224     case unaryExpr:
1225       temp = constraintExprData_unaryExprGetExpr (c->data);
1226       temp = constraintExpr_copy(temp);
1227       temp = constraintExpr_simplify (temp);
1228       c->data = constraintExprData_unaryExprSetExpr (c->data, temp);
1229       break;           
1230     case binaryexpr:
1231       DPRINTF((message("constraintExpr_simplfiyChildren: simplify binary expression: %s",constraintExpr_unparse(c) ) ) );
1232       temp = constraintExprData_binaryExprGetExpr1 (c->data);
1233       temp = constraintExpr_copy(temp);
1234       temp = constraintExpr_simplify (temp);
1235
1236       c->data = constraintExprData_binaryExprSetExpr1 (c->data, temp);
1237        
1238       temp = constraintExprData_binaryExprGetExpr2 (c->data);
1239       temp = constraintExpr_copy(temp);
1240       temp = constraintExpr_simplify (temp);
1241
1242       c->data = constraintExprData_binaryExprSetExpr2 (c->data, temp);
1243       break;
1244     default:
1245       llassert(FALSE);
1246     }
1247   return c;
1248   
1249 }
1250
1251
1252 constraintExpr constraintExpr_setFileloc (/*@returned@*/ constraintExpr c, fileloc loc) /*@modifies c @*/
1253 {
1254   constraintTerm t;
1255   constraintExpr temp;
1256
1257   llassert(c != NULL);
1258   
1259   switch (c->kind)
1260     {
1261     case term:
1262       t = constraintExprData_termGetTerm (c->data);
1263       t = constraintTerm_copy(t);
1264       t = constraintTerm_setFileloc (t, loc);
1265       c->data = constraintExprData_termSetTerm (c->data, t);
1266       break;
1267     case binaryexpr:
1268       
1269       temp = constraintExprData_binaryExprGetExpr1 (c->data);
1270       temp = constraintExpr_copy(temp);
1271       temp = constraintExpr_setFileloc (temp, loc);
1272       c->data = constraintExprData_binaryExprSetExpr1 (c->data, temp);
1273       
1274       temp = constraintExprData_binaryExprGetExpr2 (c->data);
1275       temp = constraintExpr_copy(temp);
1276       temp = constraintExpr_setFileloc (temp, loc);
1277       c->data = constraintExprData_binaryExprSetExpr2 (c->data, temp);
1278       break;
1279     case unaryExpr:
1280       temp = constraintExprData_unaryExprGetExpr (c->data);
1281       temp = constraintExpr_copy(temp);
1282       temp = constraintExpr_setFileloc (temp, loc);
1283       c->data = constraintExprData_unaryExprSetExpr (c->data, temp);
1284       break;
1285     }
1286   return c;
1287 }
1288
1289 static /*@only@*/ constraintExpr constraintExpr_simplifybinaryExpr (/*@only@*/ /*@notnull@*/ constraintExpr c)
1290 {
1291   constraintExpr e1, e2;
1292   constraintExprBinaryOpKind  op;
1293   
1294   e1 = constraintExprData_binaryExprGetExpr1 (c->data);
1295   e2 = constraintExprData_binaryExprGetExpr2 (c->data);
1296
1297   if (constraintExpr_canGetValue (e1) && constraintExpr_canGetValue(e2) )
1298     {
1299       long i;
1300
1301       i = constraintExpr_getValue(e1) + constraintExpr_getValue (e2);
1302       constraintExpr_free(c);
1303       c = constraintExpr_makeIntLiteral (i);
1304     }
1305   else
1306     {
1307       op = constraintExprData_binaryExprGetOp (c->data);      
1308       if (op == BINARYOP_MINUS)
1309         if (constraintExpr_similar(e1, e2) )
1310           {
1311             constraintExpr_free(c);
1312             c =  constraintExpr_makeIntLiteral (0);
1313           }
1314     }
1315   
1316   return c;
1317 }
1318
1319 /*
1320   this thing takes the lexpr and expr of a constraint and modifies lexpr
1321   and returns a (possiblly new) value for expr
1322 */
1323 /* 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 */
1324
1325 /* the approach is a little Kludgy but seems to work.  I should probably use something cleaner at some point ... */
1326
1327
1328 /*@only@*/ constraintExpr constraintExpr_solveBinaryExpr (constraintExpr lexpr, /*@only@*/ constraintExpr expr)
1329 {
1330   constraintExpr expr1, expr2;
1331   constraintExprBinaryOpKind op;
1332
1333   llassert(constraintExpr_isDefined (lexpr)  && constraintExpr_isDefined (expr)  );
1334   
1335   if (lexpr->kind != binaryexpr)
1336     return expr;
1337
1338   expr2 = constraintExprData_binaryExprGetExpr2 (lexpr->data);
1339   expr1 = constraintExprData_binaryExprGetExpr1 (lexpr->data);
1340
1341   op    = constraintExprData_binaryExprGetOp (lexpr->data);
1342
1343   expr1 = constraintExpr_copy(expr1);
1344   expr2 = constraintExpr_copy(expr2);
1345   
1346   llassert(constraintExpr_isDefined (expr1)  && constraintExpr_isDefined (expr2)  );
1347   
1348   /* drl possible problem : warning make sure this works */
1349   
1350   lexpr->kind = expr1->kind;
1351   sfree (lexpr->data);
1352   
1353   lexpr->data = copyExprData (expr1->data, expr1->kind);
1354   constraintExpr_free(expr1);
1355   
1356   if (op == BINARYOP_PLUS)
1357     expr = constraintExpr_makeSubtractExpr (expr, expr2);
1358   else if (op == BINARYOP_MINUS)
1359     expr = constraintExpr_makeAddExpr (expr, expr2);
1360   else
1361     BADEXIT;
1362   
1363   
1364   return expr;
1365
1366   /*
1367     #warning this needs to be checked
1368     expr = constraintExpr_solveBinaryExpr (expr1, expr);
1369     
1370     expr = constraintExpr_solveBinaryExpr (expr2, expr);
1371     return expr;
1372   */
1373 }
1374
1375 static /*@only@*/ constraintExpr constraintExpr_simplifyunaryExpr (/*@only@*/ constraintExpr c)
1376 {
1377   constraintExpr exp;
1378
1379   llassert(constraintExpr_isDefined (c) );
1380   llassert (c->kind == unaryExpr);
1381
1382   DPRINTF ((message ("Doing constraintExpr_simplifyunaryExpr:%s", constraintExpr_unparse (c) ) ) );
1383   
1384   if ((constraintExprData_unaryExprGetOp (c->data) != MAXSET) &&
1385        (constraintExprData_unaryExprGetOp (c->data) != MAXREAD) )
1386     {
1387       return c;
1388     }
1389   
1390   exp = constraintExprData_unaryExprGetExpr (c->data);
1391   exp = constraintExpr_copy(exp);
1392   
1393   llassert(constraintExpr_isDefined (exp)  );
1394   
1395   if (exp->kind == term)
1396     {
1397       constraintTerm cterm;
1398
1399       cterm = constraintExprData_termGetTerm (exp->data);
1400       
1401       if (constraintTerm_isStringLiteral(cterm) )
1402         {
1403           cstring val;
1404           val = constraintTerm_getStringLiteral (cterm);
1405           if (constraintExprData_unaryExprGetOp (c->data) == MAXSET)
1406             {
1407               constraintExpr temp;
1408
1409               temp = constraintExpr_makeIntLiteral ((int)strlen (cstring_toCharsSafe(val) ) );
1410               cstring_free(val);              
1411               constraintExpr_free(c);
1412               constraintExpr_free(exp);
1413
1414               return temp;
1415               
1416             }
1417           if (constraintExprData_unaryExprGetOp (c->data) == MAXREAD)
1418             {
1419               constraintExpr temp;
1420
1421               temp = constraintExpr_makeIntLiteral ((int)strlen (cstring_toCharsSafe(val) ) );
1422               cstring_free(val);              
1423               constraintExpr_free(c);
1424               constraintExpr_free(exp);
1425
1426               return temp;
1427             }
1428           BADEXIT;
1429         }
1430
1431       /* slight Kludge to hanlde var [] = { , , };
1432       ** type syntax  I don't think this is sounds but it should be good
1433       ** enough.  The C stanrad is very confusing about initialization
1434       ** -- DRL 7/25/01
1435       */
1436       
1437       if (constraintTerm_isInitBlock(cterm) )
1438         {
1439           constraintExpr temp;
1440           int len;
1441
1442           len = constraintTerm_getInitBlockLength(cterm);
1443
1444           temp = constraintExpr_makeIntLiteral (len );
1445           
1446           constraintExpr_free(c);
1447           DPRINTF(( message("Changed too %q", constraintExpr_print(temp)
1448                             ) ));
1449           constraintExpr_free(exp);
1450           return temp;
1451         }
1452       
1453       constraintExpr_free(exp);
1454       return c;
1455     }
1456   
1457   if (exp->kind != binaryexpr)
1458     {
1459       constraintExpr_free(exp);
1460       return c;
1461     }
1462   
1463   if (constraintExprData_binaryExprGetOp (exp->data) == BINARYOP_PLUS  )
1464     {
1465  
1466       /* if (constraintExpr_canGetValue (constraintExprData_binaryExprGetExpr2 (exp->data) ) ) */
1467         {
1468         
1469           constraintExpr  temp, temp2;
1470
1471           DPRINTF ((message ("Doing fancy simplification") ) );
1472
1473           temp = constraintExprData_binaryExprGetExpr2 (exp->data);
1474
1475           temp2 = constraintExprData_binaryExprGetExpr1 (exp->data);
1476
1477           temp2 = constraintExpr_copy(temp2);
1478           c->data = constraintExprData_unaryExprSetExpr (c->data, temp2);
1479           
1480           
1481           temp = constraintExpr_copy (temp);
1482
1483           c = constraintExpr_makeSubtractExpr (c, temp);
1484
1485           DPRINTF ((message ("Done fancy simplification:%s", constraintExpr_unparse (c) ) ) );
1486         }
1487     }
1488   
1489   DPRINTF ((message ("constraintExpr_simplifyUnaryExpr: Done simplification:%s", constraintExpr_unparse (c) ) ) );
1490
1491   constraintExpr_free(exp);
1492   return c;
1493 }
1494
1495
1496 /*@only@*/ constraintExpr constraintExpr_simplify (/*@only@*/ constraintExpr c)
1497 {
1498   constraintExprKind kind;
1499   constraintExpr ret;
1500   constraintTerm t;
1501   
1502   DPRINTF ((message ("Doing constraintExpr_simplify:%s", constraintExpr_unparse (c) ) ) );  
1503   
1504
1505   
1506   llassert ( constraintExpr_isDefined (c) );
1507   if (constraintExpr_isUndefined (c) )
1508     {
1509       return constraintExpr_undefined;
1510     }
1511   
1512   ret =  constraintExpr_copy(c);
1513   llassert(constraintExpr_isDefined (ret) );
1514            
1515   constraintExpr_free(c);
1516
1517   ret = constraintExpr_simplifyChildren (ret);
1518
1519   ret = constraintExpr_combineConstants (ret);
1520   
1521   ret = constraintExpr_simplifyChildren (ret);
1522   
1523
1524   kind = ret->kind;
1525   
1526   switch (kind)
1527     {
1528     case term:
1529       t = constraintExprData_termGetTerm (ret->data);
1530       t = constraintTerm_copy(t);
1531       t = constraintTerm_simplify (t);
1532       ret->data = constraintExprData_termSetTerm (ret->data, t);
1533       break;      
1534     case unaryExpr:
1535       ret = constraintExpr_simplifyunaryExpr (ret);
1536       break;           
1537     case binaryexpr:
1538       ret = constraintExpr_simplifybinaryExpr (ret);      
1539       break;
1540     default:
1541       llassert(FALSE);
1542     }    
1543   
1544   DPRINTF ((message ("constraintExpr_simplify returning :%s", constraintExpr_unparse (ret) ) ) );  
1545   return ret;
1546   
1547 }
1548
1549 /*@only@*/
1550 cstring constraintExpr_unparse (/*@temp@*/ constraintExpr ex) /*@*/
1551 {
1552   cstring st;
1553   constraintExprKind kind;
1554
1555   llassert (ex != NULL);
1556
1557   kind = ex->kind;
1558   
1559   switch (kind)
1560     {
1561     case term:
1562       if (context_getFlag (FLG_PARENCONSTRAINT) )
1563         {
1564           st = message ("(%q) ", constraintTerm_unparse (constraintExprData_termGetTerm (ex->data)));
1565         }
1566       else
1567         {
1568           st = message ("%q", constraintTerm_unparse (constraintExprData_termGetTerm (ex->data)));
1569         }
1570       break;
1571     case unaryExpr:
1572       st = message ("%q(%q)",
1573                     constraintExprUnaryOpKind_print (constraintExprData_unaryExprGetOp (ex->data) ),
1574                     constraintExpr_unparse (constraintExprData_unaryExprGetExpr (ex->data) )
1575                     );
1576       break;
1577     case binaryexpr:
1578       if (context_getFlag (FLG_PARENCONSTRAINT) )
1579         {
1580           st = message ("(%q) %q (%q)",
1581                         constraintExpr_unparse (constraintExprData_binaryExprGetExpr1 (ex->data) ),
1582                         constraintExprBinaryOpKind_print (constraintExprData_binaryExprGetOp (ex->data)),
1583                         constraintExpr_unparse (constraintExprData_binaryExprGetExpr2 (ex->data) )
1584                         );
1585         }
1586       else
1587         {
1588           st = message ("%q %q %q",
1589                         constraintExpr_unparse (constraintExprData_binaryExprGetExpr1 (ex->data)),
1590                         constraintExprBinaryOpKind_print (constraintExprData_binaryExprGetOp (ex->data)),
1591                         constraintExpr_unparse (constraintExprData_binaryExprGetExpr2 (ex->data))
1592                         );
1593         }
1594       
1595       break;
1596     default:
1597       llassert(FALSE);
1598       st = message ("error");
1599       
1600     }
1601
1602   DPRINTF((message ("constraintExpr_unparse: '%s'",st) ) );
1603   return st;
1604 }
1605
1606 constraintExpr constraintExpr_doSRefFixBaseParam (/*@returned@*/  constraintExpr expr, exprNodeList arglist)
1607 {
1608   constraintTerm Term;
1609   constraintExprKind kind;
1610   constraintExpr expr1, expr2;
1611   constraintExprData data;
1612   llassert (expr != NULL);
1613
1614   data = expr->data;
1615   
1616   kind = expr->kind;
1617   
1618   switch (kind)
1619     {
1620     case term:
1621       Term = constraintExprData_termGetTerm(data);
1622       Term = constraintTerm_copy(Term);
1623
1624       Term = constraintTerm_doSRefFixBaseParam (Term, arglist);
1625       data = constraintExprData_termSetTerm(data, Term);
1626       break;
1627     case unaryExpr:
1628       expr1 = constraintExprData_unaryExprGetExpr (data);
1629       expr1 = constraintExpr_copy(expr1);
1630
1631       expr1 = constraintExpr_doSRefFixBaseParam (expr1, arglist);
1632       data = constraintExprData_unaryExprSetExpr (data, expr1);
1633       break;
1634     case binaryexpr:
1635       expr1 = constraintExprData_binaryExprGetExpr1 (data);
1636       expr2 = constraintExprData_binaryExprGetExpr2 (data);
1637       
1638       expr1 = constraintExpr_copy(expr1);
1639       expr2 = constraintExpr_copy(expr2);
1640
1641       expr1 = constraintExpr_doSRefFixBaseParam (expr1, arglist);
1642       data = constraintExprData_binaryExprSetExpr1 (data, expr1);
1643       expr2 = constraintExpr_doSRefFixBaseParam (expr2, arglist);
1644       data = constraintExprData_binaryExprSetExpr2 (data, expr2);
1645       
1646       break;
1647     default:
1648       llassert(FALSE);
1649       data = NULL;
1650     }
1651   return expr;
1652 }
1653
1654 /*
1655 / *@only@* / constraintExpr constraintExpr_doSRefFixInvarConstraint (/ *@only@* / constraintExpr expr, sRef s, ctype ct)
1656 {
1657   constraintExprKind kind;
1658   constraintExpr expr1, expr2;
1659   constraintExprData data;
1660   llassert (expr != NULL);
1661
1662   data = expr->data;
1663   
1664   kind = expr->kind;
1665   
1666   switch (kind)
1667     {
1668     case term:
1669       expr = doSRefFixInvarConstraintTerm (expr, s, ct);
1670       break;
1671     case unaryExpr:
1672       expr1 = constraintExprData_unaryExprGetExpr (data);
1673       expr1 = constraintExpr_copy(expr1);
1674       expr1 = constraintExpr_doSRefFixInvarConstraint (expr1, s, ct);
1675       data = constraintExprData_unaryExprSetExpr (data, expr1);
1676       break;
1677     case binaryexpr:
1678       expr1 = constraintExprData_binaryExprGetExpr1 (data);
1679       expr2 = constraintExprData_binaryExprGetExpr2 (data);
1680       
1681       expr1 = constraintExpr_copy(expr1);
1682       expr2 = constraintExpr_copy(expr2);
1683
1684       expr1 = constraintExpr_doSRefFixInvarConstraint (expr1, s, ct);
1685       data = constraintExprData_binaryExprSetExpr1 (data, expr1);
1686       expr2 = constraintExpr_doSRefFixInvarConstraint (expr2, s, ct);
1687       data = constraintExprData_binaryExprSetExpr2 (data, expr2);
1688       
1689       break;
1690     default:
1691       llassert(FALSE);
1692       data = NULL;
1693     }
1694   return expr;
1695 }
1696 */
1697
1698 /*@only@*/ constraintExpr constraintExpr_doSRefFixConstraintParam (/*@only@*/ constraintExpr expr, exprNodeList arglist) /*@modifies expr@*/
1699 {
1700   constraintExprKind kind;
1701   constraintExpr expr1, expr2;
1702   constraintExprData data;
1703   llassert (expr != NULL);
1704
1705   data = expr->data;
1706   
1707   kind = expr->kind;
1708   
1709   switch (kind)
1710     {
1711     case term:
1712       expr = doSRefFixConstraintParamTerm (expr, arglist);
1713       break;
1714     case unaryExpr:
1715       expr1 = constraintExprData_unaryExprGetExpr (data);
1716       expr1 = constraintExpr_copy(expr1);
1717       expr1 = constraintExpr_doSRefFixConstraintParam (expr1, arglist);
1718       data = constraintExprData_unaryExprSetExpr (data, expr1);
1719       break;
1720     case binaryexpr:
1721       expr1 = constraintExprData_binaryExprGetExpr1 (data);
1722       expr2 = constraintExprData_binaryExprGetExpr2 (data);
1723       
1724       expr1 = constraintExpr_copy(expr1);
1725       expr2 = constraintExpr_copy(expr2);
1726
1727       expr1 = constraintExpr_doSRefFixConstraintParam (expr1, arglist);
1728       data = constraintExprData_binaryExprSetExpr1 (data, expr1);
1729       expr2 = constraintExpr_doSRefFixConstraintParam (expr2, arglist);
1730       data = constraintExprData_binaryExprSetExpr2 (data, expr2);
1731       
1732       break;
1733     default:
1734       llassert(FALSE);
1735       data = NULL;
1736     }
1737   return expr;
1738 }
1739
1740 /*@only@*/ constraintExpr constraintExpr_doFixResult (/*@only@*/  constraintExpr expr, /*@observer@*/ exprNode fcnCall)
1741 {
1742   constraintExprKind kind;
1743   constraintExpr expr1, expr2;
1744   constraintExprData data;
1745   llassert (expr != NULL);
1746
1747   data = expr->data;
1748   
1749   kind = expr->kind;
1750   
1751   switch (kind)
1752     {
1753     case term:
1754       expr = doFixResultTerm (expr, fcnCall);
1755       break;
1756     case unaryExpr:
1757       expr1 = constraintExprData_unaryExprGetExpr (data);
1758       expr1 = constraintExpr_copy(expr1);
1759
1760       expr1 = constraintExpr_doFixResult (expr1, fcnCall);
1761       data = constraintExprData_unaryExprSetExpr (data, expr1);
1762       break;
1763     case binaryexpr:
1764       expr1 = constraintExprData_binaryExprGetExpr1 (data);
1765       expr2 = constraintExprData_binaryExprGetExpr2 (data);
1766       
1767       expr1 = constraintExpr_copy(expr1);
1768       expr2 = constraintExpr_copy(expr2);
1769
1770       expr1 = constraintExpr_doFixResult (expr1, fcnCall);
1771       data = constraintExprData_binaryExprSetExpr1 (data, expr1);
1772       expr2 = constraintExpr_doFixResult (expr2, fcnCall);
1773       data = constraintExprData_binaryExprSetExpr2 (data, expr2);
1774       
1775       break;
1776     default:
1777       llassert(FALSE);
1778       data = NULL;
1779     }
1780   return expr;
1781 }
1782
1783 cstring constraintExpr_print (constraintExpr expr) /*@*/
1784 {
1785   return constraintExpr_unparse (expr);
1786 }
1787
1788 bool constraintExpr_hasMaxSet (constraintExpr expr) /*@*/
1789 {
1790   cstring t;
1791
1792   t = constraintExpr_unparse(expr);
1793
1794   if (cstring_containsLit(t, "maxSet") != NULL )
1795     {
1796       cstring_free(t);
1797       return (TRUE);
1798     }
1799   else
1800     {
1801       cstring_free(t);
1802       return FALSE;
1803     }
1804 }
1805
1806
1807
1808       /*returns 1 0 -1 like strcmp
1809         1 => expr1 > expr2
1810         0 => expr1 == expr2
1811         -1 => expr1 < expr2
1812        */
1813
1814 int constraintExpr_compare (constraintExpr expr1, constraintExpr expr2)
1815 {
1816   long value1, value2;
1817
1818   if (constraintExpr_similar (expr1, expr2) )
1819     {
1820       return 0;
1821     }
1822   
1823   value1 = constraintExpr_getValue(expr1);
1824   value2 = constraintExpr_getValue(expr2);
1825
1826   if (value1 > value2)
1827     return 1;
1828
1829   if (value1 == value2)
1830     return 0;
1831
1832   else
1833     return -1;
1834 }
1835
1836 long constraintExpr_getValue (constraintExpr expr)
1837 {
1838   llassert (constraintExpr_isDefined(expr) );
1839   llassert (expr->kind == term);
1840   
1841   return (constraintTerm_getValue (constraintExprData_termGetTerm (expr->data)));
1842 }
1843
1844 bool constraintExpr_canGetValue (constraintExpr expr)
1845 {
1846   llassert ( constraintExpr_isDefined (expr) );
1847   if (constraintExpr_isUndefined (expr) )
1848     {
1849       return FALSE;
1850     }
1851
1852   switch (expr->kind)
1853     {
1854     case term:
1855       return constraintTerm_canGetValue (constraintExprData_termGetTerm (expr->data) );
1856     default:
1857       return FALSE;
1858       
1859     }
1860
1861   BADEXIT;
1862 }
1863
1864 fileloc constraintExpr_loc (constraintExpr expr)
1865 {
1866   constraintExpr e;
1867 constraintTerm t;
1868   constraintExprKind kind;
1869
1870   llassert ( constraintExpr_isDefined (expr) );
1871   if (constraintExpr_isUndefined (expr) )
1872     {
1873       return fileloc_undefined;
1874     }
1875
1876   
1877  kind = expr->kind;
1878   
1879   switch (kind)
1880     {
1881     case term:
1882       t = constraintExprData_termGetTerm (expr->data);
1883       return (constraintTerm_getFileloc (t) );
1884       /*@notreached@*/
1885       break;      
1886     case unaryExpr:
1887       e = constraintExprData_unaryExprGetExpr (expr->data);
1888       return (constraintExpr_loc (e) );
1889       /*@notreached@*/
1890       break;           
1891     case binaryexpr:
1892       e = constraintExprData_binaryExprGetExpr1 (expr->data);
1893       return (constraintExpr_loc (e) );
1894       /*@notreached@*/
1895       break;
1896     }
1897   llassert (FALSE);
1898   return (fileloc_undefined);
1899 }
1900
1901 /*drl moved from constriantTerm.c 5/20/001*/
1902 static /*@only@*/ constraintExpr 
1903 doFixResultTerm (/*@only@*/ constraintExpr e, /*@exposed@*/ exprNode fcnCall)
1904 {
1905   constraintTerm t;
1906   sRef s;
1907   constraintExprData data;
1908   constraintExprKind kind;
1909   constraintExpr ret;
1910   
1911   llassert (constraintExpr_isDefined (e) );
1912   
1913   data = e->data;
1914   kind = e->kind;
1915   
1916   llassert (kind == term);
1917   
1918   t = constraintExprData_termGetTerm (data);
1919   llassert (constraintTerm_isDefined (t));
1920   
1921   ret = e;
1922
1923   switch (constraintTerm_getKind (t))
1924     {
1925     case CTT_EXPR:
1926     case CTT_INTLITERAL:
1927       break;
1928       
1929     case CTT_SREF:
1930       s = constraintTerm_getSRef(t);
1931       if (sRef_isResult (s))
1932         {
1933           ret = constraintExpr_makeExprNode(fcnCall);
1934           constraintExpr_free(e);
1935           e = NULL;
1936         }
1937       else
1938         {
1939           e = NULL;
1940         }
1941       break;
1942     default:
1943       BADEXIT;
1944     }
1945   
1946   return ret;
1947   
1948 }
1949
1950 #if 0
1951
1952 /*to be used for structure checking */
1953
1954 / *@only@* / static constraintExpr
1955 doSRefFixInvarConstraintTerm (/ *@only@* / constraintExpr e,
1956  sRef s, ctype ct)
1957 {
1958   constraintTerm t;
1959
1960   constraintExprData data = e->data;
1961   
1962   constraintExprKind kind = e->kind;
1963   
1964   constraintExpr ret;
1965
1966   llassert(kind == term);
1967
1968   t = constraintExprData_termGetTerm (data);
1969   llassert (constraintTerm_isDefined(t) );
1970
1971   ret = e;
1972
1973   DPRINTF (("Fixing: %s", constraintExpr_print (e)));
1974
1975   switch (constraintTerm_getKind(t))
1976     {
1977     case CTT_EXPR:
1978       DPRINTF((message ("%q @ %q ", constraintTerm_unparse(t),
1979                         fileloc_unparse (constraintTerm_getFileloc(t) ) ) ));
1980       break;
1981     case CTT_INTLITERAL:
1982       DPRINTF((message (" %q ", constraintTerm_unparse (t)) ));
1983       break;
1984       
1985     case CTT_SREF:
1986       / * evans 2001-07-24: constants should use the original term * /
1987       if (!constraintTerm_canGetValue (t))
1988         {
1989           sRef snew;
1990           DPRINTF ((message("Doing sRef_fixInvarConstraint for %q ", 
1991                              constraintTerm_unparse (t) ) ));
1992
1993           snew = fixSref (ct, s, constraintTerm_getSRef(t));
1994
1995           ret = constraintExpr_makeTermsRef(snew);
1996           
1997           constraintExpr_free (e);
1998           
1999           DPRINTF (( message("After Doing sRef_fixConstraintParam constraintExpr is %q ", 
2000                              constraintExpr_print (ret) ) ));
2001           / *@-branchstate@* /
2002         } / *@=branchstate@* /
2003
2004       break;
2005     default:
2006       BADEXIT;
2007     }
2008
2009   return ret;
2010   
2011 }
2012 #endif
2013  
2014 /*drl moved from constriantTerm.c 5/20/001*/
2015 /*@only@*/ static constraintExpr 
2016 doSRefFixConstraintParamTerm (/*@only@*/ constraintExpr e, /*@observer@*/ /*@temp@*/ exprNodeList arglist)
2017 {
2018   constraintTerm t;
2019
2020   constraintExprData data;
2021   
2022   constraintExprKind kind;
2023   
2024   constraintExpr ret;
2025
2026
2027   llassert(constraintExpr_isDefined (e) );
2028
2029   data = e->data;
2030   
2031   kind = e->kind;
2032
2033   
2034
2035   llassert(kind == term);
2036
2037   t = constraintExprData_termGetTerm (data);
2038   llassert (constraintTerm_isDefined(t) );
2039
2040   ret = e;
2041
2042   DPRINTF (("Fixing: %s", constraintExpr_print (e)));
2043
2044   switch (constraintTerm_getKind(t))
2045     {
2046     case CTT_EXPR:
2047       DPRINTF((message ("%q @ %q ", constraintTerm_unparse(t),
2048                         fileloc_unparse (constraintTerm_getFileloc(t) ) ) ));
2049       break;
2050     case CTT_INTLITERAL:
2051       DPRINTF((message (" %q ", constraintTerm_unparse (t)) ));
2052       break;
2053     case CTT_SREF:
2054       /* evans 2001-07-24: constants should use the original term */
2055       if (!constraintTerm_canGetValue (t))
2056         {
2057           DPRINTF ((message("Doing sRef_fixConstraintParam for %q ", 
2058                              constraintTerm_unparse (t) ) ));
2059           ret = sRef_fixConstraintParam (constraintTerm_getSRef(t), arglist);
2060           
2061           constraintExpr_free (e);
2062           
2063           DPRINTF (( message("After Doing sRef_fixConstraintParam constraintExpr is %q ", 
2064                              constraintExpr_print (ret) ) ));
2065           /*@-branchstate@*/
2066         } /*@=branchstate@*/
2067
2068       break;
2069     default:
2070       BADEXIT;
2071     }
2072
2073   return ret;
2074   
2075 }
2076
2077
2078 #if 0
2079 bool constraintExpr_includesTerm (constraintExpr expr, constraintTerm term)
2080 {
2081   if (constraintTerm_hasTerm (expr->term, term) )
2082     return TRUE;
2083
2084   if ((expr->expr) != NULL)
2085     {
2086       return ( constraintExpr_includesTerm (expr->expr, term) );
2087     }
2088   return FALSE;
2089
2090 }
2091 #endif
2092
2093 /*drl added 6/11/01 */
2094 bool constraintExpr_isBinaryExpr (/*@observer@*/ constraintExpr c)
2095 {
2096
2097   llassert(constraintExpr_isDefined (c) );
2098
2099   if ( ! (constraintExpr_isDefined (c) ) )
2100     return FALSE;
2101   
2102   if (c->kind == binaryexpr)
2103     return TRUE;
2104
2105   else
2106     return FALSE;
2107 }
2108
2109 /*drl added 8/08/001 */
2110 bool constraintExpr_isTerm (/*@observer@*/ constraintExpr c) /*@*/
2111 {
2112   llassert(constraintExpr_isDefined (c) );
2113   
2114   if (c->kind == term)
2115     return TRUE;
2116
2117   else
2118     return FALSE;
2119 }
2120
2121 /*@observer@*/ /*@temp@*/ constraintTerm constraintExpr_getTerm ( /*@temp@*/ /*@observer@*/ constraintExpr c) /*@*/
2122 {
2123   constraintTerm term;
2124   
2125   llassert(constraintExpr_isDefined (c) );
2126   
2127   llassert(constraintExpr_isTerm(c) );
2128
2129   term = constraintExprData_termGetTerm(c->data);
2130
2131   return term;
2132 }
2133
2134 static void  binaryExpr_dump (/*@observer@*/ constraintExprData data,  FILE *f)
2135 {
2136   constraintExpr expr1;
2137   constraintExprBinaryOpKind binaryOp;
2138   constraintExpr expr2;
2139
2140
2141   binaryOp = constraintExprData_binaryExprGetOp (data);
2142
2143   fprintf(f, "%d\n", (int) binaryOp);
2144   
2145   expr1 = constraintExprData_binaryExprGetExpr1 (data);
2146   expr2 = constraintExprData_binaryExprGetExpr2 (data);
2147
2148   fprintf(f, "e1\n");
2149
2150   constraintExpr_dump(expr1, f);
2151
2152   fprintf(f, "e2\n");
2153   constraintExpr_dump(expr2, f);
2154 }
2155
2156
2157 static constraintExpr  binaryExpr_undump (FILE *f)
2158 {
2159   constraintExpr expr1;
2160   constraintExprBinaryOpKind binaryOp;
2161   constraintExpr expr2;
2162
2163   constraintExpr ret;
2164
2165   
2166
2167   char * str;
2168   char * os;
2169
2170   os = mstring_create (MAX_DUMP_LINE_LENGTH);
2171
2172   str = fgets(os, MAX_DUMP_LINE_LENGTH, f);
2173
2174   if (! mstring_isDefined(str) )
2175     {
2176       llfatalbug(message("Library file is corrupted") );
2177     }
2178   
2179   binaryOp = (constraintExprBinaryOpKind) reader_getInt(&str);
2180   
2181   str = fgets(os, MAX_DUMP_LINE_LENGTH, f);
2182
2183   if (! mstring_isDefined(str) )
2184     {
2185       llfatalbug(message("Library file is corrupted") );
2186     }
2187
2188   reader_checkChar (&str, 'e');
2189   reader_checkChar (&str, '1');
2190   
2191   expr1 = constraintExpr_undump (f);
2192
2193   str = fgets(os, MAX_DUMP_LINE_LENGTH, f);
2194
2195   reader_checkChar (&str, 'e');
2196   reader_checkChar (&str, '2');  
2197
2198   expr2 = constraintExpr_undump (f);
2199
2200   ret = constraintExpr_makeBinaryOpConstraintExpr (expr1, expr2);
2201   ret->data = constraintExprData_binaryExprSetOp(ret->data, binaryOp);
2202
2203   free(os);
2204   return ret;
2205 }
2206
2207
2208
2209 static void  unaryExpr_dump (/*@observer@*/ constraintExprData data,  FILE *f)
2210 {
2211
2212   constraintExpr expr;
2213   constraintExprUnaryOpKind unaryOp;
2214
2215   unaryOp = constraintExprData_unaryExprGetOp (data);
2216
2217   fprintf(f, "%d\n", (int) unaryOp);
2218   
2219   expr = constraintExprData_unaryExprGetExpr (data);
2220
2221   constraintExpr_dump(expr, f);  
2222 }
2223
2224 static  constraintExpr  unaryExpr_undump ( FILE *f)
2225 {
2226
2227   constraintExpr expr;
2228   constraintExprUnaryOpKind unaryOp;
2229   constraintExpr ret;
2230   
2231   char * str;
2232   char * os;
2233
2234   str = mstring_create (MAX_DUMP_LINE_LENGTH);
2235   os = str;
2236   str = fgets(os, MAX_DUMP_LINE_LENGTH, f);
2237
2238   if (! mstring_isDefined(str) )
2239     {
2240       llfatalbug(message("Library file is corrupted") );
2241     }
2242
2243   unaryOp = (constraintExprUnaryOpKind) reader_getInt(&str);
2244   
2245   expr = constraintExpr_undump (f);
2246
2247   ret = constraintExpr_makeUnaryOp (expr, unaryOp);
2248
2249   free(os);
2250   
2251   return ret;
2252 }
2253
2254 void  constraintExpr_dump (/*@observer@*/ constraintExpr expr,  FILE *f)
2255 {
2256   constraintExprKind kind;
2257   constraintTerm t;
2258   
2259
2260   llassert(constraintExpr_isDefined(expr) );
2261   
2262   DPRINTF((message("constraintExpr_dump:: dumping constraintExpr %s",
2263                    constraintExpr_unparse(expr)
2264                    ) ));
2265   
2266   kind = expr->kind;
2267   
2268   fprintf(f,"%d\n", (int) kind);
2269   
2270   switch (kind)
2271     {
2272     case term:
2273       t = constraintExprData_termGetTerm (expr->data);
2274       constraintTerm_dump (t, f);
2275       break;      
2276     case unaryExpr:
2277       unaryExpr_dump (expr->data, f);
2278       break;           
2279     case binaryexpr:
2280       binaryExpr_dump  (expr->data, f);
2281       break;
2282     }  
2283 }
2284
2285 /*@only@*/ constraintExpr  constraintExpr_undump (FILE *f)
2286 {
2287   constraintExprKind kind;
2288   constraintTerm t;
2289   constraintExpr ret;
2290   
2291   char * s;
2292   char * os;
2293   
2294   s = mstring_create (MAX_DUMP_LINE_LENGTH);
2295
2296   os = s;
2297   
2298   s = fgets(os, MAX_DUMP_LINE_LENGTH, f);
2299
2300   if (! mstring_isDefined(s) )
2301     {
2302       llfatalbug(message("Library file is corrupted") );
2303     }
2304
2305   kind = (constraintExprKind) reader_getInt(&s);
2306
2307   free (os);
2308   
2309   switch (kind)
2310     {
2311     case term:
2312       t = constraintTerm_undump (f);
2313       ret = constraintExpr_makeTerm(t);
2314       break;      
2315     case unaryExpr:
2316       ret = unaryExpr_undump (f);
2317       break;           
2318     case binaryexpr:
2319       ret = binaryExpr_undump  (f);
2320       break;
2321     }
2322
2323   return ret;
2324
2325 }
2326
2327 int constraintExpr_getDepth (constraintExpr ex)
2328 {
2329   int ret;
2330   
2331   constraintExprKind kind;
2332
2333   llassert (ex != NULL);
2334
2335   kind = ex->kind;
2336   
2337   switch (kind)
2338     {
2339     case term:
2340       ret = 1;
2341       break;
2342     case unaryExpr:
2343       ret =  constraintExpr_getDepth (constraintExprData_unaryExprGetExpr (ex->data) );
2344       ret++;
2345       
2346       break;
2347     case binaryexpr:
2348       ret = 0;
2349       ret = constraintExpr_getDepth (constraintExprData_binaryExprGetExpr1 (ex->data) );
2350
2351       ret++;
2352
2353       ret += constraintExpr_getDepth (constraintExprData_binaryExprGetExpr2 (ex->data) );
2354
2355       break;
2356     default:
2357       BADEXIT;
2358     }
2359
2360   return ret;
2361 }
2362
2363
2364 bool constraintExpr_canGetCType (constraintExpr e) /*@*/
2365 {
2366   if (constraintExpr_isUndefined(e))
2367     return FALSE;
2368   
2369   if (e->kind == term)
2370     {
2371       return TRUE;
2372     }
2373   else
2374     {
2375       DPRINTF (("constraintExpr_canGetCType: can't get type for %s", constraintExpr_unparse (e)));
2376       return FALSE;
2377     }
2378 }
2379
2380 ctype constraintExpr_getCType (constraintExpr e) /*@*/
2381 {
2382   constraintTerm t;
2383
2384   llassert (constraintExpr_isDefined (e));
2385   llassert (constraintExpr_canGetCType (e));
2386
2387   switch (e->kind)
2388     {
2389     case term:
2390       t = constraintExprData_termGetTerm (e->data);
2391       return (constraintTerm_getCType(t) );
2392       /* assume that a unary expression will be an int ... */
2393     case unaryExpr:
2394       return ctype_unknown; /* was ctype_signedintegral; */
2395       /* drl for just return type of first operand */
2396     case binaryexpr:
2397       return (constraintExpr_getCType (constraintExprData_binaryExprGetExpr1 (e->data)));
2398     default:
2399       BADEXIT;
2400     }
2401   BADEXIT;
2402 }
2403
2404 /* drl add 10-5-001 */
2405
2406 static bool constraintExpr_hasTypeChange (constraintExpr e)
2407 {
2408   llassert(constraintExpr_isDefined(e));
2409
2410   if (constraintExpr_isDefined((e)) && (e->ct == TRUE))
2411     {
2412       return TRUE;
2413     }
2414
2415   if (e->kind == unaryExpr)
2416     {
2417       if (constraintExprData_unaryExprGetOp (e->data) == MAXSET)
2418         {
2419           constraintExpr ce = constraintExprData_unaryExprGetExpr(e->data);
2420           DPRINTF (("Unary type change: [%x] %s", ce, constraintExpr_unparse (ce)));
2421           DPRINTF (("Types: %s / %s", ctype_unparse (constraintExpr_getCType (ce)),
2422                     ctype_unparse (constraintExpr_getOrigType (ce))));
2423           return (constraintExpr_hasTypeChange(ce));
2424         }
2425     }
2426   
2427   return FALSE;
2428 }
2429
2430 /* drl add 10-5-001 */
2431
2432 static ctype constraintExpr_getOrigType (constraintExpr e)
2433 {
2434   llassert (constraintExpr_isDefined (e));
2435   llassert (constraintExpr_hasTypeChange (e));
2436   
2437   if (e->ct == TRUE) 
2438     {
2439       return e->origType;
2440     }
2441
2442   if (e->kind == unaryExpr)
2443     {
2444       if (constraintExprData_unaryExprGetOp (e->data) == MAXSET)
2445         {
2446           constraintExpr ce = constraintExprData_unaryExprGetExpr (e->data);
2447           return (constraintExpr_getOrigType(ce));
2448         }
2449         
2450     }
2451
2452   BADEXIT;
2453
2454
2455 /*drl added these around 10/18/001*/
2456
2457 static /*@only@*/ constraintExpr constraintExpr_div (/*@only@*/ constraintExpr e, ctype tfrom, ctype tto, fileloc loc)
2458 {
2459   int sizefrom = ctype_getSize (tfrom);
2460   int sizeto = ctype_getSize (tto);
2461
2462   DPRINTF (("constraintExpr_div: %s", constraintExpr_unparse (e)));
2463   DPRINTF (("Types: %s / %s",
2464             ctype_unparse (tfrom),
2465             ctype_unparse (tto)));
2466   
2467   if (sizefrom == -1) {
2468     llbug (message ("constraintExpr_div: type size unknown: %s", ctype_unparse (tfrom)));
2469   }
2470
2471   if (sizeto == -1) {
2472     llbug (message ("constraintExpr_div: type size unknown: %s", ctype_unparse (tto)));
2473   }
2474
2475   if (sizeto == sizefrom) 
2476     {
2477       ; /* Sizes match, a-ok */
2478     }
2479   else
2480     {
2481       float scale = (float) sizefrom / (float) sizeto;
2482       constraintTerm ct;
2483       long val;
2484       float fnewval;
2485       long newval;
2486
2487       llassert (e->kind == term);
2488       ct = constraintExprData_termGetTerm (e->data);
2489       llassert (constraintTerm_canGetValue (ct));
2490       val = constraintTerm_getValue (ct);
2491
2492       DPRINTF (("Scaling constraints by: %ld * %f", val, scale));
2493
2494       // If scale * val is not an integer, give a warning
2495       fnewval = val * scale;
2496       newval = (long) fnewval;
2497
2498       DPRINTF (("Values: %f / %ld", fnewval, newval));
2499       if ((fnewval - (float) newval) > FLT_EPSILON) 
2500         {
2501           voptgenerror (FLG_ALLOCMISMATCH,
2502                         message ("Allocated memory is converted to type %s of (size %d), "
2503                                  "which is not divisible into original allocation of space for %d elements of type %s (size %d)",
2504                                  ctype_unparse (tto), sizeto,
2505                                  val, ctype_unparse (tfrom), sizefrom),
2506                         loc);
2507         }  
2508
2509       constraintTerm_setValue (ct, newval);
2510     }
2511
2512   DPRINTF (("After div: %s", constraintExpr_unparse (e)));
2513   return e;
2514 }
2515
2516
2517 /*@access exprNode@*/ 
2518 static /*@only@*/ constraintExpr constraintTerm_simpleDivTypeExprNode (/*@only@*/ constraintExpr e, ctype tfrom, ctype tto, fileloc loc)
2519 {
2520   exprData data;
2521   exprNode t1, t2, expr;
2522   lltok tok;
2523   constraintTerm t;
2524
2525   llassert (constraintExpr_isDefined(e) );
2526   
2527   DPRINTF (("constraintTerm_simpleDivTypeExprNode e=%s [%s => %s]", constraintExpr_print(e), 
2528             ctype_unparse(tfrom), ctype_unparse (tto)));
2529   
2530   t = constraintExprData_termGetTerm (e->data);
2531   
2532   expr = constraintTerm_getExprNode (t);
2533
2534   llassert (constraintExpr_isDefined(e));
2535   llassert (exprNode_isDefined(expr));
2536   
2537   if (expr->kind == XPR_OP)
2538     {
2539       data = expr->edata;
2540       
2541       t1 = exprData_getOpA (data);
2542       t2 = exprData_getOpB (data);
2543       tok = exprData_getOpTok (data);
2544
2545       if (lltok_isMult (tok))
2546         {
2547           llassert (exprNode_isDefined(t1) && exprNode_isDefined(t2) );
2548           /*drl 3/2/2003 we know this from the fact that it's a
2549             multiplication operation...*/
2550           
2551           if  ((t1->kind == XPR_SIZEOF) || (t1->kind == XPR_SIZEOFT))
2552             {
2553               ctype ct2;
2554               
2555               if (t1->kind == XPR_SIZEOFT)
2556                 {
2557                   ct2 = qtype_getType (exprData_getType (t1->edata));
2558                 }
2559               else
2560                 {
2561                   exprNode tempE = exprData_getSingle (t1->edata);
2562                   ct2 = exprNode_getType (tempE); 
2563                 }
2564
2565               if (ctype_match (ctype_makePointer(ct2), tfrom)) //!
2566                 {
2567                   /* this is a bit sloopy but ... */
2568                   constraintExpr_free(e);
2569                   return constraintExpr_makeExprNode (t2);
2570                 }
2571               else
2572                 {
2573                   /* nothing was here */
2574                   DPRINTF (("MISMATCHING TYPES!"));
2575                 }
2576             }
2577           else if ((t2->kind == XPR_SIZEOF) || (t2->kind == XPR_SIZEOFT))
2578             {
2579               ctype ct2;
2580               
2581               if (t2->kind == XPR_SIZEOFT)
2582                 {
2583                   ct2 = qtype_getType (exprData_getType (t2->edata));
2584                 }
2585               else
2586                 {
2587                   exprNode exprTemp;
2588                   exprData eDTemp;
2589                   
2590                   exprTemp = exprData_getSingle (t2->edata);
2591
2592                   llassert (exprNode_isDefined (exprTemp));
2593                   eDTemp = exprTemp->edata;
2594                   
2595                   ct2 = qtype_getType (exprData_getType(eDTemp ));
2596                   
2597                 }
2598
2599               if (ctype_match (ctype_makePointer (ct2), tfrom))
2600                 {
2601                   /*a bit of a sloopy way to do this but... */
2602                   constraintExpr_free(e);
2603                   return constraintExpr_makeExprNode (t1);
2604                 }
2605             }
2606           else
2607             {
2608               DPRINTF (("NOT A SIZEOF!"));
2609               /*empty*/
2610             }
2611           
2612         }
2613     }
2614
2615   return (constraintExpr_div (e, tfrom, tto, loc));
2616 }
2617 /*@noaccess exprNode@*/ 
2618
2619 static /*@only@*/ constraintExpr simpleDivType (/*@only@*/ constraintExpr e, ctype tfrom, ctype tto, fileloc loc)
2620 {
2621   DPRINTF (("simpleDiv got %s", constraintExpr_unparse(e)));
2622   DPRINTF (("Types: %s / %s",
2623             ctype_unparse (tfrom),
2624             ctype_unparse (tto)));
2625
2626   llassert (constraintExpr_isDefined(e));
2627   
2628   switch (e->kind)
2629     {
2630     case term:
2631       {
2632         constraintTerm t = constraintExprData_termGetTerm (e->data);
2633
2634         DPRINTF (("Term: %s", constraintTerm_unparse (t)));
2635
2636         if (constraintTerm_isExprNode (t))
2637           {
2638             return constraintTerm_simpleDivTypeExprNode (e, tfrom, tto, loc);
2639             
2640             /* search for * size of ct and remove */
2641           }
2642         DPRINTF (("Here: %s / %s -> %s", constraintExpr_unparse (e), ctype_unparse (tfrom), ctype_unparse (tto)));
2643         return constraintExpr_div (e, tfrom, tto, loc);
2644       }
2645       
2646     case binaryexpr:
2647       {
2648         constraintExpr temp;
2649         
2650         temp = constraintExprData_binaryExprGetExpr1 (e->data);
2651         temp = constraintExpr_copy(temp);
2652         temp = simpleDivType (temp, tfrom, tto, loc);
2653         
2654         e->data = constraintExprData_binaryExprSetExpr1 (e->data, temp);
2655         
2656         temp = constraintExprData_binaryExprGetExpr2 (e->data);
2657         temp = constraintExpr_copy(temp);
2658         temp = simpleDivType (temp, tfrom, tto, loc);
2659         e->data = constraintExprData_binaryExprSetExpr2 (e->data, temp);
2660
2661         DPRINTF (("simpleDiv binaryexpr returning %s ", constraintExpr_unparse(e)));
2662         return e;
2663       }
2664     case unaryExpr:
2665       {
2666         return constraintExpr_div (e, tfrom, tto, loc);
2667       }
2668
2669     default:
2670       BADEXIT;
2671     }
2672 }
2673
2674 static /*@only@*/ constraintExpr constraintExpr_adjustMaxSetForCast (/*@only@*/ constraintExpr e, ctype tfrom, 
2675                                                                      ctype tto, fileloc loc)
2676 {
2677   DPRINTF (("constraintExpr_adjustMaxSetForCast got %s [%s => %s]", constraintExpr_unparse(e), 
2678             ctype_unparse (tfrom), ctype_unparse (tto)));
2679   
2680   e = constraintExpr_makeIncConstraintExpr (e);
2681   e = constraintExpr_simplify (e);
2682   e = simpleDivType (e, tfrom, tto, loc);
2683   e = constraintExpr_makeDecConstraintExpr (e);
2684   e = constraintExpr_simplify (e);
2685   
2686   DPRINTF (("constraintExpr_adjustMaxSetForCast returning %s ", constraintExpr_unparse(e)));
2687   return e;
2688 }
2689
2690
2691 bool constraintExpr_isConstantOnly (constraintExpr e)
2692 {
2693   DPRINTF (("constraintExpr_isConstantOnly %s ", constraintExpr_unparse(e)));
2694   llassert (constraintExpr_isDefined(e));
2695
2696   switch (e->kind)
2697     {
2698     case term:
2699       {
2700         constraintTerm t = constraintExprData_termGetTerm(e->data);
2701         
2702         if (constraintTerm_isConstantOnly (t))
2703           {
2704             return TRUE;
2705           }
2706         else
2707           {
2708             return FALSE;
2709           }
2710       }
2711       
2712     case binaryexpr:
2713       {
2714         constraintExpr temp1 = constraintExprData_binaryExprGetExpr1 (e->data);
2715         constraintExpr temp2 = constraintExprData_binaryExprGetExpr2 (e->data);
2716         
2717         if (constraintExpr_isConstantOnly(temp1) &&
2718             constraintExpr_isConstantOnly(temp2) )
2719           {
2720             return TRUE;
2721           }
2722         else
2723           {
2724             return FALSE;
2725           }
2726       }
2727       
2728     case unaryExpr:
2729       {
2730         constraintExpr temp;
2731         
2732         temp = constraintExprData_unaryExprGetExpr (e->data );
2733
2734         if (constraintExpr_isConstantOnly(temp) )
2735           {
2736             return TRUE;
2737           }
2738         else
2739           {
2740             return FALSE;
2741           }
2742       }
2743     default:
2744       BADEXIT;
2745     }
2746 }
2747
This page took 0.310313 seconds and 5 git commands to generate.