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