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