]> andersk Git - splint.git/blame - src/constraintTerm.c
Fixed sizeoftest test.
[splint.git] / src / constraintTerm.c
CommitLineData
616915dd 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
25/*
26** constraintTerm.c
616915dd 27*/
28
b7b694d6 29/* #define DEBUGPRINT 1 */
616915dd 30
31# include <ctype.h> /* for isdigit */
1b8ae690 32# include "splintMacros.nf"
616915dd 33# include "basic.h"
34# include "cgrammar.h"
35# include "cgrammar_tokens.h"
36
37# include "exprChecks.h"
616915dd 38# include "exprNodeSList.h"
39
616915dd 40/*@-czechfcns@*/
393e573f 41/*@-nullderef@*/ /* !!! DRL needs to fix this code! */
42/*@-nullstate@*/ /* !!! DRL needs to fix this code! */
43/*@-nullpass@*/ /* !!! DRL needs to fix this code! */
44/*@-temptrans@*/ /* !!! DRL needs to fix this code! */
616915dd 45
393e573f 46/*@access exprNode@*/ /* !!! NO! Don't do this recklessly! */
a8e557d3 47
f0171cff 48bool constraintTerm_isDefined (constraintTerm t)
990ec868 49{
50 return t != NULL;
51}
52
d46ce6a4 53void constraintTerm_free (/*@only@*/ constraintTerm term)
54{
990ec868 55 llassert (constraintTerm_isDefined (term));
56
d46ce6a4 57 fileloc_free (term->loc);
58
59 switch (term->kind)
60 {
61 case EXPRNODE:
62 /* we don't free an exprNode*/
63 break;
64 case SREF:
65 /* sref */
795e7f34 66 sRef_free (term->value.sref);
d46ce6a4 67 break;
68 case INTLITERAL:
69 /* don't free an int */
70 break;
71 case ERRORBADCONSTRAINTTERMTYPE:
72 default:
73 /* type was set incorrectly */
74 llcontbug (message("constraintTerm_free type was set incorrectly"));
75 }
b7b694d6 76
795e7f34 77 term->kind = ERRORBADCONSTRAINTTERMTYPE;
d46ce6a4 78 free (term);
79}
616915dd 80
4ab867d6 81/*@only@*/ static/*@out@*/ constraintTerm new_constraintTermExpr (void)
616915dd 82{
83 constraintTerm ret;
84 ret = dmalloc (sizeof (* ret ) );
bb25bea6 85 ret->value.intlit = 0;
616915dd 86 return ret;
87}
88
89
90bool constraintTerm_isIntLiteral (constraintTerm term)
91{
dc92450f 92 llassert(term != NULL);
616915dd 93
94 if (term->kind == INTLITERAL)
95 return TRUE;
96
97 return FALSE;
98}
99
d30bc0c7 100
101bool constraintTerm_isInitBlock (/*@observer@*/ /*@temp@*/ constraintTerm c) /*@*/
102{
103 llassert (c != NULL);
104 if (c->kind == EXPRNODE)
105 {
106
107 if (exprNode_isInitBlock(c->value.expr) )
108 {
109 return TRUE;
110 }
111 }
112 return FALSE;
113}
114
115
a779b61e 116bool constraintTerm_isExprNode (/*@observer@*/ /*@temp@*/ constraintTerm c) /*@*/
117{
118 llassert (c != NULL);
119 if (c->kind == EXPRNODE)
120 {
121 return TRUE;
122 }
123 return FALSE;
124}
125
126
d30bc0c7 127int constraintTerm_getInitBlockLength (/*@observer@*/ /*@temp@*/ constraintTerm c) /*@*/
128{
129
130 exprNodeList list;
131 int ret;
132 llassert (c != NULL);
133 llassert (constraintTerm_isInitBlock (c) );
134 llassert (c->kind == EXPRNODE);
135
136 llassert(exprNode_isDefined(c->value.expr) );
137
138 if (exprNode_isUndefined(c->value.expr) )
139 {
140 return 1;
141 }
142
143 if (c->value.expr->edata == exprData_undefined)
144 {
145 return 1;
146 }
147 list = exprData_getArgs(c->value.expr->edata);
148
149 ret = exprNodeList_size(list);
150
151 return ret;
152}
153
154
155
dc92450f 156bool constraintTerm_isStringLiteral (constraintTerm c) /*@*/
616915dd 157{
dc92450f 158 llassert (c != NULL);
616915dd 159 if (c->kind == EXPRNODE)
160 {
161 if (exprNode_knownStringValue(c->value.expr) )
162 {
163 return TRUE;
164 }
165 }
166 return FALSE;
167}
168
d30bc0c7 169
170
616915dd 171cstring constraintTerm_getStringLiteral (constraintTerm c)
172{
dc92450f 173 llassert (c != NULL);
616915dd 174 llassert (constraintTerm_isStringLiteral (c) );
175 llassert (c->kind == EXPRNODE);
176
dc92450f 177 return (cstring_copy ( multiVal_forceString (exprNode_getValue (c->value.expr) ) ) );
616915dd 178}
179
4ab867d6 180constraintTerm constraintTerm_simplify (/*@returned@*/ constraintTerm term) /*@modifies term@*/
616915dd 181{
182 if (term->kind == EXPRNODE)
183 {
184 if ( exprNode_knownIntValue (term->value.expr ) )
185 {
186 long int temp;
28bf4b0b 187
616915dd 188 temp = exprNode_getLongValue (term->value.expr);
dc92450f 189 term->value.intlit = (int)temp;
616915dd 190 term->kind = INTLITERAL;
191 }
192 }
193 return term;
194}
195
196fileloc constraintTerm_getFileloc (constraintTerm t)
197{
990ec868 198 llassert (constraintTerm_isDefined (t));
616915dd 199 return (fileloc_copy (t->loc) );
200}
201
a8e557d3 202constraintTermType constraintTerm_getKind (constraintTerm t)
203{
204 llassert (constraintTerm_isDefined(t) );
205
206 return (t->kind);
207}
208
209/*@exposed@*/ sRef constraintTerm_getSRef (constraintTerm t)
210{
211 llassert (constraintTerm_isDefined(t) );
212 llassert (t->kind == SREF);
213
214 return (t->value.sref);
215}
216
03d670b6 217/*@only@*/ constraintTerm constraintTerm_makeExprNode (/*@dependent@*/ exprNode e)
616915dd 218{
219 constraintTerm ret = new_constraintTermExpr();
d46ce6a4 220 ret->loc = fileloc_copy(exprNode_getfileloc(e));
616915dd 221 ret->value.expr = e;
222 ret->kind = EXPRNODE;
223 ret = constraintTerm_simplify(ret);
224 return ret;
225}
226
28bf4b0b 227/*@only@*/ constraintTerm constraintTerm_makesRef (/*@temp@*/ /*@observer@*/ sRef s)
616915dd 228{
229 constraintTerm ret = new_constraintTermExpr();
230 ret->loc = fileloc_undefined;
4ab867d6 231 ret->value.sref = sRef_saveCopy(s);
616915dd 232 ret->kind = SREF;
233 ret = constraintTerm_simplify(ret);
234 return ret;
235}
236
795e7f34 237
238
616915dd 239constraintTerm constraintTerm_copy (constraintTerm term)
240{
241 constraintTerm ret;
242 ret = new_constraintTermExpr();
243 ret->loc = fileloc_copy (term->loc);
795e7f34 244
245 switch (term->kind)
246 {
247 case EXPRNODE:
248 ret->value.expr = term->value.expr;
249 break;
250 case INTLITERAL:
251 ret->value.intlit = term->value.intlit;
252 break;
253
254 case SREF:
255 ret->value.sref = sRef_saveCopy(term->value.sref);
256 break;
257 default:
258 BADEXIT;
259 }
616915dd 260 ret->kind = term->kind;
261 return ret;
262}
263
d46ce6a4 264constraintTerm constraintTerm_setFileloc (/*@returned@*/ constraintTerm term, fileloc loc)
616915dd 265{
dc92450f 266 llassert(term != NULL);
d46ce6a4 267
28bf4b0b 268 if ( fileloc_isDefined( term->loc ) )
d46ce6a4 269 fileloc_free(term->loc);
270
616915dd 271 term->loc = fileloc_copy(loc);
272 return term;
273}
274
275
d46ce6a4 276static cstring constraintTerm_getName (constraintTerm term)
616915dd 277{
278 cstring s;
279 s = cstring_undefined;
280
281 llassert (term != NULL);
282
283 switch (term->kind)
284 {
285 case EXPRNODE:
b7b694d6 286 /*@i334*/ /*wtf*/
616915dd 287 s = message ("%s", exprNode_unparse (term->value.expr) );
288 break;
289 case INTLITERAL:
a1fa5e0c 290 s = message (" %d ", (int) term->value.intlit);
616915dd 291 break;
292
293 case SREF:
d46ce6a4 294 s = message ("%q", sRef_unparse (term->value.sref) );
616915dd 295
296 break;
c3e695ff 297 default:
298 BADEXIT;
299 /*@notreached@*/
616915dd 300 break;
301 }
616915dd 302
c3e695ff 303 return s;
616915dd 304}
305
306constraintTerm
d46ce6a4 307constraintTerm_doSRefFixBaseParam (/*@returned@*/constraintTerm term, exprNodeList arglist) /*@modifies term@*/
616915dd 308{
309 llassert (term != NULL);
310
311 switch (term->kind)
312 {
313 case EXPRNODE:
b7b694d6 314 /*@i334*/ /*wtf*/
616915dd 315 break;
316 case INTLITERAL:
b7b694d6 317 break;
616915dd 318
319 case SREF:
320 term->value.sref = sRef_fixBaseParam (term->value.sref, arglist);
616915dd 321 break;
c3e695ff 322 default:
323 BADEXIT;
616915dd 324 }
325 return term;
326
327}
328
616915dd 329cstring constraintTerm_print (constraintTerm term) /*@*/
330{
331 cstring s;
332 s = cstring_undefined;
333
334 llassert (term != NULL);
335
336 switch (term->kind)
337 {
338 case EXPRNODE:
b7b694d6 339 /*@i334*/ /*wtf*/
a779b61e 340 s = message ("%s @ %q", exprNode_unparse (term->value.expr),
616915dd 341 fileloc_unparse (term->loc) );
342 break;
343 case INTLITERAL:
a779b61e 344 s = message ("%d", (int)term->value.intlit);
616915dd 345 break;
346
347 case SREF:
a779b61e 348 s = message ("%q", sRef_unparseDebug (term->value.sref) );
616915dd 349
350 break;
c3e695ff 351 default:
352 BADEXIT;
616915dd 353 }
354
355 return s;
356}
357
358
b9904f57 359constraintTerm constraintTerm_makeIntLiteral (long i)
616915dd 360{
361 constraintTerm ret = new_constraintTermExpr();
362 ret->value.intlit = i;
363 ret->kind = INTLITERAL;
364 ret->loc = fileloc_undefined;
365 return ret;
366}
367
368bool constraintTerm_canGetValue (constraintTerm term)
369{
370 if (term->kind == INTLITERAL)
b9904f57 371 {
372 return TRUE;
373 }
374 else if (term->kind == SREF)
375 {
376 if (sRef_hasValue (term->value.sref))
377 {
378 multiVal mval = sRef_getValue (term->value.sref);
379
380 return multiVal_isInt (mval); /* for now, only try to deal with int values */
381 }
382 else
383 {
384 return FALSE;
385 }
386 }
387 else if (term->kind == EXPRNODE)
388 {
389 return FALSE;
390 }
616915dd 391 else
b9904f57 392 {
393 return FALSE;
394 }
616915dd 395}
396
b9904f57 397long constraintTerm_getValue (constraintTerm term)
616915dd 398{
b9904f57 399 llassert (constraintTerm_canGetValue (term));
400
401 if (term->kind == INTLITERAL)
402 {
403 return term->value.intlit;
404 }
405 else if (term->kind == SREF)
406 {
407 if (sRef_hasValue (term->value.sref))
408 {
409 multiVal mval = sRef_getValue (term->value.sref);
410
411 return multiVal_forceInt (mval); /* for now, only try to deal with int values */
412 }
413 else
414 {
415 BADBRANCH;
416 }
417 }
418 else if (term->kind == EXPRNODE)
419 {
420 BADBRANCH;
421 }
422 else
423 {
424 BADBRANCH;
425 }
426
d30bc0c7 427 BADEXIT;
616915dd 428}
429
e5f31c00 430/*drl added this 10.30.001
431 */
432
433/*@exposed@*/ exprNode constraintTerm_getExprNode (constraintTerm t)
434{
435 llassert (t != NULL);
436
437 llassert (t->kind == EXPRNODE);
438
439 return t->value.expr;
440
441}
442
443 /*@exposed@*/ sRef constraintTerm_getsRef (constraintTerm t)
616915dd 444{
dc92450f 445 llassert (t != NULL);
616915dd 446 if (t->kind == EXPRNODE)
447 {
c3e695ff 448 return exprNode_getSref(t->value.expr);
616915dd 449 }
450
451 if (t->kind == SREF)
452 {
c3e695ff 453 return t->value.sref;
616915dd 454 }
455
456 return sRef_undefined;
457}
458
459bool constraintTerm_probSame (constraintTerm term1, constraintTerm term2)
460{
461 cstring s1, s2;
462
463 llassert (term1 !=NULL && term2 !=NULL);
464
bb7c2085 465 DPRINTF ((message
616915dd 466 ("Comparing srefs for %s and %s ", constraintTerm_print(term1), constraintTerm_print(term2)
467 )
468 )
469 );
470
471 s1 = constraintTerm_getName (term1);
472 s2 = constraintTerm_getName (term2);
473
474 if (cstring_equal (s1, s2) )
475 {
d46ce6a4 476 DPRINTF ((message (" %q and %q are same", s1, s2 ) ) );
616915dd 477 return TRUE;
478 }
479 else
480 {
d46ce6a4 481 DPRINTF ((message (" %q and %q are not same", s1, s2 ) ) );
616915dd 482 return FALSE;
483 }
484}
485
486bool constraintTerm_similar (constraintTerm term1, constraintTerm term2)
487{
488 sRef s1, s2;
489
490 llassert (term1 !=NULL && term2 !=NULL);
90bc41f7 491
b9904f57 492 if (constraintTerm_canGetValue (term1) && constraintTerm_canGetValue (term2))
493 /* evans 2001-07-24: was (term1->kind == INTLITERAL) && (term2->kind == INTLITERAL) ) */
90bc41f7 494 {
b9904f57 495 long t1, t2;
90bc41f7 496
b9904f57 497 t1 = constraintTerm_getValue (term1);
90bc41f7 498 t2 = constraintTerm_getValue (term2);
b9904f57 499
500 return (t1 == t2);
90bc41f7 501 }
b9904f57 502
503 if (constraintTerm_canGetValue (term1) || constraintTerm_canGetValue (term2))
504 {
505 /* evans 2001-07-24: is this right? */ /*@i534@*/
506 return FALSE;
507 }
508
616915dd 509 s1 = constraintTerm_getsRef (term1);
510 s2 = constraintTerm_getsRef (term2);
511
b9904f57 512 if (!(sRef_isValid(s1) && sRef_isValid(s2)))
616915dd 513 {
514 return FALSE;
515 }
516
bb7c2085 517 DPRINTF((message
616915dd 518 ("Comparing srefs for %s and %s ", constraintTerm_print(term1), constraintTerm_print(term2)
519 )
520 )
521 );
b9904f57 522
523 if (sRef_similarRelaxed(s1, s2) || sRef_sameName (s1, s2) )
524 {
525 DPRINTF ((message (" %s and %s are same", constraintTerm_print(term1), constraintTerm_print(term2) ) ));
526 return TRUE;
527 }
528 else
529 {
530 DPRINTF ((message (" %s and %s are not same", constraintTerm_print(term1), constraintTerm_print(term2) ) ));
531 return FALSE;
532 }
616915dd 533}
920a3797 534
6fcd0b1e 535void constraintTerm_dump (/*@observer@*/ constraintTerm t, FILE *f)
920a3797 536{
537 fileloc loc;
538 constraintTermValue value;
539 constraintTermType kind;
540 uentry u;
541
542 loc = t->loc;
543
544 value = t->value;
545
546 kind = t->kind;
547
548 fprintf(f, "%d\n", (int) kind);
549
550 switch (kind)
551 {
552
553 case EXPRNODE:
554 u = exprNode_getUentry(t->value.expr);
6fcd0b1e 555 fprintf (f, "%s\n", cstring_toCharsSafe (uentry_rawName (u)));
920a3797 556 break;
557
558 case SREF:
559 {
560 sRef s;
561
562 s = t->value.sref;
563
564 if (sRef_isResult (s ) )
565 {
566 fprintf(f, "Result\n");
567 }
6fcd0b1e 568 else if (sRef_isParam (s))
920a3797 569 {
570 int param;
571 ctype ct;
572 cstring ctString;
573
574
575 ct = sRef_getType (s);
576 param = sRef_getParam(s);
577
578 ctString = ctype_dump(ct);
579
28bf4b0b 580 fprintf(f, "Param %s %d\n", cstring_toCharsSafe(ctString), (int) param );
920a3797 581 cstring_free(ctString);
582 }
0f9b7373 583 else if (sRef_isField (s) )
584 {
585 fprintf(f, "sRef_dump %s\n", cstring_toCharsSafe(sRef_dump(s)) );
586 }
920a3797 587 else
588 {
589 u = sRef_getUentry(s);
6fcd0b1e 590 fprintf (f, "%s\n", cstring_toCharsSafe (uentry_rawName (u)));
920a3797 591 }
592
593 }
594 break;
595
596 case INTLITERAL:
b9904f57 597 fprintf (f, "%ld\n", t->value.intlit);
920a3797 598 break;
599
600 default:
601 BADEXIT;
602 }
603
604}
605
606
abd7f895 607/*@only@*/ constraintTerm constraintTerm_undump (FILE *f)
920a3797 608{
920a3797 609 constraintTermType kind;
610 constraintTerm ret;
611
612 uentry ue;
613
6970c11b 614 char *str;
615 char *os;
920a3797 616
3be9a165 617 os = mstring_create (MAX_DUMP_LINE_LENGTH);
618
6970c11b 619 str = fgets (os, MAX_DUMP_LINE_LENGTH, f);
920a3797 620
abd7f895 621 llassert (str != NULL);
622
28bf4b0b 623 kind = (constraintTermType) reader_getInt(&str);
920a3797 624 str = fgets(os, MAX_DUMP_LINE_LENGTH, f);
625
abd7f895 626 llassert (str != NULL);
627
920a3797 628 switch (kind)
629 {
630
631 case SREF:
632 {
633 sRef s;
634 char * term;
28bf4b0b 635 term = reader_getWord(&str);
920a3797 636
637 if (strcmp (term, "Result") == 0 )
638 {
b072092f 639 s = sRef_makeResult (ctype_unknown);
920a3797 640 }
641 else if (strcmp (term, "Param" ) == 0 )
642 {
643 int param;
644 char *str2, *ostr2;
645
646 ctype t;
647
28bf4b0b 648 reader_checkChar(&str, ' ');
649 str2 = reader_getWord(&str);
650 param = reader_getInt(&str);
920a3797 651
652 ostr2 = str2;
653 t = ctype_undump(&str2) ;
16c024b5 654 s = sRef_makeParam (param, t, stateInfo_makeLoc (g_currentloc, SA_CREATED));
920a3797 655 free (ostr2);
656 }
0f9b7373 657 else if (strcmp (term, "sRef_dump" ) == 0 )
658 {
659 reader_checkChar(&str, ' ');
660 s = sRef_undump (&str);
661 }
b7b694d6 662 else /* This must be an identified that we can search for in usymTab */
920a3797 663 {
28bf4b0b 664 cstring termStr = cstring_makeLiteralTemp(term);
665
666 ue = usymtab_lookup (termStr);
920a3797 667 s = uentry_getSref(ue);
668 }
669
670 ret = constraintTerm_makesRef(s);
671
672 free(term);
673 }
674 break;
675
676 case EXPRNODE:
677 {
678 sRef s;
679 char * term;
28bf4b0b 680 cstring termStr;
920a3797 681
28bf4b0b 682 term = reader_getWord(&str);
b7b694d6 683 /* This must be an identifier that we can search for in usymTab */
28bf4b0b 684 termStr = cstring_makeLiteralTemp(term);
920a3797 685
28bf4b0b 686 ue = usymtab_lookup (termStr);
920a3797 687 s = uentry_getSref(ue);
688 ret = constraintTerm_makesRef(s);
689
690 free (term);
691 }
692 break;
693
694
695 case INTLITERAL:
696 {
697 int i;
698
28bf4b0b 699 i = reader_getInt(&str);
920a3797 700 ret = constraintTerm_makeIntLiteral (i);
701 }
702 break;
703
704 default:
705 BADEXIT;
706 }
707 free (os);
708
709 return ret;
710}
711
712
713
86d93ed3 714/* drl added sometime before 10/17/001*/
715ctype constraintTerm_getCType (constraintTerm term)
716{
717 ctype ct;
718
719 switch (term->kind)
720 {
721 case EXPRNODE:
722 ct = exprNode_getType (term->value.expr);
723 break;
724
725 case INTLITERAL:
726 /*@i888*/ /* hack */
727 ct = ctype_signedintegral;
728 break;
729
730 case SREF:
731 ct = sRef_getType (term->value.sref) ;
732 break;
733 default:
734 BADEXIT;
735 }
736 return ct;
737}
920a3797 738
This page took 1.179238 seconds and 5 git commands to generate.