]> andersk Git - splint.git/blob - src/constraintExpr.c
Fixed off by one bug involving arrays initialized with a block of values.
[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 handle var [] = { , , };
1435       ** type syntax  I don't think this is sound but it should be good
1436       ** enough.  The C standard 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           /* -- drl 12/08/2003 : decrementing to fix off by one error */
1448
1449           len--;
1450
1451           temp = constraintExpr_makeIntLiteral (len );
1452           
1453           constraintExpr_free(c);
1454           DPRINTF(( message("Changed to %q", constraintExpr_print(temp)
1455                             ) ));
1456           constraintExpr_free(exp);
1457           return temp;
1458         }
1459       
1460       constraintExpr_free(exp);
1461       return c;
1462     }
1463   
1464   if (exp->kind != binaryexpr)
1465     {
1466       constraintExpr_free(exp);
1467       return c;
1468     }
1469   
1470   if (constraintExprData_binaryExprGetOp (exp->data) == BINARYOP_PLUS  )
1471     {
1472  
1473       /* if (constraintExpr_canGetValue (constraintExprData_binaryExprGetExpr2 (exp->data) ) ) */
1474         {
1475         
1476           constraintExpr  temp, temp2;
1477
1478           DPRINTF ((message ("Doing fancy simplification") ) );
1479
1480           temp = constraintExprData_binaryExprGetExpr2 (exp->data);
1481
1482           temp2 = constraintExprData_binaryExprGetExpr1 (exp->data);
1483
1484           temp2 = constraintExpr_copy(temp2);
1485           c->data = constraintExprData_unaryExprSetExpr (c->data, temp2);
1486           
1487           
1488           temp = constraintExpr_copy (temp);
1489
1490           c = constraintExpr_makeSubtractExpr (c, temp);
1491
1492           DPRINTF ((message ("Done fancy simplification:%s", constraintExpr_unparse (c) ) ) );
1493         }
1494     }
1495   
1496   DPRINTF ((message ("constraintExpr_simplifyUnaryExpr: Done simplification:%s", constraintExpr_unparse (c) ) ) );
1497
1498   constraintExpr_free(exp);
1499   return c;
1500 }
1501
1502
1503 /*@only@*/ constraintExpr constraintExpr_simplify (/*@only@*/ constraintExpr c)
1504 {
1505   constraintExprKind kind;
1506   constraintExpr ret;
1507   constraintTerm t;
1508   
1509   DPRINTF ((message ("Doing constraintExpr_simplify:%s", constraintExpr_unparse (c) ) ) );  
1510   
1511
1512   
1513   llassert ( constraintExpr_isDefined (c) );
1514   if (constraintExpr_isUndefined (c) )
1515     {
1516       return constraintExpr_undefined;
1517     }
1518   
1519   ret =  constraintExpr_copy(c);
1520   llassert(constraintExpr_isDefined (ret) );
1521            
1522   constraintExpr_free(c);
1523
1524   ret = constraintExpr_simplifyChildren (ret);
1525
1526   ret = constraintExpr_combineConstants (ret);
1527   
1528   ret = constraintExpr_simplifyChildren (ret);
1529   
1530
1531   kind = ret->kind;
1532   
1533   switch (kind)
1534     {
1535     case term:
1536       t = constraintExprData_termGetTerm (ret->data);
1537       t = constraintTerm_copy(t);
1538       t = constraintTerm_simplify (t);
1539       ret->data = constraintExprData_termSetTerm (ret->data, t);
1540       break;      
1541     case unaryExpr:
1542       ret = constraintExpr_simplifyunaryExpr (ret);
1543       break;           
1544     case binaryexpr:
1545       ret = constraintExpr_simplifybinaryExpr (ret);      
1546       break;
1547     default:
1548       llassert(FALSE);
1549     }    
1550   
1551   DPRINTF ((message ("constraintExpr_simplify returning :%s", constraintExpr_unparse (ret) ) ) );  
1552   return ret;
1553   
1554 }
1555
1556 /*@only@*/
1557 cstring constraintExpr_unparse (/*@temp@*/ constraintExpr ex) /*@*/
1558 {
1559   cstring st;
1560   constraintExprKind kind;
1561
1562   llassert (ex != NULL);
1563
1564   kind = ex->kind;
1565   
1566   switch (kind)
1567     {
1568     case term:
1569       if (context_getFlag (FLG_PARENCONSTRAINT) )
1570         {
1571           st = message ("(%q) ", constraintTerm_unparse (constraintExprData_termGetTerm (ex->data)));
1572         }
1573       else
1574         {
1575           st = message ("%q", constraintTerm_unparse (constraintExprData_termGetTerm (ex->data)));
1576         }
1577       break;
1578     case unaryExpr:
1579       st = message ("%q(%q)",
1580                     constraintExprUnaryOpKind_print (constraintExprData_unaryExprGetOp (ex->data) ),
1581                     constraintExpr_unparse (constraintExprData_unaryExprGetExpr (ex->data) )
1582                     );
1583       break;
1584     case binaryexpr:
1585       if (context_getFlag (FLG_PARENCONSTRAINT) )
1586         {
1587           st = message ("(%q) %q (%q)",
1588                         constraintExpr_unparse (constraintExprData_binaryExprGetExpr1 (ex->data) ),
1589                         constraintExprBinaryOpKind_print (constraintExprData_binaryExprGetOp (ex->data)),
1590                         constraintExpr_unparse (constraintExprData_binaryExprGetExpr2 (ex->data) )
1591                         );
1592         }
1593       else
1594         {
1595           st = message ("%q %q %q",
1596                         constraintExpr_unparse (constraintExprData_binaryExprGetExpr1 (ex->data)),
1597                         constraintExprBinaryOpKind_print (constraintExprData_binaryExprGetOp (ex->data)),
1598                         constraintExpr_unparse (constraintExprData_binaryExprGetExpr2 (ex->data))
1599                         );
1600         }
1601       
1602       break;
1603     default:
1604       llassert(FALSE);
1605       st = message ("error");
1606       
1607     }
1608
1609   DPRINTF((message ("constraintExpr_unparse: '%s'",st) ) );
1610   return st;
1611 }
1612
1613 constraintExpr constraintExpr_doSRefFixBaseParam (/*@returned@*/  constraintExpr expr, exprNodeList arglist)
1614 {
1615   constraintTerm Term;
1616   constraintExprKind kind;
1617   constraintExpr expr1, expr2;
1618   constraintExprData data;
1619   llassert (expr != NULL);
1620
1621   data = expr->data;
1622   
1623   kind = expr->kind;
1624   
1625   switch (kind)
1626     {
1627     case term:
1628       Term = constraintExprData_termGetTerm(data);
1629       Term = constraintTerm_copy(Term);
1630
1631       Term = constraintTerm_doSRefFixBaseParam (Term, arglist);
1632       data = constraintExprData_termSetTerm(data, Term);
1633       break;
1634     case unaryExpr:
1635       expr1 = constraintExprData_unaryExprGetExpr (data);
1636       expr1 = constraintExpr_copy(expr1);
1637
1638       expr1 = constraintExpr_doSRefFixBaseParam (expr1, arglist);
1639       data = constraintExprData_unaryExprSetExpr (data, expr1);
1640       break;
1641     case binaryexpr:
1642       expr1 = constraintExprData_binaryExprGetExpr1 (data);
1643       expr2 = constraintExprData_binaryExprGetExpr2 (data);
1644       
1645       expr1 = constraintExpr_copy(expr1);
1646       expr2 = constraintExpr_copy(expr2);
1647
1648       expr1 = constraintExpr_doSRefFixBaseParam (expr1, arglist);
1649       data = constraintExprData_binaryExprSetExpr1 (data, expr1);
1650       expr2 = constraintExpr_doSRefFixBaseParam (expr2, arglist);
1651       data = constraintExprData_binaryExprSetExpr2 (data, expr2);
1652       
1653       break;
1654     default:
1655       llassert(FALSE);
1656       data = NULL;
1657     }
1658   return expr;
1659 }
1660
1661 /*
1662 / *@only@* / constraintExpr constraintExpr_doSRefFixInvarConstraint (/ *@only@* / constraintExpr expr, sRef s, ctype ct)
1663 {
1664   constraintExprKind kind;
1665   constraintExpr expr1, expr2;
1666   constraintExprData data;
1667   llassert (expr != NULL);
1668
1669   data = expr->data;
1670   
1671   kind = expr->kind;
1672   
1673   switch (kind)
1674     {
1675     case term:
1676       expr = doSRefFixInvarConstraintTerm (expr, s, ct);
1677       break;
1678     case unaryExpr:
1679       expr1 = constraintExprData_unaryExprGetExpr (data);
1680       expr1 = constraintExpr_copy(expr1);
1681       expr1 = constraintExpr_doSRefFixInvarConstraint (expr1, s, ct);
1682       data = constraintExprData_unaryExprSetExpr (data, expr1);
1683       break;
1684     case binaryexpr:
1685       expr1 = constraintExprData_binaryExprGetExpr1 (data);
1686       expr2 = constraintExprData_binaryExprGetExpr2 (data);
1687       
1688       expr1 = constraintExpr_copy(expr1);
1689       expr2 = constraintExpr_copy(expr2);
1690
1691       expr1 = constraintExpr_doSRefFixInvarConstraint (expr1, s, ct);
1692       data = constraintExprData_binaryExprSetExpr1 (data, expr1);
1693       expr2 = constraintExpr_doSRefFixInvarConstraint (expr2, s, ct);
1694       data = constraintExprData_binaryExprSetExpr2 (data, expr2);
1695       
1696       break;
1697     default:
1698       llassert(FALSE);
1699       data = NULL;
1700     }
1701   return expr;
1702 }
1703 */
1704
1705 /*@only@*/ constraintExpr constraintExpr_doSRefFixConstraintParam (/*@only@*/ constraintExpr expr, exprNodeList arglist) /*@modifies expr@*/
1706 {
1707   constraintExprKind kind;
1708   constraintExpr expr1, expr2;
1709   constraintExprData data;
1710   llassert (expr != NULL);
1711
1712   data = expr->data;
1713   
1714   kind = expr->kind;
1715   
1716   switch (kind)
1717     {
1718     case term:
1719       expr = doSRefFixConstraintParamTerm (expr, arglist);
1720       break;
1721     case unaryExpr:
1722       expr1 = constraintExprData_unaryExprGetExpr (data);
1723       expr1 = constraintExpr_copy(expr1);
1724       expr1 = constraintExpr_doSRefFixConstraintParam (expr1, arglist);
1725       data = constraintExprData_unaryExprSetExpr (data, expr1);
1726       break;
1727     case binaryexpr:
1728       expr1 = constraintExprData_binaryExprGetExpr1 (data);
1729       expr2 = constraintExprData_binaryExprGetExpr2 (data);
1730       
1731       expr1 = constraintExpr_copy(expr1);
1732       expr2 = constraintExpr_copy(expr2);
1733
1734       expr1 = constraintExpr_doSRefFixConstraintParam (expr1, arglist);
1735       data = constraintExprData_binaryExprSetExpr1 (data, expr1);
1736       expr2 = constraintExpr_doSRefFixConstraintParam (expr2, arglist);
1737       data = constraintExprData_binaryExprSetExpr2 (data, expr2);
1738       
1739       break;
1740     default:
1741       llassert(FALSE);
1742       data = NULL;
1743     }
1744   return expr;
1745 }
1746
1747 /*@only@*/ constraintExpr constraintExpr_doFixResult (/*@only@*/  constraintExpr expr, /*@observer@*/ exprNode fcnCall)
1748 {
1749   constraintExprKind kind;
1750   constraintExpr expr1, expr2;
1751   constraintExprData data;
1752   llassert (expr != NULL);
1753
1754   data = expr->data;
1755   
1756   kind = expr->kind;
1757   
1758   switch (kind)
1759     {
1760     case term:
1761       expr = doFixResultTerm (expr, fcnCall);
1762       break;
1763     case unaryExpr:
1764       expr1 = constraintExprData_unaryExprGetExpr (data);
1765       expr1 = constraintExpr_copy(expr1);
1766
1767       expr1 = constraintExpr_doFixResult (expr1, fcnCall);
1768       data = constraintExprData_unaryExprSetExpr (data, expr1);
1769       break;
1770     case binaryexpr:
1771       expr1 = constraintExprData_binaryExprGetExpr1 (data);
1772       expr2 = constraintExprData_binaryExprGetExpr2 (data);
1773       
1774       expr1 = constraintExpr_copy(expr1);
1775       expr2 = constraintExpr_copy(expr2);
1776
1777       expr1 = constraintExpr_doFixResult (expr1, fcnCall);
1778       data = constraintExprData_binaryExprSetExpr1 (data, expr1);
1779       expr2 = constraintExpr_doFixResult (expr2, fcnCall);
1780       data = constraintExprData_binaryExprSetExpr2 (data, expr2);
1781       
1782       break;
1783     default:
1784       llassert(FALSE);
1785       data = NULL;
1786     }
1787   return expr;
1788 }
1789
1790 cstring constraintExpr_print (constraintExpr expr) /*@*/
1791 {
1792   return constraintExpr_unparse (expr);
1793 }
1794
1795 bool constraintExpr_hasMaxSet (constraintExpr expr) /*@*/
1796 {
1797   cstring t;
1798
1799   t = constraintExpr_unparse(expr);
1800
1801   if (cstring_containsLit(t, "maxSet") != NULL )
1802     {
1803       cstring_free(t);
1804       return (TRUE);
1805     }
1806   else
1807     {
1808       cstring_free(t);
1809       return FALSE;
1810     }
1811 }
1812
1813
1814
1815       /*returns 1 0 -1 like strcmp
1816         1 => expr1 > expr2
1817         0 => expr1 == expr2
1818         -1 => expr1 < expr2
1819        */
1820
1821 int constraintExpr_compare (constraintExpr expr1, constraintExpr expr2)
1822 {
1823   long value1, value2;
1824
1825   if (constraintExpr_similar (expr1, expr2) )
1826     {
1827       return 0;
1828     }
1829   
1830   value1 = constraintExpr_getValue(expr1);
1831   value2 = constraintExpr_getValue(expr2);
1832
1833   if (value1 > value2)
1834     return 1;
1835
1836   if (value1 == value2)
1837     return 0;
1838
1839   else
1840     return -1;
1841 }
1842
1843 long constraintExpr_getValue (constraintExpr expr)
1844 {
1845   llassert (constraintExpr_isDefined(expr) );
1846   llassert (expr->kind == term);
1847   
1848   return (constraintTerm_getValue (constraintExprData_termGetTerm (expr->data)));
1849 }
1850
1851 bool constraintExpr_canGetValue (constraintExpr expr)
1852 {
1853   llassert ( constraintExpr_isDefined (expr) );
1854   if (constraintExpr_isUndefined (expr) )
1855     {
1856       return FALSE;
1857     }
1858
1859   switch (expr->kind)
1860     {
1861     case term:
1862       return constraintTerm_canGetValue (constraintExprData_termGetTerm (expr->data) );
1863     default:
1864       return FALSE;
1865       
1866     }
1867
1868   BADEXIT;
1869 }
1870
1871 fileloc constraintExpr_loc (constraintExpr expr)
1872 {
1873   constraintExpr e;
1874 constraintTerm t;
1875   constraintExprKind kind;
1876
1877   llassert ( constraintExpr_isDefined (expr) );
1878   if (constraintExpr_isUndefined (expr) )
1879     {
1880       return fileloc_undefined;
1881     }
1882
1883   
1884  kind = expr->kind;
1885   
1886   switch (kind)
1887     {
1888     case term:
1889       t = constraintExprData_termGetTerm (expr->data);
1890       return (constraintTerm_getFileloc (t) );
1891       /*@notreached@*/
1892       break;      
1893     case unaryExpr:
1894       e = constraintExprData_unaryExprGetExpr (expr->data);
1895       return (constraintExpr_loc (e) );
1896       /*@notreached@*/
1897       break;           
1898     case binaryexpr:
1899       e = constraintExprData_binaryExprGetExpr1 (expr->data);
1900       return (constraintExpr_loc (e) );
1901       /*@notreached@*/
1902       break;
1903     }
1904   llassert (FALSE);
1905   return (fileloc_undefined);
1906 }
1907
1908 /*drl moved from constriantTerm.c 5/20/001*/
1909 static /*@only@*/ constraintExpr 
1910 doFixResultTerm (/*@only@*/ constraintExpr e, /*@exposed@*/ exprNode fcnCall)
1911 {
1912   constraintTerm t;
1913   sRef s;
1914   constraintExprData data;
1915   constraintExprKind kind;
1916   constraintExpr ret;
1917   
1918   llassert (constraintExpr_isDefined (e) );
1919   
1920   data = e->data;
1921   kind = e->kind;
1922   
1923   llassert (kind == term);
1924   
1925   t = constraintExprData_termGetTerm (data);
1926   llassert (constraintTerm_isDefined (t));
1927   
1928   ret = e;
1929
1930   switch (constraintTerm_getKind (t))
1931     {
1932     case CTT_EXPR:
1933     case CTT_INTLITERAL:
1934       break;
1935       
1936     case CTT_SREF:
1937       s = constraintTerm_getSRef(t);
1938       if (sRef_isResult (s))
1939         {
1940           ret = constraintExpr_makeExprNode(fcnCall);
1941           constraintExpr_free(e);
1942           e = NULL;
1943         }
1944       else
1945         {
1946           e = NULL;
1947         }
1948       break;
1949     default:
1950       BADEXIT;
1951     }
1952   
1953   return ret;
1954   
1955 }
1956
1957 #if 0
1958
1959 /*to be used for structure checking */
1960
1961 / *@only@* / static constraintExpr
1962 doSRefFixInvarConstraintTerm (/ *@only@* / constraintExpr e, sRef s, ctype ct)
1963 {
1964   constraintTerm t;
1965
1966   constraintExprData data = e->data;
1967   
1968   constraintExprKind kind = e->kind;
1969   
1970   constraintExpr ret;
1971
1972   llassert(kind == term);
1973
1974   t = constraintExprData_termGetTerm (data);
1975   llassert (constraintTerm_isDefined(t) );
1976
1977   ret = e;
1978
1979   DPRINTF (("Fixing: %s", constraintExpr_print (e)));
1980
1981   switch (constraintTerm_getKind(t))
1982     {
1983     case CTT_EXPR:
1984       DPRINTF((message ("%q @ %q ", constraintTerm_unparse(t),
1985                         fileloc_unparse (constraintTerm_getFileloc(t) ) ) ));
1986       break;
1987     case CTT_INTLITERAL:
1988       DPRINTF((message (" %q ", constraintTerm_unparse (t)) ));
1989       break;
1990       
1991     case CTT_SREF:
1992       / * evans 2001-07-24: constants should use the original term * /
1993       if (!constraintTerm_canGetValue (t))
1994         {
1995           sRef snew;
1996           DPRINTF ((message("Doing sRef_fixInvarConstraint for %q ", 
1997                              constraintTerm_unparse (t) ) ));
1998
1999           snew = fixSref (ct, s, constraintTerm_getSRef(t));
2000
2001           ret = constraintExpr_makeTermsRef(snew);
2002           
2003           constraintExpr_free (e);
2004           
2005           DPRINTF (( message("After Doing sRef_fixConstraintParam constraintExpr is %q ", 
2006                              constraintExpr_print (ret) ) ));
2007           / *@-branchstate@* /
2008         } / *@=branchstate@* /
2009
2010       break;
2011     default:
2012       BADEXIT;
2013     }
2014
2015   return ret;
2016   
2017 }
2018 #endif
2019  
2020 /*drl moved from constriantTerm.c 5/20/001*/
2021 /*@only@*/ static constraintExpr 
2022 doSRefFixConstraintParamTerm (/*@only@*/ constraintExpr e, /*@observer@*/ /*@temp@*/ exprNodeList arglist)
2023 {
2024   constraintTerm t;
2025
2026   constraintExprData data;
2027   
2028   constraintExprKind kind;
2029   
2030   constraintExpr ret;
2031
2032
2033   llassert(constraintExpr_isDefined (e) );
2034
2035   data = e->data;
2036   
2037   kind = e->kind;
2038
2039   
2040
2041   llassert(kind == term);
2042
2043   t = constraintExprData_termGetTerm (data);
2044   llassert (constraintTerm_isDefined(t) );
2045
2046   ret = e;
2047
2048   DPRINTF (("Fixing: %s", constraintExpr_print (e)));
2049
2050   switch (constraintTerm_getKind(t))
2051     {
2052     case CTT_EXPR:
2053       DPRINTF((message ("%q @ %q ", constraintTerm_unparse(t),
2054                         fileloc_unparse (constraintTerm_getFileloc(t) ) ) ));
2055       break;
2056     case CTT_INTLITERAL:
2057       DPRINTF((message (" %q ", constraintTerm_unparse (t)) ));
2058       break;
2059     case CTT_SREF:
2060       /* evans 2001-07-24: constants should use the original term */
2061       if (!constraintTerm_canGetValue (t))
2062         {
2063           DPRINTF ((message("Doing sRef_fixConstraintParam for %q ", 
2064                              constraintTerm_unparse (t) ) ));
2065           ret = sRef_fixConstraintParam (constraintTerm_getSRef(t), arglist);
2066           
2067           constraintExpr_free (e);
2068           
2069           DPRINTF (( message("After Doing sRef_fixConstraintParam constraintExpr is %q ", 
2070                              constraintExpr_print (ret) ) ));
2071           /*@-branchstate@*/
2072         } /*@=branchstate@*/
2073
2074       break;
2075     default:
2076       BADEXIT;
2077     }
2078
2079   return ret;
2080   
2081 }
2082
2083
2084 #if 0
2085 bool constraintExpr_includesTerm (constraintExpr expr, constraintTerm term)
2086 {
2087   if (constraintTerm_hasTerm (expr->term, term) )
2088     return TRUE;
2089
2090   if ((expr->expr) != NULL)
2091     {
2092       return ( constraintExpr_includesTerm (expr->expr, term) );
2093     }
2094   return FALSE;
2095
2096 }
2097 #endif
2098
2099 /*drl added 6/11/01 */
2100 bool constraintExpr_isBinaryExpr (/*@observer@*/ constraintExpr c)
2101 {
2102
2103   llassert(constraintExpr_isDefined (c) );
2104
2105   if ( ! (constraintExpr_isDefined (c) ) )
2106     return FALSE;
2107   
2108   if (c->kind == binaryexpr)
2109     return TRUE;
2110
2111   else
2112     return FALSE;
2113 }
2114
2115 /*drl added 8/08/001 */
2116 bool constraintExpr_isTerm (/*@observer@*/ constraintExpr c) /*@*/
2117 {
2118   llassert(constraintExpr_isDefined (c) );
2119   
2120   if (c->kind == term)
2121     return TRUE;
2122
2123   else
2124     return FALSE;
2125 }
2126
2127 /*@observer@*/ /*@temp@*/ constraintTerm constraintExpr_getTerm ( /*@temp@*/ /*@observer@*/ constraintExpr c) /*@*/
2128 {
2129   constraintTerm term;
2130   
2131   llassert(constraintExpr_isDefined (c) );
2132   
2133   llassert(constraintExpr_isTerm(c) );
2134
2135   term = constraintExprData_termGetTerm(c->data);
2136
2137   return term;
2138 }
2139
2140 static void  binaryExpr_dump (/*@observer@*/ constraintExprData data,  FILE *f)
2141 {
2142   constraintExpr expr1;
2143   constraintExprBinaryOpKind binaryOp;
2144   constraintExpr expr2;
2145
2146
2147   binaryOp = constraintExprData_binaryExprGetOp (data);
2148
2149   fprintf(f, "%d\n", (int) binaryOp);
2150   
2151   expr1 = constraintExprData_binaryExprGetExpr1 (data);
2152   expr2 = constraintExprData_binaryExprGetExpr2 (data);
2153
2154   fprintf(f, "e1\n");
2155
2156   constraintExpr_dump(expr1, f);
2157
2158   fprintf(f, "e2\n");
2159   constraintExpr_dump(expr2, f);
2160 }
2161
2162
2163 static constraintExpr  binaryExpr_undump (FILE *f)
2164 {
2165   constraintExpr expr1;
2166   constraintExprBinaryOpKind binaryOp;
2167   constraintExpr expr2;
2168
2169   constraintExpr ret;
2170
2171   
2172
2173   char * str;
2174   char * os;
2175
2176   os = mstring_create (MAX_DUMP_LINE_LENGTH);
2177
2178   str = fgets(os, MAX_DUMP_LINE_LENGTH, f);
2179
2180   if (! mstring_isDefined(str) )
2181     {
2182       llfatalbug(message("Library file is corrupted") );
2183     }
2184   
2185   binaryOp = (constraintExprBinaryOpKind) reader_getInt(&str);
2186   
2187   str = fgets(os, MAX_DUMP_LINE_LENGTH, f);
2188
2189   if (! mstring_isDefined(str) )
2190     {
2191       llfatalbug(message("Library file is corrupted") );
2192     }
2193
2194   reader_checkChar (&str, 'e');
2195   reader_checkChar (&str, '1');
2196   
2197   expr1 = constraintExpr_undump (f);
2198
2199   str = fgets(os, MAX_DUMP_LINE_LENGTH, f);
2200
2201   reader_checkChar (&str, 'e');
2202   reader_checkChar (&str, '2');  
2203
2204   expr2 = constraintExpr_undump (f);
2205
2206   ret = constraintExpr_makeBinaryOpConstraintExpr (expr1, expr2);
2207   ret->data = constraintExprData_binaryExprSetOp(ret->data, binaryOp);
2208
2209   free(os);
2210   return ret;
2211 }
2212
2213
2214
2215 static void  unaryExpr_dump (/*@observer@*/ constraintExprData data,  FILE *f)
2216 {
2217
2218   constraintExpr expr;
2219   constraintExprUnaryOpKind unaryOp;
2220
2221   unaryOp = constraintExprData_unaryExprGetOp (data);
2222
2223   fprintf(f, "%d\n", (int) unaryOp);
2224   
2225   expr = constraintExprData_unaryExprGetExpr (data);
2226
2227   constraintExpr_dump(expr, f);  
2228 }
2229
2230 static  constraintExpr  unaryExpr_undump ( FILE *f)
2231 {
2232
2233   constraintExpr expr;
2234   constraintExprUnaryOpKind unaryOp;
2235   constraintExpr ret;
2236   
2237   char * str;
2238   char * os;
2239
2240   str = mstring_create (MAX_DUMP_LINE_LENGTH);
2241   os = str;
2242   str = fgets(os, MAX_DUMP_LINE_LENGTH, f);
2243
2244   if (! mstring_isDefined(str) )
2245     {
2246       llfatalbug(message("Library file is corrupted") );
2247     }
2248
2249   unaryOp = (constraintExprUnaryOpKind) reader_getInt(&str);
2250   
2251   expr = constraintExpr_undump (f);
2252
2253   ret = constraintExpr_makeUnaryOp (expr, unaryOp);
2254
2255   free(os);
2256   
2257   return ret;
2258 }
2259
2260 void  constraintExpr_dump (/*@observer@*/ constraintExpr expr,  FILE *f)
2261 {
2262   constraintExprKind kind;
2263   constraintTerm t;
2264   
2265
2266   llassert(constraintExpr_isDefined(expr) );
2267   
2268   DPRINTF((message("constraintExpr_dump:: dumping constraintExpr %s",
2269                    constraintExpr_unparse(expr)
2270                    ) ));
2271   
2272   kind = expr->kind;
2273   
2274   fprintf(f,"%d\n", (int) kind);
2275   
2276   switch (kind)
2277     {
2278     case term:
2279       t = constraintExprData_termGetTerm (expr->data);
2280       constraintTerm_dump (t, f);
2281       break;      
2282     case unaryExpr:
2283       unaryExpr_dump (expr->data, f);
2284       break;           
2285     case binaryexpr:
2286       binaryExpr_dump  (expr->data, f);
2287       break;
2288     }  
2289 }
2290
2291 /*@only@*/ constraintExpr  constraintExpr_undump (FILE *f)
2292 {
2293   constraintExprKind kind;
2294   constraintTerm t;
2295   constraintExpr ret;
2296   
2297   char * s;
2298   char * os;
2299   
2300   s = mstring_create (MAX_DUMP_LINE_LENGTH);
2301
2302   os = s;
2303   
2304   s = fgets(os, MAX_DUMP_LINE_LENGTH, f);
2305
2306   if (! mstring_isDefined(s) )
2307     {
2308       llfatalbug(message("Library file is corrupted") );
2309     }
2310
2311   kind = (constraintExprKind) reader_getInt(&s);
2312
2313   free (os);
2314   
2315   switch (kind)
2316     {
2317     case term:
2318       t = constraintTerm_undump (f);
2319       ret = constraintExpr_makeTerm(t);
2320       break;      
2321     case unaryExpr:
2322       ret = unaryExpr_undump (f);
2323       break;           
2324     case binaryexpr:
2325       ret = binaryExpr_undump  (f);
2326       break;
2327     }
2328
2329   return ret;
2330
2331 }
2332
2333 int constraintExpr_getDepth (constraintExpr ex)
2334 {
2335   int ret;
2336   
2337   constraintExprKind kind;
2338
2339   llassert (ex != NULL);
2340
2341   kind = ex->kind;
2342   
2343   switch (kind)
2344     {
2345     case term:
2346       ret = 1;
2347       break;
2348     case unaryExpr:
2349       ret =  constraintExpr_getDepth (constraintExprData_unaryExprGetExpr (ex->data) );
2350       ret++;
2351       
2352       break;
2353     case binaryexpr:
2354       ret = 0;
2355       ret = constraintExpr_getDepth (constraintExprData_binaryExprGetExpr1 (ex->data) );
2356
2357       ret++;
2358
2359       ret += constraintExpr_getDepth (constraintExprData_binaryExprGetExpr2 (ex->data) );
2360
2361       break;
2362     default:
2363       BADEXIT;
2364     }
2365
2366   return ret;
2367 }
2368
2369
2370 bool constraintExpr_canGetCType (constraintExpr e) /*@*/
2371 {
2372   if (constraintExpr_isUndefined(e))
2373     return FALSE;
2374   
2375   if (e->kind == term)
2376     {
2377       return TRUE;
2378     }
2379   else
2380     {
2381       DPRINTF (("constraintExpr_canGetCType: can't get type for %s", constraintExpr_unparse (e)));
2382       return FALSE;
2383     }
2384 }
2385
2386 ctype constraintExpr_getCType (constraintExpr e) /*@*/
2387 {
2388   constraintTerm t;
2389
2390   llassert (constraintExpr_isDefined (e));
2391   llassert (constraintExpr_canGetCType (e));
2392
2393   switch (e->kind)
2394     {
2395     case term:
2396       t = constraintExprData_termGetTerm (e->data);
2397       return (constraintTerm_getCType(t) );
2398       /* assume that a unary expression will be an int ... */
2399     case unaryExpr:
2400       return ctype_unknown; /* was ctype_signedintegral; */
2401       /* drl for just return type of first operand */
2402     case binaryexpr:
2403       return (constraintExpr_getCType (constraintExprData_binaryExprGetExpr1 (e->data)));
2404     default:
2405       BADEXIT;
2406     }
2407   BADEXIT;
2408 }
2409
2410 /* drl add 10-5-001 */
2411
2412 static bool constraintExpr_hasTypeChange (constraintExpr e)
2413 {
2414   llassert(constraintExpr_isDefined(e));
2415
2416   if (constraintExpr_isDefined((e)) && (e->ct == TRUE))
2417     {
2418       return TRUE;
2419     }
2420
2421   if (e->kind == unaryExpr)
2422     {
2423       if (constraintExprData_unaryExprGetOp (e->data) == MAXSET)
2424         {
2425           constraintExpr ce = constraintExprData_unaryExprGetExpr(e->data);
2426           DPRINTF (("Unary type change: [%x] %s", ce, constraintExpr_unparse (ce)));
2427           DPRINTF (("Types: %s / %s", ctype_unparse (constraintExpr_getCType (ce)),
2428                     ctype_unparse (constraintExpr_getOrigType (ce))));
2429           return (constraintExpr_hasTypeChange(ce));
2430         }
2431     }
2432   
2433   return FALSE;
2434 }
2435
2436 /* drl add 10-5-001 */
2437
2438 static ctype constraintExpr_getOrigType (constraintExpr e)
2439 {
2440   llassert (constraintExpr_isDefined (e));
2441   llassert (constraintExpr_hasTypeChange (e));
2442   
2443   if (e->ct == TRUE) 
2444     {
2445       return e->origType;
2446     }
2447
2448   if (e->kind == unaryExpr)
2449     {
2450       if (constraintExprData_unaryExprGetOp (e->data) == MAXSET)
2451         {
2452           constraintExpr ce = constraintExprData_unaryExprGetExpr (e->data);
2453           return (constraintExpr_getOrigType(ce));
2454         }
2455         
2456     }
2457
2458   BADEXIT;
2459
2460
2461 /*drl added these around 10/18/001*/
2462
2463 static /*@only@*/ constraintExpr 
2464 constraintExpr_div (/*@only@*/ constraintExpr e, ctype tfrom, ctype tto, fileloc loc)
2465 {
2466   int sizefrom = ctype_getSize (tfrom);
2467   int sizeto = ctype_getSize (tto);
2468
2469   DPRINTF (("constraintExpr_div: %s", constraintExpr_unparse (e)));
2470   DPRINTF (("Types: %s / %s",
2471             ctype_unparse (tfrom),
2472             ctype_unparse (tto)));
2473   
2474   if (sizefrom == -1) {
2475     llbug (message ("constraintExpr_div: type size unknown: %s", ctype_unparse (tfrom)));
2476   }
2477
2478   if (sizeto == -1) {
2479     llbug (message ("constraintExpr_div: type size unknown: %s", ctype_unparse (tto)));
2480   }
2481
2482   if (sizeto == sizefrom) 
2483     {
2484       DPRINTF (("Sizes match: %d / %d", sizeto, sizefrom));
2485       ; /* Sizes match, a-ok */
2486     }
2487   else
2488     {
2489       float scale = (float) sizefrom / (float) sizeto;
2490       constraintTerm ct;
2491       long val;
2492       float fnewval;
2493       long newval;
2494
2495       llassert (e != NULL);
2496       llassert (e->kind == term);
2497       ct = constraintExprData_termGetTerm (e->data);
2498       DPRINTF (("constraint: %s / %s", constraintExpr_unparse (e), constraintTerm_unparse (ct)));
2499       llassert (constraintTerm_canGetValue (ct));
2500       val = constraintTerm_getValue (ct);
2501
2502       DPRINTF (("Scaling constraints by: %ld * %f", val, scale));
2503
2504       fnewval = ((float) val) * scale;
2505       newval = (long) fnewval;
2506
2507       DPRINTF (("Values: %f / %ld", fnewval, newval));
2508
2509       if ((fnewval - (float) newval) > FLT_EPSILON) 
2510         {
2511           voptgenerror (FLG_ALLOCMISMATCH,
2512                         message ("Allocated memory is converted to type %s of (size %d), "
2513                                  "which is not divisible into original allocation of space "
2514                                  "for %d elements of type %s (size %d)",
2515                                  ctype_unparse (tto), sizeto,
2516                                  long_toInt (val), ctype_unparse (tfrom), sizefrom),
2517                         loc);
2518         }  
2519
2520       constraintTerm_setValue (ct, newval);
2521     }
2522
2523   DPRINTF (("After div: %s", constraintExpr_unparse (e)));
2524   return e;
2525 }
2526
2527
2528 /*@access exprNode@*/ 
2529 static /*@only@*/ constraintExpr 
2530 constraintTerm_simpleDivTypeExprNode (/*@only@*/ constraintExpr e, ctype tfrom, ctype tto, fileloc loc)
2531 {
2532   exprData data;
2533   exprNode t1, t2, expr;
2534   lltok tok;
2535   constraintTerm t;
2536
2537   llassert (constraintExpr_isDefined(e) );
2538   
2539   DPRINTF (("constraintTerm_simpleDivTypeExprNode e=%s [%s => %s]", constraintExpr_print(e), 
2540             ctype_unparse(tfrom), ctype_unparse (tto)));
2541   
2542   t = constraintExprData_termGetTerm (e->data);
2543   
2544   expr = constraintTerm_getExprNode (t);
2545
2546   llassert (constraintExpr_isDefined(e));
2547   llassert (exprNode_isDefined(expr));
2548   
2549   if (expr->kind == XPR_OP)
2550     {
2551       data = expr->edata;
2552       
2553       t1 = exprData_getOpA (data);
2554       t2 = exprData_getOpB (data);
2555       tok = exprData_getOpTok (data);
2556
2557       if (lltok_isMult (tok))
2558         {
2559           /*
2560           ** If the sizeof is first, flip them.
2561           */
2562
2563           llassert (exprNode_isDefined(t1) && exprNode_isDefined(t2));
2564
2565           if (t2->kind == XPR_SIZEOF || t2->kind == XPR_SIZEOFT) 
2566             {
2567               exprNode tmp = t1;
2568               t1 = t2;
2569               t2 = tmp;
2570             }
2571           
2572           /*drl 3/2/2003 we know this from the fact that it's a
2573             multiplication operation...*/
2574           
2575           if (t1->kind == XPR_SIZEOF || t1->kind == XPR_SIZEOFT)
2576             {
2577               ctype multype;
2578               
2579               if (t1->kind == XPR_SIZEOFT)
2580                 {
2581                   multype = qtype_getType (exprData_getType (t1->edata));
2582                 }
2583               else
2584                 {
2585                   exprNode tempE = exprData_getSingle (t1->edata);
2586                   multype = exprNode_getType (tempE); 
2587                 }
2588
2589               DPRINTF (("Here we go sizeof: %s / %s / %s",
2590                         ctype_unparse (multype), ctype_unparse (tfrom), ctype_unparse (tto)));
2591               llassert (ctype_isPointer (tfrom));
2592
2593               if (ctype_almostEqual (ctype_makePointer (multype), tto))
2594                 {
2595                   /* this is a bit sloopy but ... */
2596                   constraintExpr_free (e);
2597                   DPRINTF (("Sizeof types match okay!"));
2598                   return constraintExpr_makeExprNode (t2);
2599                 }
2600               else
2601                 {
2602                   int sizemul = ctype_getSize (multype);
2603                   ctype tobase = ctype_baseArrayPtr (tto);
2604                   int sizeto = ctype_getSize (tobase);
2605
2606                   DPRINTF (("Types: %s / %s / %s",
2607                             ctype_unparse (tfrom), ctype_unparse (tto), ctype_unparse (multype)));
2608
2609                   voptgenerror (FLG_ALLOCMISMATCH,
2610                                 message ("Allocated memory is used as a different type (%s) from the sizeof type (%s)",
2611                                          ctype_unparse (tobase), ctype_unparse (multype)),
2612                                 loc);
2613                   
2614                   if (sizemul == sizeto) 
2615                     {
2616                       constraintExpr_free (e);
2617                       DPRINTF (("Sizeof types match okay!"));
2618                       return constraintExpr_makeExprNode (t2);
2619                     }
2620                   else
2621                     {
2622                       /* nothing was here */
2623                       DPRINTF (("MISMATCHING TYPES!"));
2624                       return (constraintExpr_div (constraintExpr_makeExprNode (t2), multype, tto, loc));
2625                     }
2626                 }
2627             }
2628           else
2629             {
2630               DPRINTF (("NOT A SIZEOF!"));
2631               /* empty */
2632             }
2633         }
2634       else 
2635         {
2636           DPRINTF (("Not a mult: %s", constraintExpr_unparse (e)));
2637         }
2638     }
2639
2640   return (constraintExpr_div (e, tfrom, tto, loc));
2641 }
2642 /*@noaccess exprNode@*/ 
2643
2644 static /*@only@*/ constraintExpr simpleDivType (/*@only@*/ constraintExpr e, ctype tfrom, ctype tto, fileloc loc)
2645 {
2646   DPRINTF (("simpleDiv got %s", constraintExpr_unparse(e)));
2647   DPRINTF (("Types: %s / %s",
2648             ctype_unparse (tfrom),
2649             ctype_unparse (tto)));
2650
2651   llassert (constraintExpr_isDefined(e));
2652   
2653   switch (e->kind)
2654     {
2655     case term:
2656       {
2657         constraintTerm t = constraintExprData_termGetTerm (e->data);
2658
2659         DPRINTF (("Term: %s", constraintTerm_unparse (t)));
2660
2661         if (constraintTerm_isExprNode (t))
2662           {
2663             return constraintTerm_simpleDivTypeExprNode (e, tfrom, tto, loc);
2664             
2665             /* search for * size of ct and remove */
2666           }
2667         DPRINTF (("Here: %s / %s -> %s", constraintExpr_unparse (e), ctype_unparse (tfrom), ctype_unparse (tto)));
2668         return constraintExpr_div (e, tfrom, tto, loc);
2669       }
2670       
2671     case binaryexpr:
2672       {
2673         constraintExpr temp;
2674         
2675         temp = constraintExprData_binaryExprGetExpr1 (e->data);
2676         temp = constraintExpr_copy(temp);
2677         temp = simpleDivType (temp, tfrom, tto, loc);
2678         
2679         e->data = constraintExprData_binaryExprSetExpr1 (e->data, temp);
2680         
2681         temp = constraintExprData_binaryExprGetExpr2 (e->data);
2682         temp = constraintExpr_copy(temp);
2683         temp = simpleDivType (temp, tfrom, tto, loc);
2684         e->data = constraintExprData_binaryExprSetExpr2 (e->data, temp);
2685
2686         DPRINTF (("simpleDiv binaryexpr returning %s ", constraintExpr_unparse(e)));
2687         return e;
2688       }
2689     case unaryExpr:
2690       {
2691         return constraintExpr_div (e, tfrom, tto, loc);
2692       }
2693
2694     default:
2695       BADEXIT;
2696     }
2697 }
2698
2699 static /*@only@*/ constraintExpr constraintExpr_adjustMaxSetForCast (/*@only@*/ constraintExpr e, ctype tfrom, 
2700                                                                      ctype tto, fileloc loc)
2701 {
2702   DPRINTF (("constraintExpr_adjustMaxSetForCast got %s [%s => %s]", constraintExpr_unparse(e), 
2703             ctype_unparse (tfrom), ctype_unparse (tto)));
2704   
2705   e = constraintExpr_makeIncConstraintExpr (e);
2706   e = constraintExpr_simplify (e);
2707   e = simpleDivType (e, tfrom, tto, loc);
2708   e = constraintExpr_makeDecConstraintExpr (e);
2709   e = constraintExpr_simplify (e);
2710   
2711   DPRINTF (("constraintExpr_adjustMaxSetForCast returning %s ", constraintExpr_unparse(e)));
2712   return e;
2713 }
2714
2715
2716 bool constraintExpr_isConstantOnly (constraintExpr e)
2717 {
2718   DPRINTF (("constraintExpr_isConstantOnly %s ", constraintExpr_unparse(e)));
2719   llassert (constraintExpr_isDefined(e));
2720
2721   switch (e->kind)
2722     {
2723     case term:
2724       {
2725         constraintTerm t = constraintExprData_termGetTerm(e->data);
2726         
2727         if (constraintTerm_isConstantOnly (t))
2728           {
2729             return TRUE;
2730           }
2731         else
2732           {
2733             return FALSE;
2734           }
2735       }
2736       
2737     case binaryexpr:
2738       {
2739         constraintExpr temp1 = constraintExprData_binaryExprGetExpr1 (e->data);
2740         constraintExpr temp2 = constraintExprData_binaryExprGetExpr2 (e->data);
2741         
2742         if (constraintExpr_isConstantOnly(temp1) &&
2743             constraintExpr_isConstantOnly(temp2) )
2744           {
2745             return TRUE;
2746           }
2747         else
2748           {
2749             return FALSE;
2750           }
2751       }
2752       
2753     case unaryExpr:
2754       {
2755         constraintExpr temp;
2756         
2757         temp = constraintExprData_unaryExprGetExpr (e->data );
2758
2759         if (constraintExpr_isConstantOnly(temp) )
2760           {
2761             return TRUE;
2762           }
2763         else
2764           {
2765             return FALSE;
2766           }
2767       }
2768     default:
2769       BADEXIT;
2770     }
2771 }
2772
This page took 0.312177 seconds and 5 git commands to generate.