]> andersk Git - splint.git/blame - src/constraintTerm.c
Added pointers.c and pointers.h to CVS.
[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
535void constraintTerm_dump ( /*@observer@*/ constraintTerm t, FILE *f)
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);
28bf4b0b 555 fprintf(f, "%s\n", cstring_toCharsSafe( uentry_rawName (u) )
556 );
920a3797 557 break;
558
559 case SREF:
560 {
561 sRef s;
562
563 s = t->value.sref;
564
565 if (sRef_isResult (s ) )
566 {
567 fprintf(f, "Result\n");
568 }
569 else if (sRef_isParam (s ) )
570 {
571 int param;
572 ctype ct;
573 cstring ctString;
574
575
576 ct = sRef_getType (s);
577 param = sRef_getParam(s);
578
579 ctString = ctype_dump(ct);
580
28bf4b0b 581 fprintf(f, "Param %s %d\n", cstring_toCharsSafe(ctString), (int) param );
920a3797 582 cstring_free(ctString);
583 }
584 else
585 {
586 u = sRef_getUentry(s);
28bf4b0b 587 fprintf(f, "%s\n", cstring_toCharsSafe(uentry_rawName (u) ) );
920a3797 588 }
589
590 }
591 break;
592
593 case INTLITERAL:
b9904f57 594 fprintf (f, "%ld\n", t->value.intlit);
920a3797 595 break;
596
597 default:
598 BADEXIT;
599 }
600
601}
602
603
abd7f895 604/*@only@*/ constraintTerm constraintTerm_undump (FILE *f)
920a3797 605{
920a3797 606 constraintTermType kind;
607 constraintTerm ret;
608
609 uentry ue;
610
6970c11b 611 char *str;
612 char *os;
920a3797 613
3be9a165 614 os = mstring_create (MAX_DUMP_LINE_LENGTH);
615
6970c11b 616 str = fgets (os, MAX_DUMP_LINE_LENGTH, f);
920a3797 617
abd7f895 618 llassert (str != NULL);
619
28bf4b0b 620 kind = (constraintTermType) reader_getInt(&str);
920a3797 621 str = fgets(os, MAX_DUMP_LINE_LENGTH, f);
622
abd7f895 623 llassert (str != NULL);
624
920a3797 625 switch (kind)
626 {
627
628 case SREF:
629 {
630 sRef s;
631 char * term;
28bf4b0b 632 term = reader_getWord(&str);
920a3797 633
634 if (strcmp (term, "Result") == 0 )
635 {
b072092f 636 s = sRef_makeResult (ctype_unknown);
920a3797 637 }
638 else if (strcmp (term, "Param" ) == 0 )
639 {
640 int param;
641 char *str2, *ostr2;
642
643 ctype t;
644
28bf4b0b 645 reader_checkChar(&str, ' ');
646 str2 = reader_getWord(&str);
647 param = reader_getInt(&str);
920a3797 648
649 ostr2 = str2;
650 t = ctype_undump(&str2) ;
6970c11b 651 s = sRef_makeParam (param, t, stateInfo_makeLoc (g_currentloc));
920a3797 652 free (ostr2);
653 }
b7b694d6 654 else /* This must be an identified that we can search for in usymTab */
920a3797 655 {
28bf4b0b 656 cstring termStr = cstring_makeLiteralTemp(term);
657
658 ue = usymtab_lookup (termStr);
920a3797 659 s = uentry_getSref(ue);
660 }
661
662 ret = constraintTerm_makesRef(s);
663
664 free(term);
665 }
666 break;
667
668 case EXPRNODE:
669 {
670 sRef s;
671 char * term;
28bf4b0b 672 cstring termStr;
920a3797 673
28bf4b0b 674 term = reader_getWord(&str);
b7b694d6 675 /* This must be an identifier that we can search for in usymTab */
28bf4b0b 676 termStr = cstring_makeLiteralTemp(term);
920a3797 677
28bf4b0b 678 ue = usymtab_lookup (termStr);
920a3797 679 s = uentry_getSref(ue);
680 ret = constraintTerm_makesRef(s);
681
682 free (term);
683 }
684 break;
685
686
687 case INTLITERAL:
688 {
689 int i;
690
28bf4b0b 691 i = reader_getInt(&str);
920a3797 692 ret = constraintTerm_makeIntLiteral (i);
693 }
694 break;
695
696 default:
697 BADEXIT;
698 }
699 free (os);
700
701 return ret;
702}
703
704
705
86d93ed3 706/* drl added sometime before 10/17/001*/
707ctype constraintTerm_getCType (constraintTerm term)
708{
709 ctype ct;
710
711 switch (term->kind)
712 {
713 case EXPRNODE:
714 ct = exprNode_getType (term->value.expr);
715 break;
716
717 case INTLITERAL:
718 /*@i888*/ /* hack */
719 ct = ctype_signedintegral;
720 break;
721
722 case SREF:
723 ct = sRef_getType (term->value.sref) ;
724 break;
725 default:
726 BADEXIT;
727 }
728 return ct;
729}
920a3797 730
This page took 0.181723 seconds and 5 git commands to generate.