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