]> andersk Git - splint.git/blob - src/constraintExpr.c
Fixed problem with global struct assignments.
[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, sRef s, ctype ct)
1959 {
1960   constraintTerm t;
1961
1962   constraintExprData data = e->data;
1963   
1964   constraintExprKind kind = e->kind;
1965   
1966   constraintExpr ret;
1967
1968   llassert(kind == term);
1969
1970   t = constraintExprData_termGetTerm (data);
1971   llassert (constraintTerm_isDefined(t) );
1972
1973   ret = e;
1974
1975   DPRINTF (("Fixing: %s", constraintExpr_print (e)));
1976
1977   switch (constraintTerm_getKind(t))
1978     {
1979     case CTT_EXPR:
1980       DPRINTF((message ("%q @ %q ", constraintTerm_unparse(t),
1981                         fileloc_unparse (constraintTerm_getFileloc(t) ) ) ));
1982       break;
1983     case CTT_INTLITERAL:
1984       DPRINTF((message (" %q ", constraintTerm_unparse (t)) ));
1985       break;
1986       
1987     case CTT_SREF:
1988       / * evans 2001-07-24: constants should use the original term * /
1989       if (!constraintTerm_canGetValue (t))
1990         {
1991           sRef snew;
1992           DPRINTF ((message("Doing sRef_fixInvarConstraint for %q ", 
1993                              constraintTerm_unparse (t) ) ));
1994
1995           snew = fixSref (ct, s, constraintTerm_getSRef(t));
1996
1997           ret = constraintExpr_makeTermsRef(snew);
1998           
1999           constraintExpr_free (e);
2000           
2001           DPRINTF (( message("After Doing sRef_fixConstraintParam constraintExpr is %q ", 
2002                              constraintExpr_print (ret) ) ));
2003           / *@-branchstate@* /
2004         } / *@=branchstate@* /
2005
2006       break;
2007     default:
2008       BADEXIT;
2009     }
2010
2011   return ret;
2012   
2013 }
2014 #endif
2015  
2016 /*drl moved from constriantTerm.c 5/20/001*/
2017 /*@only@*/ static constraintExpr 
2018 doSRefFixConstraintParamTerm (/*@only@*/ constraintExpr e, /*@observer@*/ /*@temp@*/ exprNodeList arglist)
2019 {
2020   constraintTerm t;
2021
2022   constraintExprData data;
2023   
2024   constraintExprKind kind;
2025   
2026   constraintExpr ret;
2027
2028
2029   llassert(constraintExpr_isDefined (e) );
2030
2031   data = e->data;
2032   
2033   kind = e->kind;
2034
2035   
2036
2037   llassert(kind == term);
2038
2039   t = constraintExprData_termGetTerm (data);
2040   llassert (constraintTerm_isDefined(t) );
2041
2042   ret = e;
2043
2044   DPRINTF (("Fixing: %s", constraintExpr_print (e)));
2045
2046   switch (constraintTerm_getKind(t))
2047     {
2048     case CTT_EXPR:
2049       DPRINTF((message ("%q @ %q ", constraintTerm_unparse(t),
2050                         fileloc_unparse (constraintTerm_getFileloc(t) ) ) ));
2051       break;
2052     case CTT_INTLITERAL:
2053       DPRINTF((message (" %q ", constraintTerm_unparse (t)) ));
2054       break;
2055     case CTT_SREF:
2056       /* evans 2001-07-24: constants should use the original term */
2057       if (!constraintTerm_canGetValue (t))
2058         {
2059           DPRINTF ((message("Doing sRef_fixConstraintParam for %q ", 
2060                              constraintTerm_unparse (t) ) ));
2061           ret = sRef_fixConstraintParam (constraintTerm_getSRef(t), arglist);
2062           
2063           constraintExpr_free (e);
2064           
2065           DPRINTF (( message("After Doing sRef_fixConstraintParam constraintExpr is %q ", 
2066                              constraintExpr_print (ret) ) ));
2067           /*@-branchstate@*/
2068         } /*@=branchstate@*/
2069
2070       break;
2071     default:
2072       BADEXIT;
2073     }
2074
2075   return ret;
2076   
2077 }
2078
2079
2080 #if 0
2081 bool constraintExpr_includesTerm (constraintExpr expr, constraintTerm term)
2082 {
2083   if (constraintTerm_hasTerm (expr->term, term) )
2084     return TRUE;
2085
2086   if ((expr->expr) != NULL)
2087     {
2088       return ( constraintExpr_includesTerm (expr->expr, term) );
2089     }
2090   return FALSE;
2091
2092 }
2093 #endif
2094
2095 /*drl added 6/11/01 */
2096 bool constraintExpr_isBinaryExpr (/*@observer@*/ constraintExpr c)
2097 {
2098
2099   llassert(constraintExpr_isDefined (c) );
2100
2101   if ( ! (constraintExpr_isDefined (c) ) )
2102     return FALSE;
2103   
2104   if (c->kind == binaryexpr)
2105     return TRUE;
2106
2107   else
2108     return FALSE;
2109 }
2110
2111 /*drl added 8/08/001 */
2112 bool constraintExpr_isTerm (/*@observer@*/ constraintExpr c) /*@*/
2113 {
2114   llassert(constraintExpr_isDefined (c) );
2115   
2116   if (c->kind == term)
2117     return TRUE;
2118
2119   else
2120     return FALSE;
2121 }
2122
2123 /*@observer@*/ /*@temp@*/ constraintTerm constraintExpr_getTerm ( /*@temp@*/ /*@observer@*/ constraintExpr c) /*@*/
2124 {
2125   constraintTerm term;
2126   
2127   llassert(constraintExpr_isDefined (c) );
2128   
2129   llassert(constraintExpr_isTerm(c) );
2130
2131   term = constraintExprData_termGetTerm(c->data);
2132
2133   return term;
2134 }
2135
2136 static void  binaryExpr_dump (/*@observer@*/ constraintExprData data,  FILE *f)
2137 {
2138   constraintExpr expr1;
2139   constraintExprBinaryOpKind binaryOp;
2140   constraintExpr expr2;
2141
2142
2143   binaryOp = constraintExprData_binaryExprGetOp (data);
2144
2145   fprintf(f, "%d\n", (int) binaryOp);
2146   
2147   expr1 = constraintExprData_binaryExprGetExpr1 (data);
2148   expr2 = constraintExprData_binaryExprGetExpr2 (data);
2149
2150   fprintf(f, "e1\n");
2151
2152   constraintExpr_dump(expr1, f);
2153
2154   fprintf(f, "e2\n");
2155   constraintExpr_dump(expr2, f);
2156 }
2157
2158
2159 static constraintExpr  binaryExpr_undump (FILE *f)
2160 {
2161   constraintExpr expr1;
2162   constraintExprBinaryOpKind binaryOp;
2163   constraintExpr expr2;
2164
2165   constraintExpr ret;
2166
2167   
2168
2169   char * str;
2170   char * os;
2171
2172   os = mstring_create (MAX_DUMP_LINE_LENGTH);
2173
2174   str = fgets(os, MAX_DUMP_LINE_LENGTH, f);
2175
2176   if (! mstring_isDefined(str) )
2177     {
2178       llfatalbug(message("Library file is corrupted") );
2179     }
2180   
2181   binaryOp = (constraintExprBinaryOpKind) reader_getInt(&str);
2182   
2183   str = fgets(os, MAX_DUMP_LINE_LENGTH, f);
2184
2185   if (! mstring_isDefined(str) )
2186     {
2187       llfatalbug(message("Library file is corrupted") );
2188     }
2189
2190   reader_checkChar (&str, 'e');
2191   reader_checkChar (&str, '1');
2192   
2193   expr1 = constraintExpr_undump (f);
2194
2195   str = fgets(os, MAX_DUMP_LINE_LENGTH, f);
2196
2197   reader_checkChar (&str, 'e');
2198   reader_checkChar (&str, '2');  
2199
2200   expr2 = constraintExpr_undump (f);
2201
2202   ret = constraintExpr_makeBinaryOpConstraintExpr (expr1, expr2);
2203   ret->data = constraintExprData_binaryExprSetOp(ret->data, binaryOp);
2204
2205   free(os);
2206   return ret;
2207 }
2208
2209
2210
2211 static void  unaryExpr_dump (/*@observer@*/ constraintExprData data,  FILE *f)
2212 {
2213
2214   constraintExpr expr;
2215   constraintExprUnaryOpKind unaryOp;
2216
2217   unaryOp = constraintExprData_unaryExprGetOp (data);
2218
2219   fprintf(f, "%d\n", (int) unaryOp);
2220   
2221   expr = constraintExprData_unaryExprGetExpr (data);
2222
2223   constraintExpr_dump(expr, f);  
2224 }
2225
2226 static  constraintExpr  unaryExpr_undump ( FILE *f)
2227 {
2228
2229   constraintExpr expr;
2230   constraintExprUnaryOpKind unaryOp;
2231   constraintExpr ret;
2232   
2233   char * str;
2234   char * os;
2235
2236   str = mstring_create (MAX_DUMP_LINE_LENGTH);
2237   os = str;
2238   str = fgets(os, MAX_DUMP_LINE_LENGTH, f);
2239
2240   if (! mstring_isDefined(str) )
2241     {
2242       llfatalbug(message("Library file is corrupted") );
2243     }
2244
2245   unaryOp = (constraintExprUnaryOpKind) reader_getInt(&str);
2246   
2247   expr = constraintExpr_undump (f);
2248
2249   ret = constraintExpr_makeUnaryOp (expr, unaryOp);
2250
2251   free(os);
2252   
2253   return ret;
2254 }
2255
2256 void  constraintExpr_dump (/*@observer@*/ constraintExpr expr,  FILE *f)
2257 {
2258   constraintExprKind kind;
2259   constraintTerm t;
2260   
2261
2262   llassert(constraintExpr_isDefined(expr) );
2263   
2264   DPRINTF((message("constraintExpr_dump:: dumping constraintExpr %s",
2265                    constraintExpr_unparse(expr)
2266                    ) ));
2267   
2268   kind = expr->kind;
2269   
2270   fprintf(f,"%d\n", (int) kind);
2271   
2272   switch (kind)
2273     {
2274     case term:
2275       t = constraintExprData_termGetTerm (expr->data);
2276       constraintTerm_dump (t, f);
2277       break;      
2278     case unaryExpr:
2279       unaryExpr_dump (expr->data, f);
2280       break;           
2281     case binaryexpr:
2282       binaryExpr_dump  (expr->data, f);
2283       break;
2284     }  
2285 }
2286
2287 /*@only@*/ constraintExpr  constraintExpr_undump (FILE *f)
2288 {
2289   constraintExprKind kind;
2290   constraintTerm t;
2291   constraintExpr ret;
2292   
2293   char * s;
2294   char * os;
2295   
2296   s = mstring_create (MAX_DUMP_LINE_LENGTH);
2297
2298   os = s;
2299   
2300   s = fgets(os, MAX_DUMP_LINE_LENGTH, f);
2301
2302   if (! mstring_isDefined(s) )
2303     {
2304       llfatalbug(message("Library file is corrupted") );
2305     }
2306
2307   kind = (constraintExprKind) reader_getInt(&s);
2308
2309   free (os);
2310   
2311   switch (kind)
2312     {
2313     case term:
2314       t = constraintTerm_undump (f);
2315       ret = constraintExpr_makeTerm(t);
2316       break;      
2317     case unaryExpr:
2318       ret = unaryExpr_undump (f);
2319       break;           
2320     case binaryexpr:
2321       ret = binaryExpr_undump  (f);
2322       break;
2323     }
2324
2325   return ret;
2326
2327 }
2328
2329 int constraintExpr_getDepth (constraintExpr ex)
2330 {
2331   int ret;
2332   
2333   constraintExprKind kind;
2334
2335   llassert (ex != NULL);
2336
2337   kind = ex->kind;
2338   
2339   switch (kind)
2340     {
2341     case term:
2342       ret = 1;
2343       break;
2344     case unaryExpr:
2345       ret =  constraintExpr_getDepth (constraintExprData_unaryExprGetExpr (ex->data) );
2346       ret++;
2347       
2348       break;
2349     case binaryexpr:
2350       ret = 0;
2351       ret = constraintExpr_getDepth (constraintExprData_binaryExprGetExpr1 (ex->data) );
2352
2353       ret++;
2354
2355       ret += constraintExpr_getDepth (constraintExprData_binaryExprGetExpr2 (ex->data) );
2356
2357       break;
2358     default:
2359       BADEXIT;
2360     }
2361
2362   return ret;
2363 }
2364
2365
2366 bool constraintExpr_canGetCType (constraintExpr e) /*@*/
2367 {
2368   if (constraintExpr_isUndefined(e))
2369     return FALSE;
2370   
2371   if (e->kind == term)
2372     {
2373       return TRUE;
2374     }
2375   else
2376     {
2377       DPRINTF (("constraintExpr_canGetCType: can't get type for %s", constraintExpr_unparse (e)));
2378       return FALSE;
2379     }
2380 }
2381
2382 ctype constraintExpr_getCType (constraintExpr e) /*@*/
2383 {
2384   constraintTerm t;
2385
2386   llassert (constraintExpr_isDefined (e));
2387   llassert (constraintExpr_canGetCType (e));
2388
2389   switch (e->kind)
2390     {
2391     case term:
2392       t = constraintExprData_termGetTerm (e->data);
2393       return (constraintTerm_getCType(t) );
2394       /* assume that a unary expression will be an int ... */
2395     case unaryExpr:
2396       return ctype_unknown; /* was ctype_signedintegral; */
2397       /* drl for just return type of first operand */
2398     case binaryexpr:
2399       return (constraintExpr_getCType (constraintExprData_binaryExprGetExpr1 (e->data)));
2400     default:
2401       BADEXIT;
2402     }
2403   BADEXIT;
2404 }
2405
2406 /* drl add 10-5-001 */
2407
2408 static bool constraintExpr_hasTypeChange (constraintExpr e)
2409 {
2410   llassert(constraintExpr_isDefined(e));
2411
2412   if (constraintExpr_isDefined((e)) && (e->ct == TRUE))
2413     {
2414       return TRUE;
2415     }
2416
2417   if (e->kind == unaryExpr)
2418     {
2419       if (constraintExprData_unaryExprGetOp (e->data) == MAXSET)
2420         {
2421           constraintExpr ce = constraintExprData_unaryExprGetExpr(e->data);
2422           DPRINTF (("Unary type change: [%x] %s", ce, constraintExpr_unparse (ce)));
2423           DPRINTF (("Types: %s / %s", ctype_unparse (constraintExpr_getCType (ce)),
2424                     ctype_unparse (constraintExpr_getOrigType (ce))));
2425           return (constraintExpr_hasTypeChange(ce));
2426         }
2427     }
2428   
2429   return FALSE;
2430 }
2431
2432 /* drl add 10-5-001 */
2433
2434 static ctype constraintExpr_getOrigType (constraintExpr e)
2435 {
2436   llassert (constraintExpr_isDefined (e));
2437   llassert (constraintExpr_hasTypeChange (e));
2438   
2439   if (e->ct == TRUE) 
2440     {
2441       return e->origType;
2442     }
2443
2444   if (e->kind == unaryExpr)
2445     {
2446       if (constraintExprData_unaryExprGetOp (e->data) == MAXSET)
2447         {
2448           constraintExpr ce = constraintExprData_unaryExprGetExpr (e->data);
2449           return (constraintExpr_getOrigType(ce));
2450         }
2451         
2452     }
2453
2454   BADEXIT;
2455
2456
2457 /*drl added these around 10/18/001*/
2458
2459 static /*@only@*/ constraintExpr 
2460 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       DPRINTF (("Sizes match: %d / %d", sizeto, sizefrom));
2481       ; /* Sizes match, a-ok */
2482     }
2483   else
2484     {
2485       float scale = (float) sizefrom / (float) sizeto;
2486       constraintTerm ct;
2487       long val;
2488       float fnewval;
2489       long newval;
2490
2491       llassert (e != NULL);
2492       llassert (e->kind == term);
2493       ct = constraintExprData_termGetTerm (e->data);
2494       DPRINTF (("constraint: %s / %s", constraintExpr_unparse (e), constraintTerm_unparse (ct)));
2495       llassert (constraintTerm_canGetValue (ct));
2496       val = constraintTerm_getValue (ct);
2497
2498       DPRINTF (("Scaling constraints by: %ld * %f", val, scale));
2499
2500       fnewval = ((float) val) * scale;
2501       newval = (long) fnewval;
2502
2503       DPRINTF (("Values: %f / %ld", fnewval, newval));
2504
2505       if ((fnewval - (float) newval) > FLT_EPSILON) 
2506         {
2507           voptgenerror (FLG_ALLOCMISMATCH,
2508                         message ("Allocated memory is converted to type %s of (size %d), "
2509                                  "which is not divisible into original allocation of space "
2510                                  "for %d elements of type %s (size %d)",
2511                                  ctype_unparse (tto), sizeto,
2512                                  long_toInt (val), ctype_unparse (tfrom), sizefrom),
2513                         loc);
2514         }  
2515
2516       constraintTerm_setValue (ct, newval);
2517     }
2518
2519   DPRINTF (("After div: %s", constraintExpr_unparse (e)));
2520   return e;
2521 }
2522
2523
2524 /*@access exprNode@*/ 
2525 static /*@only@*/ constraintExpr 
2526 constraintTerm_simpleDivTypeExprNode (/*@only@*/ constraintExpr e, ctype tfrom, ctype tto, fileloc loc)
2527 {
2528   exprData data;
2529   exprNode t1, t2, expr;
2530   lltok tok;
2531   constraintTerm t;
2532
2533   llassert (constraintExpr_isDefined(e) );
2534   
2535   DPRINTF (("constraintTerm_simpleDivTypeExprNode e=%s [%s => %s]", constraintExpr_print(e), 
2536             ctype_unparse(tfrom), ctype_unparse (tto)));
2537   
2538   t = constraintExprData_termGetTerm (e->data);
2539   
2540   expr = constraintTerm_getExprNode (t);
2541
2542   llassert (constraintExpr_isDefined(e));
2543   llassert (exprNode_isDefined(expr));
2544   
2545   if (expr->kind == XPR_OP)
2546     {
2547       data = expr->edata;
2548       
2549       t1 = exprData_getOpA (data);
2550       t2 = exprData_getOpB (data);
2551       tok = exprData_getOpTok (data);
2552
2553       if (lltok_isMult (tok))
2554         {
2555           /*
2556           ** If the sizeof is first, flip them.
2557           */
2558
2559           llassert (exprNode_isDefined(t1) && exprNode_isDefined(t2));
2560
2561           if (t2->kind == XPR_SIZEOF || t2->kind == XPR_SIZEOFT) 
2562             {
2563               exprNode tmp = t1;
2564               t1 = t2;
2565               t2 = tmp;
2566             }
2567           
2568           /*drl 3/2/2003 we know this from the fact that it's a
2569             multiplication operation...*/
2570           
2571           if (t1->kind == XPR_SIZEOF || t1->kind == XPR_SIZEOFT)
2572             {
2573               ctype multype;
2574               
2575               if (t1->kind == XPR_SIZEOFT)
2576                 {
2577                   multype = qtype_getType (exprData_getType (t1->edata));
2578                 }
2579               else
2580                 {
2581                   exprNode tempE = exprData_getSingle (t1->edata);
2582                   multype = exprNode_getType (tempE); 
2583                 }
2584
2585               DPRINTF (("Here we go sizeof: %s / %s / %s",
2586                         ctype_unparse (multype), ctype_unparse (tfrom), ctype_unparse (tto)));
2587               llassert (ctype_isPointer (tfrom));
2588
2589               if (ctype_almostEqual (ctype_makePointer (multype), tto))
2590                 {
2591                   /* this is a bit sloopy but ... */
2592                   constraintExpr_free (e);
2593                   DPRINTF (("Sizeof types match okay!"));
2594                   return constraintExpr_makeExprNode (t2);
2595                 }
2596               else
2597                 {
2598                   int sizemul = ctype_getSize (multype);
2599                   ctype tobase = ctype_baseArrayPtr (tto);
2600                   int sizeto = ctype_getSize (tobase);
2601
2602                   DPRINTF (("Types: %s / %s / %s",
2603                             ctype_unparse (tfrom), ctype_unparse (tto), ctype_unparse (multype)));
2604
2605                   voptgenerror (FLG_ALLOCMISMATCH,
2606                                 message ("Allocated memory is used as a different type (%s) from the sizeof type (%s)",
2607                                          ctype_unparse (tobase), ctype_unparse (multype)),
2608                                 loc);
2609                   
2610                   if (sizemul == sizeto) 
2611                     {
2612                       constraintExpr_free (e);
2613                       DPRINTF (("Sizeof types match okay!"));
2614                       return constraintExpr_makeExprNode (t2);
2615                     }
2616                   else
2617                     {
2618                       /* nothing was here */
2619                       DPRINTF (("MISMATCHING TYPES!"));
2620                       return (constraintExpr_div (constraintExpr_makeExprNode (t2), multype, tto, loc));
2621                     }
2622                 }
2623             }
2624           else
2625             {
2626               DPRINTF (("NOT A SIZEOF!"));
2627               /* empty */
2628             }
2629         }
2630       else 
2631         {
2632           DPRINTF (("Not a mult: %s", constraintExpr_unparse (e)));
2633         }
2634     }
2635
2636   return (constraintExpr_div (e, tfrom, tto, loc));
2637 }
2638 /*@noaccess exprNode@*/ 
2639
2640 static /*@only@*/ constraintExpr simpleDivType (/*@only@*/ constraintExpr e, ctype tfrom, ctype tto, fileloc loc)
2641 {
2642   DPRINTF (("simpleDiv got %s", constraintExpr_unparse(e)));
2643   DPRINTF (("Types: %s / %s",
2644             ctype_unparse (tfrom),
2645             ctype_unparse (tto)));
2646
2647   llassert (constraintExpr_isDefined(e));
2648   
2649   switch (e->kind)
2650     {
2651     case term:
2652       {
2653         constraintTerm t = constraintExprData_termGetTerm (e->data);
2654
2655         DPRINTF (("Term: %s", constraintTerm_unparse (t)));
2656
2657         if (constraintTerm_isExprNode (t))
2658           {
2659             return constraintTerm_simpleDivTypeExprNode (e, tfrom, tto, loc);
2660             
2661             /* search for * size of ct and remove */
2662           }
2663         DPRINTF (("Here: %s / %s -> %s", constraintExpr_unparse (e), ctype_unparse (tfrom), ctype_unparse (tto)));
2664         return constraintExpr_div (e, tfrom, tto, loc);
2665       }
2666       
2667     case binaryexpr:
2668       {
2669         constraintExpr temp;
2670         
2671         temp = constraintExprData_binaryExprGetExpr1 (e->data);
2672         temp = constraintExpr_copy(temp);
2673         temp = simpleDivType (temp, tfrom, tto, loc);
2674         
2675         e->data = constraintExprData_binaryExprSetExpr1 (e->data, temp);
2676         
2677         temp = constraintExprData_binaryExprGetExpr2 (e->data);
2678         temp = constraintExpr_copy(temp);
2679         temp = simpleDivType (temp, tfrom, tto, loc);
2680         e->data = constraintExprData_binaryExprSetExpr2 (e->data, temp);
2681
2682         DPRINTF (("simpleDiv binaryexpr returning %s ", constraintExpr_unparse(e)));
2683         return e;
2684       }
2685     case unaryExpr:
2686       {
2687         return constraintExpr_div (e, tfrom, tto, loc);
2688       }
2689
2690     default:
2691       BADEXIT;
2692     }
2693 }
2694
2695 static /*@only@*/ constraintExpr constraintExpr_adjustMaxSetForCast (/*@only@*/ constraintExpr e, ctype tfrom, 
2696                                                                      ctype tto, fileloc loc)
2697 {
2698   DPRINTF (("constraintExpr_adjustMaxSetForCast got %s [%s => %s]", constraintExpr_unparse(e), 
2699             ctype_unparse (tfrom), ctype_unparse (tto)));
2700   
2701   e = constraintExpr_makeIncConstraintExpr (e);
2702   e = constraintExpr_simplify (e);
2703   e = simpleDivType (e, tfrom, tto, loc);
2704   e = constraintExpr_makeDecConstraintExpr (e);
2705   e = constraintExpr_simplify (e);
2706   
2707   DPRINTF (("constraintExpr_adjustMaxSetForCast returning %s ", constraintExpr_unparse(e)));
2708   return e;
2709 }
2710
2711
2712 bool constraintExpr_isConstantOnly (constraintExpr e)
2713 {
2714   DPRINTF (("constraintExpr_isConstantOnly %s ", constraintExpr_unparse(e)));
2715   llassert (constraintExpr_isDefined(e));
2716
2717   switch (e->kind)
2718     {
2719     case term:
2720       {
2721         constraintTerm t = constraintExprData_termGetTerm(e->data);
2722         
2723         if (constraintTerm_isConstantOnly (t))
2724           {
2725             return TRUE;
2726           }
2727         else
2728           {
2729             return FALSE;
2730           }
2731       }
2732       
2733     case binaryexpr:
2734       {
2735         constraintExpr temp1 = constraintExprData_binaryExprGetExpr1 (e->data);
2736         constraintExpr temp2 = constraintExprData_binaryExprGetExpr2 (e->data);
2737         
2738         if (constraintExpr_isConstantOnly(temp1) &&
2739             constraintExpr_isConstantOnly(temp2) )
2740           {
2741             return TRUE;
2742           }
2743         else
2744           {
2745             return FALSE;
2746           }
2747       }
2748       
2749     case unaryExpr:
2750       {
2751         constraintExpr temp;
2752         
2753         temp = constraintExprData_unaryExprGetExpr (e->data );
2754
2755         if (constraintExpr_isConstantOnly(temp) )
2756           {
2757             return TRUE;
2758           }
2759         else
2760           {
2761             return FALSE;
2762           }
2763       }
2764     default:
2765       BADEXIT;
2766     }
2767 }
2768
This page took 0.260163 seconds and 5 git commands to generate.