]> andersk Git - splint.git/blame - src/uentry.c
Moved doc/lclint.1 to doc/splint.1
[splint.git] / src / uentry.c
CommitLineData
616915dd 1/*
11db3170 2** Splint - annotation-assisted static program checker
77d37419 3** Copyright (C) 1994-2002 University of Virginia,
616915dd 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
616915dd 23*/
24/*
25** uentry.c
26*/
27
1b8ae690 28# include "splintMacros.nf"
616915dd 29# include "basic.h"
30# include "structNames.h"
31# include "nameChecks.h"
32
616915dd 33static /*@dependent@*/ uentry posRedeclared = uentry_undefined;
34static /*@only@*/ fileloc posLoc = fileloc_undefined;
35static int nuentries = 0;
36static int totuentries = 0;
37
38static void checkGlobalsModifies (/*@notnull@*/ uentry p_ue, sRefSet p_sr) ;
39static void uentry_setDeclDef (uentry p_e, fileloc p_f) /*@modifies p_e@*/ ;
40static bool uentry_isRefCounted (uentry p_ue) /*@*/ ;
41static bool uentry_isRefsField (uentry p_ue) /*@*/ ;
42static bool uentry_isReallySpecified (uentry p_e) /*@*/ ;
43static void uentry_checkIterArgs (uentry p_ue);
44static cstring uentry_dumpAux (uentry p_v, bool p_isParam);
45
146e25eb 46static void uentry_showWhereLastKind (uentry p_spec) /*@modifies g_msgstream@*/ ;
f2b6724f 47
28bf4b0b 48static void uentry_combineModifies (uentry p_ue, /*@owned@*/ sRefSet p_sr)
49 /*@modifies p_ue@*/ ;
50
51static void uentry_addStateClause (uentry p_ue, /*@only@*/ stateClause p_sc)
52 /*@modifies p_ue@*/ ;
53
616915dd 54/*@access ekind@*/
55static void checkAliasState (/*@notnull@*/ uentry p_old,
56 /*@notnull@*/ uentry p_unew,
57 bool p_mustConform, bool p_completeConform)
58 /*@modifies p_old, p_unew@*/ ;
59static void checkNullState (/*@notnull@*/ uentry p_old,
60 /*@notnull@*/ uentry p_unew,
61 bool p_mustConform, bool p_completeConform)
62 /*@modifies p_old, p_unew@*/ ;
63
64static void checkVarConformance (/*@notnull@*/ uentry p_old,
65 /*@notnull@*/ uentry p_unew,
66 bool p_mustConform, bool p_completeConform)
67 /*@modifies p_old, p_unew@*/;
68
69# ifndef NOLCL
70static void uentry_setHasMods (uentry p_ue) /*@modifies p_ue@*/;
71static void uentry_setHasGlobs (uentry p_ue) /*@modifies p_ue@*/;
72# endif
73
74static void uentry_reallyFree (/*@notnull@*/ /*@only@*/ uentry p_e);
75
76static void uentry_setSpecDef (/*@special@*/ uentry p_e, /*@keep@*/ fileloc p_f)
77 /*@defines p_e->whereSpecified, p_e->whereDeclared, p_e->whereDefined@*/
78 /*@modifies p_e@*/;
79
80static void returnValueError (/*@notnull@*/ uentry p_old, /*@notnull@*/ uentry p_unew);
81static void nargsError (/*@notnull@*/ uentry p_old, /*@notnull@*/ uentry p_unew);
82static /*@observer@*/ cstring paramStorageName (uentry p_ue) /*@*/ ;
83static /*@observer@*/ cstring fcnErrName (uentry p_ue) /*@*/ ;
84static /*@observer@*/ cstring checkedName (chkind p_checked) /*@*/ ;
85static void
86 paramTypeError (/*@notnull@*/ uentry p_old, /*@notnull@*/ uentry p_oldCurrent,
87 ctype p_oldType, /*@notnull@*/ uentry p_unew,
88 /*@notnull@*/ uentry p_newCurrent,
89 ctype p_newType, int p_paramno) /*@modifies g_msgstream@*/ ;
90
91static /*@only@*/ /*@notnull@*/ uentry
92 uentry_makeVariableAux (cstring p_n, ctype p_t, /*@keep@*/ fileloc p_f,
93 /*@exposed@*/ sRef p_s, bool p_priv, vkind p_kind);
94
3e3ec469 95static /*@only@*/ /*@notnull@*/ uentry
96 uentry_makeConstantAux (cstring p_n, ctype p_t,
97 /*@keep@*/ fileloc p_f, bool p_priv, bool p_macro,
98 /*@only@*/ multiVal p_m) /*@*/ ;
5e211f69 99
efd360a3 100static void uentry_convertVarFunction (uentry ue) /*@modifies ue@*/
101{
102 if (uentry_isVariable (ue)
103 && (ctype_isFunction (ctype_realType (uentry_getType (ue)))
104 || ctype_isUnknown (uentry_getType (ue))))
105 {
106 uentry_makeVarFunction (ue);
107 }
108}
109
616915dd 110static /*@out@*/ /*@notnull@*/ uentry uentry_alloc (void) /*@*/
111{
112 uentry ue = (uentry) dmalloc (sizeof (*ue));
28bf4b0b 113 ue->warn = warnClause_undefined; /*@i32@*/
616915dd 114 nuentries++;
115 totuentries++;
116
117 return ue;
118}
119
120static cstring uentry_getOptName (uentry p_e) /*@*/ ;
efd360a3 121static void uentry_updateInto (/*@unique@*/ uentry p_unew, uentry p_old) /*@modifies p_unew, p_old@*/ ;
122
616915dd 123static void uentry_setNullState (/*@notnull@*/ uentry p_ue, nstate p_ns);
124static void uentry_setAliasKind (/*@notnull@*/ uentry p_ue, alkind p_ak);
125static /*@only@*/ /*@null@*/ uinfo uinfo_copy (uinfo p_u, ekind p_kind);
126static void uinfo_free (/*@only@*/ uinfo p_u, ekind p_kind);
b072092f 127static void ucinfo_free (/*@only@*/ ucinfo p_u);
616915dd 128static void uvinfo_free (/*@only@*/ uvinfo p_u);
129
130# ifdef DOANNOTS
131
132static /*@only@*/ cstring ancontext_unparse (ancontext an)
133{
134 switch (an)
135 {
136 case AN_UNKNOWN: return cstring_makeLiteral ("unknown");
137 case AN_FCNRETURN: return cstring_makeLiteral ("return value");
138 case AN_FCNPARAM: return cstring_makeLiteral ("function param");
139 case AN_SUFIELD: return cstring_makeLiteral ("su field");
140 case AN_TDEFN: return cstring_makeLiteral ("type definition");
141 case AN_GSVAR: return cstring_makeLiteral ("global/static var");
142 case AN_CONST: return cstring_makeLiteral ("constant");
143 BADDEFAULT;
144 }
145 BADEXIT;
146}
147
148static int annots[AN_LAST][QU_LAST];
149static int decls[AN_LAST];
150static int shdecls[AN_LAST];
151static int idecls[AN_LAST];
152
153void initAnnots ()
154{
155 int i, j;
156
157 for (i = AN_UNKNOWN; i < AN_LAST; i++)
158 {
159 decls[i] = 0;
160 shdecls[i] = 0;
161 idecls[i] = 0;
162
163 for (j = QU_UNKNOWN; j < QU_LAST; j++)
164 {
165 annots[i][j] = 0;
166 }
167 }
168}
169
170static void tallyAnnot (ancontext ac, qual q)
171{
172 (annots[ac][q])++;
173}
174
175void printAnnots ()
176{
177 int total[QU_LAST];
178 int alltotals = 0;
179 int totdecls = 0;
180 int totshdecls = 0;
181 int totidecls = 0;
182 int i, j;
183
184 for (j = QU_UNKNOWN; j < QU_LAST; j++)
185 {
186 total[j] = 0;
187 }
188
189 for (i = AN_UNKNOWN; i < AN_LAST; i++)
190 {
191 int tmptot;
192
193 if (decls[i] > 0)
194 {
195 printf ("Context: %s (%d declarations, %d sharable, %d indirect)\n",
196 ancontext_unparse (i),
197 decls[i], shdecls[i], idecls[i]);
198
199 totdecls += decls[i];
200 totshdecls += shdecls[i];
201 totidecls += idecls[i];
202
203 for (j = QU_UNKNOWN; j < QU_LAST; j++)
204 {
205 total[j] += annots[i][j];
206 alltotals += annots[i][j];
207 }
208
209 printf (" Allocation:\n");
210
211 tmptot = 0;
212
213 for (j = QU_UNKNOWN; j < QU_LAST; j++)
214 {
215 if (qual_isAliasQual (j) && !qual_isUnique (j))
216 {
217 if (annots[i][j] > 0)
218 {
219 printf ("\t%10s: %5d (%3.2f%%)\n", qual_unparse (j), annots[i][j],
220 100.0 * (double)annots[i][j] / (double)decls[i]);
221 tmptot += annots[i][j];
222 }
223 }
224 }
225
226 printf (" Exposure:\n");
227
228 tmptot = 0;
229
230 for (j = QU_UNKNOWN; j < QU_LAST; j++)
231 {
232 if (qual_isExQual (j))
233 {
234 if (annots[i][j] > 0)
235 {
236 printf ("\t%10s: %5d (%3.2f%%)\n", qual_unparse (j), annots[i][j],
237 100.0 * (double)annots[i][j] / (double)decls[i]);
238 tmptot += annots[i][j];
239 }
240 }
241 }
242
243 printf (" Definition:\n");
244
245 for (j = QU_UNKNOWN; j < QU_LAST; j++)
246 {
247 if (qual_isAllocQual (j))
248 {
249 if (annots[i][j] > 0)
250 {
251 printf ("\t%10s: %5d (%3.2f%%)\n", qual_unparse (j), annots[i][j],
252 100.0 * (double)annots[i][j] / (double)decls[i]);
253 }
254 }
255 }
256
257 printf (" Null:\n");
258
259 for (j = QU_UNKNOWN; j < QU_LAST; j++)
260 {
261 if (qual_isNull (j) || qual_isNotNull (j) || qual_isRelNull (j))
262 {
263 if (annots[i][j] > 0)
264 {
265 printf ("\t%10s: %5d (%3.2f%%)\n", qual_unparse (j), annots[i][j],
266 100.0 * (double)annots[i][j] / (double)decls[i]);
267 }
268 }
269 }
270
271 printf ("\n");
272 }
273 }
274
275 for (j = QU_UNKNOWN; j < QU_LAST; j++)
276 {
277 bool hasone = FALSE;
278
279 for (i = AN_UNKNOWN; i < AN_LAST; i++)
280 {
281 if (annots[i][j] > 0)
282 {
283 hasone = TRUE;
284 break;
285 }
286 }
287
288 if (hasone)
289 {
290 printf ("Annotation: %s\n", qual_unparse (j));
291
292 for (i = AN_UNKNOWN; i < AN_LAST; i++)
293 {
294 if (annots[i][j] > 0)
295 {
296 printf ("%25s: %5d\n", ancontext_unparse (i), annots[i][j]);
297 }
298 }
299 printf ("\n");
300 }
301 }
302
303 printf ("All Contexts\n");
304
305 for (j = QU_UNKNOWN; j < QU_LAST; j++)
306 {
307 if (total[j] > 0)
308 {
309 printf ("%10s: %5d (%3.2f%%)\n", qual_unparse (j), total[j],
310 100.0 * (double)total[j] / (double)(totdecls));
311 }
312 }
313 printf ("\n");
314
4ab867d6 315 printf ("Total Annotations: %d (%d decls, %d sharable, %d indirect)\n", alltotals, totdecls, totshdecls, totidecls); }
616915dd 316
317extern void uentry_tallyAnnots (uentry u, ancontext kind)
318{
319 alkind ak = sRef_getAliasKind (u->sref);
320 exkind ek = sRef_getExKind (u->sref);
321 nstate ns = sRef_getNullState (u->sref);
322 sstate ss = sRef_getDefState (u->sref);
323 bool recordUnknown = FALSE;
616915dd 324
325 if (kind == AN_UNKNOWN)
326 {
327 ekind e = u->ukind;
328
329 if (e == KENDITER)
330 {
331 return;
332 }
333 else if (e == KCONST || e == KENUMCONST)
334 {
335 kind = AN_CONST;
336 }
337 else if (e == KFCN || e == KITER)
338 {
339 uentryList params = uentry_getParams (u);
340 bool hasRet = FALSE;
341
342 uentryList_elements (params, current)
343 {
344 if (uentry_isReturned (current))
345 {
346 hasRet = TRUE;
347 }
348 if (!uentry_isElipsisMarker (current))
349 {
350 uentry_tallyAnnots (current, AN_FCNPARAM);
351 }
352 } end_uentryList_elements;
353
354 kind = AN_FCNRETURN;
355
356 if (ctype_isFunction (u->utype)
357 && !hasRet
28bf4b0b 358 && ctype_isVisiblySharable (ctype_realType (ctype_getReturnType (u->utype))))
616915dd 359 {
360 recordUnknown = TRUE;
361 }
362 }
363 else if (e == KDATATYPE || e == KSTRUCTTAG || e == KUNIONTAG || e == KENUMTAG)
364 {
365 ctype t = ctype_realType (u->utype);
366
367 if (ctype_isSU (t))
368 {
369 uentryList fields = ctype_getFields (t);
370
371 uentryList_elements (fields, current)
372 {
373 uentry_tallyAnnots (current, AN_SUFIELD);
374 }
375 } end_uentryList_elements;
376
377 kind = AN_TDEFN;
378
379 if (ctype_isVisiblySharable (u->utype))
380 {
381 recordUnknown = TRUE;
382 }
383 }
384 else
385 {
386 kind = AN_GSVAR;
387
388
389 if (ctype_isVisiblySharable (ctype_realType (u->utype)))
390 {
391 recordUnknown = TRUE;
392 }
393 }
394 }
395
396 decls[kind]++;
397
398 if (kind == AN_FCNRETURN)
399 {
400 if (recordUnknown)
401 {
402 shdecls[kind]++;
403 idecls[kind]++;
404 }
405 else
406 {
407 ;
408 }
409 }
410 else
411 {
412 if (ctype_isVisiblySharable (ctype_realType (u->utype)))
413 {
414 shdecls[kind]++;
415 }
416
417 if (ctype_isRealPointer (ctype_realType (u->utype)))
418 {
419 idecls[kind]++;
420 }
421 }
422
616915dd 423 switch (ss)
424 {
425 case SS_ALLOCATED: tallyAnnot (kind, QU_OUT); break;
426 case SS_PARTIAL: tallyAnnot (kind, QU_PARTIAL); break;
427 case SS_RELDEF: tallyAnnot (kind, QU_RELDEF); break;
428 case SS_SPECIAL: tallyAnnot (kind, QU_SPECIAL); break;
429 default: break;
430 }
431
432 if (uentry_isReturned (u))
433 {
434 tallyAnnot (kind, QU_RETURNED);
435 }
436
437 switch (ak)
438 {
439 case AK_UNKNOWN:
440 if (ctype_isRefCounted (ctype_realType (u->utype))
441 || (ctype_isFunction (u->utype) &&
28bf4b0b 442 ctype_isRefCounted (ctype_realType (ctype_getReturnType (u->utype)))))
616915dd 443 {
444 ;
445 }
446 else
447 {
448 if (kind == AN_FCNPARAM)
449 {
450 tallyAnnot (kind, QU_TEMP);
451 }
452 else if (recordUnknown)
453 {
454 if (kind == AN_FCNRETURN)
455 {
456 }
457 tallyAnnot (kind, QU_UNKNOWN);
458 }
459 }
460 break;
461 case AK_ONLY: tallyAnnot (kind, QU_ONLY); break;
462 case AK_IMPONLY: tallyAnnot (kind, QU_ONLY); break;
463 case AK_KEEP: tallyAnnot (kind, QU_KEEP); break;
464 case AK_KEPT: tallyAnnot (kind, QU_KEPT); break;
465 case AK_IMPTEMP:
466 case AK_TEMP: tallyAnnot (kind, QU_TEMP); break;
467 case AK_SHARED: tallyAnnot (kind, QU_SHARED); break;
468 case AK_UNIQUE: tallyAnnot (kind, QU_UNIQUE); break;
469 case AK_RETURNED: tallyAnnot (kind, QU_RETURNED); break;
470 case AK_REFCOUNTED: tallyAnnot (kind, QU_UNKNOWN); break;
471 case AK_REFS: tallyAnnot (kind, QU_REFS); break;
472 case AK_KILLREF: tallyAnnot (kind, QU_KILLREF); break;
473 case AK_NEWREF: tallyAnnot (kind, QU_NEWREF); break;
474 case AK_OWNED: tallyAnnot (kind, QU_OWNED); break;
475 case AK_IMPDEPENDENT:
476 case AK_DEPENDENT: tallyAnnot (kind, QU_DEPENDENT); break;
477 case AK_ERROR:
478 case AK_FRESH:
479 case AK_STACK:
480 case AK_LOCAL:
481 break;
482 }
483
484 switch (ek)
485 {
486 case XO_EXPOSED: tallyAnnot (kind, QU_EXPOSED); break;
487 case XO_OBSERVER: tallyAnnot (kind, QU_OBSERVER); break;
488 default: break;
489 }
490
491 switch (ns)
492 {
493 case NS_ERROR: break;
494 case NS_UNKNOWN: break;
495 case NS_NOTNULL: break;
496 case NS_MNOTNULL: tallyAnnot (kind, QU_NOTNULL); break;
497 case NS_RELNULL: tallyAnnot (kind, QU_RELNULL); break;
498 case NS_CONSTNULL: tallyAnnot (kind, QU_NULL); break;
499 case NS_POSNULL: tallyAnnot (kind, QU_NULL); break;
500 case NS_DEFNULL:
501 case NS_ABSNULL: break;
502 }
503}
504
505# endif
506
507static /*@observer@*/ cstring specCode_unparse (specCode s) /*@*/
508{
509 switch (s)
510 {
511 case SPC_NONE: return cstring_makeLiteralTemp ("normal");
512 case SPC_PRINTFLIKE: return cstring_makeLiteralTemp ("printflike");
513 case SPC_SCANFLIKE: return cstring_makeLiteralTemp ("scanflike");
514 case SPC_MESSAGELIKE: return cstring_makeLiteralTemp ("messagelike");
515 case SPC_LAST: return cstring_makeLiteralTemp ("<error>");
516 }
517
518 BADEXIT;
519}
520
521static specCode specCode_fromInt (int i)
522{
523 /*@+enumint@*/
524 llassert (i >= SPC_NONE && i < SPC_LAST);
525
526 return ((specCode) i);
527 /*@=enumint@*/
528}
529
530/*@observer@*/ cstring uentry_specOrDefName (uentry u)
531{
532 if (uentry_isDeclared (u))
533 {
534 return cstring_makeLiteralTemp ("previously declared");
535 }
536 else
537 {
538 return cstring_makeLiteralTemp ("specified");
539 }
540}
541
542/*@observer@*/ cstring uentry_specDeclName (uentry u)
543{
544 if (uentry_isDeclared (u))
545 {
546 return cstring_makeLiteralTemp ("previous declaration");
547 }
548 else
549 {
550 return cstring_makeLiteralTemp ("specification");
551 }
552}
553
554static /*@observer@*/ cstring uentry_reDefDecl (uentry old, uentry unew) /*@*/
555{
556 if (uentry_isCodeDefined (old) && uentry_isCodeDefined (unew))
557 {
558 return cstring_makeLiteralTemp ("redefined");
559 }
560 else if (uentry_isCodeDefined (unew))
561 {
562 return cstring_makeLiteralTemp ("defined");
563 }
564 else if (uentry_isDeclared (old) && uentry_isDeclared (unew))
565 {
566 return cstring_makeLiteralTemp ("redeclared");
567 }
568 else
569 {
570 return cstring_makeLiteralTemp ("declared");
571 }
572}
573
ccf0a4a8 574static constraintList uentry_getFunctionConditions (uentry ue, bool isPost)
616915dd 575{
576 if (uentry_isValid (ue))
577 {
ccf0a4a8 578 functionConstraint constraint;
616915dd 579
bb7c2085 580 DPRINTF((message ("called uentry_getFcnPostconditions on %s",
ccf0a4a8 581 uentry_unparse (ue) ) ) );
582
583 if (uentry_isVariable (ue) && ctype_isFunction (uentry_getType (ue)))
616915dd 584 {
bb7c2085 585 DPRINTF((message ("called uentry_getFunctionConditions on nonfunction %s",
ccf0a4a8 586 uentry_unparse (ue) ) ) );
587 if (!uentry_isFunction (ue) )
616915dd 588 {
ccf0a4a8 589 DPRINTF((message ("called uentry_getFunctionConditions on nonfunction %s",
590 uentry_unparse (ue) ) ));
591 return constraintList_undefined;
28bf4b0b 592 }
ccf0a4a8 593
594
595 return constraintList_undefined;
596 }
597
598 if (!uentry_isFunction(ue))
599 {
600
bb7c2085 601 DPRINTF((message ("called uentry_getFunctionConditions on non function %s",
ccf0a4a8 602 uentry_unparse (ue) ) ) );
603 return constraintList_undefined;
604
605 }
3814599d 606
ccf0a4a8 607 llassert (uentry_isFunction (ue));
3814599d 608
ccf0a4a8 609 if (isPost)
610 {
611 constraint = ue->info->fcn->postconditions;
616915dd 612 }
ccf0a4a8 613 else
614 {
615 constraint = ue->info->fcn->preconditions;
616 }
617
618 return functionConstraint_getBufferConstraints (constraint);
616915dd 619 }
620
621 return constraintList_undefined;
622
623}
624
ccf0a4a8 625/*drl7x*/
626/*@only@*/ constraintList uentry_getFcnPreconditions (uentry ue)
627{
628 return uentry_getFunctionConditions (ue, FALSE);
629}
630
631/*drl
632 12/28/2000
633*/
634
635constraintList uentry_getFcnPostconditions (uentry ue)
636{
637 return uentry_getFunctionConditions (ue, TRUE);
638}
616915dd 639
640static /*@only@*/ fileloc setLocation (void)
641{
642 fileloc fl = context_getSaveLocation ();
643
644 if (fileloc_isDefined (fl))
645 {
646 return fl;
647 }
648 else
649 {
650 return fileloc_copy (g_currentloc);
651 }
652}
653
b9904f57 654static void uentry_setConstantValue (uentry ue, /*@only@*/ multiVal val)
655{
656 llassert (uentry_isEitherConstant (ue));
657 sRef_setValue (ue->sref, val);
658}
659
616915dd 660/*@notnull@*/ uentry uentry_makeEnumConstant (cstring n, ctype t)
661{
662 fileloc loc = setLocation ();
663 uentry ue = uentry_makeConstant (n, t, loc);
664
665 ue->ukind = KENUMCONST;
666 uentry_setDefined (ue, loc);
667 return ue;
668}
669
670/*@notnull@*/ uentry uentry_makeEnumInitializedConstant (cstring n, ctype t, exprNode expr)
671{
672 fileloc loc = setLocation ();
673 uentry ue = uentry_makeConstant (n, t, loc);
674 ctype etype = exprNode_getType (expr);
675
676 if (!ctype_isRealInt (etype)) {
677 voptgenerror
678 (FLG_ENUMMEMBERS,
679 message
680 ("Value of enum member is not an integeral type (type %s): %s",
681 ctype_unparse (etype), exprNode_unparse (expr)),
682 exprNode_loc (expr));
683 }
684
685 ue->ukind = KENUMCONST;
686 uentry_setDefined (ue, loc);
687 return ue;
688}
689
690# ifndef NOLCL
691/*@notnull@*/ uentry uentry_makeSpecEnumConstant (cstring n, ctype t, fileloc loc)
692{
693 uentry ue = uentry_makeConstant (n, t, loc);
694
695 ue->ukind = KENUMCONST;
696 return ue;
697}
698# endif
699
700/*@notnull@*/ uentry uentry_makeVariableLoc (cstring n, ctype t)
701{
702 return uentry_makeVariable (n, t, setLocation (), FALSE);
703}
704
705# ifndef NOLCL
706/*@notnull@*/ /*@only@*/ uentry uentry_makeUnnamedVariable (ctype t)
707{
708 return uentry_makeVariable (cstring_undefined, t, setLocation (), FALSE);
709}
710# endif
711
712/*@notnull@*/ uentry uentry_makeIdDatatype (idDecl id)
713{
714 ctype ct = idDecl_getCtype (id);
715 uentry ue = uentry_makeDatatype (idDecl_observeId (id), ct,
716 MAYBE, MAYBE, setLocation ());
717
718 uentry_reflectQualifiers (ue, idDecl_getQuals (id));
719
720 if (!ynm_isOn (ue->info->datatype->abs))
721 {
722 if (ctype_isUnknown (ct))
723 {
724 ue->info->datatype->mut = MAYBE;
725 }
726 else
727 {
728 ue->info->datatype->mut = ynm_fromBool (ctype_isMutable (ct));
729 }
730 }
731
732 return ue;
733}
734
735void uentry_checkParams (uentry ue)
736{
737 if (uentry_isValid (ue))
738 {
739 bool isExt = uentry_isExtern (ue);
740
741 if (uentry_isRealFunction (ue))
742 {
743 uentryList params = uentry_getParams (ue);
744
745 uentryList_elements (params, current)
746 {
747 if (uentry_isValid (current))
748 {
749 ctype ct = current->utype;
750
751 if (ctype_isFixedArray (ct))
752 {
753 if (ctype_isArray (ctype_baseArrayPtr (ct))
754 && !ctype_isFixedArray (ctype_baseArrayPtr (ct)))
755 {
756 ;
757 }
758 else
759 {
760 voptgenerror
761 (FLG_FIXEDFORMALARRAY,
762 message ("Function parameter %q declared as "
763 "manifest array (size constant is meaningless)",
764 uentry_getName (current)),
765 uentry_whereDeclared (current));
766 }
767 }
768 else
769 {
770 if (ctype_isArray (ct))
771 {
772 voptgenerror
773 (FLG_FORMALARRAY,
774 message ("Function parameter %q declared as "
775 "array (treated as pointer)",
776 uentry_getName (current)),
777 uentry_whereDeclared (current));
778 }
779 }
780
781 if (sRef_getNullState (uentry_getSref (current)) == NS_MNOTNULL)
782 {
783 if (ctype_isAbstract (ct) &&
784 (isExt || (ctype_isAbstract (ctype_realType (ct))
785 && !context_hasFileAccess (ctype_typeId (ct)))))
786 {
787 vgenhinterror
788 (FLG_INCONDEFS,
789 message
790 ("Function %q declared with notnull parameter %q of abstract "
791 "type %s",
792 uentry_getName (ue),
793 uentry_getName (current),
794 ctype_unparse (ct)),
795 message
796 ("Since %s is an abstract type, notnull can only be "
797 "used for parameters if the function is static to a "
798 "module where %s is accessible.",
799 ctype_unparse (ct),
800 ctype_unparse (ct)),
801 uentry_whereDeclared (current));
802 }
803 }
804 }
805 } end_uentryList_elements;
806
807 if (sRef_getNullState (uentry_getSref (ue)) == NS_MNOTNULL)
808 {
809 ctype ct = ue->utype;
810
811 if (ctype_isAbstract (ct)
812 && (isExt || (ctype_isAbstract (ctype_realType (ct))
813 && !context_hasFileAccess (ctype_typeId (ct)))))
814 {
815 vgenhinterror
816 (FLG_INCONDEFS,
817 message
818 ("%s %q declared %s notnull storage of abstract type %s",
819 ekind_capName (uentry_getKind (ue)),
820 uentry_getName (ue),
821 fcnErrName (ue),
822 ctype_unparse (ct)),
823 message
824 ("Since %s is an abstract type, notnull can only be used "
825 "if it is static to a module where %s is accessible.",
826 ctype_unparse (ct),
827 ctype_unparse (ct)),
828 uentry_whereDeclared (ue));
829 }
830 }
831 }
832 }
833}
834
835static void reflectImplicitFunctionQualifiers (/*@notnull@*/ uentry ue, bool spec)
836{
837 alkind ak = sRef_getAliasKind (ue->sref);
838
839 if (alkind_isRefCounted (ak))
840 {
841 sRef_setAliasKind (ue->sref, AK_NEWREF, fileloc_undefined);
842 }
843 else
844 {
845 if (alkind_isUnknown (ak))
846 {
847 exkind ek = sRef_getExKind (ue->sref);
848
849 if (exkind_isKnown (ek))
850 {
28bf4b0b 851 DPRINTF (("Setting imp dependent: %s",
852 uentry_unparseFull (ue)));
616915dd 853 sRef_setAliasKind (ue->sref, AK_IMPDEPENDENT, fileloc_undefined);
854 }
855 else
856 {
857 if (context_getFlag (spec ? FLG_SPECRETIMPONLY : FLG_RETIMPONLY))
858 {
28bf4b0b 859 /* evans 2000-12-22 removed ctype_realType so it will
860 not apply to immutable abstract types. */
861
616915dd 862 if (ctype_isVisiblySharable
28bf4b0b 863 (ctype_realType (ctype_getReturnType (ue->utype))))
616915dd 864 {
865 if (uentryList_hasReturned (uentry_getParams (ue)))
866 {
867 ;
868 }
28bf4b0b 869 else
616915dd 870 {
28bf4b0b 871 if (ctype_isImmutableAbstract (ctype_getReturnType (ue->utype)))
872 {
873 ; /* Immutable objects are not shared. */
874 }
875 else
876 {
877 sRef_setAliasKind (ue->sref, AK_IMPONLY,
878 fileloc_undefined);
879 DPRINTF (("Ret imp only: %s",
880 ctype_unparse (ctype_getReturnType (ue->utype))));
881 }
882 }
616915dd 883 }
884 }
885 }
886 }
887 }
888}
889
890static /*@notnull@*/ uentry
891uentry_makeFunctionAux (cstring n, ctype t,
892 typeIdSet access,
893 /*@only@*/ globSet globs,
28bf4b0b 894 /*@only@*/ sRefSet mods,
895 /*@only@*/ warnClause warn,
616915dd 896 /*@keep@*/ fileloc f, bool priv,
897 /*@unused@*/ bool isForward)
898{
899 uentry e = uentry_alloc ();
900 ctype ret;
901
28bf4b0b 902 llassert (warnClause_isUndefined (warn)); /*@i325 remove parameter! */
903
ccf0a4a8 904 DPRINTF (("Make function: %s", n));
905
616915dd 906 if (ctype_isFunction (t))
907 {
28bf4b0b 908 ret = ctype_getReturnType (t);
616915dd 909 }
910 else
911 {
912 if (ctype_isKnown (t))
913 {
914 llbug (message ("not function: %s", ctype_unparse (t)));
915 }
916 ret = ctype_unknown;
917 }
918
919 e->ukind = KFCN;
920
921 if (fileloc_isSpec (f) || fileloc_isImport (f))
922 {
923 e->whereSpecified = f;
924 e->whereDeclared = fileloc_undefined;
925 }
926 else
927 {
928 e->whereSpecified = fileloc_undefined;
929 e->whereDeclared = f;
930 }
931
932 /* e->shallowCopy = FALSE; */
933 e->uname = cstring_copy (n);
934 e->utype = t;
935 e->storageclass = SCNONE;
936
b072092f 937 e->sref = sRef_makeResult (ret); /* evans 2001-07-19 - was sRef_makeType */
938
939 DPRINTF (("Result: %s", sRef_unparseFull (e->sref)));
616915dd 940
941 if (ctype_isUA (ret))
942 {
943 sRef_setStateFromType (e->sref, ret);
944 }
945
946 e->used = FALSE;
947 e->lset = FALSE;
948 e->uses = filelocList_new ();
949 e->isPrivate = priv;
950 e->hasNameError = FALSE;
951
28bf4b0b 952 e->warn = warn;
953
616915dd 954 e->info = (uinfo) dmalloc (sizeof (*e->info));
955 e->info->fcn = (ufinfo) dmalloc (sizeof (*e->info->fcn));
956
957 e->info->fcn->hasMods = sRefSet_isDefined (mods);
958 e->info->fcn->hasGlobs = globSet_isDefined (globs);
959
960 e->info->fcn->exitCode = XK_UNKNOWN;
28bf4b0b 961 e->info->fcn->nullPred = qual_createUnknown ();
616915dd 962 e->info->fcn->specialCode = SPC_NONE;
963
964 e->info->fcn->access = access;
965 e->info->fcn->globs = globs;
966 e->info->fcn->defparams = uentryList_undefined;
967
968 sRef_setDefined (e->sref, f);
969 e->whereDefined = fileloc_undefined;
970
971 e->info->fcn->mods = sRefSet_undefined;
972 e->info->fcn->specclauses = NULL;
973
974 /*drl 11 29 2000*/
975 e->info->fcn->preconditions = NULL;
976 /*end drl*/
977
978 /*drl 12 28 2000*/
979 e->info->fcn->postconditions = NULL;
980 /*end drl*/
981
982 checkGlobalsModifies (e, mods);
983 e->info->fcn->mods = mods;
984
985 return (e);
986}
987
28bf4b0b 988static void uentry_reflectClauses (uentry ue, functionClauseList clauses)
989{
990 functionClauseList_elements (clauses, el)
991 {
992 DPRINTF (("Reflect clause: %s on %s",
993 functionClause_unparse (el), uentry_getName (ue)));
994
995 if (functionClause_isNoMods (el))
996 {
997 modifiesClause mel = functionClause_getModifies (el);
998
999 if (uentry_hasGlobs (ue))
1000 {
1001 voptgenerror
1002 (FLG_SYNTAX,
1003 message
1004 ("No globals and modifies inconsistent to globals clause for %q: %q",
1005 uentry_getName (ue),
1006 globSet_unparse (uentry_getGlobs (ue))),
1007 modifiesClause_getLoc (mel));
1008
1009 }
1010
1011 if (uentry_hasMods (ue))
1012 {
1013 voptgenerror
1014 (FLG_SYNTAX,
1015 message
1016 ("No globals and modifies inconsistent to modifies clause for %q: %q",
1017 uentry_getName (ue),
1018 sRefSet_unparse (uentry_getMods (ue))),
1019 modifiesClause_getLoc (mel));
1020 }
1021
1022 uentry_setGlobals (ue, globSet_undefined);
1023 uentry_setModifies (ue, sRefSet_undefined);
1024 }
1025 else if (functionClause_isGlobals (el))
1026 {
1027 globalsClause glc = functionClause_getGlobals (el);
1028
1029 DPRINTF (("Globals: %s / %s", uentry_unparse (ue),
1030 globalsClause_unparse (glc)));
1031
1032 if (uentry_hasGlobs (ue))
1033 {
1034 voptgenerror
1035 (FLG_SYNTAX,
1036 message
1037 ("Multiple globals clauses for %q: %q",
1038 uentry_getName (ue),
1039 globalsClause_unparse (glc)),
1040 globalsClause_getLoc (glc));
1041 uentry_setGlobals (ue, globalsClause_takeGlobs (glc)); /*@i32@*/
1042 }
1043 else
1044 {
bb7c2085 1045 DPRINTF (("Taking globs: %s", globalsClause_unparse (glc)));
28bf4b0b 1046 uentry_setGlobals (ue, globalsClause_takeGlobs (glc));
bb7c2085 1047 DPRINTF (("Taking globs after: %s", globalsClause_unparse (glc)));
28bf4b0b 1048 }
1049 }
1050 else if (functionClause_isModifies (el))
1051 {
1052 modifiesClause mlc = functionClause_getModifies (el);
1053
1054 DPRINTF (("Has modifies: %s", uentry_unparseFull (ue)));
1055
1056 if (uentry_hasMods (ue))
1057 {
1058 /*
1059 ** Not an error:
1060
1061 if (optgenerror
1062 (FLG_SYNTAX,
1063 message
1064 ("Multiple modifies clauses for %s: %s",
1065 uentry_getName (ue),
1066 modifiesClause_unparse (mlc)),
1067 modifiesClause_getLoc (mlc)))
1068 {
1069 llhint (message ("Previous modifies clause: ",
1070 sRefSet_unparse (uentry_getMods (ue))));
1071 }
1072
1073 **
1074 */
1075
1076 uentry_combineModifies (ue, modifiesClause_takeMods (mlc)); /*@i32@*/
1077 }
1078 else
1079 {
1080 uentry_setModifies (ue, modifiesClause_takeMods (mlc));
1081 }
1082 }
d9a28762 1083 else if (functionClause_isEnsures (el))
1084 {
3814599d 1085 functionConstraint cl = functionClause_takeEnsures (el);
ba45e1e4 1086 DPRINTF (("Setting post: %s / %s",
1087 uentry_unparse (ue), functionConstraint_unparse (cl)));
d9a28762 1088 uentry_setPostconditions (ue, cl);
1089 }
1090 else if (functionClause_isRequires (el))
1091 {
3814599d 1092 functionConstraint cl = functionClause_takeRequires (el);
d9a28762 1093 uentry_setPreconditions (ue, cl);
1094 }
28bf4b0b 1095 else if (functionClause_isState (el))
1096 {
1097 stateClause sc = functionClause_takeState (el);
ccf0a4a8 1098
1099 if (stateClause_isBefore (sc) && stateClause_setsMetaState (sc))
1100 {
1101 sRefSet rfs = stateClause_getRefs (sc);
1102
1103 sRefSet_elements (rfs, s)
1104 {
1105 if (sRef_isParam (s))
1106 {
1107 /*
1108 ** Can't use requires on parameters
1109 */
1110
1111 voptgenerror
1112 (FLG_ANNOTATIONERROR,
1113 message ("Requires clauses for %q concerns parameters %q should be "
1114 "a parameter annotation instead: %q",
1115 uentry_unparse (ue),
1116 sRef_unparse (s),
1117 stateClause_unparse (sc)),
1118 stateClause_loc (sc));
1119 }
1120 } end_sRefSet_elements ;
1121 }
1122
1123 DPRINTF (("State clause: %s", stateClause_unparse (sc)));
28bf4b0b 1124 uentry_addStateClause (ue, sc);
1125 }
1126 else if (functionClause_isWarn (el))
1127 {
1128 warnClause wc = functionClause_takeWarn (el);
1129 uentry_addWarning (ue, wc);
1130 }
1131 else
1132 {
1133 DPRINTF (("Unhandled clause: %s", functionClause_unparse (el)));
1134 }
1135 } end_functionClauseList_elements ;
1136
ccf0a4a8 1137 DPRINTF (("Checking all: %s", sRef_unparseFull (ue->sref)));
28bf4b0b 1138 stateClauseList_checkAll (ue);
1139}
1140
616915dd 1141/*@notnull@*/ uentry uentry_makeIdFunction (idDecl id)
1142{
28bf4b0b 1143 bool leaveFunc = FALSE;
616915dd 1144 uentry ue =
1145 uentry_makeFunction (idDecl_observeId (id), idDecl_getCtype (id),
1146 typeId_invalid, globSet_undefined,
28bf4b0b 1147 sRefSet_undefined, warnClause_undefined,
616915dd 1148 setLocation ());
28bf4b0b 1149
ccf0a4a8 1150 DPRINTF (("Id function: %s", sRef_unparseFull (ue->sref)));
1151
28bf4b0b 1152 /*
1153 ** This makes parameters names print out correctly.
1154 ** (But we might be a local variable declaration for a function type...)
1155 */
1156
1157 if (context_inFunctionLike ())
1158 {
1159 DPRINTF (("Header: %s / %s",
1160 uentry_unparse (context_getHeader ()),
1161 idDecl_unparse (id)));
1162 }
1163 else
1164 {
1165 context_enterFunctionDeclaration (ue);
1166 leaveFunc = TRUE;
1167 }
1168
ccf0a4a8 1169 DPRINTF (("Id function: %s", sRef_unparseFull (ue->sref)));
616915dd 1170 uentry_reflectQualifiers (ue, idDecl_getQuals (id));
ccf0a4a8 1171 DPRINTF (("Id function: %s", sRef_unparseFull (ue->sref)));
616915dd 1172 reflectImplicitFunctionQualifiers (ue, FALSE);
ccf0a4a8 1173 DPRINTF (("Id function: %s", sRef_unparseFull (ue->sref)));
28bf4b0b 1174 uentry_reflectClauses (ue, idDecl_getClauses (id));
ccf0a4a8 1175 DPRINTF (("Id function: %s", sRef_unparseFull (ue->sref)));
28bf4b0b 1176
616915dd 1177 if (!uentry_isStatic (ue)
1178 && cstring_equalLit (ue->uname, "main"))
1179 {
1180 ctype typ = ue->utype;
1181 ctype retval;
1182 uentryList args;
1183
1184 llassert (ctype_isFunction (typ));
1185
28bf4b0b 1186 retval = ctype_getReturnType (typ);
616915dd 1187
1188 if (!ctype_isInt (retval))
1189 {
1190 voptgenerror
1191 (FLG_MAINTYPE,
1192 message ("Function main declared to return %s, should return int",
1193 ctype_unparse (retval)),
1194 uentry_whereDeclared (ue));
1195 }
1196
1197 args = ctype_argsFunction (typ);
1198
1199 if (uentryList_isMissingParams (args)
1200 || uentryList_size (args) == 0)
1201 {
1202 ;
1203 }
1204 else
1205 {
1206 if (uentryList_size (args) != 2)
1207 {
1208 voptgenerror
1209 (FLG_MAINTYPE,
28bf4b0b 1210 message ("Function main declared with %d arg%&, "
616915dd 1211 "should have 2 (int argc, char *argv[])",
1212 uentryList_size (args)),
1213 uentry_whereLast (ue));
1214 }
1215 else
1216 {
1217 uentry arg = uentryList_getN (args, 0);
1218 ctype ct = uentry_getType (arg);
1219
1220 if (!ctype_isInt (ct))
1221 {
1222 voptgenerror
1223 (FLG_MAINTYPE,
1224 message ("Parameter 1, %q, of function main declared "
1225 "with type %t, should have type int",
1226 uentry_getName (arg), ct),
1227 uentry_whereDeclared (arg));
1228 }
1229
1230 arg = uentryList_getN (args, 1);
1231 ct = uentry_getType (arg);
1232
1233 if (ctype_isArrayPtr (ct)
1234 && ctype_isArrayPtr (ctype_baseArrayPtr (ct))
1235 && ctype_isChar (ctype_baseArrayPtr (ctype_baseArrayPtr (ct))))
1236 {
1237 ;
1238 }
1239 else
1240 {
1241 voptgenerror
1242 (FLG_MAINTYPE,
1243 message ("Parameter 2, %q, of function main declared "
1244 "with type %t, should have type char **",
1245 uentry_getName (arg), ct),
1246 uentry_whereDeclared (arg));
1247 }
1248 }
1249 }
1250 }
1251
28bf4b0b 1252 if (leaveFunc)
1253 {
1254 context_exitFunctionDeclaration ();
1255 }
1256
616915dd 1257 return ue;
1258}
1259
1260static void uentry_implicitParamAnnots (/*@notnull@*/ uentry e)
1261{
1262 alkind ak = sRef_getAliasKind (e->sref);
1263
1264 if ((alkind_isUnknown (ak) || alkind_isImplicit (ak))
1265 && context_getFlag (FLG_PARAMIMPTEMP))
1266 {
1267 exkind ek = sRef_getExKind (e->sref);
1268
1269 if (exkind_isKnown (ek))
1270 {
28bf4b0b 1271 DPRINTF (("imp dep: %s", uentry_unparseFull (e)));
616915dd 1272 sRef_setAliasKind (e->sref, AK_IMPDEPENDENT, fileloc_undefined);
1273 sRef_setOrigAliasKind (e->sref, AK_IMPDEPENDENT);
1274 }
1275 else
1276 {
1277 sRef_setAliasKind (e->sref, AK_IMPTEMP, fileloc_undefined);
1278 sRef_setOrigAliasKind (e->sref, AK_IMPTEMP);
1279 }
1280 }
1281}
1282
1283static /*@only@*/ /*@notnull@*/ uentry
6970c11b 1284uentry_makeVariableParamAux (cstring n, ctype t, /*@dependent@*/ sRef s,
1285 /*@only@*/ fileloc loc, sstate defstate) /*@i32 exposed*/
616915dd 1286{
1287 cstring pname = makeParam (n);
28bf4b0b 1288 uentry e;
1289
1290 DPRINTF (("Sref: %s", sRef_unparseFull (s)));
6970c11b 1291 e = uentry_makeVariableAux (pname, t, loc, s, FALSE, VKPARAM);
616915dd 1292
1293 cstring_free (pname);
28bf4b0b 1294 DPRINTF (("Param: %s", uentry_unparseFull (e)));
616915dd 1295 uentry_implicitParamAnnots (e);
28bf4b0b 1296 DPRINTF (("Param: %s", uentry_unparseFull (e)));
616915dd 1297
1298 if (!sRef_isAllocated (e->sref) && !sRef_isPartial (e->sref))
1299 {
28bf4b0b 1300 DPRINTF (("Param: %s", uentry_unparseFull (e)));
616915dd 1301 sRef_setDefState (e->sref, defstate, uentry_whereDeclared (e));
1302 e->info->var->defstate = defstate;
1303 }
1304
28bf4b0b 1305 DPRINTF (("Param: %s", uentry_unparseFull (e)));
616915dd 1306 return (e);
1307}
1308
1309# ifndef NOLCL
1310void
1311uentry_setRefCounted (uentry e)
1312{
1313 if (uentry_isValid (e))
1314 {
1315 uentry_setAliasKind (e, AK_REFCOUNTED);
1316 sRef_storeState (e->sref);
1317 }
1318}
1319# endif
1320
1321void
1322uentry_setStatic (uentry c)
1323{
1324 if (uentry_isValid (c))
1325 {
1326 alkind ak = sRef_getAliasKind (c->sref);
1327 c->storageclass = SCSTATIC;
1328
1329 if (uentry_isVariable (c) && !ctype_isFunction (uentry_getType (c)))
1330 {
1331 if (!alkind_isUnknown (ak)
1332 && !alkind_isStatic (ak))
1333 {
1334 if (!(ctype_isRealPointer (uentry_getType (c)))
1335 && !(ctype_isAbstract (ctype_realType (uentry_getType (c))))
1336 && !alkind_isRefCounted (ak))
1337 {
1338 if (alkind_isImplicit (ak)
1339 && alkind_isDependent (ak)
1340 && ctype_isArray (uentry_getType (c)))
1341 {
1342 ; /* no error for observer arrays */
1343 }
1344 else
1345 {
1346 voptgenerror
1347 (FLG_INCONDEFS,
1348 message ("Static storage %q declared as %s",
1349 uentry_getName (c),
1350 alkind_unparse (ak)),
1351 uentry_whereDeclared (c));
1352 }
1353 }
1354 }
1355 else
1356 {
1357 if (alkind_isUnknown (ak)
1358 || (alkind_isImplicit (sRef_getAliasKind (c->sref))
1359 && !alkind_isDependent (sRef_getAliasKind (c->sref))))
1360 {
1361 sRef_setAliasKind (c->sref, AK_STATIC, fileloc_undefined);
1362 sRef_setOrigAliasKind (c->sref, AK_STATIC);
1363 }
1364 }
1365 }
1366 }
1367}
1368
1369void
1370uentry_setExtern (uentry c)
1371{
1372 if (uentry_isValid (c))
1373 c->storageclass = SCEXTERN;
1374}
1375
1376void
1377uentry_setParamNo (uentry ue, int pno)
1378{
1379 llassert (uentry_isAnyParam (ue) && sRef_isParam (ue->sref));
1380 sRef_setParamNo (ue->sref, pno);
1381}
1382
1383static
1384void checkGlobalsModifies (/*@notnull@*/ uentry ue, sRefSet sr)
1385{
1386 sRefSet_allElements (sr, el)
1387 {
1388 sRef base = sRef_getRootBase (el);
1389
28bf4b0b 1390 if (sRef_isFileOrGlobalScope (base) || sRef_isInternalState (base)
616915dd 1391 || (sRef_isKindSpecial (base) && !sRef_isNothing (base)))
1392 {
1393 if (!globSet_member (ue->info->fcn->globs, base))
1394 {
1395 if (uentry_hasGlobs (ue)
1396 || context_getFlag (FLG_WARNMISSINGGLOBALSNOGLOBS))
1397 {
1398 if (optgenerror
1399 (FLG_WARNMISSINGGLOBALS,
1400 message
1401 ("Modifies list for %q uses global %q, "
1402 "not included in globals list.",
1403 uentry_getName (ue),
1404 sRef_unparse (base)),
1405 uentry_whereLast (ue)))
1406 {
1407 uentry_showWhereSpecified (ue);
1408 }
1409 }
1410
1411 ue->info->fcn->globs = globSet_insert (ue->info->fcn->globs,
1412 base);
1413 if (sRef_isFileStatic (base))
1414 {
1415 context_recordFileGlobals (ue->info->fcn->globs);
1416 }
1417 }
1418 }
1419 } end_sRefSet_allElements;
1420}
1421
1422uentry
6970c11b 1423uentry_makeVariableSrefParam (cstring n, ctype t, /*@only@*/ fileloc loc, /*@exposed@*/ sRef s)
616915dd 1424{
6970c11b 1425 return (uentry_makeVariableParamAux (n, t, s, loc, SS_UNKNOWN));
616915dd 1426}
1427
1428void
1429uentry_fixupSref (uentry ue)
1430{
1431 sRef sr;
1432
1433 if (uentry_isUndefined (ue) || uentry_isElipsisMarker (ue))
1434 {
1435 return;
1436 }
1437
1438 sr = uentry_getSref (ue);
1439
1440 sRef_resetState (sr);
1441 sRef_clearDerived (sr);
1442
1443 llassertprint (uentry_isVariable (ue), ("fixing: %s", uentry_unparseFull (ue)));
1444 llassert (sRef_isValid (sr));
1445
1446 if (uentry_isVariable (ue))
1447 {
b7e84605 1448 /*@i634 ue->sref = sRef_saveCopyShallow (ue->info->var->origsref); */
616915dd 1449 sRef_setDefState (sr, ue->info->var->defstate, fileloc_undefined);
1450 sRef_setNullState (sr, ue->info->var->nullstate, fileloc_undefined);
1451 }
1452}
1453
28bf4b0b 1454static void uentry_addStateClause (uentry ue, stateClause sc)
1455{
1456 /*
1457 ** Okay to allow multiple clauses of the same kind.
1458 */ /*@i834 is this true?@*/
1459
1460 ue->info->fcn->specclauses =
1461 stateClauseList_add (ue->info->fcn->specclauses, sc);
1462
1463 /* Will call checkAll to check later... */
1464}
1465
1466void uentry_setStateClauseList (uentry ue, stateClauseList clauses)
616915dd 1467{
1468 llassert (uentry_isFunction (ue));
28bf4b0b 1469 llassert (!stateClauseList_isDefined (ue->info->fcn->specclauses));
616915dd 1470
28bf4b0b 1471 DPRINTF (("checked clauses: %s", stateClauseList_unparse (clauses)));
616915dd 1472 ue->info->fcn->specclauses = clauses;
28bf4b0b 1473 stateClauseList_checkAll (ue);
1474 DPRINTF (("checked clauses: %s", uentry_unparseFull (ue)));
616915dd 1475}
1476
1477/*
1478** Used for @modifies@ @endmodifies@ syntax.
1479**
1480** If ue is specified, sr must contain *only*:
1481**
1482** o file static globals
1483** o sRef's derived from modifies spec (i.e., more specific than
1484** what was specified)
1485**
1486** Otherwise, if sr has modifies it must match sr.
1487**
1488** If it doesn't have modifies, set them to sr.
1489*/
1490
28bf4b0b 1491static bool
1492uentry_checkModifiesContext (void)
616915dd 1493{
1494 if (sRef_modInFunction ())
1495 {
1496 llparseerror
28bf4b0b 1497 (message
1498 ("Modifies list not in function context. "
1499 "A modifies list can only appear following the parameter list "
1500 "in a function declaration or header."));
1501
1502 return FALSE;
616915dd 1503 }
28bf4b0b 1504
1505 return TRUE;
1506}
616915dd 1507
28bf4b0b 1508void
1509uentry_setModifies (uentry ue, /*@owned@*/ sRefSet sr)
1510{
1511 if (!uentry_checkModifiesContext ())
616915dd 1512 {
28bf4b0b 1513 sRefSet_free (sr);
1514 return;
616915dd 1515 }
1516
1517 if (uentry_isValid (ue))
1518 {
1519 if (uentry_isIter (ue))
1520 {
1521 llassert (sRefSet_isUndefined (ue->info->iter->mods));
1522 ue->info->iter->mods = sr;
1523 }
1524 else
1525 {
efd360a3 1526 uentry_convertVarFunction (ue);
616915dd 1527 llassertfatal (uentry_isFunction (ue));
1528 llassert (sRefSet_isUndefined (ue->info->fcn->mods));
1529
1530 ue->info->fcn->mods = sr;
1531 ue->info->fcn->hasMods = TRUE;
1532
1533 checkGlobalsModifies (ue, sr);
1534 }
1535
1536 if (context_getFlag (FLG_MODIFIESIMPNOGLOBALS))
1537 {
1538 ue->info->fcn->hasGlobs = TRUE;
1539 }
28bf4b0b 1540
1541 if (sRefSet_hasStatic (ue->info->fcn->mods))
1542 {
1543 context_recordFileModifies (ue->info->fcn->mods);
1544 }
616915dd 1545 }
1546 else
1547 {
1548 sRefSet_free (sr);
1549 }
1550}
1551
28bf4b0b 1552static void
1553uentry_combineModifies (uentry ue, /*@owned@*/ sRefSet sr)
1554{
1555 /*
1556 ** Function already has one modifies clause (possibly from
1557 ** a specification).
1558 */
1559
1560 if (!uentry_checkModifiesContext ())
1561 {
1562 BADBRANCH;
1563 }
1564
1565 llassert (uentry_isValid (ue));
1566
1567 if (uentry_isIter (ue))
1568 {
1569 ue->info->iter->mods = sRefSet_unionFree (ue->info->iter->mods, sr);
1570 }
1571 else
1572 {
1573 llassertfatal (uentry_isFunction (ue));
1574 llassert (ue->info->fcn->hasMods);
1575
1576 checkGlobalsModifies (ue, sr);
1577 ue->info->fcn->mods = sRefSet_unionFree (ue->info->fcn->mods, sr);
1578
1579 if (context_getFlag (FLG_MODIFIESIMPNOGLOBALS))
1580 {
1581 ue->info->fcn->hasGlobs = TRUE;
1582 }
1583 }
1584
1585 if (sRefSet_hasStatic (ue->info->fcn->mods))
1586 {
1587 context_recordFileModifies (ue->info->fcn->mods);
1588 }
1589}
1590
1591bool uentry_hasWarning (uentry ue)
1592{
1593 return (uentry_isValid (ue)
1594 && warnClause_isDefined (ue->warn));
1595}
1596
1597void uentry_addWarning (uentry ue, /*@only@*/ warnClause warn)
1598{
1599 llassert (warnClause_isUndefined (ue->warn));
1600 ue->warn = warn;
1601}
1602
616915dd 1603void
3814599d 1604uentry_setPreconditions (uentry ue, /*@only@*/ functionConstraint preconditions)
616915dd 1605{
1606 if (sRef_modInFunction ())
1607 {
1608 llparseerror
1609 (message ("Precondition list not in function context. "
1610 "A precondition list can only appear following the parameter list "
1611 "in a function declaration or header."));
1612
1613 /*@-mustfree@*/ return; /*@=mustfree@*/
1614 }
1615
1616 if (uentry_isValid (ue))
1617 {
efd360a3 1618 uentry_convertVarFunction (ue);
1619 llassertfatal (uentry_isFunction (ue));
3814599d 1620
efd360a3 1621 if (functionConstraint_isDefined (ue->info->fcn->preconditions))
1622 {
77d37419 1623 /* drl 11-29-2002
11db3170 1624 I changed this so it didn't appear as a Splint bug
9db43751 1625 among other things this gets triggered when there is
11db3170 1626 a function with two requires clauses. Now Splint
9db43751 1627 prints an error and tries to conjoin the lists.
1628 */
1629 llparseerror
1630 (message ("Duplicate precondition list"
1631 "Attemping the conjoin the requires clauses"
1632 ));
1633
1634
1635 /* should conjoin constraints? */
efd360a3 1636 /*@notreached@*/
1637 ue->info->fcn->preconditions = functionConstraint_conjoin (ue->info->fcn->preconditions, preconditions);
1638 }
1639 else
1640 {
1641 ue->info->fcn->preconditions = preconditions;
1642 }
616915dd 1643 }
1644 else
1645 {
bb7c2085 1646 llfatalbug ((message("uentry_setPreconditions called with invalid uentry") ));
616915dd 1647 }
1648}
1649
1650/*
1651 drl
1652 added 12/28/2000
1653*/
1654void
3814599d 1655uentry_setPostconditions (uentry ue, /*@only@*/ functionConstraint postconditions)
616915dd 1656{
1657 if (sRef_modInFunction ())
1658 {
1659 llparseerror
1660 (message ("Postcondition list not in function context. "
1661 "A postcondition list can only appear following the parameter list "
1662 "in a function declaration or header."));
3814599d 1663
616915dd 1664 /*@-mustfree@*/ return; /*@=mustfree@*/
1665 }
1666
1667 if (uentry_isValid (ue))
1668 {
efd360a3 1669 uentry_convertVarFunction (ue);
1670 llassertfatal (uentry_isFunction (ue));
1671
1672 if (functionConstraint_isUndefined (ue->info->fcn->postconditions))
1673 {
1674 ue->info->fcn->postconditions = postconditions;
1675 }
1676 else
1677 {
efd360a3 1678 ue->info->fcn->postconditions = functionConstraint_conjoin (ue->info->fcn->postconditions, postconditions);
1679 }
616915dd 1680 }
1681 else
1682 {
bb7c2085 1683 llfatalbug ((message("uentry_setPostconditions called with invalid uentry") ));
616915dd 1684 }
1685}
1686
1687/*
1688** requires: new and old are functions
1689*/
1690
1691static void
1692checkGlobalsConformance (/*@notnull@*/ uentry old,
1693 /*@notnull@*/ uentry unew,
1694 bool mustConform, bool completeConform)
1695{
1696 bool hasInternalState = FALSE;
1697
1698 old->info->fcn->hasGlobs |= unew->info->fcn->hasGlobs;
1699
1700 if (globSet_isDefined (unew->info->fcn->globs))
1701 {
1702 globSet_allElements (unew->info->fcn->globs, el)
1703 {
1704 if (sRef_isFileStatic (el))
1705 {
1706 sRef sr = globSet_lookup (old->info->fcn->globs, el);
1707
1708 if (sRef_isInvalid (sr))
1709 {
1710 bool hasError = FALSE;
1711
1712 if (!hasInternalState
1713 && sRef_isInvalid (globSet_lookup (old->info->fcn->globs,
1714 sRef_makeInternalState ()))
1715 && sRef_isInvalid (globSet_lookup (old->info->fcn->globs,
1716 sRef_makeSpecState ())))
1717 {
1718 if (mustConform
1719 && !uentry_isStatic (old)
1720 && optgenerror
1721 (FLG_INCONDEFS,
1722 message ("Globals list for %q includes internal state, %q, "
1723 "but %s without globals internalState.",
1724 uentry_getName (old),
1725 sRef_unparse (el),
1726 uentry_specOrDefName (old)),
1727 uentry_whereLast (unew)))
1728 {
1729 uentry_showWhereSpecified (old);
1730 hasError = TRUE;
1731 }
1732
1733 old->info->fcn->globs = globSet_insert (old->info->fcn->globs,
1734 sRef_makeInternalState ());
1735 hasInternalState = TRUE;
1736 }
1737
1738 if (!hasError
1739 && fileloc_sameFile (uentry_whereDeclared (unew),
1740 uentry_whereDeclared (old)))
1741 {
1742 if (mustConform
1743 && optgenerror
1744 (FLG_INCONDEFS,
1745 message ("Function %q inconsistently %rdeclared (in "
1746 "same file) with file static global %q in "
1747 "globals list",
1748 uentry_getName (unew),
1749 uentry_isDeclared (old),
1750 sRef_unparse (el)),
1751 uentry_whereDeclared (unew)))
1752 {
1753 uentry_showWhereSpecified (old);
1754 }
1755 }
1756 }
1757
1758 old->info->fcn->globs = globSet_insert (old->info->fcn->globs, el);
1759 context_recordFileGlobals (old->info->fcn->globs);
1760 }
1761 else
1762 {
1763 sRef sr = globSet_lookup (old->info->fcn->globs, el);
1764
1765 if (sRef_isInvalid (sr))
1766 {
1767 if (mustConform
1768 && optgenerror
1769 (FLG_INCONDEFS,
1770 message ("Function %q inconsistently %rdeclared with "
1771 "%q in globals list",
1772 uentry_getName (unew),
1773 uentry_isDeclared (old),
1774 sRef_unparse (el)),
1775 uentry_whereDeclared (unew)))
1776 {
1777 old->info->fcn->globs = globSet_insert (old->info->fcn->globs, el);
1778 uentry_showWhereSpecified (old);
1779 }
1780 }
1781 else
1782 {
1783 if (!bool_equal (sRef_isAllocated (el), sRef_isAllocated (sr)))
1784 {
1785 if (mustConform
1786 && optgenerror
1787 (FLG_INCONDEFS,
1788 message
1789 ("Function %q global %q inconsistently "
1790 "%rdeclared as %qout global",
1791 uentry_getName (unew),
1792 sRef_unparse (el),
1793 uentry_isDeclared (old),
1794 cstring_makeLiteral (sRef_isAllocated (el) ? "" : "non-")),
1795 uentry_whereDeclared (unew)))
1796 {
1797 uentry_showWhereSpecified (old);
1798 }
1799 }
1800 }
1801 }
1802 } end_globSet_allElements ;
1803
1804 if (completeConform)
1805 {
1806 globSet_allElements (old->info->fcn->globs, el)
1807 {
1808 sRef sr = globSet_lookup (unew->info->fcn->globs, el);
1809
1810 if (sRef_isInvalid (sr))
1811 {
1812 if (mustConform
1813 && uentry_isReallySpecified (old)
1814 && optgenerror
1815 (FLG_NEEDSPEC,
1816 message ("Function %q specified with %q in globals list, "
1817 "but declared without %q",
1818 uentry_getName (unew),
1819 sRef_unparse (el),
1820 sRef_unparse (el)),
1821 uentry_whereDeclared (unew)))
1822 {
1823 uentry_showWhereSpecified (old);
1824 }
1825 }
1826 } end_globSet_allElements;
1827 }
1828 }
1829 else
1830 {
1831 if (completeConform && !globSet_isEmpty (old->info->fcn->globs))
1832 {
1833 if (uentry_isReallySpecified (old)
1834 && optgenerror
1835 (FLG_NEEDSPEC,
1836 message ("%s %q specified with globals list, but "
1837 "declared with no globals",
1838 ekind_capName (unew->ukind),
1839 uentry_getName (unew)),
1840 uentry_whereDeclared (unew)))
1841 {
1842 llgenindentmsg
1843 (message ("Specification globals: %q",
1844 globSet_unparse (old->info->fcn->globs)),
1845 uentry_whereSpecified (old));
1846 }
1847 }
1848
28bf4b0b 1849 unew->info->fcn->globs = globSet_copyInto (unew->info->fcn->globs,
1850 old->info->fcn->globs);
616915dd 1851 }
1852}
1853
1854/*
1855** new modifies list must be included by old modifies list.
1856**
1857** file static state may be added to new, if old has internal.
1858*/
1859
1860static void
1861checkModifiesConformance (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
1862 bool mustConform, bool completeConform)
1863{
1864 sRefSet newMods;
1865 bool changedMods = FALSE;
1866 bool modInternal = FALSE;
1867
1868 llassert (uentry_isFunction (old) && uentry_isFunction (unew));
1869
1870 old->info->fcn->hasMods |= unew->info->fcn->hasMods;
1871 newMods = unew->info->fcn->mods;
1872
1873 if (sRefSet_isEmpty (newMods))
1874 {
1875 if (completeConform && !sRefSet_isEmpty (old->info->fcn->mods)
1876 && uentry_isReallySpecified (old))
1877 {
1878 if (optgenerror
1879 (FLG_NEEDSPEC,
1880 message ("%s %q specified with modifies clause, "
1881 "but declared with no modifies clause",
1882 ekind_capName (unew->ukind),
1883 uentry_getName (unew)),
1884 uentry_whereDeclared (unew)))
1885 {
1886 llgenindentmsg (message ("Specification has modifies %q",
1887 sRefSet_unparse (old->info->fcn->mods)),
1888 uentry_whereSpecified (old));
1889 }
1890 }
1891
1892 return;
1893 }
1894
1895 sRefSet_allElements (newMods, current)
1896 {
1897 if (sRef_isValid (current))
1898 {
1899 sRef rb = sRef_getRootBase (current);
1900
1901 if (sRef_isFileStatic (rb))
1902 {
1903 if (!modInternal)
1904 {
1905 if (!sRefSet_isSameMember (old->info->fcn->mods,
1906 sRef_makeInternalState ())
1907 && !sRefSet_isSameMember (old->info->fcn->mods,
1908 sRef_makeSpecState ()))
1909 {
1910 if (mustConform
1911 && !uentry_isStatic (old)
1912 && optgenerror
1913 (FLG_INCONDEFS,
1914 message
1915 ("Modifies list for %q includes internal state, "
1916 "but %s without modifies internal.",
1917 uentry_getName (old),
1918 uentry_specOrDefName (old)),
1919 uentry_whereLast (unew)))
1920 {
1921 uentry_showWhereSpecified (old);
1922 }
1923
1924 old->info->fcn->mods =
1925 sRefSet_insert (old->info->fcn->mods,
1926 sRef_makeInternalState ());
1927 modInternal = TRUE;
1928 }
1929 }
1930
1931 old->info->fcn->mods = sRefSet_insert (old->info->fcn->mods,
1932 current);
1933 changedMods = TRUE;
1934 }
1935 else
1936 {
1937 if (sRef_canModifyVal (current, old->info->fcn->mods))
1938 {
1939 int size = sRefSet_size (old->info->fcn->mods);
1940
1941 old->info->fcn->mods = sRefSet_insert (old->info->fcn->mods,
1942 current);
1943
1944 if (sRefSet_size (old->info->fcn->mods) != size)
1945 {
1946 changedMods = TRUE;
1947 }
1948 }
1949 else
1950 {
1951 if (mustConform
1952 && optgenerror
1953 (FLG_INCONDEFS,
1954 message
1955 ("Modifies list for %q contains %q, not modifiable "
1956 "according to %s",
1957 uentry_getName (old),
1958 sRef_unparse (current),
1959 uentry_specDeclName (old)),
1960 uentry_whereLast (unew)))
1961 {
1962 uentry_showWhereSpecified (old);
1963 }
1964 }
1965 }
1966 }
1967 } end_sRefSet_allElements;
1968
1969 if (completeConform && uentry_isReallySpecified (old))
1970 {
1971 sRefSet_allElements (old->info->fcn->mods, el)
1972 {
1973 if (sRef_canModify (el, newMods))
1974 {
1975 ; /* okay */
1976 }
1977 else
1978 {
1979 if (optgenerror
1980 (FLG_NEEDSPEC,
1981 message
1982 ("Specification modifies clause for %q contains %q, "
1983 "not included in declaration modifies clause",
1984 uentry_getName (old),
1985 sRef_unparse (el)),
1986 uentry_whereLast (unew)))
1987 {
1988 uentry_showWhereSpecified (old);
1989 }
1990 }
1991 } end_sRefSet_allElements ;
1992 }
1993
1994 /*
1995 ** Make sure file static elements will be removed.
1996 */
1997
1998 if (changedMods)
1999 {
2000 context_recordFileModifies (old->info->fcn->mods);
2001 }
2002}
2003
2004static void
2005 uentry_checkMutableType (uentry ue)
2006{
2007 ctype ct = uentry_getType (ue);
2008
2009 if (!ctype_isRealPointer (ct) && !ctype_isRealAbstract (ct))
2010 {
28bf4b0b 2011 DPRINTF (("Check mutable: %s", uentry_unparseFull (ue)));
2012
616915dd 2013 voptgenerror (FLG_MUTREP,
2014 message ("Mutable abstract type %q declared without pointer "
2015 "indirection: %t (violates assignment semantics)",
2016 uentry_getName (ue), ct),
2017 uentry_whereDeclared (ue));
2018 }
2019}
2020
2021void
2022uentry_setMutable (uentry e)
2023{
2024 llassert (uentry_isDatatype (e));
2025 e->info->datatype->mut = YES;
2026}
2027
2028static void
2029uentry_checkIterArgs (uentry ue)
2030{
2031 bool hasYield = FALSE;
2032 uentryList args;
2033
2034 llassert (uentry_isIter (ue));
2035
2036 args = uentry_getParams (ue);
2037
2038 uentryList_elements (args, el)
2039 {
2040 sstate ds = uentry_getDefState (el);
2041
2042 if (uentry_isYield (el))
2043 {
2044 hasYield = TRUE;
2045 }
2046
2047 if (sstate_isUnknown (ds))
2048 {
2049 uentry_setDefState (el, SS_DEFINED);
2050 }
2051 else
2052 {
2053 ;
2054 }
2055 } end_uentryList_elements;
2056
2057 if (!hasYield)
2058 {
2059 voptgenerror (FLG_HASYIELD,
2060 message ("Iterator %q declared with no yield parameters",
2061 uentry_getName (ue)),
2062 uentry_whereDeclared (ue));
2063 }
2064}
2065
2066static chkind
2067chkind_fromQual (qual qel)
2068{
2069 if (qual_isChecked (qel))
2070 {
2071 return CH_CHECKED;
2072 }
2073 else if (qual_isCheckMod (qel))
2074 {
2075 return CH_CHECKMOD;
2076 }
2077 else if (qual_isCheckedStrict (qel))
2078 {
2079 return CH_CHECKEDSTRICT;
2080 }
2081 else if (qual_isUnchecked (qel))
2082 {
2083 return CH_UNCHECKED;
2084 }
2085 else
2086 {
2087 BADEXIT;
2088 /*@notreached@*/ return CH_UNKNOWN;
2089 }
2090}
2091
2092static void
2093uentry_reflectOtherQualifier (/*@notnull@*/ uentry ue, qual qel)
2094{
2095 if (qual_isKillRef (qel) || qual_isNewRef (qel) || qual_isTempRef (qel))
2096 {
2097 if (!uentry_isRefCounted (ue))
2098 {
28bf4b0b 2099 voptgenerror
2100 (FLG_ANNOTATIONERROR,
616915dd 2101 message ("Reference counting qualifier %s used on non-reference "
2102 "counted storage: %q",
2103 qual_unparse (qel),
28bf4b0b 2104 uentry_unparse (ue)),
2105 uentry_whereLast (ue));
616915dd 2106 }
2107 else
2108 {
2109 alkind ak = alkind_fromQual (qel);
2110
2111 uentry_setAliasKind (ue, ak);
2112 }
2113 }
2114 else if (qual_isRefCounted (qel))
2115 {
2116 ctype ct = ctype_realType (uentry_getType (ue));
2117 ctype rt;
2118
2119 if (ctype_isPointer (ct)
2120 && (ctype_isStruct (rt = ctype_realType (ctype_baseArrayPtr (ct)))))
2121 {
2122 /* check there is a refs field */
2123 uentryList fields = ctype_getFields (rt);
2124 uentry refs = uentry_undefined;
2125
2126 uentryList_elements (fields, field)
2127 {
2128 if (uentry_isRefsField (field))
2129 {
2130 if (uentry_isValid (refs))
2131 {
28bf4b0b 2132 voptgenerror
2133 (FLG_ANNOTATIONERROR,
616915dd 2134 message ("Reference counted structure type %s has "
2135 "multiple refs fields: %q and %q",
2136 ctype_unparse (ct),
2137 uentry_getName (refs),
28bf4b0b 2138 uentry_getName (field)),
2139 uentry_whereLast (field));
616915dd 2140 }
2141
2142 refs = field;
2143 }
2144 } end_uentryList_elements;
2145
2146 if (uentry_isInvalid (refs))
2147 {
2148 vgenhinterror
2149 (FLG_SYNTAX,
2150 message ("Reference counted structure type %s has "
2151 "no refs field",
2152 ctype_unparse (ct)),
2153 cstring_makeLiteral
2154 ("To count reference, the structure must have a field named "
2155 "refs of type int."),
2156 g_currentloc);
2157 }
2158 else if (!ctype_isInt (uentry_getType (refs)))
2159 {
28bf4b0b 2160 voptgenerror
2161 (FLG_ANNOTATIONERROR,
616915dd 2162 message ("Reference counted structure type %s refs field has "
2163 "type %s (should be int)", ctype_unparse (ct),
28bf4b0b 2164 ctype_unparse (uentry_getType (refs))),
2165 uentry_whereLast (refs));
616915dd 2166 }
2167 else
2168 {
2169 sRef_setAliasKind (ue->sref, alkind_fromQual (qel),
2170 uentry_whereDeclared (ue));
2171 }
2172 }
2173 else
2174 {
2175 if ((ctype_isPointer (ct)
2176 && ctype_isUnknown (ctype_realType (ctype_baseArrayPtr (ct))))
2177 ||ctype_isAbstract (ct) || ctype_isUnknown (ct))
2178 {
2179 sRef_setAliasKind (ue->sref, alkind_fromQual (qel),
2180 uentry_whereDeclared (ue));
2181 }
2182 else
2183 {
28bf4b0b 2184 voptgenerror
2185 (FLG_ANNOTATIONERROR,
616915dd 2186 message ("Non-pointer to structure type %s declared with "
2187 "refcounted qualifier",
28bf4b0b 2188 ctype_unparse (ct)),
2189 uentry_whereLast (ue));
616915dd 2190 }
2191 }
2192 }
2193 else if (qual_isRefs (qel))
2194 {
2195 if (uentry_isVariable (ue) && !uentry_isParam (ue))
2196 {
2197 uentry_setAliasKind (ue, AK_REFS);
2198 }
2199 else
2200 {
28bf4b0b 2201 voptgenerror
2202 (FLG_ANNOTATIONERROR,
616915dd 2203 message ("Refs qualifier used on non-structure field: %q",
28bf4b0b 2204 uentry_unparse (ue)),
2205 uentry_whereLast (ue));
616915dd 2206 }
2207 }
2208 else if (qual_isAliasQual (qel))
2209 {
2210 alkind ak = alkind_fromQual (qel);
2211 bool okay = TRUE;
2212 alkind oldak = uentry_getAliasKind (ue);
2213 ctype ut = uentry_getType (ue);
2214
2215 if (alkind_isImplicit (ak)
2216 && (alkind_isKnown (oldak) && !alkind_isImplicit (oldak)))
2217 {
2218 /* ignore the implied qualifier */
2219 okay = FALSE;
2220 }
2221
2222 if (uentry_isEitherConstant (ue))
2223 {
28bf4b0b 2224 voptgenerror
2225 (FLG_ANNOTATIONERROR,
616915dd 2226 message ("Alias qualifier %s used on constant: %q",
28bf4b0b 2227 alkind_unparse (ak), uentry_unparse (ue)),
2228 uentry_whereLast (ue));
2229
616915dd 2230 okay = FALSE;
2231 }
2232
2233 if (ctype_isFunction (ut))
2234 {
28bf4b0b 2235 ut = ctype_getReturnType (ut);
616915dd 2236 }
2237
2238 if (!(ctype_isVisiblySharable (ut)
2239 || ctype_isRealArray (ut)
2240 || ctype_isRealSU (ut)))
2241 {
2242 if (!qual_isImplied (qel))
2243 {
28bf4b0b 2244 voptgenerror
2245 (FLG_ANNOTATIONERROR,
616915dd 2246 message ("Alias qualifier %s used on unsharable storage type %t: %q",
28bf4b0b 2247 alkind_unparse (ak), ut, uentry_getName (ue)),
2248 uentry_whereLast (ue));
616915dd 2249 }
2250
2251 okay = FALSE;
2252 }
2253 else
2254 {
2255 if (uentry_isRefCounted (ue))
2256 {
2257 if (!(qual_isRefQual (qel) || qual_isOnly (qel)
2258 || qual_isExposed (qel)
2259 || qual_isObserver (qel)))
2260 {
2261 if (!qual_isImplied (qel))
2262 {
28bf4b0b 2263 voptgenerror
2264 (FLG_ANNOTATIONERROR,
616915dd 2265 message
2266 ("Alias qualifier %s used on reference counted storage: %q",
2267 alkind_unparse (ak),
28bf4b0b 2268 uentry_unparse (ue)),
2269 uentry_whereLast (ue));
616915dd 2270 }
2271
2272 okay = FALSE;
2273 }
2274 }
2275 else
2276 {
2277 if (qual_isRefQual (qel))
2278 {
28bf4b0b 2279 voptgenerror
2280 (FLG_ANNOTATIONERROR,
616915dd 2281 message ("Qualifier %s used on non-reference counted storage: %q",
28bf4b0b 2282 alkind_unparse (ak), uentry_unparse (ue)),
2283 uentry_whereLast (ue));
616915dd 2284
2285 okay = FALSE;
2286 }
2287 }
2288 }
2289
2290 if (okay)
2291 {
2292 uentry_setAliasKind (ue, ak);
2293 }
2294 }
2295 else if (qual_isNull (qel))
2296 {
2297 if (uentry_isConstant (ue))
2298 {
2299 sRef_setNullState
2300 (ue->sref,
2301 ctype_isAbstract (ue->utype) ? NS_CONSTNULL : NS_DEFNULL,
2302 uentry_whereDeclared (ue));
2303 }
2304 else
2305 {
2306 uentry_setNullState (ue, NS_POSNULL);
2307 }
2308 }
2309 else if (qual_isRelNull (qel))
2310 {
2311 uentry_setNullState (ue, NS_RELNULL);
2312 }
2313 else if (qual_isNotNull (qel))
2314 {
2315 uentry_setNullState (ue, NS_MNOTNULL);
2316 }
2317 else if (qual_isAbstract (qel)
2318 || qual_isConcrete (qel))
2319 {
2320 if (!uentry_isDatatype (ue))
2321 {
28bf4b0b 2322 voptgenerror
2323 (FLG_ANNOTATIONERROR,
616915dd 2324 message ("Qualifier %s used with non-datatype",
28bf4b0b 2325 qual_unparse (qel)),
2326 uentry_whereLast (ue));
616915dd 2327 }
2328 else
2329 {
2330 ue->info->datatype->abs = ynm_fromBool (qual_isAbstract (qel));
2331 }
2332 }
2333 else if (qual_isMutable (qel))
2334 {
2335 if (!uentry_isDatatype (ue))
2336 {
28bf4b0b 2337 voptgenerror
2338 (FLG_ANNOTATIONERROR,
2339 message ("Qualifier %s used with non-datatype", qual_unparse (qel)),
2340 uentry_whereLast (ue));
616915dd 2341 }
2342 else
2343 {
2344 if (!ynm_isOn (ue->info->datatype->mut))
2345 {
2346 uentry_checkMutableType (ue);
2347 }
2348
2349 ue->info->datatype->mut = YES;
2350 }
2351 }
2352 else if (qual_isImmutable (qel))
2353 {
2354 if (!uentry_isDatatype (ue))
2355 {
28bf4b0b 2356 voptgenerror (FLG_ANNOTATIONERROR,
2357 message ("Qualifier %s used with non-datatype",
2358 qual_unparse (qel)),
2359 uentry_whereLast (ue));
616915dd 2360 }
2361 else
2362 {
2363 ue->info->datatype->mut = NO;
2364 }
2365 }
2366 else if (qual_isNullPred (qel))
2367 {
efd360a3 2368 uentry_convertVarFunction (ue);
2369
616915dd 2370 if (uentry_isFunction (ue))
2371 {
2372 ctype typ = uentry_getType (ue);
28bf4b0b 2373 ctype rtype = ctype_getReturnType (uentry_getType (ue));
616915dd 2374
2375 if (ctype_isRealBool (rtype))
2376 {
2377 uentryList pl = ctype_argsFunction (typ);
2378
2379 if (uentryList_size (pl) == 1)
2380 {
2381 ue->info->fcn->nullPred = qel;
2382 }
2383 else
2384 {
28bf4b0b 2385 voptgenerror (FLG_ANNOTATIONERROR,
2386 message ("Qualifier %s used with function having %d "
2387 "arguments (should have 1)",
2388 qual_unparse (qel),
2389 uentryList_size (pl)),
2390 uentry_whereLast (ue));
616915dd 2391 }
2392 }
2393 else
2394 {
28bf4b0b 2395 voptgenerror (FLG_ANNOTATIONERROR,
2396 message ("Qualifier %s used with function returning %s "
2397 "(should return bool)",
2398 qual_unparse (qel),
2399 ctype_unparse (rtype)),
2400 uentry_whereLast (ue));
616915dd 2401 }
2402 }
2403 else
2404 {
28bf4b0b 2405 voptgenerror (FLG_ANNOTATIONERROR,
2406 message ("Qualifier %s used with non-function",
2407 qual_unparse (qel)),
2408 uentry_whereLast (ue));
616915dd 2409 }
2410 }
2411 else if (qual_isExitQual (qel))
2412 {
2413 exitkind exk = exitkind_fromQual (qel);
2414
2415 if (uentry_isFunction (ue))
2416 {
2417 if (exitkind_isKnown (ue->info->fcn->exitCode))
2418 {
28bf4b0b 2419 voptgenerror (FLG_ANNOTATIONERROR,
2420 message ("Multiple exit qualifiers used on function %q: %s, %s",
2421 uentry_getName (ue),
2422 exitkind_unparse (ue->info->fcn->exitCode),
2423 exitkind_unparse (exk)),
2424 uentry_whereLast (ue));
616915dd 2425 }
2426
2427 ue->info->fcn->exitCode = exk;
2428 }
2429 else
2430 {
2431 if (uentry_isVariable (ue) && ctype_isFunction (uentry_getType (ue)))
2432 {
2433 uentry_makeVarFunction (ue);
2434 ue->info->fcn->exitCode = exk;
2435 }
2436 else
2437 {
28bf4b0b 2438 voptgenerror (FLG_ANNOTATIONERROR,
2439 message ("Exit qualifier %s used with non-function (type %s)",
2440 qual_unparse (qel),
2441 ctype_unparse (uentry_getType (ue))),
2442 uentry_whereLast (ue));
2443 }
2444 }
2445 }
2446 else if (qual_isMetaState (qel))
2447 {
2448 annotationInfo ainfo = qual_getAnnotationInfo (qel);
2449
2450 if (annotationInfo_matchesContext (ainfo, ue))
2451 {
2452 DPRINTF (("Reflecting %s on %s",
2453 annotationInfo_unparse (ainfo),
2454 uentry_unparseFull (ue)));
2455
2456 sRef_reflectAnnotation (ue->sref, ainfo, g_currentloc);
2457 DPRINTF (("==> %s", sRef_unparseFull (ue->sref)));
2458 DPRINTF (("==> %s", uentry_unparseFull (ue)));
2459 }
2460 else
2461 {
2462 if (optgenerror
2463 (FLG_ANNOTATIONERROR,
0bf5022d 2464 message ("Attribute annotation %s used in inconsistent context: %q",
28bf4b0b 2465 qual_unparse (qel),
2466 uentry_unparse (ue)),
2467 uentry_whereLast (ue)))
2468 {
2469 /*@i! annotationInfo_showContextError (ainfo, ue); */
616915dd 2470 }
2471 }
2472 }
2473 else
2474 {
2475 if (qual_isCQual (qel))
2476 {
2477 ; /* okay */
2478 }
2479 else
2480 {
28bf4b0b 2481 llbug (message ("Unhandled qualifier: %s", qual_unparse (qel)));
616915dd 2482 }
2483 }
2484}
2485
2486void
2487uentry_reflectQualifiers (uentry ue, qualList q)
2488{
2489 llassert (uentry_isValid (ue));
2490
ccf0a4a8 2491 DPRINTF (("Reflect qualifiers: %s / %s",
2492 uentry_unparseFull (ue), qualList_unparse (q)));
2493
616915dd 2494 qualList_elements (q, qel)
2495 {
2496 if (qual_isStatic (qel))
2497 {
2498 uentry_setStatic (ue);
2499 }
2500 else if (qual_isUnused (qel))
2501 {
2502 uentry_setUsed (ue, fileloc_undefined);
2503 }
2504 else if (qual_isExternal (qel))
2505 {
2506 fileloc_free (ue->whereDefined);
2507 ue->whereDefined = fileloc_createExternal ();
2508 }
2509 else if (qual_isSef (qel))
2510 {
2511 if (uentry_isVariable (ue))
2512 {
2513 vkind vk = ue->info->var->kind;
2514
2515 llassert (vk != VKREFPARAM);
2516
2517 if (vk == VKYIELDPARAM)
2518 {
28bf4b0b 2519 voptgenerror
2520 (FLG_ANNOTATIONERROR,
616915dd 2521 message ("Qualifier sef cannot be used with %s: %q",
2522 cstring_makeLiteralTemp (vk == VKYIELDPARAM ? "yield" : "returned"),
28bf4b0b 2523 uentry_unparse (ue)),
2524 uentry_whereLast (ue));
616915dd 2525 }
2526 else if (vk == VKRETPARAM)
2527 {
2528 ue->info->var->kind = VKSEFRETPARAM;
2529 }
2530 else
2531 {
2532 ue->info->var->kind = VKSEFPARAM;
2533 }
2534 }
2535 else
2536 {
28bf4b0b 2537 voptgenerror
2538 (FLG_ANNOTATIONERROR,
616915dd 2539 message ("Qualifier sef is meaningful only on parameters: %q",
28bf4b0b 2540 uentry_unparse (ue)),
2541 uentry_whereLast (ue));
616915dd 2542 }
2543 }
2544 else if (qual_isExtern (qel))
2545 {
2546 ue->storageclass = SCEXTERN;
2547 }
2548 else if (qual_isGlobalQual (qel)) /* undef, killed */
2549 {
28bf4b0b 2550 DPRINTF (("Reflecting qual: %s / %s",
2551 qual_unparse (qel), uentry_unparse (ue)));
2552
616915dd 2553 if (uentry_isVariable (ue))
2554 {
2555 sstate oldstate = ue->info->var->defstate;
2556 sstate defstate = sstate_fromQual (qel);
2557
2558
2559 if ((oldstate == SS_UNDEFGLOB && defstate == SS_KILLED)
2560 || (oldstate == SS_KILLED && defstate == SS_UNDEFGLOB))
2561 {
2562 defstate = SS_UNDEFKILLED;
2563 }
2564 else
2565 {
2566 ; /* any errors? */
2567 }
2568
2569 sRef_setDefState (ue->sref, defstate, fileloc_undefined);
2570 ue->info->var->defstate = defstate;
2571 }
2572 else
2573 {
28bf4b0b 2574 voptgenerror
2575 (FLG_ANNOTATIONERROR,
616915dd 2576 message ("Qualifier %s used on non-variable: %q",
28bf4b0b 2577 qual_unparse (qel), uentry_unparse (ue)),
2578 uentry_whereLast (ue));
616915dd 2579 }
28bf4b0b 2580
2581 DPRINTF (("After: %s", uentry_unparseFull (ue)));
616915dd 2582 }
2583 /* start modifications */
616915dd 2584 else if( qual_isBufQualifier(qel) ) {
2585 ctype ct = ctype_realType(uentry_getType(ue));
616915dd 2586 if( ctype_isArray(ct) || ctype_isPointer(ct) ) {
2587
2588 if( uentry_hasBufStateInfo(ue) ) {
616915dd 2589 if( qual_isNullTerminated(qel) ) { /* handle Nullterm */
2590
2591 if (uentry_isAnyParam(ue) || uentry_isReturned (ue)) {
2592 /* If formal func param */
2593 uentry_setNullTerminatedState(ue);
2594 uentry_setLen (ue, 1);
2595 uentry_setSize (ue, 1);
2596
2597 sRef_setNullTerminatedState(uentry_getSref(ue));
2598 sRef_setLen (uentry_getSref(ue), 1);
2599 sRef_setSize (uentry_getSref(ue), 1);
2600 } else {
2601 uentry_setPossiblyNullTerminatedState(ue);
2602
2603 sRef_setPossiblyNullTerminatedState(uentry_getSref(ue));
2604 }
2605
2606 }
2607 /* put other BufState Qualifiers here */
2608 } else {
2609 cstring s = uentry_getName(ue);
2610 llfatalbug(message("INTERNAL Error: we have a NULL BufState \
2611 struct for identifier %s\n", s) );
2612 }
2613 } else if (ctype_isFunction (ct)) { /* We have to handle function */
2614
2615 sRef retSref = uentry_getSref (ue);
2616 ctype retType = sRef_getType (retSref);
2617
2618 if (ctype_isPointer (retType) || ctype_isArray (retType)) {
2619 sRef_setNullTerminatedState (retSref);
2620
2621 } else {
2622
2623 llerror
2624 (FLG_SYNTAX,
2625 message ("Qualifier %s used on non-pointer on \
2626 function return: %q", qual_unparse (qel),
2627 uentry_unparse (ue)));
2628 }
2629 }
2630
2631 else {
2632 llerror
2633 (FLG_SYNTAX,
2634 message ("Qualifier %s used on non-pointer: %q",
2635 qual_unparse (qel), uentry_unparse (ue)));
2636 }
28bf4b0b 2637 DPRINTF (("After: %s", uentry_unparseFull (ue)));
616915dd 2638 }/* end else if */
2639 else if (qual_isAllocQual (qel)) /* out, partial, reldef, special, etc. */
2640 {
2641 ctype realType = ctype_realType (ue->utype);
2642 sstate defstate = sstate_fromQual (qel);
2643
2644 if (ctype_isFunction (realType))
2645 {
28bf4b0b 2646 realType = ctype_realType (ctype_getReturnType (realType));
616915dd 2647 }
2648
2649 if (qual_isRelDef (qel))
2650 {
2651 ; /* okay anywhere */
2652 }
2653 else
2654 {
2655 if (!ctype_isAP (realType)
2656 && !ctype_isSU (realType)
2657 && !ctype_isUnknown (realType)
2658 && !ctype_isAbstract (ue->utype))
2659 {
28bf4b0b 2660 voptgenerror
2661 (FLG_ANNOTATIONERROR,
616915dd 2662 message ("Qualifier %s used on non-pointer or struct: %q",
28bf4b0b 2663 qual_unparse (qel), uentry_unparse (ue)),
2664 uentry_whereLast (ue));
616915dd 2665 }
2666 }
2667
2668 uentry_setDefState (ue, defstate);
2669
2670 if (sRef_isStateSpecial (ue->sref)
2671 && alkind_isImplicit (sRef_getAliasKind (ue->sref)))
2672 {
2673 sRef_setAliasKind (ue->sref, AK_ERROR, fileloc_undefined);
2674 }
2675 }
2676 else if (qual_isYield (qel))
2677 {
2678 if (uentry_isVariable (ue))
2679 {
2680 ue->info->var->kind = VKYIELDPARAM;
2681 }
2682 else
2683 {
28bf4b0b 2684 voptgenerror
2685 (FLG_ANNOTATIONERROR,
616915dd 2686 message ("Qualifier %s used on non-iterator parameter: %q",
28bf4b0b 2687 qual_unparse (qel), uentry_unparse (ue)),
2688 uentry_whereLast (ue));
616915dd 2689 }
2690 }
2691 else if (qual_isExQual (qel))
2692 {
2693 exkind ek = exkind_fromQual (qel);
2694 ctype ut = uentry_getType (ue);
2695
28bf4b0b 2696 DPRINTF (("Reflect ex qual: %s / %s",
2697 uentry_unparse (ue), exkind_unparse (ek)));
2698
616915dd 2699 if (ctype_isFunction (ut))
2700 {
28bf4b0b 2701 ut = ctype_getReturnType (ut);
616915dd 2702 }
2703
2704 if (!(ctype_isVisiblySharable (ut))
2705 && !(ctype_isArray (ut)) /* can apply to arrays also! */
2706 && !(ctype_isStruct (ctype_realType (ut)))) /* applies to structure fields! */
2707 {
2708 if (!qual_isImplied (qel))
2709 {
28bf4b0b 2710 if (ctype_isImmutableAbstract (ut)) {
2711 voptgenerror
2712 (FLG_REDUNDANTSHAREQUAL,
2713 message ("Qualifier %s used on unsharable storage type %t: %q",
2714 exkind_unparse (ek), ut, uentry_getName (ue)),
2715 uentry_whereLast (ue));
2716 } else {
2717 voptgenerror
2718 (FLG_MISPLACEDSHAREQUAL,
2719 message ("Qualifier %s used on unsharable storage type %t: %q",
2720 exkind_unparse (ek), ut, uentry_getName (ue)),
2721 uentry_whereLast (ue));
2722 }
616915dd 2723 }
2724 }
2725 else
2726 {
2727 alkind ak = sRef_getAliasKind (ue->sref);
2728
2729 sRef_setExKind (ue->sref, ek, uentry_whereDeclared (ue));
28bf4b0b 2730 DPRINTF (("Set exkind: %s", sRef_unparseFull (ue->sref)));
616915dd 2731
2732 if (alkind_isUnknown (ak) || alkind_isImplicit (ak) || alkind_isStatic (ak))
2733 {
2734 if (!alkind_isTemp (ak))
2735 {
28bf4b0b 2736 DPRINTF (("imp dep: %s", uentry_unparseFull (ue)));
616915dd 2737 uentry_setAliasKind (ue, AK_IMPDEPENDENT);
2738 }
2739 }
2740 else if (alkind_isDependent (ak) || alkind_isTemp (ak)
2741 || alkind_isOwned (ak))
2742 {
2743 ; /* okay */
2744 }
2745 else
2746 {
2747 llerror
2748 (FLG_SYNTAX,
2749 message ("Exposure qualifier %s used on %s storage (should "
2750 "be dependent): %q",
2751 qual_unparse (qel),
2752 alkind_unparse (ak),
2753 uentry_unparse (ue)));
2754 }
2755 }
2756 }
2757 else if (qual_isGlobCheck (qel))
2758 {
2759 if (uentry_isVariable (ue))
2760 {
2761 chkind ch = chkind_fromQual (qel);
2762
2763 if (ue->info->var->checked != CH_UNKNOWN)
2764 {
2765 if (ch == ue->info->var->checked)
2766 {
2767 llerror (FLG_SYNTAX,
2768 message ("Redundant %s qualifier on %q",
2769 qual_unparse (qel),
2770 uentry_getName (ue)));
2771 }
2772 else
2773 {
2774 llerror (FLG_SYNTAX,
2775 message
2776 ("Contradictory %s and %s qualifiers on %q",
2777 qual_unparse (qel),
2778 checkedName (ue->info->var->checked),
2779 uentry_getName (ue)));
2780 }
2781 }
2782
2783 ue->info->var->checked = ch;
2784 }
2785 else
2786 {
2787 llerror
2788 (FLG_SYNTAX,
2789 message ("Qualifier %s used with non-variable",
2790 qual_unparse (qel)));
2791 }
2792 }
2793 else if (qual_isReturned (qel))
2794 {
2795 if (uentry_isVariable (ue))
2796 {
2797 ue->info->var->kind = VKRETPARAM;
2798 }
2799 else
2800 {
2801 llerror (FLG_SYNTAX, message ("Qualifier %s used with non-variable",
2802 qual_unparse (qel)));
2803 }
2804 }
2805 else
2806 {
2807 uentry_reflectOtherQualifier (ue, qel);
2808 }
2809
2810 sRef_storeState (ue->sref);
2811 } end_qualList_elements;
2812
2813 qualList_clear (q);
ccf0a4a8 2814
2815 DPRINTF (("Done: %s", sRef_unparseFull (ue->sref)));
616915dd 2816}
2817
2818bool
2819uentry_isOnly (uentry ue)
2820{
2821 return (!uentry_isUndefined (ue)
2822 && uentry_isVariable (ue)
2823 && alkind_isOnly (sRef_getOrigAliasKind (ue->sref)));
2824}
2825
2826static void
2827uentry_setAliasKind (/*@notnull@*/ uentry ue, alkind ak)
2828{
2829 sRef_setAliasKind (ue->sref, ak, uentry_whereDeclared (ue));
2830 sRef_setOrigAliasKind (ue->sref, ak);
2831}
2832
2833static void
2834uentry_setNullState (/*@notnull@*/ uentry ue, nstate ns)
2835{
2836 if (uentry_isVariable (ue))
2837 {
2838 ue->info->var->nullstate = ns;
2839 }
2840
2841 sRef_setNullState (ue->sref, ns, uentry_whereDeclared (ue));
2842}
2843
2844bool
2845uentry_isUnique (uentry ue)
2846{
2847 return (!uentry_isUndefined (ue)
2848 && uentry_isVariable (ue)
2849 && alkind_isUnique (sRef_getOrigAliasKind (ue->sref)));
2850}
2851
2852bool
2853uentry_isFileStatic (uentry ue)
2854{
2855 return (uentry_isStatic (ue)
2856 && (!uentry_isVariable (ue)
2857 || sRef_isFileStatic (uentry_getSref (ue))));
2858}
2859
2860bool
2861uentry_isExported (uentry ue)
2862{
2863 if (uentry_isValid (ue))
2864 {
2865 if (uentry_isVariable (ue))
2866 {
2867 return (sRef_isRealGlobal (uentry_getSref (ue)));
2868 }
2869 else
2870 {
2871 return !uentry_isStatic (ue);
2872 }
2873 }
2874
2875 return FALSE;
2876}
2877
2878bool
2879uentry_isNonLocal (uentry ue)
2880{
2881 return (uentry_isValid (ue) && uentry_isVariable (ue)
28bf4b0b 2882 && (sRef_isFileOrGlobalScope (ue->sref) || uentry_isStatic (ue)));
2883}
2884
2885bool
2886uentry_isGlobalVariable (uentry ue)
2887{
2888 return (uentry_isValid (ue) && uentry_isVariable (ue)
2889 && sRef_isFileOrGlobalScope (ue->sref));
616915dd 2890}
2891
2892bool
28bf4b0b 2893uentry_isVisibleExternally (uentry ue)
616915dd 2894{
28bf4b0b 2895 return (uentry_isValid (ue)
2896 && ((uentry_isVariable (ue) && sRef_isRealGlobal (ue->sref))
2897 || (!uentry_isStatic (ue)
2898 && (uentry_isFunction (ue)
2899 || uentry_isIter (ue)
2900 || uentry_isEndIter (ue)
2901 || uentry_isConstant (ue)
2902 || uentry_isDatatype (ue)
2903 || uentry_isAnyTag (ue)))));
616915dd 2904}
2905
2906bool
2907uentry_isPrintfLike (uentry ue)
2908{
2909 return (uentry_isFunction (ue)
2910 && (ue->info->fcn->specialCode == SPC_PRINTFLIKE));
2911}
2912
2913bool
2914uentry_isScanfLike (uentry ue)
2915{
2916 return (uentry_isFunction (ue)
2917 && (ue->info->fcn->specialCode == SPC_SCANFLIKE));
2918}
2919
2920bool
2921uentry_isMessageLike (uentry ue)
2922{
2923 return (uentry_isFunction (ue)
2924 && (ue->info->fcn->specialCode == SPC_MESSAGELIKE));
2925}
2926
2927static void checkSpecialFunction (/*@notnull@*/ uentry ue)
2928{
2929 uentryList args = uentry_getParams (ue);
2930
2931 if (!uentryList_isMissingParams (args))
2932 {
2933 uentry last = uentry_undefined;
2934
2935 uentryList_elements (args, current)
2936 {
2937 if (uentry_isElipsisMarker (current))
2938 {
2939 if (uentry_isUndefined (last))
2940 {
2941 voptgenerror
2942 (FLG_SYNTAX,
2943 message ("Function %q is marked %s, but has no format "
2944 "string argument before elipsis",
2945 uentry_getName (ue),
2946 specCode_unparse (ue->info->fcn->specialCode)),
2947 uentry_whereLast (ue));
2948 ue->info->fcn->specialCode = SPC_NONE;
2949 }
2950 else
2951 {
2952 ctype rt = ctype_realType (uentry_getType (last));
2953
2954 if (!ctype_match (rt, ctype_string))
2955 {
2956 bool okay = FALSE;
2957
2958 /* wchar_t * is okay too */
2959 if (ctype_isAP (rt))
2960 {
2961 ctype base = ctype_baseArrayPtr (rt);
2962
2963 if (ctype_isArbitraryIntegral (base))
2964 {
2965 okay = TRUE;
2966 }
2967 }
2968
2969 if (!okay)
2970 {
2971 voptgenerror
2972 (FLG_SYNTAX,
2973 message ("Function %q is marked %s, but the argument "
2974 "before the elipsis has type %s (should be char *)",
2975 uentry_getName (ue),
2976 specCode_unparse (ue->info->fcn->specialCode),
2977 ctype_unparse (uentry_getType (last))),
2978 uentry_whereLast (ue));
2979
2980 ue->info->fcn->specialCode = SPC_NONE;
2981 }
2982 }
2983 }
2984 return;
2985 }
2986 last = current;
2987 } end_uentryList_elements ;
2988
2989 voptgenerror
2990 (FLG_SYNTAX,
2991 message ("Function %q is marked %s, but has no elipsis parameter",
2992 uentry_getName (ue),
2993 specCode_unparse (ue->info->fcn->specialCode)),
2994 uentry_whereLast (ue));
2995
2996 ue->info->fcn->specialCode = SPC_NONE;
2997 }
2998}
2999
3000void
3001uentry_setPrintfLike (uentry ue)
3002{
efd360a3 3003 uentry_convertVarFunction (ue);
616915dd 3004 llassertfatal (uentry_isFunction (ue));
3005 ue->info->fcn->specialCode = SPC_PRINTFLIKE;
3006 checkSpecialFunction (ue);
3007}
3008
3009void
3010uentry_setScanfLike (uentry ue)
3011{
efd360a3 3012 uentry_convertVarFunction (ue);
616915dd 3013 llassertfatal (uentry_isFunction (ue));
3014 ue->info->fcn->specialCode = SPC_SCANFLIKE;
3015 checkSpecialFunction (ue);
3016}
3017
3018void
3019uentry_setMessageLike (uentry ue)
3020{
efd360a3 3021 uentry_convertVarFunction (ue);
616915dd 3022 llassertfatal (uentry_isFunction (ue));
3023 ue->info->fcn->specialCode = SPC_MESSAGELIKE;
3024 checkSpecialFunction (ue);
3025}
3026
3027bool
3028uentry_isSpecialFunction (uentry ue)
3029{
3030 return (uentry_isFunction (ue)
3031 && (ue->info->fcn->specialCode != SPC_NONE));
3032}
3033
3034/*@notnull@*/ uentry uentry_makeParam (idDecl t, int i)
3035{
3036 ctype ct = idDecl_getCtype (t);
3037 ctype base = ct;
6970c11b 3038 fileloc loc = setLocation ();
3039 sRef pref = sRef_makeParam (i, ct, stateInfo_makeLoc (loc));
3040 uentry ue = uentry_makeVariableSrefParam (idDecl_observeId (t), ct, loc, pref);
616915dd 3041
6970c11b 3042 DPRINTF (("Make param: %s", uentry_unparseFull (ue)));
616915dd 3043 uentry_reflectQualifiers (ue, idDecl_getQuals (t));
3044 uentry_implicitParamAnnots (ue);
3045
3046 /* Parameter type [][] or [x][] is invalid */
3047
3048 while (ctype_isFixedArray (base)) {
3049 base = ctype_baseArrayPtr (base);
3050 }
3051
3052 if (ctype_isIncompleteArray (base)) {
3053 base = ctype_baseArrayPtr (base);
3054
3055 if (ctype_isArray (base)) {
3056 if (!uentry_hasName (ue)) {
3057 (void) optgenerror (FLG_INCOMPLETETYPE,
3058 message ("Unnamed function parameter %d is incomplete type (inner array must have bounds): %s",
3059 i + 1,
3060 ctype_unparse (ct)),
3061 uentry_whereLast (ue));
3062 } else {
3063 (void) optgenerror (FLG_INCOMPLETETYPE,
3064 message ("Function parameter %q is incomplete type (inner array must have bounds): %s",
3065 uentry_getName (ue),
3066 ctype_unparse (ct)),
3067 uentry_whereLast (ue));
3068 }
3069 }
3070 }
3071
28bf4b0b 3072 DPRINTF (("Param: %s", uentry_unparseFull (ue)));
616915dd 3073 return ue;
3074}
3075
3076/*@only@*/ /*@notnull@*/ uentry uentry_makeIdVariable (idDecl t)
3077{
3078 ctype ct = idDecl_getCtype (t);
3079
3080 if (ctype_isFunction (ct))
3081 {
3082 return (uentry_makeIdFunction (t));
3083 }
3084 else
3085 {
3086 fileloc loc = setLocation ();
3087 uentry ue = uentry_makeVariable (idDecl_observeId (t), ct, loc, FALSE);
3088
3089 uentry_reflectQualifiers (ue, idDecl_getQuals (t));
3090
3091 if (!uentry_isExtern (ue))
3092 {
3093 uentry_setDefined (ue, loc);
3094 }
3095
3096 return ue;
3097 }
3098}
3099
3100# ifndef NOLCL
6970c11b 3101/*@notnull@*/ uentry uentry_makeVariableParam (cstring n, ctype t, fileloc loc)
616915dd 3102{
6970c11b 3103 return (uentry_makeVariableParamAux (n, t, sRef_makeType (t), fileloc_copy (loc), SS_DEFINED));
616915dd 3104}
3105# endif
3106
3107/*
3108** constants
3109*/
3110
5e211f69 3111static /*@only@*/ /*@notnull@*/
616915dd 3112uentry uentry_makeConstantAux (cstring n, ctype t,
5e211f69 3113 /*@keep@*/ fileloc f, bool priv, bool macro,
616915dd 3114 /*@only@*/ multiVal m)
3115{
3116 uentry e = uentry_alloc ();
3117
3118 e->ukind = KCONST;
3119 e->uname = cstring_copy (n);
3120 e->utype = t;
3121 e->storageclass = SCNONE;
3122
28bf4b0b 3123 e->warn = warnClause_undefined; /*@i32 warnings for constants? */
3124
616915dd 3125 e->sref = sRef_makeConst (t);
3126
3127 e->lset = FALSE;
3128 e->used = FALSE;
3129
3130 e->uses = filelocList_new ();
3131 e->isPrivate = priv;
3132 e->hasNameError = FALSE;
3133
3134 e->info = (uinfo) dmalloc (sizeof (*e->info));
3135 e->info->uconst = (ucinfo) dmalloc (sizeof (*e->info->uconst));
616915dd 3136 e->info->uconst->access = typeIdSet_undefined;
5e211f69 3137 e->info->uconst->macro = macro;
616915dd 3138
3139 uentry_setSpecDef (e, f);
3140
3141 if (multiVal_isInt (m) && (multiVal_forceInt (m) == 0))
3142 {
3143 sRef_setDefNull (e->sref, uentry_whereDeclared (e));
3144 }
3145
b9904f57 3146 uentry_setConstantValue (e, m);
3147
616915dd 3148 return (e);
3149}
3150
3151/*@notnull@*/ uentry uentry_makeConstant (cstring n, ctype t, fileloc f)
3152{
5e211f69 3153 return (uentry_makeConstantAux (n, t, f, FALSE, FALSE, multiVal_unknown ()));
3154}
3155
3e3ec469 3156/*@notnull@*/ uentry uentry_makeConstantValue (cstring n, ctype t, fileloc f, bool priv, multiVal val)
5e211f69 3157{
3158 return (uentry_makeConstantAux (n, t, f, priv, FALSE, val));
3159}
3160
3161/*@notnull@*/ uentry uentry_makeMacroConstant (cstring n, ctype t, fileloc f)
3162{
3163 return (uentry_makeConstantAux (n, t, f, FALSE, TRUE, multiVal_unknown ()));
616915dd 3164}
3165
3166/*@notnull@*/ uentry uentry_makeIdConstant (idDecl t)
3167{
3168 uentry ue = uentry_makeConstant (idDecl_observeId (t),
3169 idDecl_getCtype (t),
3170 fileloc_undefined);
3171
3172 llassert (fileloc_isUndefined (ue->whereDeclared));
3173 ue->whereDeclared = setLocation ();
616915dd 3174 uentry_reflectQualifiers (ue, idDecl_getQuals (t));
3175
b9904f57 3176 DPRINTF (("Constant: %s", uentry_unparseFull (ue)));
7534721d 3177 DPRINTF (("Value: %s", multiVal_unparse (uentry_getConstantValue (ue))));
616915dd 3178 return ue;
3179}
3180
3181/*
3182** variables
3183*/
3184
3185void uentry_setDefState (uentry ue, sstate defstate)
3186{
3187 if (uentry_isValid (ue))
3188 {
3189 sRef_setDefState (ue->sref, defstate, fileloc_undefined);
3190
3191 if (uentry_isVariable (ue))
3192 {
3193 ue->info->var->defstate = defstate; /* evs 2000-05-17: fixed bug, was SS_DEFINED! */
3194 }
3195 }
3196}
3197
3198bool uentry_isCheckedUnknown (uentry ue)
3199{
3200 return (uentry_isVar (ue)
3201 && (ue->info->var->checked == CH_UNKNOWN));
3202}
3203
3204bool uentry_isCheckMod (uentry ue)
3205{
3206 return (uentry_isVar (ue)
3207 && (ue->info->var->checked == CH_CHECKMOD));
3208}
3209
3210bool uentry_isUnchecked (uentry ue)
3211{
3212 return (uentry_isVar (ue)
3213 && (ue->info->var->checked == CH_UNCHECKED));
3214}
3215
3216bool uentry_isChecked (uentry ue)
3217{
3218 return (uentry_isVar (ue)
3219 && (ue->info->var->checked == CH_CHECKED));
3220}
3221
3222bool uentry_isCheckedModify (uentry ue)
3223{
3224 return (uentry_isVar (ue)
3225 && (ue->info->var->checked == CH_CHECKED
3226 || ue->info->var->checked == CH_CHECKMOD
3227 || ue->info->var->checked == CH_CHECKEDSTRICT));
3228}
3229
3230bool uentry_isCheckedStrict (uentry ue)
3231{
3232 return (uentry_isVar (ue)
3233 && (ue->info->var->checked == CH_CHECKEDSTRICT));
3234}
3235
3236void uentry_setUnchecked (uentry ue)
3237{
3238 llassert (uentry_isVar (ue));
3239
3240 ue->info->var->checked = CH_UNCHECKED;
3241}
3242
3243void uentry_setChecked (uentry ue)
3244{
3245 llassert (uentry_isVar (ue));
3246
3247 ue->info->var->checked = CH_CHECKED;
3248}
3249
3250void uentry_setCheckMod (uentry ue)
3251{
3252 llassert (uentry_isVar (ue));
3253
3254 ue->info->var->checked = CH_CHECKMOD;
3255}
3256
3257void uentry_setCheckedStrict (uentry ue)
3258{
3259 llassert (uentry_isVar (ue));
3260
3261 ue->info->var->checked = CH_CHECKEDSTRICT;
3262}
3263
3264static /*@only@*/ /*@notnull@*/
3265 uentry uentry_makeVariableAux (cstring n, ctype t,
3266 fileloc f,
3267 /*@exposed@*/ sRef s,
3268 bool priv, vkind kind)
3269{
3270 uentry e = uentry_alloc ();
3271 ctype rt = t;
3272
3273 DPRINTF (("Make variable: %s %s %s", n, ctype_unparse (t), sRef_unparse (s)));
3274
3275 e->ukind = KVAR;
3276 e->uname = cstring_copy (n);
3277 e->utype = t;
3278
3279 e->storageclass = SCNONE;
3280
28bf4b0b 3281 e->warn = warnClause_undefined; /*@i32 warnings for variable @*/
3282
616915dd 3283 e->sref = s;
3284
3285 e->used = FALSE;
3286 e->lset = FALSE;
3287
3288 e->uses = filelocList_new ();
3289 e->isPrivate = priv;
3290 e->hasNameError = FALSE;
3291
3292 e->info = (uinfo) dmalloc (sizeof (*e->info));
3293 e->info->var = (uvinfo) dmalloc (sizeof (*e->info->var));
3294 e->info->var->kind = kind;
3295
b7e84605 3296 /*@i523 e->info->var->origsref = sRef_saveCopy (e->sref); */
616915dd 3297 e->info->var->checked = CH_UNKNOWN;
3298
28bf4b0b 3299 DPRINTF (("Here we are: %s", sRef_unparseFull (e->sref)));
616915dd 3300 uentry_setSpecDef (e, f);
28bf4b0b 3301 DPRINTF (("Here we are: %s", sRef_unparseFull (e->sref)));
616915dd 3302
3303 if (ctype_isFunction (rt))
3304 {
28bf4b0b 3305 rt = ctype_getReturnType (rt);
616915dd 3306 }
3307
3308 if (ctype_isUA (rt))
3309 {
28bf4b0b 3310 DPRINTF (("Here we are: %s", sRef_unparseFull (e->sref)));
616915dd 3311 sRef_setStateFromType (e->sref, rt);
3312 }
3313
28bf4b0b 3314 DPRINTF (("Here we are: %s", sRef_unparseFull (e->sref)));
616915dd 3315 e->info->var->defstate = sRef_getDefState (e->sref);
3316 e->info->var->nullstate = sRef_getNullState (e->sref);
3317
6970c11b 3318 /* start modifications */
3319 /* This function sets the uentry for a pointer or array variable declaration,
3320 it allocates memory and sets the fields. We check if the type of the variable
3321 is a pointer or array and allocate a `bbufinfo' struct accordingly */
3322
616915dd 3323 if( ctype_isArray (t) || ctype_isPointer(t)) {
3324 /*@i222@*/e->info->var->bufinfo = dmalloc( sizeof(*e->info->var->bufinfo) );
3325 e->info->var->bufinfo->bufstate = BB_NOTNULLTERMINATED;
28bf4b0b 3326 /*@access sRef@*/ /*i@222*/
3327 /* It probably isn't necessary to violate the abstraction here
3328 I'll fix this later
3329 */
616915dd 3330 s->bufinfo.bufstate = BB_NOTNULLTERMINATED;
28bf4b0b 3331 /*@noaccess sRef@*/
616915dd 3332 } else {
3333 e->info->var->bufinfo = NULL;
3334 }/* end else */
3335/* end modification */
3336
3337 return (e);
3338}
3339
3340bool
3341uentry_isYield (uentry ue)
3342{
3343 return (uentry_isVariable (ue)
3344 && (ue->info->var->kind == VKYIELDPARAM
3345 || ue->info->var->kind == VKREFYIELDPARAM));
3346}
3347
3348static bool
3349uentry_isRefsField (uentry ue)
3350{
3351 return (uentry_isVariable (ue) && sRef_isRefsField (ue->sref));
3352}
3353
3354/*@only@*/ /*@notnull@*/
3355uentry uentry_makeVariable (cstring n, ctype t, fileloc f, bool isPriv)
3356{
3357 return (uentry_makeVariableAux (n, t, f, sRef_makeType (t), isPriv,
3358 fileloc_isSpec (f) ? VKSPEC : VKNORMAL));
3359}
3360
3361/*
3362** functions
3363*/
3364
3365void uentry_makeVarFunction (uentry ue)
3366{
3367 alkind ak;
3368 exkind ek;
3369 uvinfo oldInfo;
3370 fileloc loc;
3371
3372 llassert (uentry_isValid (ue));
3373 llassert (!sRef_modInFunction ());
3374
3375 ak = sRef_getOrigAliasKind (ue->sref);
3376 ek = sRef_getOrigExKind (ue->sref);
3377
b072092f 3378 llassert (uentry_isVariable (ue));
616915dd 3379 oldInfo = ue->info->var;
3380
ac35a6ab 3381 DPRINTF (("ue: %s", uentry_unparseFull (ue)));
3382 llassert (ctype_isUnknown (ue->utype) || ctype_isFunction (ctype_realType (ue->utype)));
616915dd 3383
3384 /*
ac35a6ab 3385 ** expanded macro is marked used
616915dd 3386 */
3387
efd360a3 3388 ue->used = ue->used || (oldInfo->kind == VKEXPMACRO);
616915dd 3389
3390 ue->ukind = KFCN;
3391 ue->info->fcn = (ufinfo) dmalloc (sizeof (*ue->info->fcn));
3392 ue->info->fcn->exitCode = XK_UNKNOWN;
28bf4b0b 3393 ue->info->fcn->nullPred = qual_createUnknown ();
616915dd 3394 ue->info->fcn->specialCode = SPC_NONE;
3395 ue->info->fcn->access = typeIdSet_undefined;
3396 ue->info->fcn->hasGlobs = FALSE;
3397 ue->info->fcn->globs = globSet_undefined;
3398 ue->info->fcn->hasMods = FALSE;
3399 ue->info->fcn->mods = sRefSet_undefined;
3400 ue->info->fcn->specclauses = NULL;
3401 ue->info->fcn->defparams = uentryList_undefined;
3402
3403 /*drl*/
3814599d 3404 ue->info->fcn->preconditions = functionConstraint_undefined;
616915dd 3405 /*end */
3406
3407 /*drl 12/28/2000*/
efd360a3 3408 ue->info->fcn->postconditions = functionConstraint_undefined;
616915dd 3409 /*end */
616915dd 3410
3411 if (ctype_isFunction (ue->utype))
3412 {
28bf4b0b 3413 ue->sref = sRef_makeType (ctype_getReturnType (ue->utype));
616915dd 3414 }
3415 else
3416 {
3417 ue->sref = sRef_makeType (ctype_unknown);
3418 }
3419
3420 if (sRef_isRefCounted (ue->sref))
3421 {
3422 ak = AK_NEWREF;
3423 }
3424 else
3425 {
3426 if (alkind_isUnknown (ak))
3427 {
3428 if (exkind_isKnown (ek))
3429 {
28bf4b0b 3430 DPRINTF (("imp dep: %s", uentry_unparseFull (ue)));
616915dd 3431 ak = AK_IMPDEPENDENT;
3432 }
3433 else
3434 {
3435 if (context_getFlag (FLG_RETIMPONLY))
3436 {
3437 if (ctype_isFunction (ue->utype)
3438 && ctype_isVisiblySharable
28bf4b0b 3439 (ctype_realType (ctype_getReturnType (ue->utype))))
616915dd 3440 {
3441 if (uentryList_hasReturned (uentry_getParams (ue)))
3442 {
3443 ;
3444 }
3445 else
3446 {
28bf4b0b 3447 if (ctype_isImmutableAbstract (ctype_getReturnType (ue->utype)))
3448 {
3449 ;
3450 }
3451 else
3452 {
3453 ak = AK_IMPONLY;
3454 }
3455 }
616915dd 3456 }
3457 }
3458 }
3459 }
3460 }
3461
3462 loc = ue->whereDeclared;
3463
3464 sRef_setAliasKind (ue->sref, ak, loc);
3465 sRef_setNullState (ue->sref, oldInfo->nullstate, loc);
3466 sRef_setDefState (ue->sref, oldInfo->defstate, loc);
3467 sRef_setExKind (ue->sref, ek, loc);
3468
3469 if (oldInfo->kind == VKEXPMACRO)
3470 {
efd360a3 3471 ;
616915dd 3472 }
3473 else
3474 {
3475 fileloc_free (ue->whereDefined);
3476 ue->whereDefined = fileloc_undefined;
3477 }
3478
3479 uvinfo_free (oldInfo);
3480}
3481
b072092f 3482void uentry_makeConstantFunction (uentry ue)
3483{
3484 alkind ak;
3485 exkind ek;
3486 ucinfo oldInfo;
3487 fileloc loc;
3488
3489 llassert (uentry_isValid (ue));
3490 llassert (!sRef_modInFunction ());
3491
3492 ak = sRef_getOrigAliasKind (ue->sref);
3493 ek = sRef_getOrigExKind (ue->sref);
3494
3495 llassert (uentry_isConstant (ue));
3496 oldInfo = ue->info->uconst;
3497
3498 llassert (ctype_isUnknown (ue->utype) || ctype_isFunction (ue->utype));
3499
3500 /*
3501 ** expanded macro is marked used (until I write a pre-processor)
3502 */
3503
3504 ue->ukind = KFCN;
3505 ue->info->fcn = (ufinfo) dmalloc (sizeof (*ue->info->fcn));
3506 ue->info->fcn->exitCode = XK_UNKNOWN;
3507 ue->info->fcn->nullPred = qual_createUnknown ();
3508 ue->info->fcn->specialCode = SPC_NONE;
3509 ue->info->fcn->access = typeIdSet_undefined;
3510 ue->info->fcn->hasGlobs = FALSE;
3511 ue->info->fcn->globs = globSet_undefined;
3512 ue->info->fcn->hasMods = FALSE;
3513 ue->info->fcn->mods = sRefSet_undefined;
3514 ue->info->fcn->specclauses = NULL;
3515 ue->info->fcn->defparams = uentryList_undefined;
3516
3517 /*drl*/
3518 ue->info->fcn->preconditions = functionConstraint_undefined;
3519 /*end */
3520
3521 /*drl 12/28/2000*/
3522 ue->info->fcn->postconditions = functionConstraint_undefined;
3523 /*end */
3524
3525
3526 if (ctype_isFunction (ue->utype))
3527 {
3528 ue->sref = sRef_makeType (ctype_getReturnType (ue->utype));
3529 }
3530 else
3531 {
3532 ue->sref = sRef_makeType (ctype_unknown);
3533 }
3534
3535 if (sRef_isRefCounted (ue->sref))
3536 {
3537 ak = AK_NEWREF;
3538 }
3539 else
3540 {
3541 if (alkind_isUnknown (ak))
3542 {
3543 if (exkind_isKnown (ek))
3544 {
3545 DPRINTF (("imp dep: %s", uentry_unparseFull (ue)));
3546 ak = AK_IMPDEPENDENT;
3547 }
3548 else
3549 {
3550 if (context_getFlag (FLG_RETIMPONLY))
3551 {
3552 if (ctype_isFunction (ue->utype)
3553 && ctype_isVisiblySharable
3554 (ctype_realType (ctype_getReturnType (ue->utype))))
3555 {
3556 if (uentryList_hasReturned (uentry_getParams (ue)))
3557 {
3558 ;
3559 }
3560 else
3561 {
3562 if (ctype_isImmutableAbstract (ctype_getReturnType (ue->utype)))
3563 {
3564 ;
3565 }
3566 else
3567 {
3568 ak = AK_IMPONLY;
3569 }
3570 }
3571 }
3572 }
3573 }
3574 }
3575 }
3576
3577 loc = ue->whereDeclared;
3578
3579 sRef_setAliasKind (ue->sref, ak, loc);
3580 sRef_setExKind (ue->sref, ek, loc);
3581
3582 fileloc_free (ue->whereDefined);
3583 ue->whereDefined = fileloc_undefined;
3584 ucinfo_free (oldInfo);
3585}
3586
616915dd 3587void
3588uentry_setGlobals (uentry ue, /*@owned@*/ globSet globs)
3589{
3590 llassert (uentry_isValid (ue));
3591
3592 if (uentry_isIter (ue))
3593 {
3594 llassert (globSet_isUndefined (ue->info->iter->globs));
3595 ue->info->iter->globs = globs;
3596 }
3597 else
3598 {
efd360a3 3599 uentry_convertVarFunction (ue);
616915dd 3600
3601 llassert (uentry_isFunction (ue));
3602 llassert (!ue->info->fcn->hasGlobs
3603 && globSet_isUndefined (ue->info->fcn->globs));
3604
3605 ue->info->fcn->hasGlobs = TRUE;
28bf4b0b 3606 globSet_markImmutable (globs);
616915dd 3607 /*@-mustfree@*/ ue->info->fcn->globs = globs;
3608 /*@=mustfree@*/
3609 }
3610
68de3f33 3611 /*@i23*/
3612 /* ??? - evans 2001-09-09 not sure what's going on here...?
616915dd 3613 if (globSet_hasStatic (globs))
3614 {
3615 context_recordFileGlobals (globs);
3616 }
28bf4b0b 3617 */
616915dd 3618
3619 if (context_getFlag (FLG_GLOBALSIMPMODIFIESNOTHING))
3620 {
3621 ue->info->fcn->hasMods = TRUE;
3622 }
3623}
3624
3625void uentry_addAccessType (uentry ue, typeId tid)
3626{
3627 if (uentry_isFunction (ue))
3628 {
3629 ue->info->fcn->access = typeIdSet_insert (ue->info->fcn->access, tid);
3630 }
3631 else if (uentry_isEitherConstant (ue))
3632 {
3633 ue->info->uconst->access = typeIdSet_insert (ue->info->uconst->access, tid);
3634 }
3635 else if (uentry_isIter (ue))
3636 {
3637 ue->info->iter->access = typeIdSet_insert (ue->info->iter->access, tid);
3638 }
3639 else if (uentry_isEndIter (ue))
3640 {
3641 ue->info->enditer->access = typeIdSet_insert (ue->info->enditer->access, tid);
3642 }
3643 else
3644 {
3645 llbug (message ("no access for: %q", uentry_unparse (ue)));
3646 }
3647}
3648
3649/*@only@*/ /*@notnull@*/ uentry
3650 uentry_makeFunction (cstring n, ctype t,
3651 typeId access,
3652 /*@only@*/ globSet globs, /*@only@*/ sRefSet mods,
28bf4b0b 3653 /*@only@*/ warnClause warn,
616915dd 3654 fileloc f)
3655{
28bf4b0b 3656 llassert (warnClause_isUndefined (warn)); /*@i325 remove parameter! */
616915dd 3657 return (uentry_makeFunctionAux (n, t,
3658 ((typeId_isInvalid (access)) ? typeIdSet_emptySet ()
3659 : typeIdSet_single (access)),
28bf4b0b 3660 globs, mods, warn,
3661 f,
616915dd 3662 FALSE, FALSE));
3663}
3664
3665# ifndef NOLCL
3666/*@notnull@*/ uentry
3667 uentry_makePrivFunction2 (cstring n, ctype t,
3668 typeIdSet access,
3669 globSet globs, sRefSet mods,
3670 fileloc f)
3671{
28bf4b0b 3672 return (uentry_makeFunctionAux (n, t, access, globs, mods, warnClause_undefined,
3673 f, TRUE, FALSE));
616915dd 3674}
3675
3676
3677/*@notnull@*/ uentry
3678 uentry_makeSpecFunction (cstring n, ctype t,
3679 typeIdSet access,
3680 /*@only@*/ globSet globs,
3681 /*@only@*/ sRefSet mods,
3682 fileloc f)
3683{
3684 uentry ue = uentry_makeFunctionAux (n, t, access,
28bf4b0b 3685 globs, mods, warnClause_undefined,
3686 f, FALSE, FALSE);
616915dd 3687
3688 uentry_setHasGlobs (ue);
3689 uentry_setHasMods (ue);
3690
3691 reflectImplicitFunctionQualifiers (ue, TRUE);
3692 return (ue);
3693}
3694# endif
3695
3696uentry uentry_makeExpandedMacro (cstring s, fileloc f)
3697{
3698 uentry ue = uentry_makeVariableAux (s, ctype_unknown, fileloc_undefined,
3699 sRef_undefined, FALSE, VKEXPMACRO);
3700
3701 uentry_setDefined (ue, f);
3702 return ue;
3703}
3704
3705/*@notnull@*/ /*@notnull@*/ uentry
3706 uentry_makeForwardFunction (cstring n, typeId access, fileloc f)
3707{
3708 uentry ue = uentry_makeFunctionAux (n, ctype_unknown,
3709 typeIdSet_singleOpt (access),
3710 globSet_undefined, sRefSet_undefined,
28bf4b0b 3711 warnClause_undefined,
616915dd 3712 fileloc_undefined,
3713 FALSE, TRUE);
3714
3715 ue->whereDeclared = fileloc_update (ue->whereDeclared, f);
3716 return ue;
3717}
3718
3719bool uentry_isForward (uentry e)
3720{
3721 if (uentry_isValid (e))
3722 {
3723 ctype ct = uentry_getType (e);
3724
3725 return (ctype_isUnknown (ct)
3726 || (ctype_isFunction (ct)
28bf4b0b 3727 && ctype_isUnknown (ctype_getReturnType (ct))));
616915dd 3728 }
3729
3730 return FALSE;
3731}
3732
3733# ifndef NOLCL
3734/*@notnull@*/ uentry
3735uentry_makeTypeListFunction (cstring n, typeIdSet access, fileloc f)
3736{
3737 return (uentry_makeFunctionAux (n, ctype_unknown, access,
28bf4b0b 3738 globSet_undefined, sRefSet_undefined, warnClause_undefined,
3739 f,FALSE, TRUE));
616915dd 3740}
3741
3742/*@notnull@*/ uentry
3743uentry_makeUnspecFunction (cstring n, ctype t,
3744 typeIdSet access,
3745 fileloc f)
3746{
28bf4b0b 3747 uentry ue = uentry_makeFunctionAux (n, t, access, globSet_undefined,
3748 sRefSet_undefined, warnClause_undefined,
3749 f, FALSE, TRUE);
616915dd 3750
3751 reflectImplicitFunctionQualifiers (ue, TRUE);
3752 return ue;
3753}
3754# endif
3755
3756/*
3757** datatypes
3758*/
3759
3760/* is exported for use by usymtab_interface */
3761
3762/*@notnull@*/ uentry
28bf4b0b 3763 uentry_makeDatatypeAux (cstring n, ctype t, ynm mut, ynm abstract,
616915dd 3764 fileloc f, bool priv)
3765{
3766 uentry e = uentry_alloc ();
3767
3768 DPRINTF (("Make datatype: %s / %s",
3769 n, ctype_unparse (t)));
3770
3771 /* e->shallowCopy = FALSE; */
3772 e->ukind = KDATATYPE;
3773 e->uname = cstring_copy (n);
3774 e->utype = t;
3775 e->storageclass = SCNONE;
3776 e->sref = sRef_makeUnknown ();
3777
3778 if (ctype_isUA (t))
3779 {
3780 sRef_setStateFromType (e->sref, t);
3781 }
3782
3783 uentry_setSpecDef (e, f);
3784
28bf4b0b 3785 e->warn = warnClause_undefined; /*@i634@*/
616915dd 3786 e->uses = filelocList_new ();
3787 e->isPrivate = priv;
3788 e->hasNameError = FALSE;
3789
3790 e->used = FALSE;
3791 e->lset = FALSE;
3792
3793 e->info = (uinfo) dmalloc (sizeof (*e->info));
3794 e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
28bf4b0b 3795 e->info->datatype->abs = abstract;
616915dd 3796 e->info->datatype->mut = mut;
3797 e->info->datatype->type = ctype_undefined;
3798
3799 if (uentry_isDeclared (e))
3800 {
3801 uentry_setDefined (e, f);
3802 }
3803
28bf4b0b 3804 if (ynm_isOn (abstract) && !(uentry_isCodeDefined (e)))
616915dd 3805 {
3806 sRef_setNullState (e->sref, NS_ABSNULL, uentry_whereDeclared (e));
3807 }
3808
3809 return (e);
3810}
3811
3812/*@notnull@*/ uentry
28bf4b0b 3813 uentry_makeDatatype (cstring n, ctype t, ynm mut, ynm abstract, fileloc f)
616915dd 3814{
28bf4b0b 3815 return (uentry_makeDatatypeAux (n, t, mut, abstract, f, FALSE));
616915dd 3816}
3817
28bf4b0b 3818/*@notnull@*/ uentry uentry_makeBoolDatatype (ynm abstract)
616915dd 3819{
3820 uentry ret = uentry_makeDatatypeAux (context_getBoolName (),
28bf4b0b 3821 ctype_bool, NO, abstract,
616915dd 3822 fileloc_getBuiltin (),
3823 FALSE);
3824
3825 ret->info->datatype->type = ctype_bool;
3826 return ret;
3827}
3828
3829/*
3830** iters
3831*/
3832
3833static /*@only@*/ /*@notnull@*/ uentry
3834 uentry_makeIterAux (cstring n, typeIdSet access, ctype ct,
3835 /*@only@*/ fileloc f)
3836{
3837 uentry e = uentry_alloc ();
3838
3839 e->ukind = KITER;
3840 e->uname = cstring_copy (n);
3841 e->utype = ct;
3842 e->sref = sRef_makeUnknown ();
3843 e->storageclass = SCNONE;
3844 e->used = FALSE;
3845 e->lset = FALSE;
3846
3847 uentry_setSpecDef (e, f);
3848
28bf4b0b 3849 e->warn = warnClause_undefined; /*@i452@*/
616915dd 3850 e->uses = filelocList_new ();
3851 e->isPrivate = FALSE;
3852 e->hasNameError = FALSE;
3853
3854 e->info = (uinfo) dmalloc (sizeof (*e->info));
3855 e->info->iter = (uiinfo) dmalloc (sizeof (*e->info->iter));
3856 e->info->iter->access = access;
3857 e->info->iter->mods = sRefSet_undefined;
3858 e->info->iter->globs = globSet_undefined;
3859
3860 uentry_checkIterArgs (e);
3861 return (e);
3862}
3863
3864/*@notnull@*/ uentry uentry_makeIter (cstring n, ctype ct, fileloc f)
3865{
3866 return (uentry_makeIterAux (n, context_fileAccessTypes (), ct, f));
3867}
3868
3869static /*@notnull@*/ uentry
3870uentry_makeEndIterAux (cstring n, typeIdSet access, /*@only@*/ fileloc f)
3871{
3872 uentry e = uentry_alloc ();
3873
3874 /* e->shallowCopy = FALSE; */
3875 e->ukind = KENDITER;
3876 e->storageclass = SCNONE;
3877 e->uname = message ("end_%s", n);
3878 e->utype = ctype_unknown;
3879 e->sref = sRef_makeUnknown ();
3880
3881 uentry_setSpecDef (e, f);
3882
3883 e->used = FALSE;
3884 e->lset = FALSE;
3885
3886 e->uses = filelocList_new ();
3887 e->isPrivate = FALSE;
3888 e->hasNameError = FALSE;
3889
3890 e->info = (uinfo) dmalloc (sizeof (*e->info));
3891 e->info->enditer = (ueinfo) dmalloc (sizeof (*e->info->enditer));
3892
3893 e->info->enditer->access = access;
3894
28bf4b0b 3895 e->warn = warnClause_undefined; /*@i452@*/
616915dd 3896 return (e);
3897}
3898
3899/*@notnull@*/ /*@only@*/ uentry uentry_makeEndIter (cstring n, fileloc f)
3900{
3901 return (uentry_makeEndIterAux (n, context_fileAccessTypes (), f));
3902}
3903
3904/*
3905** tags
3906*/
3907
3908static /*@only@*/ /*@notnull@*/ uentry
3909 uentry_makeTagAux (cstring n, ctype t,
3910 /*@only@*/ fileloc fl,
3911 bool priv, ekind kind)
3912{
3913 uentry e = uentry_alloc ();
3914
3915 if (kind != KSTRUCTTAG && kind != KUNIONTAG && kind != KENUMTAG)
3916 {
3917 llbuglit ("uentry_makeTagAux: not a tag type");
3918 }
3919
3920 e->ukind = kind;
3921 /* e->shallowCopy = FALSE; */
3922 e->uname = cstring_copy (n);
3923
3924 e->utype = t;
3925 e->sref = sRef_makeUnknown ();
3926 e->storageclass = SCNONE;
3927
3928 uentry_setSpecDef (e, fl);
3929
3930 e->used = FALSE;
3931 e->lset = FALSE;
3932
3933 e->uses = filelocList_new ();
3934 e->isPrivate = priv;
3935 e->hasNameError = FALSE;
3936
3937 e->info = (uinfo) dmalloc (sizeof (*e->info));
3938 e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
3939 e->info->datatype->abs = NO;
3940 e->info->datatype->mut = (kind == KENUMTAG) ? NO : MAYBE;
3941 e->info->datatype->type = t;
28bf4b0b 3942 e->warn = warnClause_undefined; /*@i452@*/
616915dd 3943
3944 if (uentry_isDeclared (e))
3945 {
3946 uentry_setDefined (e, fl);
3947 }
3948
3949 return (e);
3950}
3951
3952uentry uentry_makeStructTagLoc (cstring n, ctype t)
3953{
3954 cstring sname = makeStruct (n);
3955 uentry ret = uentry_makeTagAux (sname, t, setLocation (), FALSE, KSTRUCTTAG);
3956
3957 cstring_free (sname);
3958 return (ret);
3959}
3960
3961/*@only@*/ uentry
3962uentry_makeStructTag (cstring n, ctype t, fileloc loc)
3963{
3964 cstring sname = makeStruct (n);
3965 uentry ret = uentry_makeTagAux (sname, t, loc, FALSE, KSTRUCTTAG);
3966
3967 cstring_free (sname);
3968 return ret;
3969}
3970
3971/*@only@*/ uentry
3972uentry_makeUnionTag (cstring n, ctype t, fileloc loc)
3973{
3974 cstring uname = makeUnion (n);
3975 uentry ret = uentry_makeTagAux (uname, t, loc, FALSE, KUNIONTAG);
3976
3977 cstring_free (uname);
3978 return (ret);
3979}
3980
3981# ifndef NOLCL
3982uentry
3983uentry_makeEnumTag (cstring n, ctype t, fileloc loc)
3984{
3985 cstring ename = makeEnum (n);
3986 uentry ret = uentry_makeTagAux (ename, t, loc, FALSE, KENUMTAG);
3987
3988 cstring_free (ename);
3989 return ret;
3990}
3991# endif
3992
3993uentry
3994uentry_makeUnionTagLoc (cstring n, ctype t)
3995{
3996 cstring uname = makeUnion (n);
3997 uentry ret = uentry_makeTagAux (uname, t, setLocation (), FALSE, KUNIONTAG);
3998
3999 cstring_free (uname);
4000 return ret;
4001}
4002
4003uentry
4004uentry_makeEnumTagLoc (cstring n, ctype t)
4005{
4006 cstring ename = makeEnum (n);
4007 uentry ret = uentry_makeTagAux (ename, t, setLocation (), FALSE, KENUMTAG);
4008
4009 cstring_free (ename);
4010 return ret;
4011}
4012
4013bool
4014uentry_isStructTag (uentry ue)
4015{
4016 return (uentry_isValid (ue) && ue->ukind == KSTRUCTTAG);
4017}
4018
4019bool
4020uentry_isUnionTag (uentry ue)
4021{
4022 return (uentry_isValid (ue) && ue->ukind == KUNIONTAG);
4023}
4024
4025bool
4026uentry_isEnumTag (uentry ue)
4027{
4028 return (uentry_isValid (ue) && ue->ukind == KENUMTAG);
4029}
4030
4031bool
4032uentry_isAnyTag (uentry ue)
4033{
4034 return (uentry_isStructTag (ue)
4035 || uentry_isUnionTag (ue)
4036 || uentry_isEnumTag (ue));
4037}
4038
4039static /*@unchecked@*/ /*@only@*/ uentry emarker = NULL;
4040
4041extern void uentry_destroyMod (void)
4042 /*@globals killed emarker@*/ /*@modifies emarker@*/
4043{
4044 static bool wasDestroyed = FALSE;
4045
4046 llassert (!wasDestroyed);
4047
4048 if (emarker != NULL)
4049 {
4050 uentry_reallyFree (emarker);
4051 }
4052
4053 wasDestroyed = TRUE;
4054}
4055
4056uentry
4057uentry_makeElipsisMarker (void)
4058{
4059 if (emarker == NULL)
4060 {
4061 emarker = uentry_alloc ();
4062
4063 emarker->ukind = KELIPSMARKER;
4064 emarker->uname = cstring_makeLiteral ("...");
4065 emarker->utype = ctype_elipsMarker;
4066 emarker->sref = sRef_undefined;
4067 emarker->storageclass = SCNONE;
4068 emarker->used = FALSE;
4069 emarker->lset = FALSE;
4070 emarker->info = NULL;
4071
4072 uentry_setSpecDef (emarker, fileloc_undefined);
4073 emarker->uses = filelocList_new ();
4074 emarker->isPrivate = FALSE;
4075 emarker->hasNameError = FALSE;
4076 }
4077
4078 /*@ignore@*/ return (emarker); /*@end@*/
4079}
4080
4081/*
4082** comparisons
4083*/
4084
4085bool
4086uentry_equiv (uentry p1, uentry p2)
4087{
4088 if (uentry_compare (p1, p2) != 0)
4089 {
4090 return FALSE;
4091 }
4092 else
4093 {
4094 return TRUE;
4095 }
4096}
4097
4098int
4099uentry_xcomparealpha (uentry *p1, uentry *p2)
4100{
4101 int res;
4102
4103 if ((res = uentry_compare (*p1, *p2)) == 0) {
4104 if ((*p1 != NULL) && (*p2 != NULL)) {
4105 res = cstring_compare ((*p1)->uname,
4106 (*p2)->uname);
4107 }
4108 }
4109
4110 return res;
4111}
4112
4113int
4114uentry_xcompareuses (uentry *p1, uentry *p2)
4115{
4116 uentry u1 = *p1;
4117 uentry u2 = *p2;
4118
4119 if (uentry_isValid (u1))
4120 {
4121 if (uentry_isValid (u2))
4122 {
4123 return (-1 * int_compare (filelocList_size (u1->uses),
4124 filelocList_size (u2->uses)));
4125 }
4126 else
4127 {
4128 return 1;
4129 }
4130 }
4131 else
4132 {
4133 if (uentry_isValid (u2))
4134 {
4135 return -1;
4136 }
4137 else
4138 {
4139 return 0;
4140 }
4141 }
4142}
4143
4144int
4145uentry_compareStrict (uentry v1, uentry v2)
4146{
4147 COMPARERETURN (uentry_compare (v1, v2));
4148
4149 if (v1 != v2 && uentry_isValid (v1) && uentry_isValid (v2))
4150 {
4151 COMPARERETURN (fileloc_compare (v1->whereDeclared, v2->whereDeclared));
4152 COMPARERETURN (fileloc_compare (v1->whereDefined, v2->whereDefined));
4153 COMPARERETURN (fileloc_compare (v1->whereSpecified, v2->whereSpecified));
4154 }
4155
4156 return 0;
4157}
4158
4159int
4160uentry_compare (uentry u1, uentry u2)
4161{
4162 if (u1 == u2) return 0;
4163
4164 if (uentry_isInvalid (u1)) return -1;
4165 if (uentry_isInvalid (u2)) return 1;
4166
4167 INTCOMPARERETURN (u1->ukind, u2->ukind);
4168 COMPARERETURN (ctype_compare (u1->utype, u2->utype));
4169 COMPARERETURN (bool_compare (uentry_isPriv (u1), uentry_isPriv (u2)));
616915dd 4170 COMPARERETURN (sRef_compare (u1->sref, u2->sref));
4171
4172 switch (u1->ukind)
4173 {
4174 case KINVALID:
4175 case KELIPSMARKER:
1b8ae690 4176 /* bug detected by splint:
616915dd 4177 ** uentry.c:753,14: Return value type bool does not match declared type int: TRUE
4178 */
4179 return 0;
4180 case KENUMCONST:
4181 case KCONST:
b9904f57 4182 return (multiVal_compare (uentry_getConstantValue (u1),
4183 uentry_getConstantValue (u2)));
616915dd 4184 case KSTRUCTTAG:
4185 case KUNIONTAG:
4186 case KENUMTAG:
4187 return (ctype_compare (u1->info->datatype->type, u2->info->datatype->type));
4188 case KITER:
4189 COMPARERETURN (typeIdSet_compare (uentry_accessType (u1),
4190 uentry_accessType (u2)));
4191 return (uentryList_compareParams (uentry_getParams (u1),
4192 uentry_getParams (u2)));
4193 case KENDITER:
4194 return (typeIdSet_compare (uentry_accessType (u1),
4195 uentry_accessType (u2)));
4196 case KFCN:
28bf4b0b 4197 /*
4198 ** Functions are never equivalent
4199 */
4200
b7e84605 4201 if (u1 - u2 < 0) /* evans 2001-08-21: was: ((int) u1 < (int) u2), changed to remove gcc warning */
28bf4b0b 4202 {
4203 return -1;
4204 }
4205 else
4206 {
4207 return 1;
4208 }
4209 case KVAR:
4210
4211 COMPARERETURN (generic_compare (u1->info->var->kind, u2->info->var->kind));
4212 COMPARERETURN (generic_compare (sRef_getOrigAliasKind (u1->sref),
4213 sRef_getOrigAliasKind (u2->sref)));
4214 COMPARERETURN (generic_compare (sRef_getOrigExKind (u1->sref),
4215 sRef_getOrigExKind (u2->sref)));
616915dd 4216 COMPARERETURN (generic_compare (u1->info->var->checked,
4217 u2->info->var->checked));
4218 COMPARERETURN (generic_compare (u1->info->var->defstate,
4219 u2->info->var->defstate));
4220 return (generic_compare (u1->info->var->nullstate,
4221 u2->info->var->nullstate));
4222 case KDATATYPE:
4223 COMPARERETURN (ctype_compare (u1->info->datatype->type,
4224 u2->info->datatype->type));
4225 COMPARERETURN (ynm_compare (u1->info->datatype->mut,
4226 u2->info->datatype->mut));
4227 return (ynm_compare (u1->info->datatype->abs, u2->info->datatype->abs));
4228 }
4229
4230 BADEXIT;
4231}
4232
4233/*
4234** library format:
4235**
4236** all entries are: <type>[@<info>]*#<name>
4237**
4238** info depends on kind:
4239*/
4240
4241static void
4242advanceField (char **s)
4243{
28bf4b0b 4244 reader_checkChar (s, '@');
616915dd 4245}
4246
4247static void
4248advanceName (char **s)
4249{
28bf4b0b 4250 reader_checkChar (s, '#');
616915dd 4251}
4252
4253static vkind
4254vkind_fromInt (int i)
4255{
4256 if /*@+enumint@*/ (i < VKFIRST || i > VKLAST) /*@=enumint@*/
4257 {
4258 llbuglit ("vkind_fromInt: out of range");
4259 }
4260
4261 return (vkind)i;
4262}
4263
4264static uentry
4265 uentry_makeConstantBase (/*@only@*/ cstring name, ctype ct,
4266 typeIdSet access, nstate nullstate,
4267 /*@keep@*/ fileloc loc, /*@only@*/ multiVal m)
4268{
4269 uentry e = uentry_alloc ();
4270
4271 e->ukind = KCONST;
4272 e->uname = name;
4273 e->utype = ct;
4274 e->sref = sRef_makeConst (ct);
4275
4276 sRef_setNullState (e->sref, nullstate, loc);
4277 e->storageclass = SCNONE;
4278
4279 if (fileloc_isSpec (loc))
4280 {
4281 e->whereSpecified = loc;
4282 e->whereDeclared = fileloc_undefined;
4283 }
4284 else
4285 {
4286 e->whereSpecified = fileloc_undefined;
4287 e->whereDeclared = loc;
4288 }
4289
4290 e->whereDefined = fileloc_undefined;
4291 e->uses = filelocList_new ();
4292 e->isPrivate = FALSE;
4293 e->hasNameError = FALSE;
4294
4295 e->used = FALSE;
4296 e->lset = FALSE;
4297
28bf4b0b 4298 e->warn = warnClause_undefined; /*@i452@*/
4299
616915dd 4300 e->info = (uinfo) dmalloc (sizeof (*e->info));
4301 e->info->uconst = (ucinfo) dmalloc (sizeof (*e->info->uconst));
616915dd 4302 e->info->uconst->access = access;
3e3ec469 4303 e->info->uconst->macro = FALSE; /*@i523! fix this when macro info added to library */
b9904f57 4304 uentry_setConstantValue (e, m);
616915dd 4305 sRef_storeState (e->sref);
4306
4307 return (e);
4308}
4309
4310static /*@only@*/ uentry
4311 uentry_makeVariableBase (/*@only@*/ cstring name, ctype ct, vkind kind,
4312 sstate defstate, nstate isnull, alkind aliased,
4313 exkind exp, chkind checked,
4314 /*@only@*/ fileloc loc)
4315{
4316 uentry e = uentry_alloc ();
4317
4318 e->ukind = KVAR;
4319 e->uname = name;
4320 e->utype = ct;
4321 e->storageclass = SCNONE;
4322
4323 e->sref = sRef_makeType (ct);
4324 sRef_setNullState (e->sref, isnull, loc);
4325
4326 e->whereDefined = fileloc_undefined;
4327
4328 if (fileloc_isSpec (loc))
4329 {
4330 e->whereSpecified = loc;
4331 e->whereDeclared = fileloc_undefined;
4332 }
4333 else
4334 {
4335 e->whereSpecified = fileloc_undefined;
4336 e->whereDeclared = loc;
4337 }
4338
4339 e->isPrivate = FALSE;
4340 e->hasNameError = FALSE;
4341
4342 e->used = FALSE;
4343 e->lset = FALSE;
4344
4345 e->uses = filelocList_new ();
28bf4b0b 4346 e->warn = warnClause_undefined; /*@i452@*/
616915dd 4347
4348 e->info = (uinfo) dmalloc (sizeof (*e->info));
4349 e->info->var = (uvinfo) dmalloc (sizeof (*e->info->var));
4350 e->info->var->kind = kind;
4351 e->info->var->checked = checked;
4352 e->info->var->defstate = defstate;
4353
4354 sRef_setDefState (e->sref, defstate, loc);
4355
4356 e->info->var->nullstate = sRef_getNullState (e->sref);
4357
4358 sRef_setExKind (e->sref, exp, loc);
4359 sRef_setAliasKind (e->sref, aliased, loc);
4360
4361 sRef_storeState (e->sref);
4362
4363 /*DRL ADDED 9-1-2000 */
4364 e->info->var->bufinfo = NULL;
4365
4366 return (e);
4367}
4368
4369static /*@only@*/ uentry
28bf4b0b 4370uentry_makeDatatypeBase (/*@only@*/ cstring name, ctype ct, ynm abstract,
616915dd 4371 ynm mut, ctype rtype, alkind ak, exkind exp,
4372 sstate defstate, nstate isnull,
4373 /*@only@*/ fileloc loc)
4374{
4375 uentry e = uentry_alloc ();
4376
4377 e->ukind = KDATATYPE;
4378 /* e->shallowCopy = FALSE; */
4379 e->uname = name;
4380 e->utype = ct;
4381 e->storageclass = SCNONE;
4382 e->sref = sRef_makeUnknown ();
28bf4b0b 4383 DPRINTF (("Merge null 1: %s", sRef_unparseFull (e->sref)));
616915dd 4384
4385 /*
4386 ** This is only setting null state. (I think?)
4387 */
4388
4389 if (ctype_isUA (ct))
4390 {
4391 uentry te = usymtab_getTypeEntrySafe (ctype_typeId (ct));
4392
4393 if (uentry_isValid (te))
4394 {
4395 sRef_setStateFromUentry (e->sref, te);
4396 }
4397 else
4398 {
4399 /* problem for recursive type definitions */
4400 }
4401 }
4402
4403 sRef_setAliasKind (e->sref, ak, loc);
4404 sRef_setExKind (e->sref, exp, loc);
4405
4406 sRef_setDefState (e->sref, defstate, loc);
4407
28bf4b0b 4408 if (ynm_isOn (abstract) && ctype_isUnknown (ct) && isnull == NS_UNKNOWN)
616915dd 4409 {
4410 isnull = NS_ABSNULL;
4411 }
4412
28bf4b0b 4413 DPRINTF (("Merge null: %s", sRef_unparseFull (e->sref)));
616915dd 4414 sRef_mergeNullState (e->sref, isnull);
4415
4416 e->whereDefined = fileloc_copy (loc); /*< bogus! (but necessary for lexer) >*/
4417
4418 if (fileloc_isSpec (loc))
4419 {
4420 e->whereSpecified = loc;
4421 e->whereDeclared = fileloc_undefined;
4422 }
4423 else
4424 {
4425 e->whereSpecified = fileloc_undefined;
4426 e->whereDeclared = loc;
4427 }
4428
4429 e->isPrivate = FALSE;
4430 e->hasNameError = FALSE;
4431
28bf4b0b 4432 e->warn = warnClause_undefined; /*@i452@*/
4433
616915dd 4434 e->used = FALSE;
4435 e->lset = FALSE;
4436 e->uses = filelocList_new ();
4437
4438 e->info = (uinfo) dmalloc (sizeof (*e->info));
4439 e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
28bf4b0b 4440 e->info->datatype->abs = abstract;
616915dd 4441 e->info->datatype->mut = mut;
4442 e->info->datatype->type = rtype;
28bf4b0b 4443
4444 DPRINTF (("About to store: %s", sRef_unparseFull (e->sref)));
616915dd 4445 sRef_storeState (e->sref);
28bf4b0b 4446 DPRINTF (("After store: %s", sRef_unparseFull (e->sref)));
616915dd 4447
4448 return (e);
4449}
4450
4451# ifndef NOLCL
4452static void uentry_setHasGlobs (uentry ue)
4453{
4454 llassert (uentry_isFunction (ue));
4455
4456 ue->info->fcn->hasGlobs = TRUE;
4457}
4458
4459static void uentry_setHasMods (uentry ue)
4460{
4461 llassert (uentry_isFunction (ue));
4462
4463 ue->info->fcn->hasMods = TRUE;
4464}
4465# endif
4466
4467bool uentry_hasGlobs (uentry ue)
4468{
4469 if (uentry_isFunction (ue))
4470 {
4471 return (ue->info->fcn->hasGlobs);
4472 }
4473
4474 return FALSE;
4475}
4476
28bf4b0b 4477bool uentry_hasStateClauseList (uentry ue)
616915dd 4478{
28bf4b0b 4479 return (uentry_isFunction (ue) && stateClauseList_isDefined (ue->info->fcn->specclauses));
616915dd 4480}
4481
ccf0a4a8 4482bool uentry_hasConditions (uentry ue)
4483{
4484 return (uentry_isFunction (ue)
4485 && (functionConstraint_isDefined (ue->info->fcn->preconditions)
4486 || functionConstraint_isDefined (ue->info->fcn->postconditions)));
4487}
4488
28bf4b0b 4489stateClauseList uentry_getStateClauseList (uentry ue)
616915dd 4490{
28bf4b0b 4491 if (!uentry_isFunction (ue))
4492 {
4493 llassert (uentry_isFunction (ue));
4494 return stateClauseList_undefined;
4495 }
4496
4497 DPRINTF (("Get state clause list: %s", uentry_unparse (ue)));
616915dd 4498 return ue->info->fcn->specclauses;
4499}
4500
4501bool uentry_hasMods (uentry ue)
4502{
4503 if (uentry_isFunction (ue))
4504 {
4505 return (ue->info->fcn->hasMods);
4506 }
4507
4508 return FALSE;
4509}
4510
4511static uentry
4512 uentry_makeFunctionBase (/*@only@*/ cstring name, ctype ct,
4513 typeIdSet access,
4514 bool hasGlobs, /*@only@*/ globSet globs,
4515 bool hasMods, /*@only@*/ sRefSet mods,
4516 alkind ak, exkind exp,
4517 sstate defstate, nstate isnull,
4518 exitkind exitCode,
4519 specCode sCode,
4520 qual nullPred,
28bf4b0b 4521 /*@only@*/ stateClauseList specclauses,
4522 /*@only@*/ warnClause warnclause,
616915dd 4523 /*@only@*/ fileloc loc)
4524{
4525 uentry e = uentry_alloc ();
4526 ctype ret;
4527
4528 /* e->shallowCopy = FALSE; */
4529 e->ukind = KFCN;
4530 e->uname = name;
4531 e->utype = ct;
4532 e->storageclass = SCNONE;
4533
4534 if (ctype_isFunction (ct))
4535 {
28bf4b0b 4536 ret = ctype_getReturnType (ct);
616915dd 4537 }
4538 else
4539 {
4540 if (ctype_isKnown (ct))
4541 {
4542 llbug (message ("not function: %s", ctype_unparse (ct)));
4543 }
4544
4545 ret = ctype_unknown;
4546 }
4547
4548 e->sref = sRef_makeType (ret);
4549
4550 if (ctype_isUA (ret))
4551 {
4552 sRef_setStateFromType (e->sref, ret);
4553 }
4554
4555 sRef_setDefined (e->sref, loc);
4556 sRef_setNullState (e->sref, isnull, loc);
4557
4558 sRef_setAliasKind (e->sref, ak, loc);
4559 sRef_setExKind (e->sref, exp, loc);
4560 sRef_setDefState (e->sref, defstate, loc);
4561
4562 e->whereSpecified = loc;
4563 e->whereDefined = fileloc_undefined;
4564
4565 e->isPrivate = FALSE;
4566 e->hasNameError = FALSE;
4567
4568 e->used = FALSE;
4569 e->lset = FALSE;
4570 e->uses = filelocList_new ();
28bf4b0b 4571 e->warn = warnclause;
616915dd 4572
4573 e->info = (uinfo) dmalloc (sizeof (*e->info));
4574 e->info->fcn = (ufinfo) dmalloc (sizeof (*e->info->fcn));
4575
4576 e->info->fcn->exitCode = exitCode;
4577 e->info->fcn->specialCode = sCode;
4578 e->info->fcn->nullPred = nullPred;
4579 e->info->fcn->access = access;
4580
4581 e->info->fcn->specclauses = specclauses;
4582 e->info->fcn->hasGlobs = hasGlobs;
4583 e->info->fcn->globs = globs;
4584
4585 e->info->fcn->hasMods = hasMods;
4586 e->info->fcn->mods = mods;
4587
4588 e->info->fcn->defparams = uentryList_undefined;
4589 e->whereDeclared = fileloc_undefined;
4590
4591 sRef_storeState (e->sref);
4592
4593 /*drl 111 30 2000*/
4594 e->info->fcn->preconditions = NULL;
4595 /* end drl */
4596
4597 /*drl 12 28 2000*/
4598 e->info->fcn->postconditions = NULL;
4599 /* end drl */
4600
4601 return (e);
4602}
4603
4604static /*@only@*/ uentry
4605 uentry_makeTagBase (/*@only@*/ cstring name, ekind tagkind,
4606 ctype ct, ctype rtype, /*@only@*/ fileloc loc)
4607{
4608 uentry e = uentry_alloc ();
4609
4610 if (tagkind != KSTRUCTTAG && tagkind != KUNIONTAG && tagkind != KENUMTAG)
4611 {
4612 llbuglit ("uentry_makeTagBase: not a tag type");
4613 }
4614
4615 /* e->shallowCopy = FALSE; */
4616 e->ukind = tagkind;
4617 e->uname = name;
4618 e->utype = ct;
4619 e->sref = sRef_makeUnknown ();
4620 e->storageclass = SCNONE;
4621
4622 if (fileloc_isSpec (loc))
4623 {
4624 e->whereSpecified = loc;
4625 e->whereDeclared = fileloc_undefined;
4626 }
4627 else
4628 {
4629 e->whereDeclared = loc;
4630 e->whereSpecified = fileloc_undefined;
4631 }
4632
4633 e->whereDefined = fileloc_undefined;
4634
4635 e->isPrivate = FALSE;
4636 e->hasNameError = FALSE;
4637
4638 e->used = FALSE;
4639 e->lset = FALSE;
4640 e->uses = filelocList_new ();
28bf4b0b 4641 e->warn = warnClause_undefined; /*@i452@*/
616915dd 4642
4643 e->info = (uinfo) dmalloc (sizeof (*e->info));
4644 e->info->datatype = (udinfo) dmalloc (sizeof (*e->info->datatype));
4645 e->info->datatype->abs = NO;
4646 e->info->datatype->mut = MAYBE;
4647 e->info->datatype->type = rtype;
4648
4649 sRef_storeState (e->sref);
4650
4651 return (e);
4652}
4653
4654static uentry
4655 uentry_makeIterBase (/*@only@*/ cstring name, typeIdSet access,
4656 ctype ct, /*@only@*/ fileloc loc)
4657{
4658 uentry e = uentry_alloc ();
4659
4660 /* e->shallowCopy = FALSE; */
4661 e->ukind = KITER;
4662 e->uname = name;
4663 e->utype = ct;
4664 e->sref = sRef_makeUnknown ();
4665 e->storageclass = SCNONE;
4666
4667 if (fileloc_isSpec (loc))
4668 {
4669 e->whereSpecified = loc;
4670 e->whereDeclared = fileloc_undefined;
4671 }
4672 else
4673 {
4674 e->whereDeclared = loc;
4675 e->whereSpecified = fileloc_undefined;
4676 }
4677
4678 e->whereDefined = fileloc_undefined;
4679
4680 e->isPrivate = FALSE;
4681 e->hasNameError = FALSE;
4682
4683 e->used = FALSE;
4684 e->lset = FALSE;
4685 e->uses = filelocList_new ();
28bf4b0b 4686 e->warn = warnClause_undefined; /*@i452@*/
616915dd 4687
4688 e->info = (uinfo) dmalloc (sizeof (*e->info));
4689 e->info->iter = (uiinfo) dmalloc (sizeof (*e->info->iter));
4690 e->info->iter->access = access;
4691 e->info->iter->mods = sRefSet_undefined;
4692 e->info->iter->globs = globSet_undefined;
4693
4694 sRef_storeState (e->sref);
4695 return (e);
4696}
4697
4698static uentry
4699 uentry_makeEndIterBase (/*@only@*/ cstring name, typeIdSet access,
4700 /*@only@*/ fileloc loc)
4701{
4702 uentry e = uentry_alloc ();
4703
4704 /* e->shallowCopy = FALSE; */
4705 e->ukind = KENDITER;
4706 e->storageclass = SCNONE;
4707 e->uname = name;
4708 e->utype = ctype_unknown;
4709 e->sref = sRef_makeUnknown ();
4710
4711 if (fileloc_isSpec (loc))
4712 {
4713 e->whereSpecified = loc;
4714 e->whereDeclared = fileloc_undefined;
4715 }
4716 else
4717 {
4718 e->whereDeclared = loc;
4719 e->whereSpecified = fileloc_undefined;
4720 }
4721
4722 e->whereDefined = fileloc_undefined;
4723
4724 e->isPrivate = FALSE;
4725 e->hasNameError = FALSE;
4726
4727 e->used = FALSE;
4728 e->lset = FALSE;
4729 e->uses = filelocList_new ();
28bf4b0b 4730 e->warn = warnClause_undefined; /*@i452@*/
616915dd 4731
4732 e->info = (uinfo) dmalloc (sizeof (*e->info));
4733 e->info->enditer = (ueinfo) dmalloc (sizeof (*e->info->enditer));
4734 e->info->enditer->access = access;
4735 sRef_storeState (e->sref);
4736
4737 return (e);
4738}
4739
4740void uentry_markFree (/*@unused@*/ /*@owned@*/ uentry u)
4741{
4742 /* should save u */
4743/*@-mustfree@*/
4744}
4745/*@=mustfree@*/
4746
4747/*@only@*/ uentry
4748uentry_undump (ekind kind, fileloc loc, char **s)
4749{
4750 uentry ue;
4751
28bf4b0b 4752 DPRINTF (("Uentry undump: %s", *s));
4753
616915dd 4754 if (**s == '!')
4755 {
28bf4b0b 4756 reader_checkChar (s, '!');
4757 reader_checkChar (s, '.');
616915dd 4758 ue = uentry_makeElipsisMarker ();
4759 }
4760 else
4761 {
4762 ctype ct = ctype_undump (s);
4763 cstring name;
4764
4765 switch (kind)
4766 {
4767 case KVAR:
4768 {
4769 vkind tkind;
4770 sstate defstate;
4771 nstate isnull;
4772 alkind aliased;
4773 exkind exp;
4774 chkind checked;
4775
28bf4b0b 4776 reader_checkChar (s, '|');
616915dd 4777
28bf4b0b 4778 if (reader_optCheckChar (s, '@'))
616915dd 4779 {
28bf4b0b 4780 tkind = vkind_fromInt (reader_getInt (s));
4781 reader_checkChar (s, '|');
616915dd 4782 }
4783 else
4784 {
4785 tkind = VKPARAM;
4786 }
4787
28bf4b0b 4788 if (reader_optCheckChar (s, '$'))
616915dd 4789 {
4790 defstate = SS_UNKNOWN;
4791 isnull = NS_UNKNOWN;
4792 aliased = AK_IMPTEMP;
4793 exp = XO_UNKNOWN;
4794 checked = CH_UNKNOWN;
4795 }
28bf4b0b 4796 else if (reader_optCheckChar (s, '&'))
616915dd 4797 {
4798 defstate = SS_DEFINED;
4799 isnull = NS_UNKNOWN;
4800 aliased = AK_IMPTEMP;
4801 exp = XO_UNKNOWN;
4802 checked = CH_UNKNOWN;
4803 }
28bf4b0b 4804 else if (reader_optCheckChar (s, '^'))
616915dd 4805 {
4806 defstate = SS_UNKNOWN;
4807 isnull = NS_UNKNOWN;
4808 aliased = AK_IMPTEMP;
4809 exp = XO_UNKNOWN;
4810 checked = CH_UNKNOWN;
4811 }
4812 else
4813 {
28bf4b0b 4814 defstate = sstate_fromInt (reader_getInt (s));
4815 advanceField (s); isnull = nstate_fromInt (reader_getInt (s));
4816 advanceField (s); aliased = alkind_fromInt (reader_getInt (s));
616915dd 4817
28bf4b0b 4818 if (reader_optCheckChar (s, '&'))
616915dd 4819 {
4820 exp = XO_UNKNOWN;
4821 checked = CH_UNKNOWN;
4822 }
4823 else
4824 {
28bf4b0b 4825 advanceField (s); exp = exkind_fromInt (reader_getInt (s));
4826 advanceField (s); checked = (chkind) (reader_getInt (s));
616915dd 4827 }
4828 }
4829
4830 advanceName (s);
28bf4b0b 4831 name = reader_getStringWord (s);
616915dd 4832
28bf4b0b 4833 llassert (!cstring_equal (name, GLOBAL_MARKER_NAME));
4834
616915dd 4835 ue = uentry_makeVariableBase (name, ct, tkind, defstate,
4836 isnull, aliased, exp,
4837 checked, fileloc_copy (loc));
4838 }
4839 break;
4840 case KDATATYPE:
4841 {
28bf4b0b 4842 ynm abstract;
616915dd 4843 ynm mut;
4844 ctype rtype;
4845 sstate defstate;
4846 nstate isnull;
4847 alkind aliased;
4848 exkind exp;
4849
28bf4b0b 4850 advanceField (s); abstract = ynm_fromCodeChar (reader_loadChar (s));
4851 advanceField (s); mut = ynm_fromCodeChar (reader_loadChar (s));
4852 advanceField (s); defstate = sstate_fromInt (reader_getInt (s));
4853 advanceField (s); isnull = nstate_fromInt (reader_getInt (s));
4854 advanceField (s); aliased = alkind_fromInt (reader_getInt (s));
4855 advanceField (s); exp = exkind_fromInt (reader_getInt (s));
616915dd 4856 advanceField (s); rtype = ctype_undump (s);
4857 advanceName (s);
28bf4b0b 4858 name = reader_getStringWord (s);
4859 DPRINTF (("Datatype %s, Exp = %s", name, exkind_unparse (exp)));
4860 ue = uentry_makeDatatypeBase (name, ct, abstract, mut, rtype,
616915dd 4861 aliased, exp, defstate, isnull,
4862 fileloc_copy (loc));
4863 }
4864 break;
4865 case KFCN:
4866 {
4867 alkind ak;
4868 exkind exp;
4869 sstate defstate;
4870 nstate isnull;
4871 exitkind exitCode;
4872 specCode specc;
4873 qual nullPred;
4874 typeIdSet access;
4875 bool hasGlobs;
4876 globSet globs;
4877 bool hasMods;
4878 sRefSet mods;
28bf4b0b 4879 stateClauseList specclauses = stateClauseList_undefined;
4880 warnClause warnclause = warnClause_undefined;
616915dd 4881
28bf4b0b 4882 if (reader_optCheckChar (s, '$'))
616915dd 4883 {
4884 defstate = SS_DEFINED;
4885 isnull = NS_UNKNOWN;
4886 exitCode = XK_UNKNOWN;
4887 specc = SPC_NONE;
28bf4b0b 4888 nullPred = qual_createUnknown ();
616915dd 4889 }
4890 else
4891 {
28bf4b0b 4892 advanceField (s); defstate = sstate_fromInt (reader_getInt (s));
4893 advanceField (s); isnull = nstate_fromInt (reader_getInt (s));
4894 advanceField (s); exitCode = exitkind_fromInt (reader_getInt (s));
4895 advanceField (s); specc = specCode_fromInt (reader_getInt (s));
4896 advanceField (s); nullPred = qual_undump (s);
616915dd 4897 }
4898
28bf4b0b 4899 if (reader_optCheckChar (s, '$'))
616915dd 4900 {
4901 hasGlobs = FALSE;
4902 globs = globSet_undefined;
4903 hasMods = FALSE;
4904 mods = sRefSet_undefined;
4905 }
28bf4b0b 4906 else if (reader_optCheckChar (s, '^'))
616915dd 4907 {
4908 hasGlobs = TRUE;
4909 globs = globSet_undefined;
4910 hasMods = TRUE;
4911 mods = sRefSet_undefined;
4912 }
4913 else
4914 {
28bf4b0b 4915 advanceField (s); hasGlobs = bool_fromInt (reader_getInt (s));
616915dd 4916 advanceField (s); globs = globSet_undump (s);
28bf4b0b 4917 advanceField (s); hasMods = bool_fromInt (reader_getInt (s));
616915dd 4918 advanceField (s); mods = sRefSet_undump (s);
4919 }
4920
28bf4b0b 4921 if (reader_optCheckChar (s, '$'))
616915dd 4922 {
4923 ak = AK_UNKNOWN;
4924 exp = XO_UNKNOWN;
4925 }
4926 else
4927 {
28bf4b0b 4928 advanceField (s); ak = alkind_fromInt (reader_getInt (s));
4929 advanceField (s); exp = exkind_fromInt (reader_getInt (s));
616915dd 4930 }
4931
4932 advanceField (s); access = typeIdSet_undump (s);
4933
28bf4b0b 4934 /*
4935 ** Optional clauses: Start with @<code>:
4936 */
4937
4938 while (reader_optCheckChar (s, '@'))
616915dd 4939 {
28bf4b0b 4940 if (reader_optCheckChar (s, 'W')) /* Warn clause */
4941 {
4942 reader_checkChar (s, ':');
4943 warnclause = warnClause_undump (s);
4944 }
4945 else if (reader_optCheckChar (s, 'S')) /* stateClause List */
4946 {
4947 reader_checkChar (s, ':');
4948 specclauses = stateClauseList_undump (s);
4949 }
4950 else
4951 {
4952 BADBRANCH;
4953 }
616915dd 4954 }
4955
28bf4b0b 4956 advanceName (s); name = reader_getStringWord (s);
616915dd 4957
4958 ue = uentry_makeFunctionBase (name, ct, access,
4959 hasGlobs, globs,
4960 hasMods, mods,
4961 ak, exp, defstate, isnull,
4962 exitCode, specc, nullPred,
4963 specclauses,
28bf4b0b 4964 warnclause,
616915dd 4965 fileloc_copy (loc));
4966 DPRINTF (("Undump: %s", uentry_unparse (ue)));
4967 }
4968 break;
4969 case KITER:
4970 {
4971 typeIdSet access;
4972
4973 advanceField (s); access = typeIdSet_undump (s);
28bf4b0b 4974 advanceName (s); name = reader_getStringWord (s);
616915dd 4975
4976 ue = uentry_makeIterBase (name, access, ct,
4977 fileloc_copy (loc));
4978 }
4979 break;
4980 case KENDITER:
4981 {
4982 typeIdSet access;
4983
4984 advanceField (s); access = typeIdSet_undump (s);
28bf4b0b 4985 advanceName (s); name = reader_getStringWord (s);
616915dd 4986
4987 ue = uentry_makeEndIterBase (name, access, fileloc_copy (loc));
4988 }
4989 break;
4990 case KENUMCONST:
4991 case KCONST:
4992 {
4993 typeIdSet access;
4994 multiVal val;
4995 nstate nullstate;
4996
28bf4b0b 4997 if (reader_optCheckChar (s, '$'))
616915dd 4998 {
4999 val = multiVal_undefined;
5000 access = typeIdSet_undefined;
5001 nullstate = NS_UNKNOWN;
5002 }
5003 else
5004 {
5005 advanceField (s); val = multiVal_undump (s);
5006 advanceField (s); access = typeIdSet_undump (s);
28bf4b0b 5007 advanceField (s); nullstate = nstate_fromInt (reader_getInt (s));
616915dd 5008 }
5009
28bf4b0b 5010 advanceName (s); name = reader_getStringWord (s);
616915dd 5011
5012 ue = uentry_makeConstantBase (name, ct, access,
5013 nullstate, fileloc_copy (loc), val);
5014 break;
5015 }
5016 case KSTRUCTTAG:
5017 case KUNIONTAG:
5018 case KENUMTAG:
5019 {
5020 ctype rtype;
5021
5022 advanceField (s); rtype = ctype_undump (s);
28bf4b0b 5023 advanceName (s); name = reader_getStringWord (s);
616915dd 5024 ue = uentry_makeTagBase (name, kind, ct, rtype, fileloc_copy (loc));
5025 }
5026 break;
5027 case KINVALID:
5028 llcontbuglit ("uentry_undump: invalid");
5029 ue = uentry_undefined;
5030 break;
5031 case KELIPSMARKER:
5032 llcontbuglit ("uentry_undump: elips marker");
5033 ue = uentry_undefined;
5034 break;
5035 }
5036 }
5037
5038 return (ue);
5039}
5040
5041cstring
5042uentry_dump (uentry v)
5043{
5044 return (uentry_dumpAux (v, FALSE));
5045}
5046
5047cstring
5048uentry_dumpParam (uentry v)
5049{
5050 llassertprint (uentry_isVariable (v) || uentry_isElipsisMarker (v),
5051 ("dump: %s", uentry_unparseFull (v)));
5052
5053 return (uentry_dumpAux (v, TRUE));
5054}
5055
5056static cstring
5057uentry_dumpAux (uentry v, bool isParam)
5058{
5059 llassert (uentry_isValid (v));
28bf4b0b 5060 llassert (!uentry_isGlobalMarker (v));
616915dd 5061
28bf4b0b 5062 DPRINTF (("Dump uentry: [%p]", v));
616915dd 5063 DPRINTF (("Dumping entry: %s", uentry_unparseFull (v)));
28bf4b0b 5064
616915dd 5065 switch (v->ukind)
5066 {
5067 case KINVALID:
5068 llcontbuglit ("uentry_dump: invalid entry");
5069 return cstring_undefined;
5070 case KELIPSMARKER:
5071 return (message ("!."));
5072 case KVAR:
5073 {
5074 cstring sdump;
5075 vkind vk = v->info->var->kind;
5076 sstate dss = sRef_getDefState (v->sref);
5077 nstate nst = sRef_getNullState (v->sref);
5078 alkind alk = sRef_getAliasKind (v->sref);
5079 exkind exk = sRef_getExKind (v->sref);
5080 chkind chk = v->info->var->checked;
5081
5082 DPRINTF (("Dumping var"));
5083
5084 if (dss == SS_UNKNOWN
5085 && nst == NS_UNKNOWN
5086 && alk == AK_IMPTEMP
5087 && exk == XO_UNKNOWN
5088 && chk == CH_UNKNOWN)
5089 {
5090 sdump = cstring_makeLiteral ("$");
5091 }
5092 else if (dss == SS_DEFINED
5093 && nst == NS_UNKNOWN
5094 && alk == AK_IMPTEMP
5095 && exk == XO_UNKNOWN
5096 && chk == CH_UNKNOWN)
5097 {
5098 sdump = cstring_makeLiteral ("&");
5099 }
5100 else if (dss == SS_UNKNOWN
5101 && nst == NS_UNKNOWN
5102 && alk == AK_UNKNOWN
5103 && exk == XO_UNKNOWN
5104 && chk == CH_UNKNOWN)
5105 {
5106 sdump = cstring_makeLiteral ("^");
5107 }
5108 else if (exk == XO_UNKNOWN
5109 && chk == CH_UNKNOWN)
5110 {
5111 sdump = message ("%d@%d@%d&",
5112 (int) dss,
5113 (int) nst,
5114 (int) alk);
5115 }
5116 else
5117 {
5118 sdump = message ("%d@%d@%d@%d@%d",
5119 (int) dss,
5120 (int) nst,
5121 (int) alk,
5122 (int) exk,
5123 (int) chk);
5124 }
5125
5126
5127 if (vk != VKPARAM)
5128 {
5129 return (message ("%q|@%d|%q#%s",
5130 ctype_dump (v->utype),
5131 (int) vk,
5132 sdump,
5133 isParam ? cstring_undefined : v->uname));
5134 }
5135 else
5136 {
5137 return (message ("%q|%q#%s",
5138 ctype_dump (v->utype),
5139 sdump,
5140 isParam ? cstring_undefined : v->uname));
5141 }
5142
5143 }
5144 case KDATATYPE:
28bf4b0b 5145 /*
5146 DPRINTF (("Dumping datatype: %s -> %s type: %s [%d]",
5147 uentry_unparse (v),
5148 exkind_unparse (sRef_getExKind (v->sref)),
5149 ctype_unparse (v->utype), (int) v->utype));
5150 */
5151
616915dd 5152 return (message ("%q@%s@%s@%d@%d@%d@%d@%q#%s",
5153 ctype_dump (v->utype),
5154 ynm_unparseCode (v->info->datatype->abs),
5155 ynm_unparseCode (v->info->datatype->mut),
5156 (int) sRef_getDefState (v->sref),
5157 (int) sRef_getNullState (v->sref),
5158 (int) sRef_getAliasKind (v->sref),
5159 (int) sRef_getExKind (v->sref),
5160 ctype_dump (v->info->datatype->type),
5161 v->uname));
5162 case KFCN:
5163 {
28bf4b0b 5164 cstring sdump, gdump, adump, xdump;
616915dd 5165 alkind alk = sRef_getAliasKind (v->sref);
5166 exkind exk = sRef_getExKind (v->sref);
5167
5168 if (sRef_getDefState (v->sref) == SS_DEFINED
5169 && !nstate_isKnown (sRef_getNullState (v->sref))
5170 && !exitkind_isKnown (v->info->fcn->exitCode)
5171 && v->info->fcn->specialCode == SPC_NONE
28bf4b0b 5172 && qual_isUnknown (v->info->fcn->nullPred))
616915dd 5173 {
5174 sdump = cstring_makeLiteral ("$");
5175 }
5176 else
5177 {
28bf4b0b 5178 sdump = message ("@%d@%d@%d@%d@%x",
616915dd 5179 (int) sRef_getDefState (v->sref),
5180 (int) sRef_getNullState (v->sref),
5181 (int) v->info->fcn->exitCode,
5182 (int) v->info->fcn->specialCode,
28bf4b0b 5183 qual_dump (v->info->fcn->nullPred));
616915dd 5184 }
5185
5186 if (!uentry_hasGlobs(v) && !uentry_hasMods (v))
5187 {
5188 gdump = cstring_makeLiteral ("$");
5189 }
5190 else if (uentry_hasGlobs (v) && globSet_isEmpty (uentry_getGlobs (v))
5191 && uentry_hasMods (v) && sRefSet_isEmpty (uentry_getMods (v)))
5192 {
5193 gdump = cstring_makeLiteral ("^");
5194 }
5195 else
5196 {
5197 gdump = message ("@%s@%q@%s@%q",
5198 bool_dump (uentry_hasGlobs (v)),
5199 globSet_dump (uentry_getGlobs (v)),
5200 bool_dump (uentry_hasMods (v)),
5201 sRefSet_dump (uentry_getMods (v)));
5202 }
5203
5204 if (alk == AK_UNKNOWN && exk == XO_UNKNOWN)
5205 {
5206 adump = cstring_makeLiteral ("$");
5207 }
5208 else
5209 {
5210 adump = message ("@%d@%d", (int) alk, (int) exk);
5211 }
5212
28bf4b0b 5213 xdump = cstring_undefined;
5214
5215 if (uentry_hasWarning (v))
616915dd 5216 {
28bf4b0b 5217 xdump = message ("%q@W:%q", xdump, warnClause_dump (v->warn));
616915dd 5218 }
28bf4b0b 5219
5220 if (uentry_hasStateClauseList (v))
616915dd 5221 {
28bf4b0b 5222 xdump = message ("%q@S:%q", xdump, stateClauseList_dump (v->info->fcn->specclauses));
616915dd 5223 }
28bf4b0b 5224
5225 return (message ("%q%q%q%q@%q%q#%s",
5226 ctype_dump (v->utype),
5227 sdump,
5228 gdump,
5229 adump,
5230 typeIdSet_dump (uentry_accessType (v)),
5231 xdump,
5232 v->uname));
616915dd 5233 }
5234 case KITER:
5235 return (message ("%q@%q#%s",
5236 ctype_dump (v->utype),
5237 typeIdSet_dump (v->info->iter->access),
5238 v->uname));
5239 case KENDITER:
5240 return (message ("%q@%q#%s",
5241 ctype_dump (v->utype),
5242 typeIdSet_dump (uentry_accessType (v)),
5243 v->uname));
5244 case KENUMCONST:
5245 case KCONST:
5246 {
5247 cstring sdump;
5248
b9904f57 5249 if (multiVal_isUnknown (uentry_getConstantValue (v))
616915dd 5250 && typeIdSet_isEmpty (uentry_accessType (v))
5251 && (sRef_getNullState (v->sref) == NS_UNKNOWN))
5252 {
5253 sdump = cstring_makeLiteral ("$");
5254 }
5255 else
5256 {
5257 sdump = message ("@%q@%q@%d",
b9904f57 5258 multiVal_dump (uentry_getConstantValue (v)),
616915dd 5259 typeIdSet_dump (uentry_accessType (v)),
5260 (int) sRef_getNullState (v->sref));
5261 }
5262
5263 return (message ("%q%q#%s",
5264 ctype_dump (v->utype),
5265 sdump,
5266 v->uname));
5267 }
5268 case KSTRUCTTAG:
5269 case KUNIONTAG:
5270 case KENUMTAG:
5271 return (message ("%q@%q#%s",
5272 ctype_dump (v->utype),
5273 ctype_dump (v->info->datatype->type), v->uname));
5274 }
5275
5276 BADEXIT;
5277}
5278
5279/*@only@*/ cstring
5280uentry_unparseAbbrev (uentry v)
5281{
5282 if (!uentry_isVariable (v))
5283 {
5284 llcontbuglit ("uentry_unparseAbbrev: not variable");
5285 return uentry_unparse (v);
5286 }
5287
5288 return (message ("%s %q", ctype_unparseDeep (v->utype), uentry_getName (v)));
5289}
5290
5291/*@only@*/ cstring
5292uentry_unparse (uentry v)
5293{
5294 cstring st;
5295
5296 if (uentry_isUndefined (v)) return (cstring_makeLiteral ("<undefined>"));
5297 if (uentry_isElipsisMarker (v)) return (cstring_makeLiteral ("..."));
5298
5299 st = uentry_getName (v);
5300
5301 if (cstring_isDefined (st))
5302 {
5303 return (ctype_unparseDeclaration (v->utype, st));
5304 }
5305 else
5306 {
5307 cstring_free (st);
5308 return (cstring_copy (ctype_unparse (v->utype)));
5309 }
5310}
5311
5312/*@only@*/ cstring
5313uentry_unparseFull (uentry v)
5314{
5315 if (uentry_isUndefined (v))
5316 {
5317 return (cstring_makeLiteral ("<undefined>"));
5318 }
616915dd 5319 else
5320 {
28bf4b0b 5321 cstring res;
5322
5323 res = message ("[%w] %s %s: %s [spec: %q; decl: %q; def: %q]",
5324 (unsigned long) v, ekind_unparse (v->ukind), v->uname,
5325 ctype_unparse (v->utype),
5326 fileloc_unparse (uentry_whereSpecified (v)),
5327 fileloc_unparse (uentry_whereDeclared (v)),
5328 fileloc_unparse (uentry_whereDefined (v)));
5329
5330 DPRINTF (("uentry: %s", res));
5331
5332 if (uentry_isDatatype (v))
5333 {
5334 res = message ("%q / type: %s mut: %s abs: %s state: %q",
5335 res,
5336 ctype_unparse
5337 (ctype_isDefined (v->info->datatype->type)
5338 ? v->info->datatype->type : ctype_unknown),
5339 ynm_unparse (v->info->datatype->mut),
5340 ynm_unparse (v->info->datatype->abs),
5341 sRef_unparseState (v->sref));
5342 }
5343 else if (uentry_isFunction (v))
5344 {
5345 res = message ("%q / sref: %q / mods: %q / "
ba45e1e4 5346 "globs: %q / clauses: %q / pre: %q / post: %q",
28bf4b0b 5347 res,
5348 sRef_unparseFull (v->sref),
5349 sRefSet_unparse (v->info->fcn->mods),
5350 globSet_unparse (v->info->fcn->globs),
ba45e1e4 5351 stateClauseList_unparse (v->info->fcn->specclauses),
5352 functionConstraint_unparse (v->info->fcn->preconditions),
5353 functionConstraint_unparse (v->info->fcn->postconditions));
28bf4b0b 5354 }
5355 else if (uentry_isIter (v))
5356 {
5357 res = message ("%q / sref: %q",
5358 res,
5359 sRef_unparseFull (v->sref));
5360 }
5361 else if (uentry_isVariable (v))
5362 {
5363 res = message ("%q / sref: %q / kind <%d> isout <%d> null <%d> used <%d>",
5364 res,
5365 sRef_unparseFull (v->sref),
5366 (int) v->info->var->kind,
5367 (int) v->info->var->defstate,
5368 (int) v->info->var->nullstate,
5369 (int) v->used);
5370 DPRINTF (("sref: [%p]", v->sref));
5371 DPRINTF (("sref: %s", sRef_unparseDebug (v->sref)));
5372 /* DPRINTF (("sref: %s", sRef_unparseDeep (v->sref))); */
5373 }
b9904f57 5374 else if (uentry_isConstant (v))
5375 {
5376 res = message ("%q = %q",
5377 res, multiVal_unparse (uentry_getConstantValue (v)));
5378 }
28bf4b0b 5379 else
5380 {
5381 res = message ("%q :: %q", res, uentry_unparse (v));
5382 }
5383
5384 return res;
616915dd 5385 }
5386}
5387
5388bool uentry_hasAccessType (uentry e)
5389{
5390 if (uentry_isValid (e))
5391 {
5392 switch (e->ukind)
5393 {
5394 case KITER:
5395 return (!typeIdSet_isEmpty (e->info->iter->access));
5396 case KENDITER:
5397 return (!typeIdSet_isEmpty (e->info->enditer->access));
5398 case KFCN:
5399 return (!typeIdSet_isEmpty (e->info->fcn->access));
5400 case KENUMCONST:
5401 case KCONST:
5402 return (!typeIdSet_isEmpty (e->info->uconst->access));
5403 default:
5404 return FALSE;
5405 }
5406 }
5407
5408 return FALSE;
5409}
5410
5411typeIdSet uentry_accessType (uentry e)
5412{
5413 if (uentry_isValid (e))
5414 {
5415 switch (e->ukind)
5416 {
5417 case KITER:
5418 return (e->info->iter->access);
5419 case KENDITER:
5420 return (e->info->enditer->access);
5421 case KFCN:
5422 return (e->info->fcn->access);
5423 case KENUMCONST:
5424 case KCONST:
5425 return (e->info->uconst->access);
5426 default:
5427 break;
5428 }
5429 }
5430
5431 return typeIdSet_undefined;
5432}
5433
5434bool
5435uentry_isVariable (uentry e)
5436{
5437 return (uentry_isVar (e));
5438}
5439
5440bool
5441uentry_isSpecified (uentry e)
5442{
5443 return (uentry_isValid (e) && !fileloc_isUndefined (e->whereSpecified));
5444}
5445
5446static bool
5447uentry_isReallySpecified (uentry e)
5448{
5449 return (uentry_isValid (e)
5450 && fileloc_isRealSpec (e->whereSpecified));
5451}
5452
5453bool
5454uentry_isVar (uentry e)
5455{
5456 return (!uentry_isUndefined (e) && e->ukind == KVAR);
5457}
5458
5459bool
5460uentry_isFakeTag (uentry e)
5461{
5462 return (uentry_isValid (e) && strchr (cstring_toCharsSafe (e->uname), '!') != 0);
5463}
5464
5465bool
5466uentry_isDatatype (uentry e)
5467{
5468 return (!uentry_isUndefined (e) &&
5469 (e->ukind == KDATATYPE || e->ukind == KSTRUCTTAG ||
5470 e->ukind == KUNIONTAG || e->ukind == KENUMTAG));
5471}
5472
5473void
5474uentry_setAbstract (uentry e)
5475{
5476 typeId oldid;
5477
5478 llassert (uentry_isDatatype (e)
5479 && (ynm_isMaybe (e->info->datatype->abs)));
5480
5481 oldid = ctype_typeId (e->info->datatype->type);
5482 e->info->datatype->abs = YES;
5483 e->info->datatype->type = ctype_createAbstract (oldid);
5484}
5485
5486void
5487uentry_setConcrete (uentry e)
5488{
5489 llassert (uentry_isDatatype (e)
5490 && (ynm_isMaybe (e->info->datatype->abs)));
5491
5492 e->info->datatype->abs = NO;
5493}
5494
5495bool
5496uentry_isAbstractDatatype (uentry e)
5497{
5498 return (uentry_isDatatype (e)
5499 && (ynm_isOn (e->info->datatype->abs)));
5500}
5501
5502bool
5503uentry_isMaybeAbstract (uentry e)
5504{
5505 return (uentry_isDatatype (e)
5506 && (ynm_isMaybe (e->info->datatype->abs)));
5507}
5508
5509bool
5510uentry_isMutableDatatype (uentry e)
5511{
5512 bool res = uentry_isDatatype (e)
5513 && (ynm_toBoolRelaxed (e->info->datatype->mut));
5514
5515 return res;
5516}
5517
5518bool
5519uentry_isRefCountedDatatype (uentry e)
5520{
5521 return (uentry_isDatatype (e) && (sRef_isRefCounted (uentry_getSref (e))));
5522}
5523
5524bool
5525uentry_isParam (uentry u)
5526{
5527 return (uentry_isVariable (u) && (u->info->var->kind == VKPARAM
5528 || u->info->var->kind == VKYIELDPARAM));
5529}
5530
5531bool
5532uentry_isExpandedMacro (uentry u)
5533{
5534 return (uentry_isVariable (u) && (u->info->var->kind == VKEXPMACRO));
5535}
5536
5537bool
5538uentry_isSefParam (uentry u)
5539{
5540 return (uentry_isVariable (u)
5541 && (u->info->var->kind == VKSEFPARAM
5542 || u->info->var->kind == VKREFSEFPARAM
5543 || u->info->var->kind == VKSEFRETPARAM
5544 || u->info->var->kind == VKREFSEFRETPARAM));
5545}
5546
5547bool
5548uentry_isRefParam (uentry u)
5549{
5550 return (uentry_isVariable (u)
5551 && (u->info->var->kind == VKREFPARAM
5552 || u->info->var->kind == VKREFYIELDPARAM
5553 || u->info->var->kind == VKREFSEFPARAM
5554 || u->info->var->kind == VKREFSEFRETPARAM));
5555}
5556
5557bool
5558uentry_isAnyParam (uentry u)
5559{
5560 return (uentry_isVariable (u)
5561 && ((u->info->var->kind == VKPARAM)
5562 || (u->info->var->kind == VKSEFPARAM)
5563 || (u->info->var->kind == VKYIELDPARAM)
5564 || (u->info->var->kind == VKRETPARAM)
5565 || (u->info->var->kind == VKSEFRETPARAM)));
5566}
5567
5568sstate
5569uentry_getDefState (uentry u)
5570{
5571 if (uentry_isValid (u))
5572 {
5573 return (sRef_getDefState (u->sref));
5574 }
5575 else
5576 {
5577 return (SS_UNKNOWN);
5578 }
5579}
5580
5581bool
5582uentry_isOut (uentry u)
5583{
5584 return ((uentry_isVariable (u) && (u->info->var->defstate == SS_ALLOCATED))
5585 || (uentry_isDatatype (u) && (sRef_isAllocated (u->sref))));
5586}
5587
5588bool
5589uentry_isPartial (uentry u)
5590{
5591 return ((uentry_isVariable (u) && (u->info->var->defstate == SS_PARTIAL))
5592 || (uentry_isDatatype (u) && (sRef_isAllocated (u->sref))));
5593}
5594
5595bool
5596uentry_isStateSpecial (uentry u)
5597{
5598 return ((uentry_isVariable (u)
5599 && (u->info->var->defstate == SS_SPECIAL))
5600 || (uentry_isValid (u) && sRef_isStateSpecial (u->sref)));
5601}
5602
5603exitkind uentry_getExitCode (uentry ue)
5604{
5605 if (uentry_isFunction (ue))
5606 {
5607 return ue->info->fcn->exitCode;
5608 }
5609 else
5610 {
5611 return XK_UNKNOWN;
5612 }
5613}
5614
28bf4b0b 5615qual uentry_nullPred (uentry u)
616915dd 5616{
5617 llassert (uentry_isRealFunction (u));
5618
5619 if (uentry_isFunction (u))
5620 {
5621 return (u->info->fcn->nullPred);
5622 }
5623 else
5624 {
28bf4b0b 5625 return qual_createUnknown ();
616915dd 5626 }
5627}
5628
28bf4b0b 5629/*
5630** Note for variables, this is checking the declared state, not the current state.
5631*/
5632
616915dd 5633bool
5634uentry_possiblyNull (uentry u)
5635{
5636 return ((uentry_isVariable (u) && (nstate_possiblyNull (u->info->var->nullstate)))
5637 || (uentry_isDatatype (u) && (sRef_possiblyNull (u->sref))));
5638}
5639
5640alkind
5641uentry_getAliasKind (uentry u)
5642{
5643 if (uentry_isValid (u))
5644 {
5645 return (sRef_getAliasKind (uentry_getSref (u)));
5646 }
5647 else
5648 {
5649 return AK_UNKNOWN;
5650 }
5651}
5652
5653exkind
5654uentry_getExpKind (uentry u)
5655{
5656 if (uentry_isValid (u))
5657 {
5658 return (sRef_getExKind (uentry_getSref (u)));
5659 }
5660 else
5661 {
5662 return XO_UNKNOWN;
5663 }
5664}
5665
5666bool
5667uentry_isIter (uentry e)
5668{
5669 return (!uentry_isUndefined (e) && e->ukind == KITER);
5670}
5671
5672bool
5673uentry_isEndIter (uentry e)
5674{
5675 return (!uentry_isUndefined (e) && e->ukind == KENDITER);
5676}
5677
5678bool
5679uentry_isRealFunction (uentry e)
5680{
5681 return (uentry_isFunction (e) ||
5682 (uentry_isVariable (e) && ctype_isFunction (uentry_getType (e))));
5683}
5684
5685bool
5686uentry_hasName (uentry e)
5687{
5688 if (uentry_isValid (e))
5689 {
5690 cstring s = e->uname;
5691
28bf4b0b 5692 return (!(cstring_isEmpty (s) || cstring_equalLit (s, "...")
5693 || uentry_isFakeTag (e)));
616915dd 5694 }
5695 else
5696 {
5697 return FALSE;
5698 }
5699}
5700
28bf4b0b 5701/*
5702** Returns true for fake tags.
5703** This is used for dumping the library
5704*/
5705
616915dd 5706bool uentry_hasRealName (uentry e)
5707{
28bf4b0b 5708 return (uentry_isValid (e)
5709 && cstring_isNonEmpty (e->uname)
5710 && !uentry_isGlobalMarker (e));
616915dd 5711}
5712
5713
5714/*@observer@*/ globSet
5715uentry_getGlobs (uentry l)
5716{
5717 if (uentry_isInvalid (l))
5718 {
5719 return globSet_undefined;
5720 }
5721
5722 if (l->ukind != KFCN)
5723 {
5724 if (l->ukind != KITER && l->ukind != KENDITER)
5725 {
5726 if (l->ukind == KVAR)
5727 {
5728 llbug (message ("Bad call to uentry_getGlobs (var): %q (%s)",
5729 uentry_unparse (l),
5730 ekind_unparse (l->ukind)));
5731 }
5732 else
5733 {
5734 llbug (message ("Bad call to uentry_getGlobs: %q (%s)",
5735 uentry_unparse (l),
5736 ekind_unparse (l->ukind)));
5737 }
5738 }
5739 return globSet_undefined;
5740 }
5741
5742 return l->info->fcn->globs;
5743}
5744
5745/*@observer@*/ sRefSet
5746uentry_getMods (uentry l)
5747{
5748 llassert (uentry_isValid (l));
5749
5750 if (l->ukind != KFCN && l->ukind != KITER && l->ukind != KENDITER)
5751 {
5752 llcontbug (message ("Bad call to uentry_getMods: %q", uentry_unparse (l)));
5753 return sRefSet_undefined;
5754 }
5755
5756 return l->info->fcn->mods;
5757}
5758
5759ekind
5760uentry_getKind (uentry e)
5761{
5762 llassert (uentry_isValid (e));
5763
5764 return (e->ukind);
5765}
5766
5767/*@observer@*/ multiVal uentry_getConstantValue (uentry e)
5768{
b9904f57 5769 llassert (uentry_isEitherConstant (e));
5770 return (sRef_getValue (e->sref));
616915dd 5771}
5772
5773/*@observer@*/ uentryList
5774uentry_getParams (uentry l)
5775{
5776 if (uentry_isInvalid (l)) return uentryList_undefined;
5777
5778 switch (l->ukind)
5779 {
5780 case KFCN:
5781 case KITER:
5782 {
5783 ctype ct = l->utype;
5784
5785 if (ctype_isFunction (ct))
5786 {
5787 return (ctype_argsFunction (ct));
5788 }
5789 else
5790 {
5791 return uentryList_undefined;
5792 }
5793 }
5794 case KVAR:
5795 {
5796 ctype ct = l->utype;
5797
5798 llassert (ctype_isFunction (ct));
5799 return (ctype_argsFunction (ct));
5800 }
5801 BADDEFAULT;
5802 }
5803 BADEXIT;
5804}
5805
5806/*@observer@*/ cstring
5807uentry_rawName (uentry e)
5808{
5809 if (uentry_isValid (e))
5810 {
5811 return (e->uname);
5812 }
5813 else
5814 {
5815 return cstring_undefined;
5816 }
5817}
5818
5819static cstring
5820uentry_getOptName (uentry e)
5821{
5822 cstring s = uentry_getName (e);
5823
5824 if (cstring_isDefined (s))
5825 {
5826 s = cstring_appendChar (s, ' ');
5827 }
5828
5829 return s;
5830}
5831
5832/*@only@*/ cstring
5833uentry_getName (uentry e)
5834{
5835 cstring ret = cstring_undefined;
5836
5837 if (uentry_isValid (e))
5838 {
616915dd 5839 if (uentry_isAnyTag (e))
5840 {
28bf4b0b 5841 ret = fixTagName (e->uname);
616915dd 5842 }
5843 else if (uentry_isAnyParam (e))
5844 {
5845 ret = cstring_copy (fixParamName (e->uname));
5846 }
5847 else
5848 {
5849 ret = cstring_copy (e->uname);
5850 }
5851 }
5852
5853 return ret;
5854}
5855
28bf4b0b 5856cstring uentry_observeRealName (uentry e)
5857{
5858 cstring ret = cstring_undefined;
5859
5860 if (uentry_isValid (e))
5861 {
5862 if (uentry_isAnyTag (e))
5863 {
5864 if (isFakeTag (e->uname))
5865 {
5866 ret = cstring_undefined;
5867 }
5868 else
5869 {
5870 ret = plainTagName (e->uname);
5871 }
5872 }
5873 else if (uentry_isAnyParam (e))
5874 {
5875 ret = fixParamName (e->uname);
5876 }
5877 else
5878 {
5879 ret = e->uname;
5880 }
5881 }
5882
5883 return ret;
5884}
5885
616915dd 5886cstring uentry_getRealName (uentry e)
5887{
5888 if (uentry_isValid (e))
5889 {
5890 if (uentry_isAnyTag (e))
5891 {
5892 return (cstring_undefined);
5893 }
5894 else
5895 {
5896 return (e->uname);
5897 }
5898 }
5899 return cstring_undefined;
5900}
5901
5902ctype uentry_getType (uentry e)
5903{
5904 if (uentry_isValid (e))
5905 {
5906 return e->utype;
5907 }
5908 else
5909 {
5910 return ctype_unknown;
5911 }
5912}
5913
5914fileloc uentry_whereLast (uentry e)
5915{
5916 fileloc loc;
5917
5918 if (uentry_isInvalid (e))
5919 {
5920 return fileloc_undefined;
5921 }
5922
5923 loc = e->whereDefined;
5924
5925 if (fileloc_isValid (loc) && !fileloc_isExternal (loc))
5926 {
5927 return loc;
5928 }
5929
5930 loc = uentry_whereDeclared (e);
5931
5932 if (fileloc_isValid (loc) && !fileloc_isExternal (loc))
5933 {
5934 return loc;
5935 }
5936
5937 loc = uentry_whereSpecified (e);
5938 return loc;
5939}
5940
5941fileloc uentry_whereEither (uentry e)
5942{
5943 if (uentry_isInvalid (e)) return fileloc_undefined;
5944
5945 if (fileloc_isDefined (e->whereDefined)
5946 && !fileloc_isExternal (e->whereDefined))
5947 {
5948 return e->whereDefined;
5949 }
5950 else if (fileloc_isDefined (e->whereDeclared))
5951 {
5952 return e->whereDeclared;
5953 }
5954 else
5955 {
5956 return e->whereSpecified;
5957 }
5958}
5959
5960fileloc uentry_whereSpecified (uentry e)
5961{
5962 if (uentry_isInvalid (e)) return fileloc_undefined;
5963
5964 return (e->whereSpecified);
5965}
5966
5967fileloc uentry_whereDefined (uentry e)
5968{
5969 if (uentry_isInvalid (e)) return fileloc_undefined;
5970
5971 return (e->whereDefined);
5972}
5973
5974fileloc uentry_whereDeclared (uentry e)
5975{
5976 if (uentry_isInvalid (e)) return fileloc_undefined;
5977
5978 return (e->whereDeclared);
5979}
5980
5981/*@observer@*/ fileloc
5982uentry_whereEarliest (uentry e)
5983{
5984 if (uentry_isInvalid (e)) return fileloc_undefined;
5985
5986 if (fileloc_isDefined (e->whereSpecified))
5987 {
5988 return (e->whereSpecified);
5989 }
5990 else if (fileloc_isDefined (e->whereDeclared))
5991 {
5992 return (e->whereDeclared);
5993 }
5994 else
5995 {
5996 return e->whereDefined;
5997 }
5998}
5999
6000void
6001uentry_setFunctionDefined (uentry e, fileloc loc)
6002{
6003 if (uentry_isValid (e))
6004 {
6005 llassert (uentry_isFunction (e));
6006
6007 if (fileloc_isUndefined (e->whereDeclared))
6008 {
6009 e->whereDeclared = fileloc_update (e->whereDeclared, loc);
6010 }
6011
6012 if (!fileloc_isDefined (e->whereDefined))
6013 {
6014 e->whereDefined = fileloc_update (e->whereDefined, loc);
6015 }
6016 }
6017}
6018
6019void
6020uentry_setDeclDef (uentry e, fileloc f)
6021{
6022 uentry_setDeclared (e, f);
6023
6024 if (!uentry_isFunction (e)
6025 && !(uentry_isVariable (e) && uentry_isExtern (e)))
6026 {
6027 uentry_setDefined (e, f);
6028 }
6029}
6030
6031void
6032uentry_setDeclaredForce (uentry e, fileloc f)
6033{
6034 llassert (uentry_isValid (e));
6035 e->whereDeclared = fileloc_update (e->whereDeclared, f);
6036}
6037
6038void
6039uentry_setDeclaredForceOnly (uentry e, fileloc f)
6040{
6041 llassert (uentry_isValid (e));
6042 fileloc_free (e->whereDeclared);
6043 e->whereDeclared = f;
6044}
6045
6046void
6047uentry_setDeclaredOnly (uentry e, /*@only@*/ fileloc f)
6048{
6049 fileloc oldloc;
6050
6051 llassert (uentry_isValid (e));
6052 oldloc = e->whereDeclared;
6053
6054 if (fileloc_isDefined (oldloc))
6055 {
6056 if (fileloc_isLib (oldloc) || fileloc_isImport (oldloc))
6057 {
6058 e->whereDeclared = f;
6059 fileloc_free (oldloc);
6060 }
6061 else
6062 {
6063 fileloc_free (f);
6064 }
6065 }
6066 else
6067 {
6068 e->whereDeclared = f;
6069 fileloc_free (oldloc);
6070 }
6071}
6072
6073void
6074uentry_setDeclared (uentry e, fileloc f)
6075{
6076 fileloc oldloc;
6077
6078 llassert (uentry_isValid (e));
6079 oldloc = e->whereDeclared;
6080
6081 if (fileloc_isDefined (oldloc))
6082 {
6083 if (fileloc_isLib (oldloc) || fileloc_isImport (oldloc))
6084 {
6085 e->whereDeclared = fileloc_update (e->whereDeclared, f);
6086 }
6087 else
6088 {
6089 ;
6090 }
6091 }
6092 else
6093 {
6094 e->whereDeclared = fileloc_update (e->whereDeclared, f);
6095 }
6096}
6097
6098void
6099uentry_clearDefined (uentry e)
6100{
6101 if (uentry_isValid (e))
6102 {
6103 e->whereDefined = fileloc_update (e->whereDefined, fileloc_undefined);
6104 }
6105}
6106
6107void
6108uentry_setDefined (uentry e, fileloc f)
6109{
6110 fileloc oldloc;
6111
6112 llassert (uentry_isValid (e));
6113 oldloc = e->whereDefined;
6114
6115 if (fileloc_isDefined (oldloc))
6116 {
6117 if (fileloc_isLib (oldloc)
6118 || fileloc_isImport (oldloc)
6119 || fileloc_isBuiltin (oldloc)
6120 || fileloc_isPreproc (oldloc))
6121 {
6122 e->whereDefined = fileloc_update (e->whereDefined, f);
6123 }
6124 else
6125 {
6126 if (fileloc_equal (oldloc, f) || context_processingMacros ())
6127 {
6128 ; /* okay */
6129 }
6130 else
6131 {
6132 if (optgenerror (FLG_REDEF,
6133 message ("%s %q redefined",
6134 ekind_capName (e->ukind),
6135 uentry_getName (e)),
6136 f))
6137 {
6138 llgenindentmsg (message ("Previous definition of %q",
6139 uentry_getName (e)),
6140 e->whereDefined);
6141 }
6142 }
6143 }
6144 }
6145 else
6146 {
6147 e->whereDefined = fileloc_update (e->whereDefined, f);
6148 }
6149}
6150
6151bool
6152uentry_isCodeDefined (uentry e)
6153{
efd360a3 6154 llassert (uentry_isValid (e));
6155
6156 return (fileloc_isDefined (e->whereDefined));
616915dd 6157}
6158
6159bool
6160uentry_isDeclared (uentry e)
6161{
6162 if (uentry_isValid (e))
6163 {
6164 return (fileloc_isDefined (e->whereDeclared));
6165 }
6166
6167 return FALSE;
6168}
6169
6170sRef uentry_getSref (uentry e)
6171{
6172 /* not true, used for functions too (but shouldn't be? */
6173 /* llassertprint (e->ukind == KVAR, ("uentry_getSref: not variable!")); */
6174
6175 if (uentry_isInvalid (e)) return sRef_undefined;
6176
6177 return (e->sref);
6178}
6179
6180sRef uentry_getOrigSref (uentry e)
6181{
68de3f33 6182 /*@i523*/ /* evans 2001-09-09 - need to fix this
b7e84605 6183 if (uentry_isValid (e))
6184 {
6185 if (uentry_isVariable (e))
6186 {
6187 return e->info->var->origsref;
6188 }
6189 else
6190 {
6191 sRef sr = sRef_copy (uentry_getSref (e));
6192
6193 sRef_resetState (sr);
6194 sRef_clearDerived (sr);
6195 return (sr);
6196 }
6197 }
6198 else
6199 {
6200 return sRef_undefined;
6201 }
6202 */
6203
616915dd 6204 if (uentry_isValid (e))
6205 {
6206 sRef sr = sRef_copy (uentry_getSref (e));
6207
6208 sRef_resetState (sr);
6209 sRef_clearDerived (sr);
6210
6211 if (uentry_isVariable (e))
6212 {
6213 sRef_setDefState (sr, e->info->var->defstate, fileloc_undefined);
6214 sRef_setNullState (sr, e->info->var->nullstate, fileloc_undefined);
6215 }
6216
6217 return (sr);
6218 }
6219 else
6220 {
6221 return sRef_undefined;
6222 }
6223}
6224
6225/*
6226** requires: uentry e is not in a hashed symbol table
6227*/
6228
6229void
6230uentry_setName (uentry e, /*@only@*/ cstring n)
6231{
6232 llassert (uentry_isValid (e));
6233
6234 cstring_free (e->uname);
6235 e->uname = n;
6236}
6237
6238void
6239uentry_setType (uentry e, ctype t)
6240{
6241 if (uentry_isValid (e))
6242 {
6243 e->utype = t;
6244 sRef_setType (e->sref, t);
6245 }
6246}
6247
6248void
6249uentry_resetParams (uentry ue, /*@only@*/ uentryList pn)
6250{
6251 ctype rct;
6252 ctype rettype = ctype_unknown;
6253
6254 llassert (uentry_isValid (ue));
6255
efd360a3 6256 uentry_convertVarFunction (ue);
616915dd 6257 llassert (uentry_isFunction (ue));
6258
efd360a3 6259 rct = ctype_realType (ue->utype);
6260
616915dd 6261 if (ctype_isFunction (rct))
6262 {
28bf4b0b 6263 rettype = ctype_getReturnType (rct);
616915dd 6264 }
6265
6266 ue->utype = ctype_makeNFParamsFunction (rettype, pn);
6267}
6268
6269void
6270uentry_setRefParam (uentry e)
6271{
616915dd 6272 if (!uentry_isVar (e))
6273 {
6274 llbug (message ("uentry_setParam: not variable: %q", uentry_unparse (e)));
6275 }
6276 else
6277 {
6278 if (e->info->var->kind == VKSEFPARAM)
6279 {
6280 e->info->var->kind = VKREFSEFPARAM;
6281 }
6282 else if (e->info->var->kind == VKSEFRETPARAM)
6283 {
6284 e->info->var->kind = VKREFSEFRETPARAM;
6285 }
6286 else if (e->info->var->kind == VKYIELDPARAM)
6287 {
6288 e->info->var->kind = VKREFYIELDPARAM;
6289 }
6290 else
6291 {
6292 e->info->var->kind = VKREFPARAM;
6293 }
6294 }
6295}
6296
6297void
6298uentry_setParam (uentry e)
6299{
6300 if (!uentry_isVar (e))
6301 {
6302 if (uentry_isElipsisMarker (e))
6303 {
6304
6305 }
6306 else
6307 {
6308 llbug (message ("uentry_setParam: not variable: %q", uentry_unparse (e)));
6309 }
6310 }
6311 else
6312 {
6313 cstring oldname;
6314
6315 if (e->info->var->kind == VKYIELDPARAM
6316 || e->info->var->kind == VKSEFPARAM
6317 || e->info->var->kind == VKSEFRETPARAM)
6318 {
6319 ;
6320 }
6321 else
6322 {
6323 e->info->var->kind = VKPARAM;
6324 }
6325
6326 oldname = e->uname;
6327 e->uname = makeParam (e->uname);
6328 cstring_free (oldname);
6329 }
6330}
6331
6332void
6333uentry_setSref (uentry e, sRef s)
6334{
6335 if (uentry_isValid (e))
6336 {
6337 if (sRef_isValid (e->sref))
6338 {
6339 sRef_mergeStateQuietReverse (e->sref, s);
6340 }
6341 else
6342 {
6343 e->sref = sRef_saveCopy (s);
6344 }
6345 }
6346}
6347
6348ctype
6349uentry_getAbstractType (uentry e)
6350{
6351 llassert (uentry_isDatatype (e));
6352
6353 /*
6354 ** This assertion removed.
6355 ** Okay to have undefined type, for system types
6356
6357 llassertprintret (!ctype_isUndefined (e->info->datatype->type),
6358 ("uentry_getAbstractType %q: undefined", uentry_unparseFull (e)),
6359 e->utype);
6360
6361 */
6362
6363 if (ctype_isUndefined (e->info->datatype->type))
6364 {
6365 return ctype_unknown;
6366 }
6367
6368 /*
6369 ** Sadly, a kludge...
6370 */
6371
6372 if (ctype_isUserBool (e->info->datatype->type)) {
6373 return ctype_bool;
6374 }
6375
6376 return e->info->datatype->type;
6377}
6378
6379ctype uentry_getRealType (uentry e)
6380{
6381 ctype ct;
6382 typeId uid = USYMIDINVALID;
6383
6384 if (uentry_isInvalid (e))
6385 {
6386 return ctype_unknown;
6387 }
6388
6389 llassertprint (uentry_isDatatype (e), ("not datatype: %s", uentry_unparse (e)));
6390
6391 if (uentry_isAnyTag (e))
6392 {
6393 return (e->utype);
6394 }
6395
6396 if (uentry_isAbstractType (e))
6397 {
6398 ct = uentry_getAbstractType (e);
6399
6400 if (ctype_isManifestBool (ct)) {
6401 return ct;
6402 }
6403
6404 llassert (ctype_isUA (ct));
6405
6406 uid = ctype_typeId (ct);
6407
6408 if (!context_hasAccess (uid))
6409 {
6410 return (ct);
6411 }
6412 }
6413
6414 ct = uentry_getType (e);
6415
6416 /* if (ctype_isUserBool (ct)) return ct; */
6417
6418 if (ctype_isManifestBool (ct)) {
6419 return ctype_bool;
6420 }
6421
6422 if (ctype_isUA (ct))
6423 {
6424 usymId iid = ctype_typeId (ct);
6425
28bf4b0b 6426 if (usymId_equal (iid, uid))
616915dd 6427 {
6428 llcontbug (message ("uentry_getRealType: recursive type! %s",
6429 ctype_unparse (ct)));
6430 return ct;
6431 }
6432 else
6433 {
6434 /* evs 2000-07-25: possible infinite recursion ? */
6435 uentry ue2 = usymtab_getTypeEntry (iid);
28bf4b0b 6436
6437 if (ue2 == e)
6438 {
6439 llcontbug (message ("Bad recursion: %q", uentry_unparseFull (e)));
6440 return ctype_unknown;
6441 }
616915dd 6442
6443 return uentry_getRealType (ue2);
6444 }
6445 }
6446 else
6447 {
6448 return ct;
6449 }
6450}
6451
6452ctype uentry_getForceRealType (uentry e)
6453{
6454 ctype ct;
6455 typeId uid = USYMIDINVALID;
6456
6457 if (uentry_isInvalid (e))
6458 {
6459 return ctype_unknown;
6460 }
6461
6462 llassertprint (uentry_isDatatype (e), ("not datatype: %s", uentry_unparse (e)));
6463
6464 if (uentry_isAnyTag (e))
6465 {
6466 return (e->utype);
6467 }
6468
6469 if (uentry_isAbstractType (e))
6470 {
6471 ct = uentry_getAbstractType (e);
6472 llassert (ctype_isUA (ct));
6473
6474 uid = ctype_typeId (ct);
6475 /* no check for access! */
6476 }
6477
6478 ct = uentry_getType (e);
6479
6480 /* evs 2000-07-25 */
6481 /* if (ctype_isUserBool (ct)) return ct; */
6482
6483 if (ctype_isManifestBool (ct)) {
6484 return ctype_bool;
6485 }
6486
6487 if (ctype_isUA (ct))
6488 {
6489 usymId iid = ctype_typeId (ct);
6490
28bf4b0b 6491 if (usymId_equal (iid, uid))
616915dd 6492 {
6493 llcontbug (message ("uentry_getRealType: recursive type! %s",
6494 ctype_unparse (ct)));
6495 return ct;
6496 }
6497 else
6498 {
6499 return uentry_getForceRealType (usymtab_getTypeEntry (iid));
6500 }
6501 }
6502 else
6503 {
6504 return ct;
6505 }
6506}
6507
6508uentry uentry_nameCopy (cstring name, uentry e)
6509{
6510 uentry enew = uentry_alloc ();
6511
6512 llassert (uentry_isValid (e));
6513
6514 /* enew->shallowCopy = FALSE; */
6515 enew->ukind = e->ukind;
6516 enew->uname = name;
6517 enew->utype = e->utype;
6518 enew->whereSpecified = fileloc_copy (e->whereSpecified);
6519 enew->whereDefined = fileloc_copy (e->whereDefined);
6520 enew->whereDeclared = fileloc_copy (e->whereDeclared);
6521 enew->sref = sRef_copy (e->sref);
6522 enew->used = e->used;
6523 enew->lset = FALSE;
6524 enew->isPrivate = e->isPrivate;
6525 enew->hasNameError = FALSE;
6526
6527 enew->uses = filelocList_new ();
28bf4b0b 6528 enew->warn = warnClause_undefined;
616915dd 6529
6530 enew->storageclass = e->storageclass;
6531 enew->info = uinfo_copy (e->info, e->ukind);
6532
6533 return enew;
6534}
6535
6536void
6537uentry_setDatatype (uentry e, usymId uid)
6538{
6539 llassert (uentry_isDatatype (e));
6540
6541 if (uentry_isAbstractType (e))
6542 {
6543 e->info->datatype->type = ctype_createAbstract (uid);
6544 }
6545 else
6546 {
6547 e->info->datatype->type = ctype_createUser (uid);
6548 }
6549}
6550
6551static void
6552uentry_setSpecDef (/*@special@*/ uentry e, /*@keep@*/ fileloc f)
6553 /*@defines e->whereSpecified, e->whereDeclared, e->whereDefined@*/
6554 /*@modifies e@*/
6555{
6556 llassert (uentry_isValid (e));
6557
6558 if (fileloc_isSpec (f) || fileloc_isImport (f))
6559 {
6560 e->whereSpecified = f;
6561 e->whereDeclared = fileloc_undefined;
6562 e->whereDefined = fileloc_undefined;
6563 }
6564 else
6565 {
6566 e->whereSpecified = fileloc_undefined;
6567 e->whereDeclared = f;
6568 e->whereDefined = fileloc_undefined;
6569 }
7ebcc5bb 6570
6571 llassert (fileloc_storable (f));
616915dd 6572}
6573
6574static void
6575ucinfo_free (/*@only@*/ ucinfo u)
6576{
616915dd 6577 sfree (u);
6578}
6579
6580static void
6581uvinfo_free (/*@only@*/ uvinfo u)
6582{
28bf4b0b 6583 /*drl7x added 6/29/01 */
b072092f 6584 free (u->bufinfo); /* evans - 2001-07-19 fixed this bug */
616915dd 6585 sfree (u);
6586}
6587
6588static void
6589udinfo_free (/*@only@*/ udinfo u)
6590{
6591 sfree (u);
6592}
6593
6594static void
6595ufinfo_free (/*@only@*/ ufinfo u)
6596{
6597 globSet_free (u->globs);
6598 sRefSet_free (u->mods);
28bf4b0b 6599 stateClauseList_free (u->specclauses);
616915dd 6600 sfree (u);
6601}
6602
6603static void
6604uiinfo_free (/*@only@*/ uiinfo u)
6605{
6606 sfree (u);
6607}
6608
6609static void
6610ueinfo_free (/*@only@*/ ueinfo u)
6611{
6612 sfree (u);
6613}
6614
6615static /*@only@*/ ucinfo
6616ucinfo_copy (ucinfo u)
6617{
6618 ucinfo ret = (ucinfo) dmalloc (sizeof (*ret));
616915dd 6619 ret->access = u->access;
3e3ec469 6620 ret->macro = u->macro;
616915dd 6621 return ret;
6622}
6623
6624static /*@only@*/ uvinfo
6625uvinfo_copy (uvinfo u)
6626{
6627 uvinfo ret = (uvinfo) dmalloc (sizeof (*ret));
6628
6629 ret->kind = u->kind;
6630 ret->nullstate = u->nullstate;
6631 ret->defstate = u->defstate;
6632 ret->checked = u->checked;
28bf4b0b 6633
b7e84605 6634 /*@i523 ret->origsref = sRef_copy (u->origsref); */
6635
28bf4b0b 6636 /* drl added 07-02-001 */
6637 /* copy null terminated information */
6638
6639 if (u->bufinfo != NULL)
6640 {
6641 ret->bufinfo = (bbufinfo) dmalloc (sizeof( * u->bufinfo ) );
6642 ret->bufinfo->bufstate = u->bufinfo->bufstate;
6643 ret->bufinfo->size = u->bufinfo->size;
6644 ret->bufinfo->len = u->bufinfo->len;
6645 return ret;
6646 }
6647 else
6648 {
6649 ret->bufinfo = NULL;
6650 return ret;
6651 }
6652
616915dd 6653}
6654
6655static /*@only@*/ udinfo
6656udinfo_copy (udinfo u)
6657{
6658 udinfo ret = (udinfo) dmalloc (sizeof (*ret));
6659
6660 ret->abs = u->abs;
6661 ret->mut = u->mut;
6662 ret->type = u->type;
6663
6664 return ret;
6665}
6666
6667static /*@only@*/ ufinfo
6668ufinfo_copy (ufinfo u)
6669{
6670 ufinfo ret = (ufinfo) dmalloc (sizeof (*ret));
6671
6672 ret->hasGlobs = u->hasGlobs;
6673 ret->hasMods = u->hasMods;
6674 ret->exitCode = u->exitCode;
6675 ret->specialCode = u->specialCode;
6676 ret->nullPred = u->nullPred;
6677 ret->access = u->access;
6678 ret->globs = globSet_newCopy (u->globs);
6679 ret->mods = sRefSet_newCopy (u->mods);
6680 ret->defparams = u->defparams;
28bf4b0b 6681 ret->specclauses = stateClauseList_copy (u->specclauses);
616915dd 6682
3814599d 6683 ret->preconditions = functionConstraint_copy (u->preconditions);
6684 ret->postconditions = functionConstraint_copy (u->postconditions);
616915dd 6685
6686 return ret;
6687}
6688
6689static /*@only@*/ uiinfo
6690uiinfo_copy (uiinfo u)
6691{
6692 uiinfo ret = (uiinfo) dmalloc (sizeof (*ret));
6693
6694 ret->access = u->access;
6695 ret->globs = globSet_newCopy (u->globs);
6696 ret->mods = sRefSet_newCopy (u->mods);
6697
6698 return (ret);
6699}
6700
6701static /*@only@*/ ueinfo
6702ueinfo_copy (ueinfo u)
6703{
6704 ueinfo ret = (ueinfo) dmalloc (sizeof (*ret));
6705
6706 ret->access = u->access;
6707 return ret;
6708}
6709
6710static void
6711uinfo_free (uinfo u, ekind kind)
6712{
6713 switch (kind)
6714 {
6715 case KENUMCONST:
6716 case KCONST: ucinfo_free (u->uconst); break;
6717 case KVAR: uvinfo_free (u->var); break;
6718 case KSTRUCTTAG:
6719 case KUNIONTAG:
6720 case KENUMTAG:
6721 case KDATATYPE: udinfo_free (u->datatype); break;
6722 case KFCN: ufinfo_free (u->fcn); break;
6723 case KITER: uiinfo_free (u->iter); break;
6724 case KENDITER: ueinfo_free (u->enditer); break;
6725 case KELIPSMARKER: break;
6726 case KINVALID: break;
6727 }
6728
6729 sfree (u);
6730}
6731
6732static /*@only@*/ /*@null@*/ uinfo
6733uinfo_copy (uinfo u, ekind kind)
6734{
6735 if (kind == KELIPSMARKER || kind == KINVALID)
6736 {
6737 return NULL;
6738 }
6739 else
6740 {
6741 uinfo ret = (uinfo) dmalloc (sizeof (*ret));
6742
6743 switch (kind)
6744 {
6745 case KENUMCONST:
6746 case KCONST: ret->uconst = ucinfo_copy (u->uconst); break;
6747 case KVAR: ret->var = uvinfo_copy (u->var); break;
6748 case KSTRUCTTAG:
6749 case KUNIONTAG:
6750 case KENUMTAG:
6751 case KDATATYPE: ret->datatype = udinfo_copy (u->datatype); break;
6752 case KFCN: ret->fcn = ufinfo_copy (u->fcn); break;
6753 case KITER: ret->iter = uiinfo_copy (u->iter); break;
6754 case KENDITER: ret->enditer = ueinfo_copy (u->enditer); break;
6755 BADDEFAULT;
6756 }
6757 return ret;
6758 }
6759}
6760
6761static void
6762uentry_reallyFree (/*@notnull@*/ /*@only@*/ uentry e)
6763{
6764 filelocList_free (e->uses);
6765 cstring_free (e->uname);
6766
6767 uinfo_free (e->info, e->ukind);
6768
6769 fileloc_free (e->whereSpecified);
6770 fileloc_free (e->whereDefined);
6771 fileloc_free (e->whereDeclared);
6772
28bf4b0b 6773 warnClause_free (e->warn);
6774
616915dd 6775 nuentries--;
6776 sfree (e);
6777 }
6778
6779extern void uentry_markOwned (/*@owned@*/ uentry u)
6780{
6781 sfreeEventually (u);
6782}
6783
6784void
6785uentry_free (/*@only@*/ uentry e)
6786{
6787 if (uentry_isValid (e) && !uentry_isElipsisMarker (e))
6788 {
6789 uentry_reallyFree (e);
6790 }
6791}
6792
6793/*
6794** For uentry's in the global or file scope
6795*/
6796
6797void
6798uentry_freeComplete (/*@only@*/ uentry e)
6799{
6800 if (uentry_isValid (e) && !uentry_isElipsisMarker (e))
6801 {
28bf4b0b 6802 DPRINTF (("Free complete: %s", sRef_unparseFull (e->sref)));
616915dd 6803 /*@i@*/ sRef_free (e->sref);
6804 e->sref = sRef_undefined;
6805 uentry_reallyFree (e);
6806 }
6807}
6808
6809/*
6810** requires old->kind != new->kind, old->uname = new->uname
6811*/
6812
6813static void
6814KindConformanceError (/*@unique@*/ uentry old, uentry unew, bool mustConform)
6815{
6816 llassert (uentry_isValid (old));
6817 llassert (uentry_isValid (unew));
6818
6819 if (uentry_isEitherConstant (unew)
6820 && (fileloc_isPreproc (uentry_whereDeclared (old))
6821 || ctype_isUnknown (old->utype))
6822 && !uentry_isSpecified (old))
6823 {
6824 ; /* no error */
6825 }
6826 else
6827 {
6828 if (mustConform)
6829 {
6830 if (!uentry_isDeclared (old))
6831 {
6832 if (uentry_isSpecified (old))
6833 {
6834 if (uentry_isSpecified (unew))
6835 {
6836 llbuglit ("Respecification!");
6837 }
6838 else if (uentry_isDeclared (unew))
6839 {
6840 if (optgenerror
6841 (FLG_INCONDEFS,
6842 message ("%s %q inconsistently declared as %s: %t",
6843 ekind_capName (old->ukind),
6844 uentry_getName (unew),
6845 ekind_unparseLong (unew->ukind),
6846 unew->utype),
f2b6724f 6847 uentry_whereLast (unew))) /* evans 2001-12-30: was uentry_whereDeclared */
616915dd 6848 {
f2b6724f 6849 uentry_showWhereLastKind (old);
616915dd 6850 }
6851 }
6852 else
6853 {
6854 BADEXIT;
6855 }
6856 }
6857 else
6858 {
6859 if (optgenerror
6860 (FLG_INCONDEFS,
6861 message ("%s %q inconsistently declared as %s: %t",
6862 ekind_capName (old->ukind),
6863 uentry_getName (unew),
6864 ekind_unparseLong (unew->ukind),
6865 unew->utype),
f2b6724f 6866 uentry_whereLast (unew))) /* evans 2001-12-30: was uentry_whereDeclared */
616915dd 6867 {
f2b6724f 6868 uentry_showWhereLastKind (old);
616915dd 6869 }
6870 }
6871 }
6872 else
6873 {
6874 llassert (uentry_isDeclared (unew));
6875
f2b6724f 6876 DPRINTF (("Old: \n\t%s", uentry_unparseFull (old)));
6877 DPRINTF (("New: \n\t%s", uentry_unparseFull (unew)));
6878
616915dd 6879 if (optgenerror
6880 (FLG_INCONDEFS,
6881 message ("%s %q inconsistently redeclared as %s",
6882 ekind_capName (old->ukind),
6883 uentry_getName (unew),
6884 ekind_unparseLong (unew->ukind)),
f2b6724f 6885 uentry_whereLast (unew))) /* evans 2001-12-30: was uentry_whereDeclared */
616915dd 6886 {
f2b6724f 6887 uentry_showWhereLastKind (old);
616915dd 6888 }
6889 }
6890 }
6891 }
6892
efd360a3 6893 uentry_updateInto (old, unew);
616915dd 6894}
6895
6896/*
6897** def is the definition of spec, modifies spec
6898**
6899** reports any inconsistencies
6900** returns the summary of all available information
6901** if spec and def are inconsistent, def is returned
6902*/
6903
6904void
6905uentry_showWhereLast (uentry spec)
6906{
6907 if (uentry_isValid (spec))
6908 {
6909 if (fileloc_isDefined (spec->whereDefined)
6910 && !fileloc_isLib (spec->whereDefined)
f2b6724f 6911 /*!! && !fileloc_isPreproc (spec->whereDefined) */ )
616915dd 6912 {
6913 llgenindentmsg (message ("Previous definition of %q: %t",
6914 uentry_getName (spec),
6915 uentry_getType (spec)),
6916 uentry_whereDefined (spec));
6917 }
6918 else if (uentry_isDeclared (spec))
6919 {
6920 llgenindentmsg (message ("Previous declaration of %q: %t",
6921 uentry_getName (spec),
6922 uentry_getType (spec)),
6923 uentry_whereDeclared (spec));
6924 }
6925 else if (uentry_isSpecified (spec))
6926 {
6927 if (uentry_hasName (spec))
6928 {
6929 llgenindentmsg (message ("Specification of %q: %t",
6930 uentry_getName (spec),
6931 uentry_getType (spec)),
6932 uentry_whereSpecified (spec));
6933 }
6934 else
6935 {
6936 llgenindentmsg (message ("Specification: %t", uentry_getType (spec)),
6937 uentry_whereSpecified (spec));
6938 }
6939 }
6940 else
6941 {
6942 /* nothing to show */
6943 }
6944 }
6945}
6946
f2b6724f 6947static void
6948uentry_showWhereLastKind (uentry spec)
6949{
6950 if (uentry_isValid (spec))
6951 {
6952 if (fileloc_isDefined (spec->whereDefined)
6953 && !fileloc_isLib (spec->whereDefined)
6954 /*!! && !fileloc_isPreproc (spec->whereDefined) */ )
6955 {
6956 llgenindentmsg (message ("Previous definition of %q as %s: %t",
6957 uentry_getName (spec),
6958 ekind_unparseLong (spec->ukind),
6959 uentry_getType (spec)),
6960 uentry_whereDefined (spec));
6961 }
6962 else if (uentry_isDeclared (spec))
6963 {
6964 llgenindentmsg (message ("Previous declaration of %q as %s: %t",
6965 uentry_getName (spec),
6966 ekind_unparseLong (spec->ukind),
6967 uentry_getType (spec)),
6968 uentry_whereDeclared (spec));
6969 }
6970 else if (uentry_isSpecified (spec))
6971 {
6972 if (uentry_hasName (spec))
6973 {
6974 llgenindentmsg (message ("Specification of %q as %s: %t",
6975 uentry_getName (spec),
6976 ekind_unparseLong (spec->ukind),
6977 uentry_getType (spec)),
6978 uentry_whereSpecified (spec));
6979 }
6980 else
6981 {
6982 llgenindentmsg (message ("Specification as %s: %t",
6983 ekind_unparseLong (spec->ukind),
6984 uentry_getType (spec)),
6985 uentry_whereSpecified (spec));
6986 }
6987 }
6988 else
6989 {
6990 /* nothing to show */
6991 }
6992 }
6993}
6994
616915dd 6995void
6996uentry_showDefSpecInfo (uentry ce, fileloc fwhere)
6997{
6998 fileloc loc = uentry_whereDefined (ce);
6999
7000 if (fileloc_isUser (loc) && !fileloc_equal (loc, fwhere))
7001 {
7002 llgenindentmsg (message ("Definition of %q", uentry_getName (ce)),
7003 loc);
7004 }
7005
7006 loc = uentry_whereSpecified (ce);
7007
7008 if (fileloc_isUser (loc) && !fileloc_equal (loc, fwhere))
7009 {
7010 llgenindentmsg (message ("Specification of %q", uentry_getName (ce)),
7011 loc);
7012 }
7013}
7014
7015void uentry_showWhereLastExtra (uentry spec, cstring extra)
7016{
7017 if (uentry_isDeclared (spec))
7018 {
7019 llgenindentmsg (message ("Previous declaration of %q: %q",
7020 uentry_getName (spec), extra),
7021 uentry_whereDeclared (spec));
7022 }
7023 else if (uentry_isSpecified (spec))
7024 {
7025 llgenindentmsg (message ("Specification of %q: %q",
7026 uentry_getName (spec), extra),
7027 uentry_whereSpecified (spec));
7028 }
7029 else
7030 {
7031 cstring_free (extra);
7032 }
7033}
7034
7035void
7036uentry_showWhereDeclared (uentry spec)
7037{
7038 if (uentry_isDeclared (spec))
7039 {
7040 if (uentry_hasName (spec))
7041 {
7042 llgenindentmsg (message ("Declaration of %q", uentry_getName (spec)),
7043 uentry_whereDeclared (spec));
7044 }
7045 else
7046 {
7047 llgenindentmsg (cstring_makeLiteral ("Declaration"), uentry_whereDeclared (spec));
7048 }
7049 }
7050 else if (uentry_isSpecified (spec))
7051 {
7052 if (uentry_hasName (spec))
7053 {
7054 llgenindentmsg (message ("Specification of %q", uentry_getName (spec)),
7055 uentry_whereSpecified (spec));
7056 }
7057 else
7058 {
7059 llgenindentmsg (cstring_makeLiteral ("Specification"), uentry_whereSpecified (spec));
7060 }
7061 }
7062 else
7063 {
7064 /* nothing to show */
7065 }
7066
7067}
7068
7069void
7070uentry_showWhereAny (uentry spec)
7071{
7072 if (uentry_isDeclared (spec))
7073 {
7074 if (uentry_hasName (spec))
7075 {
7076 llgenindentmsg (message ("Declaration of %q", uentry_getName (spec)),
7077 uentry_whereDeclared (spec));
7078 }
7079 else
7080 {
7081 llgenindentmsg (cstring_makeLiteral ("Declaration"), uentry_whereDeclared (spec));
7082 }
7083 }
7084 else if (uentry_isSpecified (spec))
7085 {
7086 if (uentry_hasName (spec))
7087 {
7088 llgenindentmsg (message ("Specification of %q",
7089 uentry_getName (spec)),
7090 uentry_whereSpecified (spec));
7091 }
7092 else
7093 {
7094 llgenindentmsg (cstring_makeLiteral ("Specification"),
7095 uentry_whereSpecified (spec));
7096 }
7097 }
7098 else if (fileloc_isDefined (uentry_whereDefined (spec)))
7099 {
7100 if (uentry_hasName (spec))
7101 {
7102 llgenindentmsg (message ("Definition of %q", uentry_getName (spec)),
7103 uentry_whereDefined (spec));
7104 }
7105 else
7106 {
7107 llgenindentmsg (cstring_makeLiteral ("Definition"), uentry_whereDefined (spec));
7108 }
7109 }
7110 else
7111 {
7112 /* nothing to show */
7113 }
7114}
7115
7116void
7117uentry_showWhereDefined (uentry spec)
7118{
7119 if (uentry_isCodeDefined (spec))
7120 {
7121 llgenindentmsg (message ("Previous definition of %q", uentry_getName (spec)),
7122 uentry_whereDefined (spec));
7123 }
7124}
7125
7126void
7127uentry_showWhereLastPlain (uentry spec)
7128{
7129 if (uentry_isDeclared (spec))
7130 {
7131 llgenindentmsg (message ("Previous declaration of %q", uentry_getName (spec)),
7132 uentry_whereDeclared (spec));
7133 }
7134 else if (uentry_isSpecified (spec))
7135 {
7136 llgenindentmsg (message ("Specification of %q", uentry_getName (spec)),
7137 uentry_whereSpecified (spec));
7138 }
7139 else
7140 {
7141 }
7142}
7143
7144static void
7145uentry_showWhereLastVal (uentry spec, cstring val)
7146{
7147 if (uentry_isDeclared (spec))
7148 {
7149 llgenindentmsg (message ("Previous declaration of %q: %s",
7150 uentry_getName (spec), val),
7151 uentry_whereDeclared (spec));
7152 }
7153 else if (uentry_isSpecified (spec))
7154 {
7155 llgenindentmsg (message ("Specification of %q: %s",
7156 uentry_getName (spec), val),
7157 uentry_whereSpecified (spec));
7158 }
7159 else
7160 {
7161 }
7162}
7163
7164void
7165uentry_showWhereSpecified (uentry spec)
7166{
7167 if (uentry_isSpecified (spec))
7168 {
7169 if (uentry_hasName (spec))
7170 {
7171 llgenindentmsg (message ("Specification of %q", uentry_getName (spec)),
7172 uentry_whereSpecified (spec));
7173 }
7174 else
7175 {
7176 llgenindentmsg (cstring_makeLiteral ("Specification"),
7177 uentry_whereSpecified (spec));
7178 }
7179 }
7180 else if (uentry_isDeclared (spec))
7181 {
7182 llgenindentmsg (message ("Declaration of %q", uentry_getName (spec)),
7183 uentry_whereDeclared (spec));
7184 }
7185 else
7186 {
7187 /* nothing to show */
7188 }
7189}
7190
7191void
7192uentry_showWhereSpecifiedExtra (uentry spec, cstring s)
7193{
7194 if (uentry_isSpecified (spec))
7195 {
7196 if (uentry_hasName (spec))
7197 {
7198 llgenindentmsg (message ("Specification of %q: %q",
7199 uentry_getName (spec), s),
7200 uentry_whereSpecified (spec));
7201 }
7202 else
7203 {
7204 llgenindentmsg (message ("Specification: %q", s),
7205 uentry_whereSpecified (spec));
7206 }
7207 }
7208 else if (uentry_isDeclared (spec))
7209 {
7210 llgenindentmsg (message ("Declaration of %q: %q",
7211 uentry_getName (spec), s),
7212 uentry_whereDeclared (spec));
7213 }
7214 else
7215 {
7216 llgenindentmsg (message ("Previous: %q", s),
7217 uentry_whereLast (spec));
7218 }
7219}
7220
7221/*
7222**
7223*/
7224
7225static void
7226checkStructConformance (uentry old, uentry unew)
7227{
7228 ctype oldr, newr;
7229 uentryList fold, fnew;
7230
7231 /*
7232 ** requires: types of old and new are structs or unions
7233 */
7234
7235 llassert (uentry_isValid (old));
7236 llassert (uentry_isValid (unew));
7237
7238 oldr = ctype_realType (old->utype);
7239 fold = ctype_getFields (oldr);
7240
7241 newr = ctype_realType (unew->utype);
7242 fnew = ctype_getFields (newr);
7243
7244 if (!uentryList_matchFields (fold, fnew))
7245 {
7246 if (fileloc_equal (uentry_whereLast (old),
7247 uentry_whereLast (unew)))
7248 {
7249 ; /* cheat! */
7250 }
7251 else
7252 {
7253 if (optgenerror
7254 (FLG_MATCHFIELDS,
7255 message ("%q %q %rdeclared with fields { %q }, %s "
7256 "with fields { %q }",
7257 cstring_makeLiteral (ctype_isStruct (newr) ? "Structure": "Union"),
7258 uentry_getName (old),
7259 uentry_isDeclared (old),
7260 uentryList_unparseAbbrev (fnew),
7261 uentry_specOrDefName (old),
7262 uentryList_unparseAbbrev (fold)),
7263 uentry_whereDeclared (unew)))
7264 {
7265 uentry_showWhereLastPlain (old);
7266 uentryList_showFieldDifference (fold, fnew);
7267 }
7268 }
7269
7270 old->utype = unew->utype;
7271 }
7272}
7273
7274static void
7275checkEnumConformance (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew)
7276{
7277 /*
7278 ** requires old and new are enums
7279 */
7280
7281 ctype rold = ctype_realType (old->utype);
7282 ctype rnew = ctype_realType (unew->utype);
7283 enumNameList eold = ctype_elist (rold);
7284 enumNameList enew = ctype_elist (rnew);
7285
7286 if (!enumNameList_match (eold, enew))
7287 {
7288 if (optgenerror
7289 (FLG_MATCHFIELDS,
7290 message ("Enum %q declared with members { %q } but "
7291 "specified with members { %q }",
7292 uentry_getName (old),
7293 enumNameList_unparse (enew),
7294 enumNameList_unparse (eold)),
7295 uentry_whereDeclared (unew)))
7296 {
7297 uentry_showWhereSpecified (old);
7298 old->utype = unew->utype;
7299 }
7300 }
7301}
7302
7303/*
7304** either oldCurrent or newCurrent may be undefined!
7305*/
7306
7307static void
7308paramTypeError (uentry old, uentry oldCurrent, ctype oldType,
7309 uentry unew, uentry newCurrent, ctype newType,
7310 int paramno)
7311{
7312 bool hasError = FALSE;
7313
7314 if (uentry_isValid (newCurrent) && uentry_isDeclared (newCurrent))
7315 {
7316 if (uentry_hasName (newCurrent))
7317 {
7318 hasError = optgenerror
7319 (FLG_TYPE,
7320 message ("Parameter %d, %q, of function %q has inconsistent type: "
7321 "declared %t, %s %t",
7322 paramno + 1, uentry_getName (newCurrent),
7323 uentry_getName (unew),
7324 newType, uentry_specOrDefName (old), oldType),
7325 uentry_whereDeclared (newCurrent));
7326 }
7327 else
7328 {
7329 hasError = optgenerror
7330 (FLG_TYPE,
7331 message ("Parameter %d of function %q has inconsistent type: "
7332 "declared %t, %s %t",
7333 paramno + 1, uentry_getName (unew),
7334 newType, uentry_specOrDefName (old), oldType),
7335 uentry_whereDeclared (newCurrent));
7336
7337 DPRINTF (("type: %s / %s",
7338 ctype_unparse (newType),
7339 ctype_unparse (ctype_realType (newType))));
7340 }
7341 }
7342 else
7343 {
7344 if (uentry_isDeclared (unew))
7345 {
7346 hasError = optgenerror
7347 (FLG_TYPE,
7348 message ("Parameter %d of function %s has inconsistent type: "
7349 "declared %t, %s %t",
7350 paramno + 1, unew->uname,
7351 newType, uentry_specOrDefName (old), oldType),
7352 uentry_whereDeclared (unew));
7353 }
7354 else
7355 {
7356 hasError = optgenerror
7357 (FLG_TYPE,
7358 message ("Parameter %d of function %s has inconsistent type: "
7359 "declared %t, %s %t",
7360 paramno + 1, unew->uname,
7361 newType, uentry_specOrDefName (old), oldType),
7362 uentry_whereDeclared (unew));
7363 }
7364 }
7365
7366 if (hasError)
7367 {
6970c11b 7368 DPRINTF (("Here: %s / %s",
7369 uentry_unparseFull (oldCurrent),
7370 uentry_unparseFull (newCurrent)));
7371
616915dd 7372 if (!uentry_isUndefined (oldCurrent))
7373 {
7374 if (!uentry_isUndefined (newCurrent)
7375 && cstring_equal (uentry_rawName (newCurrent), uentry_rawName (oldCurrent)))
7376 {
7377 uentry_showWhereLast (oldCurrent);
7378 }
7379 else
7380 {
7381 uentry_showWhereLastPlain (old);
7382 }
7383
7384 uentry_setType (oldCurrent, newType);
7385 }
7386 else
7387 {
7388 uentry_showWhereLastPlain (old);
7389 }
7390 }
7391}
7392
7393static void
7394nargsError (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew)
7395{
7396 if (optgenerror
7397 (FLG_TYPE,
28bf4b0b 7398 message ("Function %s %rdeclared with %d arg%&, %s with %d",
616915dd 7399 unew->uname,
7400 uentry_isDeclared (old),
7401 uentryList_size (uentry_getParams (unew)),
7402 uentry_specOrDefName (old),
7403 uentryList_size (uentry_getParams (old))),
7404 uentry_whereDeclared (unew)))
7405 {
7406 uentry_showWhereLastPlain (old);
7407 }
7408}
7409
7410static void
7411returnValueError (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew)
7412{
7413 if (optgenerror
7414 (FLG_INCONDEFS,
7415 message ("Function %s inconsistently %rdeclared to return %t",
7416 unew->uname,
7417 uentry_isDeclared (old),
28bf4b0b 7418 ctype_getReturnType (unew->utype)),
616915dd 7419 uentry_whereDeclared (unew)))
7420 {
28bf4b0b 7421 uentry_showWhereLastVal (old, ctype_unparse (ctype_getReturnType (old->utype)));
616915dd 7422 }
7423}
7424
7425static cstring paramStorageName (uentry ue)
7426{
7427 return (cstring_makeLiteralTemp (uentry_isParam (ue) ? "param" : "storage"));
7428}
7429
7430static cstring fcnErrName (uentry ue)
7431{
7432 return (cstring_makeLiteralTemp (uentry_isFunction (ue) ? "to return" : "as"));
7433}
7434
7435extern /*@observer@*/ cstring uentry_checkedName (uentry ue)
7436{
7437 if (uentry_isVar (ue))
7438 {
7439 return (checkedName (ue->info->var->checked));
7440 }
7441 else
7442 {
7443 return (cstring_makeLiteralTemp ("<checked invalid>"));
7444 }
7445}
7446
7447static cstring checkedName (chkind checked)
7448{
7449 switch (checked)
7450 {
7451 case CH_UNKNOWN: return (cstring_makeLiteralTemp ("unknown"));
7452 case CH_UNCHECKED: return (cstring_makeLiteralTemp ("unchecked"));
7453 case CH_CHECKED: return (cstring_makeLiteralTemp ("checked"));
7454 case CH_CHECKMOD: return (cstring_makeLiteralTemp ("checkmod"));
7455 case CH_CHECKEDSTRICT: return (cstring_makeLiteralTemp ("checkedstrict"));
7456 }
7457 BADEXIT;
7458}
7459
7460static
7461void checkNullState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew, bool mustConform, bool completeConform)
7462{
7463 nstate oldState;
7464 nstate newState;
7465
7466 if (uentry_isVar (unew))
7467 {
7468 llassert (uentry_isVar (old));
7469
7470 oldState = old->info->var->nullstate;
7471 newState = unew->info->var->nullstate;
7472 }
7473 else
7474 {
7475 oldState = sRef_getNullState (old->sref);
7476 newState = sRef_getNullState (unew->sref);
7477 }
7478
7479 if (oldState == NS_ABSNULL)
7480 {
7481 if (uentry_isVar (old))
7482 {
7483 old->info->var->nullstate = newState;
7484 }
7485
7486 sRef_mergeNullState (old->sref, newState);
7487 }
7488 else if (newState == NS_UNKNOWN)
7489 {
7490 if (completeConform && newState != oldState
7491 && uentry_isReallySpecified (old))
7492 {
7493 if (optgenerror
7494 (FLG_NEEDSPEC,
7495 message ("%s %q specified as %s, but declared without %s qualifier",
7496 ekind_capName (unew->ukind),
7497 uentry_getName (unew),
7498 nstate_unparse (oldState),
7499 nstate_unparse (oldState)),
7500 uentry_whereDeclared (unew)))
7501 {
7502 uentry_showWhereSpecified (old);
7503 }
7504 }
7505
7506 if (uentry_isVar (unew))
7507 {
7508 unew->info->var->nullstate = oldState;
7509 }
7510
7511 sRef_mergeNullState (unew->sref, oldState);
7512 }
7513 else if (newState == NS_POSNULL)
7514 {
7515 if (oldState == NS_MNOTNULL
7516 && (ctype_isUA (unew->utype)
7517 || (uentry_isFunction (unew)
28bf4b0b 7518 && ctype_isUA (ctype_getReturnType (unew->utype)))))
616915dd 7519 {
7520 if (uentry_isVar (unew))
7521 {
7522 unew->info->var->nullstate = oldState;
7523 }
7524
7525 sRef_mergeNullState (unew->sref, oldState);
7526 }
7527 else
7528 {
7529 if (oldState == NS_NOTNULL || oldState == NS_MNOTNULL
7530 || oldState == NS_UNKNOWN)
7531 {
7532 if (mustConform)
7533 {
7534 if (optgenerror
7535 (FLG_INCONDEFS,
7536 message
7537 ("%s %q inconsistently %rdeclared %s possibly null storage, "
7538 "%s %q qualifier",
7539 uentry_ekindName (unew),
7540 uentry_getName (unew),
7541 uentry_isDeclared (old),
7542 fcnErrName (unew),
7543 uentry_specOrDefName (old),
7544 cstring_makeLiteral (oldState == NS_MNOTNULL ? "with notnull" : "without null")),
7545 uentry_whereDeclared (unew)))
7546 {
7547 uentry_showWhereSpecified (old);
7548 }
7549 }
7550 }
7551
7552 if (uentry_isVar (old))
7553 {
7554 old->info->var->nullstate = newState;
7555 }
7556
7557 sRef_mergeNullState (old->sref, newState);
7558 }
7559 }
7560 else if (newState == NS_MNOTNULL)
7561 {
7562 if (oldState != NS_MNOTNULL)
7563 {
7564 if (mustConform)
7565 {
7566 if (optgenerror
7567 (FLG_INCONDEFS,
7568 message ("%s %q inconsistently %rdeclared %s notnull storage, "
7569 "%s without notnull qualifier",
7570 uentry_ekindName (unew),
7571 uentry_getName (unew),
7572 uentry_isDeclared (old),
7573 fcnErrName (unew),
7574 uentry_specOrDefName (old)),
7575 uentry_whereDeclared (unew)))
7576 {
7577 uentry_showWhereSpecified (old);
7578 }
7579 }
7580
7581 if (uentry_isVar (old))
7582 {
7583 old->info->var->nullstate = newState;
7584 }
7585
7586 sRef_mergeNullState (old->sref, newState);
7587 }
7588 }
7589 else
7590 {
7591 if (uentry_isVar (unew))
7592 {
7593 unew->info->var->nullstate = oldState;
7594 }
7595
7596 sRef_mergeNullState (unew->sref, oldState);
7597 }
7598}
7599
7600static
7601void checkDefState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
7602 bool mustConform, bool completeConform)
7603{
7604 sstate oldState;
7605 sstate newState;
7606 bool vars = FALSE;
7607
7608 if (uentry_isVar (old) && uentry_isVar (unew))
7609 {
7610 oldState = old->info->var->defstate;
7611 newState = unew->info->var->defstate;
7612 vars = TRUE;
7613 }
7614 else
7615 {
7616 oldState = sRef_getDefState (old->sref);
7617 newState = sRef_getDefState (unew->sref);
7618 }
7619
28bf4b0b 7620 if (newState != oldState
7621 && newState != SS_UNKNOWN
7622 && newState != SS_DEFINED)
616915dd 7623 {
7624 if (mustConform)
7625 {
7626 if (optgenerror
7627 (FLG_INCONDEFS,
7628 message ("%s %q inconsistently %rdeclared %s %s %s, "
7629 "%s %s %s %s",
7630 uentry_ekindName (unew),
7631 uentry_getName (unew),
7632 uentry_isDeclared (old),
7633 fcnErrName (unew),
7634 sstate_unparse (newState),
7635 paramStorageName (unew),
7636 uentry_specOrDefName (old),
7637 fcnErrName (unew),
7638 sstate_unparse (oldState),
7639 paramStorageName (unew)),
7640 uentry_whereDeclared (unew)))
7641 {
7642 uentry_showWhereSpecified (old);
7643 }
7644 }
28bf4b0b 7645
616915dd 7646 if (vars) old->info->var->defstate = newState;
7647 sRef_setDefState (old->sref, newState, uentry_whereDeclared (unew));
7648 }
7649 else
7650 {
7651 if (completeConform
7652 && (newState != oldState) && (oldState != SS_DEFINED)
7653 && uentry_isReallySpecified (old))
7654 {
7655 if (optgenerror
7656 (FLG_NEEDSPEC,
7657 message ("%s %q specified as %s, but declared without %s qualifier",
7658 ekind_capName (unew->ukind),
7659 uentry_getName (unew),
7660 sstate_unparse (oldState),
7661 sstate_unparse (oldState)),
7662 uentry_whereDeclared (unew)))
7663 {
7664 uentry_showWhereSpecified (old);
7665 }
7666 }
28bf4b0b 7667
616915dd 7668 if (vars) unew->info->var->defstate = oldState;
7669 sRef_setDefState (unew->sref, oldState, uentry_whereDeclared (unew));
7670 }
7671}
7672
7673static void
7674 checkAliasState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
7675 bool mustConform, bool completeConform)
7676{
7677 alkind newKind;
7678 alkind oldKind;
7679
7680 oldKind = sRef_getAliasKind (old->sref);
7681 newKind = sRef_getAliasKind (unew->sref);
7682
7683 if (alkind_isImplicit (newKind)
7684 || (alkind_isRefCounted (newKind) && !uentry_isDatatype (unew)))
7685 {
7686 if (completeConform && !alkind_equal (newKind, oldKind)
7687 && uentry_isReallySpecified (old))
7688 {
7689 if (optgenerror
7690 (FLG_NEEDSPEC,
7691 message ("%s %q specified as %s, but declared without "
7692 "explicit alias qualifier",
7693 ekind_capName (unew->ukind),
7694 uentry_getName (unew),
7695 alkind_unparse (oldKind)),
7696 uentry_whereDeclared (unew)))
7697 {
7698 uentry_showWhereSpecified (old);
7699 }
7700 }
7701
7702 /*
7703 ** This really shouldn't be necessary, but it is!
7704 ** Function params (?) use new here.
7705 */
7706
7707 sRef_setAliasKind (unew->sref, oldKind, uentry_whereDeclared (unew));
7708 return;
7709 }
7710
7711 if (alkind_isKnown (newKind))
7712 {
7713 if (!alkind_equal (oldKind, newKind))
7714 {
7715 if (alkind_isKnown (oldKind))
7716 {
7717 if (mustConform &&
7718 optgenerror
7719 (FLG_INCONDEFS,
7720 message ("%s %q inconsistently %rdeclared %s %s storage, "
7721 "%s as %s storage",
7722 uentry_ekindName (unew),
7723 uentry_getName (unew),
7724 uentry_isDeclared (old),
7725 fcnErrName (unew),
7726 alkind_unparse (newKind),
7727 uentry_specOrDefName (old),
7728 alkind_unparse (oldKind)),
7729 uentry_whereDeclared (unew)))
7730 {
7731 uentry_showWhereSpecified (old);
7732
28bf4b0b 7733 DPRINTF (("Old: %s", sRef_unparseFull (old->sref)));
7734 DPRINTF (("New: %s", sRef_unparseFull (unew->sref)));
616915dd 7735 sRef_setAliasKind (old->sref, AK_ERROR,
7736 uentry_whereDeclared (unew));
7737 }
7738 else
7739 {
7740 sRef_setAliasKind (old->sref, newKind,
7741 uentry_whereDeclared (unew));
7742 }
7743 }
7744 else
7745 {
7746 if (!(alkind_isImplicit (newKind)))
7747 {
7748 if (mustConform &&
7749 !uentry_isFunction (unew) &&
7750 optgenerror
7751 (FLG_INCONDEFS,
7752 message ("%s %q inconsistently %rdeclared %s %s storage, "
7753 "implicitly %s as temp storage",
7754 uentry_ekindName (unew),
7755 uentry_getName (unew),
7756 uentry_isDeclared (old),
7757 fcnErrName (unew),
7758 alkind_unparse (newKind),
7759 uentry_specOrDefName (old)),
7760 uentry_whereDeclared (unew)))
7761 {
7762 uentry_showWhereSpecified (old);
7763 oldKind = AK_ERROR;
7764 }
7765
7766 sRef_setAliasKind (old->sref, newKind,
7767 uentry_whereDeclared (unew));
7768 }
7769 else /* newKind is temp or refcounted */
7770 {
7771 ;
7772 }
7773 }
7774 }
7775 }
7776 else /* newKind unknown */
7777 {
7778 ;
7779 }
7780}
7781
7782static void
7783 checkExpState(/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
7784 bool mustConform, bool completeConform)
7785{
7786 exkind newKind;
7787 exkind oldKind;
7788
7789 oldKind = sRef_getExKind (old->sref);
7790 newKind = sRef_getExKind (unew->sref);
7791
7792 if (exkind_isKnown (newKind))
7793 {
7794 if (oldKind != newKind)
7795 {
7796 if (exkind_isKnown (oldKind))
7797 {
7798 if (mustConform &&
7799 optgenerror
7800 (FLG_INCONDEFS,
7801 message ("%s %q inconsistently %rdeclared %s %s, %s as %s",
7802 uentry_ekindName (unew),
7803 uentry_getName (unew),
7804 uentry_isDeclared (old),
7805 fcnErrName (unew),
7806 exkind_unparse (newKind),
7807 uentry_specOrDefName (old),
7808 exkind_unparse (oldKind)),
7809 uentry_whereDeclared (unew)))
7810 {
7811 uentry_showWhereSpecified (old);
7812 }
7813
7814 sRef_setExKind (old->sref, newKind, uentry_whereDefined (unew));
7815 }
7816 else
7817 {
7818 if (mustConform &&
7819 optgenerror
7820 (FLG_INCONDEFS,
7821 message ("%s %q inconsistently %rdeclared %s %s, "
7822 "implicitly %s without exposure qualifier",
7823 uentry_ekindName (unew),
7824 uentry_getName (unew),
7825 uentry_isDeclared (old),
7826 fcnErrName (unew),
7827 exkind_unparse (newKind),
7828 uentry_specOrDefName (old)),
7829 uentry_whereDeclared (unew)))
7830 {
7831 uentry_showWhereSpecified (old);
7832 }
7833
7834 sRef_setExKind (old->sref, newKind, uentry_whereDefined (unew));
7835 }
7836 }
7837 }
7838 else
7839 {
7840 if (completeConform && exkind_isKnown (oldKind)
7841 && uentry_isReallySpecified (old))
7842 {
7843 if (optgenerror
7844 (FLG_NEEDSPEC,
7845 message ("%s %q specified as %s, but declared without "
7846 "exposure qualifier",
7847 ekind_capName (unew->ukind),
7848 uentry_getName (unew),
7849 exkind_unparse (oldKind)),
7850 uentry_whereDeclared (unew)))
7851 {
7852 uentry_showWhereSpecified (old);
7853 }
7854 }
7855
7856 /* yes, this is necessary! (if its a param) */
7857 sRef_setExKind (unew->sref, oldKind, fileloc_undefined);
7858 }
7859}
7860
28bf4b0b 7861static void
7862checkMetaState (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
7863 bool mustConform, /*@unused@*/ bool completeConform)
7864{
7865 valueTable newvals = sRef_getValueTable (unew->sref);
7866
7867 if (valueTable_isDefined (newvals))
7868 {
7869 DPRINTF (("Check meta state: %s -> %s",
7870 uentry_unparseFull (old),
7871 uentry_unparseFull (unew)));
7872
7873 DPRINTF (("Check meta state refs: %s -> %s",
7874 sRef_unparseFull (old->sref),
7875 sRef_unparseFull (unew->sref)));
7876
7877 DPRINTF (("Value table: %s", valueTable_unparse (newvals)));
7878
7879 /*
7880 ** Copy the new values into the old ref
7881 */
7882
7883 valueTable_elements (newvals, key, newval)
7884 {
7885 metaStateInfo msinfo = context_lookupMetaStateInfo (key);
7886 stateValue oldval = sRef_getMetaStateValue (old->sref, key);
7887
7888 llassert (metaStateInfo_isDefined (msinfo));
7889
7890 if (stateValue_isUndefined (oldval))
7891 {
7892 sRef_setMetaStateValue (old->sref, key, stateValue_getValue (newval), uentry_whereLast (unew));
7893 }
7894 else
7895 {
7896 if (stateValue_isError (oldval))
7897 {
7898 if (!stateValue_isError (newval))
7899 {
7900 sRef_setMetaStateValue (old->sref, key, stateValue_getValue (newval), uentry_whereLast (unew));
7901 }
7902 else
7903 {
7904 ; /* No change necessary. */
7905 }
7906 }
7907 else
7908 {
7909 if (stateValue_getValue (newval) != stateValue_getValue (oldval))
7910 {
7911 if (fileloc_isXHFile (uentry_whereDeclared (unew)))
7912 {
7913 ;
7914 }
7915 else
7916 {
ccf0a4a8 7917 if (!stateValue_isError (newval)
7918 && !stateValue_isImplicit (newval))
28bf4b0b 7919 {
ccf0a4a8 7920 if (uentry_hasName (unew)
7921 || !sRef_isParam (uentry_getSref (unew)))
7922 {
7923 if (mustConform
7924 && optgenerror
7925 (FLG_INCONDEFS,
7926 message ("%s %q inconsistently %rdeclared %s %q, %s as %q",
7927 uentry_ekindName (unew),
7928 uentry_getName (unew),
7929 uentry_isDeclared (old),
7930 fcnErrName (unew),
7931 stateValue_unparseValue (newval, msinfo),
7932 uentry_specOrDefName (old),
7933 stateValue_unparseValue (oldval, msinfo)),
7934 uentry_whereDeclared (unew)))
7935 {
7936 uentry_showWhereSpecified (old);
7937 }
7938 }
7939 else
abb1cb43 7940 {
ccf0a4a8 7941 if (mustConform
7942 && optgenerror
7943 (FLG_INCONDEFS,
7944 message ("%s %d inconsistently %rdeclared %s %q, %s as %q",
7945 uentry_ekindName (unew),
7946 sRef_getParam (uentry_getSref (unew)),
7947 uentry_isDeclared (old),
7948 fcnErrName (unew),
7949 stateValue_unparseValue (newval, msinfo),
7950 uentry_specOrDefName (old),
7951 stateValue_unparseValue (oldval, msinfo)),
7952 uentry_whereDeclared (unew)))
7953 {
7954 uentry_showWhereSpecified (old);
7955 }
abb1cb43 7956 }
28bf4b0b 7957 }
7958 }
7959
7960 DPRINTF (("Updating!"));
7961 sRef_setMetaStateValue (old->sref, key, stateValue_getValue (newval), uentry_whereLast (unew));
7962 }
7963 else
7964 {
7965 DPRINTF (("Values match"));
7966 }
7967 }
7968 }
7969 } end_valueTable_elements ;
7970 }
7971}
7972
616915dd 7973static void
7974uentry_checkStateConformance (/*@notnull@*/ uentry old,
7975 /*@notnull@*/ uentry unew,
7976 bool mustConform, bool completeConform)
7977{
7978 checkDefState (old, unew, mustConform, completeConform);
7979 checkNullState (old, unew, mustConform, completeConform);
7980 checkAliasState (old, unew, mustConform, completeConform);
7981 checkExpState (old, unew, mustConform, completeConform);
28bf4b0b 7982 checkMetaState (old, unew, mustConform, completeConform);
616915dd 7983
7984 sRef_storeState (old->sref);
7985 sRef_storeState (unew->sref);
7986}
7987
7988static void
7989checkVarConformance (uentry old, uentry unew, bool mustConform, bool completeConform)
7990{
7991 if (uentry_isElipsisMarker (old) || uentry_isElipsisMarker (unew))
7992 {
7993 return;
7994 }
7995
7996 llassert (uentry_isVar (old));
7997 llassert (uentry_isVar (unew));
7998
7999 if (cstring_isEmpty (old->uname))
8000 {
8001 cstring_free (old->uname);
8002 old->uname = cstring_copy (unew->uname);
8003 }
8004
8005 if (unew->info->var->kind == VKRETPARAM
8006 || unew->info->var->kind == VKSEFRETPARAM)
8007 {
8008 if (old->info->var->kind != VKRETPARAM
8009 && old->info->var->kind != VKSEFRETPARAM)
8010 {
8011 if (optgenerror
8012 (FLG_INCONDEFS,
8013 message ("Parameter %q inconsistently %rdeclared as "
8014 "returned parameter",
8015 uentry_getName (unew),
8016 uentry_isDeclared (old)),
8017 uentry_whereDeclared (unew)))
8018 {
8019 uentry_showWhereSpecified (old);
8020 old->info->var->kind = unew->info->var->kind;
8021 }
8022 }
8023 }
8024
8025
8026 if (unew->info->var->kind == VKSEFPARAM || unew->info->var->kind == VKSEFRETPARAM)
8027 {
8028 if (old->info->var->kind != VKSEFPARAM
8029 && old->info->var->kind != VKSEFRETPARAM)
8030 {
8031 if (optgenerror
8032 (FLG_INCONDEFS,
8033 message ("Parameter %qinconsistently %rdeclared as "
8034 "sef parameter",
8035 uentry_getOptName (unew),
8036 uentry_isDeclared (old)),
8037 uentry_whereDeclared (unew)))
8038 {
8039 uentry_showWhereSpecified (old);
8040 old->info->var->kind = unew->info->var->kind;
8041 }
8042 }
8043 }
8044
8045 if (old->info->var->kind == VKSPEC)
8046 {
8047 old->info->var->kind = unew->info->var->kind;
8048 }
8049 else
8050 {
8051 unew->info->var->kind = old->info->var->kind;
8052 }
8053
8054 if (unew->info->var->checked != CH_UNKNOWN
8055 && unew->info->var->checked != old->info->var->checked)
8056 {
8057 if (old->info->var->checked == CH_UNKNOWN
8058 && !fileloc_isUser (uentry_whereLast (old)))
8059 {
8060 ; /* no error */
8061 }
8062 else
8063 {
8064 if (optgenerror
8065 (FLG_INCONDEFS,
8066 message ("Variable %q inconsistently %rdeclared as "
8067 "%s parameter (was %s)",
8068 uentry_getName (unew),
8069 uentry_isDeclared (old),
8070 checkedName (unew->info->var->checked),
8071 checkedName (old->info->var->checked)),
8072 uentry_whereDeclared (unew)))
8073 {
8074 uentry_showWhereSpecified (old);
8075 }
8076 }
8077
8078 old->info->var->checked = unew->info->var->checked;
8079 }
8080 else
8081 {
8082 if (completeConform
8083 && (old->info->var->checked != CH_UNKNOWN)
8084 && uentry_isReallySpecified (old))
8085 {
8086 if (optgenerror
8087 (FLG_NEEDSPEC,
8088 message ("%s %q specified as %s, but declared without %s qualifier",
8089 ekind_capName (unew->ukind),
8090 uentry_getName (unew),
8091 checkedName (old->info->var->checked),
8092 checkedName (old->info->var->checked)),
8093 uentry_whereDeclared (unew)))
8094 {
8095 uentry_showWhereSpecified (old);
8096 }
8097 }
8098
8099 unew->info->var->checked = old->info->var->checked;
8100 }
8101
8102 uentry_checkStateConformance (old, unew, mustConform, completeConform);
8103}
8104
8105void uentry_checkMatchParam (uentry u1, uentry u2, int paramno, exprNode e)
8106{
8107 if (uentry_isElipsisMarker (u1) || uentry_isElipsisMarker (u2))
8108 {
8109 return;
8110 }
8111
8112 llassert (uentry_isVar (u1));
8113 llassert (uentry_isVar (u2));
8114
8115 if (u1->info->var->kind != u2->info->var->kind) {
8116 if (u1->info->var->kind == VKSEFRETPARAM) {
8117 if (u2->info->var->kind == VKRETPARAM) {
8118 voptgenerror
8119 (FLG_TYPE,
8120 message ("Function types are inconsistent. Parameter %d is "
8121 "sef parameter, but non-sef parameter in "
8122 "assigned function: %s",
8123 paramno, exprNode_unparse (e)),
8124 exprNode_loc (e));
8125 } else if (u2->info->var->kind == VKSEFPARAM) {
8126 voptgenerror
8127 (FLG_TYPE,
8128 message ("Function types are inconsistent. Parameter %d is "
8129 "returns parameter, but non-returns parameter in "
8130 "assigned function: %s",
8131 paramno, exprNode_unparse (e)),
8132 exprNode_loc (e));
8133 } else {
8134 voptgenerror
8135 (FLG_TYPE,
8136 message ("Function types are inconsistent. Parameter %d is "
8137 "sef returns parameter, but non-sef returns parameter in "
8138 "assigned function: %s",
8139 paramno, exprNode_unparse (e)),
8140 exprNode_loc (e));
8141 }
8142 } else if (u1->info->var->kind == VKRETPARAM) {
8143 voptgenerror
8144 (FLG_TYPE,
8145 message ("Function types are inconsistent. Parameter %d is "
8146 "returns parameter, but non-returns parameter in "
8147 "assigned function: %s",
8148 paramno, exprNode_unparse (e)),
8149 exprNode_loc (e));
8150 } else if (u1->info->var->kind == VKSEFPARAM) {
8151 voptgenerror
8152 (FLG_TYPE,
8153 message ("Function types are inconsistent. Parameter %d is "
8154 "sef parameter, but non-sef parameter in "
8155 "assigned function: %s",
8156 paramno, exprNode_unparse (e)),
8157 exprNode_loc (e));
8158 } else {
8159 if (u2->info->var->kind == VKSEFRETPARAM) {
8160 voptgenerror
8161 (FLG_TYPE,
8162 message ("Function types are inconsistent. Parameter %d is "
8163 "normal parameter, but sef returns parameter in "
8164 "assigned function: %s",
8165 paramno, exprNode_unparse (e)),
8166 exprNode_loc (e));
8167 } else if (u2->info->var->kind == VKSEFPARAM) {
8168 voptgenerror
8169 (FLG_TYPE,
8170 message ("Function types are inconsistent. Parameter %d is "
8171 "normal parameter, but sef parameter in "
8172 "assigned function: %s",
8173 paramno, exprNode_unparse (e)),
8174 exprNode_loc (e));
8175 } else if (u2->info->var->kind == VKRETPARAM) {
8176 voptgenerror
8177 (FLG_TYPE,
8178 message ("Function types are inconsistent. Parameter %d is "
8179 "normal parameter, but returns parameter in "
8180 "assigned function: %s",
8181 paramno, exprNode_unparse (e)),
8182 exprNode_loc (e));
8183 } else {
8184 BADBRANCH;
8185 }
8186 }
8187 }
8188
8189 if (u1->info->var->defstate != u2->info->var->defstate)
8190 {
8191 voptgenerror
8192 (FLG_TYPE,
8193 message ("Function types are inconsistent. Parameter %d is "
8194 "%s, but %s in assigned function: %s",
8195 paramno,
8196 sstate_unparse (u1->info->var->defstate),
8197 sstate_unparse (u2->info->var->defstate),
8198 exprNode_unparse (e)),
8199 exprNode_loc (e));
8200 }
8201
8202 if (u1->info->var->nullstate != u2->info->var->nullstate)
8203 {
8204 voptgenerror
8205 (FLG_TYPE,
8206 message ("Function types are inconsistent. Parameter %d is "
8207 "%s, but %s in assigned function: %s",
8208 paramno,
8209 nstate_unparse (u1->info->var->nullstate),
8210 nstate_unparse (u2->info->var->nullstate),
8211 exprNode_unparse (e)),
8212 exprNode_loc (e));
8213 }
8214
8215 if (sRef_getAliasKind (u1->sref) != sRef_getAliasKind (u2->sref))
8216 {
8217 voptgenerror
8218 (FLG_TYPE,
8219 message ("Function types are inconsistent. Parameter %d is "
8220 "%s, but %s in assigned function: %s",
8221 paramno,
8222 alkind_unparse (sRef_getAliasKind (u1->sref)),
8223 alkind_unparse (sRef_getAliasKind (u2->sref)),
8224 exprNode_unparse (e)),
8225 exprNode_loc (e));
8226 }
8227
8228 if (sRef_getExKind (u1->sref) != sRef_getExKind (u2->sref))
8229 {
8230 voptgenerror
8231 (FLG_TYPE,
8232 message ("Function types are inconsistent. Parameter %d is "
8233 "%s, but %s in assigned function: %s",
8234 paramno,
8235 exkind_unparse (sRef_getExKind (u1->sref)),
8236 exkind_unparse (sRef_getExKind (u2->sref)),
8237 exprNode_unparse (e)),
8238 exprNode_loc (e));
8239 }
8240}
8241
8242static void
8243checkFunctionConformance (/*@unique@*/ /*@notnull@*/ uentry old,
8244 /*@notnull@*/ uentry unew,
8245 bool mustConform, /*@unused@*/ bool completeConform)
8246{
8247 uentryList oldParams = uentry_getParams (old);
8248 uentryList newParams = uentry_getParams (unew);
8249 ctype newType = unew->utype;
ac35a6ab 8250 ctype oldType = ctype_realType (old->utype);
616915dd 8251 ctype oldRetType = ctype_unknown;
8252 ctype newRetType = ctype_unknown;
8253
28bf4b0b 8254 DPRINTF (("Function conform: %s ==> %s",
8255 uentry_unparseFull (old),
8256 uentry_unparseFull (unew)));
8257
616915dd 8258 if (uentry_isForward (old))
8259 {
8260 mustConform = FALSE;
efd360a3 8261 uentry_updateInto (old, unew);
616915dd 8262 return;
8263 }
8264
8265 /*
8266 ** check return values
8267 */
8268
8269 if (ctype_isKnown (oldType))
8270 {
8271 llassert (ctype_isFunction (oldType));
28bf4b0b 8272 oldRetType = ctype_getReturnType (oldType);
616915dd 8273 }
8274
8275 if (ctype_isKnown (newType))
8276 {
8277 llassert (ctype_isFunction (newType));
28bf4b0b 8278 newRetType = ctype_getReturnType (newType);
616915dd 8279 }
8280
8281 if (ctype_isKnown (oldRetType) && ctype_isKnown (newRetType)
8282 && !ctype_matchDef (newRetType, oldRetType))
8283 {
8284 if (mustConform) returnValueError (old, unew);
8285 }
8286 else
8287 {
8288 if (ctype_isConj (newRetType))
8289 {
8290 if (ctype_isConj (oldRetType))
8291 {
8292 if (!ctype_sameAltTypes (newRetType, oldRetType))
8293 {
8294 if (optgenerror
8295 (FLG_INCONDEFS,
8296 message ("Function %q inconsistently %rdeclared to "
8297 "return alternate types %s "
8298 "(types match, but alternates are not identical, "
8299 "so checking may not be correct)",
8300 uentry_getName (unew),
8301 uentry_isDeclared (old),
8302 ctype_unparse (newRetType)),
8303 uentry_whereDeclared (unew)))
8304 {
8305 uentry_showWhereLastVal (old, ctype_unparse (oldRetType));
8306 }
8307 }
8308 }
8309 else
8310 {
8311 old->utype = ctype_makeFunction (oldRetType, uentryList_copy (newParams));
8312 }
8313 }
8314 }
8315
28bf4b0b 8316 DPRINTF (("Before state: %s",
8317 uentry_unparseFull (old)));
616915dd 8318 uentry_checkStateConformance (old, unew, mustConform, completeConform);
28bf4b0b 8319 DPRINTF (("After state: %s",
8320 uentry_unparseFull (old)));
616915dd 8321
8322 if (!exitkind_equal (unew->info->fcn->exitCode, old->info->fcn->exitCode))
8323 {
8324 if (exitkind_isKnown (unew->info->fcn->exitCode))
8325 {
8326 if (optgenerror
8327 (FLG_INCONDEFS,
8328 message ("Function %q inconsistently %rdeclared using %s",
8329 uentry_getName (unew),
8330 uentry_isDeclared (old),
8331 exitkind_unparse (unew->info->fcn->exitCode)),
8332 uentry_whereDeclared (unew)))
8333 {
8334 uentry_showWhereSpecified (old);
8335 }
8336 }
8337 else
8338 {
8339 unew->info->fcn->exitCode = old->info->fcn->exitCode;
8340 }
8341 }
8342
8343 if (!qual_isUnknown (unew->info->fcn->nullPred))
8344 {
28bf4b0b 8345 if (!qual_match (old->info->fcn->nullPred, unew->info->fcn->nullPred))
616915dd 8346 {
8347 if (optgenerror
8348 (FLG_INCONDEFS,
8349 message ("Function %q inconsistently %rdeclared using %s",
8350 uentry_getName (unew),
8351 uentry_isDeclared (old),
8352 qual_unparse (unew->info->fcn->nullPred)),
8353 uentry_whereDeclared (unew)))
8354 {
8355 uentry_showWhereSpecified (old);
8356 }
8357 }
8358 }
8359 else
8360 {
8361 unew->info->fcn->nullPred = old->info->fcn->nullPred;
8362 }
8363
8364 if (unew->info->fcn->specialCode != SPC_NONE)
8365 {
8366 if (old->info->fcn->specialCode != unew->info->fcn->specialCode)
8367 {
8368 if (optgenerror
8369 (FLG_INCONDEFS,
8370 message ("Function %q inconsistently %rdeclared using %s",
8371 uentry_getName (unew),
8372 uentry_isDeclared (old),
8373 specCode_unparse (unew->info->fcn->specialCode)),
8374 uentry_whereDeclared (unew)))
8375 {
8376 uentry_showWhereSpecified (old);
8377 }
8378 }
8379 }
8380 else
8381 {
8382 unew->info->fcn->specialCode = old->info->fcn->specialCode;
8383 }
8384
8385 /*
8386 ** check parameters
8387 */
8388
8389 if (!uentryList_sameObject (oldParams, newParams)
8390 && (!uentryList_isMissingParams (oldParams)))
8391 {
8392 if (!uentryList_isMissingParams (newParams))
8393 {
8394 int paramno = 0;
8395 int nparams = uentryList_size (oldParams);
8396 bool checknames = context_maybeSet (FLG_DECLPARAMMATCH);
8397
8398 if (nparams != uentryList_size (newParams))
8399 {
8400 nargsError (old, unew);
8401 }
8402
8403 if (uentryList_size (newParams) < nparams)
8404 {
8405 nparams = uentryList_size (newParams);
8406 }
8407
8408 while (paramno < nparams)
8409 {
8410 uentry oldCurrent = uentryList_getN (oldParams, paramno);
8411 uentry newCurrent = uentryList_getN (newParams, paramno);
8412 ctype oldCurrentType = uentry_getType (oldCurrent);
8413 ctype newCurrentType = uentry_getType (newCurrent);
8414
8415 llassert (uentry_isValid (oldCurrent)
8416 && uentry_isValid (newCurrent));
8417
8418 if (!uentry_isElipsisMarker (oldCurrent)
8419 && !uentry_isElipsisMarker (newCurrent))
8420 {
8421 checkVarConformance (oldCurrent, newCurrent,
8422 mustConform, completeConform);
8423 }
8424
8425 if (checknames)
8426 {
8427 if (uentry_hasName (oldCurrent)
8428 && uentry_hasName (newCurrent))
8429 {
8430 cstring oldname = uentry_getName (oldCurrent);
8431 cstring pfx = context_getString (FLG_DECLPARAMPREFIX);
8432 cstring oname;
8433 cstring nname = uentry_getName (newCurrent);
8434 cstring nnamefix;
8435
8436 if (cstring_isDefined (pfx)
68de3f33 8437 && cstring_equalPrefix (oldname, pfx))
616915dd 8438 {
8439 oname = cstring_suffix (oldname, cstring_length (pfx));
8440 }
8441 else
8442 {
8443 oname = oldname;
8444 /*@-branchstate@*/ } /*@=branchstate@*/
8445
8446 if (cstring_isDefined (pfx)
68de3f33 8447 && cstring_equalPrefix (nname, pfx))
616915dd 8448 {
8449 nnamefix = cstring_suffix (nname, cstring_length (pfx));
8450 }
8451 else
8452 {
8453 nnamefix = nname;
8454 /*@-branchstate@*/ } /*@=branchstate@*/
8455
8456 if (!cstring_equal (oname, nnamefix))
8457 {
8458 if (optgenerror
8459 (FLG_DECLPARAMMATCH,
8460 message ("Definition parameter name %s does not match "
8461 "name of corresponding parameter in "
8462 "declaration: %s",
8463 nnamefix, oname),
8464 uentry_whereLast (newCurrent)))
8465 {
8466 uentry_showWhereLastPlain (oldCurrent);
8467 }
8468 }
8469
8470 cstring_free (oldname);
8471 cstring_free (nname);
8472 }
8473 }
8474
8475 if (!ctype_match (oldCurrentType, newCurrentType))
8476 {
8477 paramTypeError (old, oldCurrent, oldCurrentType,
8478 unew, newCurrent, newCurrentType, paramno);
8479 }
8480 else
8481 {
8482 if (ctype_isMissingParamsMarker (newCurrentType)
8483 || ctype_isElips (newCurrentType)
8484 || ctype_isMissingParamsMarker (oldCurrentType)
8485 || ctype_isElips (oldCurrentType))
8486 {
8487 ;
8488 }
8489 else
8490 {
8491 if (ctype_isConj (newCurrentType))
8492 {
8493 if (ctype_isConj (oldCurrentType))
8494 {
8495 if (!ctype_sameAltTypes (newCurrentType, oldCurrentType))
8496 {
8497 if (optgenerror
8498 (FLG_INCONDEFS,
8499 message ("Parameter %q inconsistently %rdeclared with "
8500 "alternate types %s "
8501 "(types match, but alternates are not identical, "
8502 "so checking may not be correct)",
8503 uentry_getName (newCurrent),
8504 uentry_isDeclared (oldCurrent),
8505 ctype_unparse (newCurrentType)),
8506 uentry_whereDeclared (unew)))
8507 {
8508 uentry_showWhereLastVal (oldCurrent,
8509 ctype_unparse (oldCurrentType));
8510 }
8511 }
8512 }
8513 else
8514 {
8515 if (optgenerror
8516 (FLG_INCONDEFS,
8517 message ("Parameter %q inconsistently %rdeclared with "
8518 "alternate types %s",
8519 uentry_getName (newCurrent),
8520 uentry_isDeclared (oldCurrent),
8521 ctype_unparse (newCurrentType)),
8522 uentry_whereDeclared (unew)))
8523 {
8524 uentry_showWhereLastVal (oldCurrent,
8525 ctype_unparse (oldCurrentType));
8526
8527 }
8528 }
8529 }
8530 else
8531 {
8532 if (ctype_isConj (oldCurrentType))
8533 {
8534 uentry_setType (newCurrent, oldCurrentType);
8535 }
8536 }
8537 }
8538 }
8539
8540 paramno++;
8541 /*
1b8ae690 8542 ** Forgot this! detected by splint:
616915dd 8543 ** uentry.c:1257,15: Suspected infinite loop
8544 */
8545 }
8546 }
8547 }
8548
8549 if (!uentryList_isMissingParams (newParams))
8550 {
8551 if (ctype_isConj (oldRetType))
8552 {
8553 old->utype = ctype_makeFunction (oldRetType,
8554 uentryList_copy (newParams));
8555 }
8556 else
8557 {
8558 old->utype = unew->utype;
8559 }
8560 }
8561
8562 checkGlobalsConformance (old, unew, mustConform, completeConform);
8563 checkModifiesConformance (old, unew, mustConform, completeConform);
8564
28bf4b0b 8565 DPRINTF (("Before list: %s",
8566 uentry_unparseFull (old)));
8567
8568 if (stateClauseList_isDefined (unew->info->fcn->specclauses))
616915dd 8569 {
28bf4b0b 8570 if (!stateClauseList_isDefined (old->info->fcn->specclauses))
616915dd 8571 {
28bf4b0b 8572 /*
616915dd 8573 if (optgenerror
8574 (FLG_INCONDEFS,
8575 message ("Function %q redeclared using special clauses (can only "
8576 "be used in first declaration)",
8577 uentry_getName (unew)),
8578 uentry_whereDeclared (unew)))
8579 {
8580 uentry_showWhereLast (old);
8581 }
28bf4b0b 8582 */
8583
8584 /*@i23 need checking @*/
8585
8586 old->info->fcn->specclauses = unew->info->fcn->specclauses;
616915dd 8587 }
8588 else
8589 {
28bf4b0b 8590 /*@i43 should be able to append? @*/
8591
8592 stateClauseList_checkEqual (old, unew);
8593 stateClauseList_free (unew->info->fcn->specclauses);
8594 unew->info->fcn->specclauses = stateClauseList_undefined;
8595 /*@-branchstate@*/
616915dd 8596 }
8597 }
146e25eb 8598 /*@=branchstate@*/ /*@i23 shouldn't need this@*/
616915dd 8599
8600 if (fileloc_isUndefined (old->whereDeclared))
8601 {
8602 old->whereDeclared = fileloc_copy (unew->whereDeclared);
8603 }
8604 else if (fileloc_isUndefined (unew->whereDeclared))
8605 {
8606 unew->whereDeclared = fileloc_copy (old->whereDeclared);
8607 }
8608 else
8609 {
8610 /* no change */
8611 }
146e25eb 8612/*@i523 @*/ }
616915dd 8613
8614void
8615uentry_mergeConstantValue (uentry ue, /*@only@*/ multiVal m)
8616{
8617 multiVal uval;
8618
8619 llassert (uentry_isValid (ue));
8620 llassert (uentry_isEitherConstant (ue));
8621
b9904f57 8622 DPRINTF (("Constant value: %s / %s", uentry_unparse (ue), multiVal_unparse (m)));
8623 uval = uentry_getConstantValue (ue);
616915dd 8624
8625 if (multiVal_isDefined (uval))
8626 {
8627 if (multiVal_isDefined (m))
8628 {
8629 if (!multiVal_equiv (uval, m))
8630 {
8631 if (optgenerror
8632 (FLG_INCONDEFS,
8633 message ("%s %q defined with inconsistent value: %q",
8634 ekind_capName (ue->ukind),
8635 uentry_getName (ue),
8636 multiVal_unparse (m)),
8637 g_currentloc))
8638 {
8639 uentry_showWhereLastExtra (ue, multiVal_unparse (uval));
8640 }
8641 }
8642 }
8643 multiVal_free (m);
8644 }
8645 else
8646 {
b9904f57 8647 uentry_setConstantValue (ue, m);
616915dd 8648 }
8649}
8650
8651static
8652bool checkTypeConformance (/*@notnull@*/ uentry old, /*@notnull@*/ uentry unew,
8653 bool mustConform)
8654{
8655 bool typeError = FALSE;
8656
8657 if (uentry_isStructTag (old) || uentry_isUnionTag (old))
8658 {
8659 if (ctype_isSU (old->utype) && ctype_isSU (unew->utype))
8660 {
8661 if (mustConform)
8662 {
28bf4b0b 8663 DPRINTF (("Check struct conformance: %s / %s",
8664 uentry_unparseFull (old),
8665 uentry_unparseFull (unew)));
616915dd 8666 checkStructConformance (old, unew);
8667 }
8668 }
8669 else
8670 {
8671 if (!(ctype_isBogus (old->utype) || ctype_isBogus (unew->utype)))
8672 {
8673 llbug (message ("struct tags: bad types: %t / %t",
8674 old->utype, unew->utype));
8675 }
8676 }
8677 }
8678 else if (uentry_isEnumTag (old))
8679 {
8680 if (ctype_isEnum (old->utype) && ctype_isEnum (unew->utype))
8681 {
8682 if (mustConform) checkEnumConformance (old, unew);
8683 }
8684 else
8685 {
8686 if (!(ctype_isBogus (old->utype) || ctype_isBogus (unew->utype)))
8687 {
8688 llbug (message ("enum! bad type: %s / %s", ctype_unparse (old->utype),
8689 ctype_unparse (unew->utype)));
8690 }
8691 }
8692 }
8693 else if (!ctype_match (old->utype, unew->utype))
8694 {
28bf4b0b 8695 DPRINTF (("Type mismatch: %s / %s",
8696 ctype_unparse (old->utype),
8697 ctype_unparse (unew->utype)));
8698
616915dd 8699 if (cstring_equal (uentry_rawName (old), context_getBoolName ()))
8700 {
8701 ctype realt = ctype_realType (unew->utype);
8702
8703 if (ctype_isRealInt (realt) || ctype_isChar (realt))
8704 {
8705 unew->utype = ctype_bool;
8706 }
8707 else
8708 {
8709 if (mustConform)
8710 {
8711 typeError = optgenerror
8712 (FLG_INCONDEFS,
8713 message ("%q defined as %s", uentry_getName (old),
8714 ctype_unparse (realt)),
8715 uentry_whereDeclared (unew));
8716 }
8717 }
8718 }
8719 else
8720 {
8721 if (mustConform)
8722 {
8723 ctype oldr = ctype_realType (old->utype);
8724 ctype newr = ctype_realType (unew->utype);
8725
8726 if (ctype_isStruct (oldr) && ctype_isStruct (newr))
8727 {
8728 checkStructConformance (old, unew);
8729 }
8730 else if (ctype_isUnion (oldr) && ctype_isUnion (newr))
8731 {
8732 checkStructConformance (old, unew);
8733 }
8734 else if (ctype_isEnum (oldr) && ctype_isEnum (newr))
8735 {
8736 checkEnumConformance (old, unew);
8737 }
8738 else if (uentry_isConstant (old)
8739 && (ctype_isAbstract (oldr) && ctype_isEnum (newr)))
8740 {
8741 /* okay...for now! (should check the type is reset later... */
8742 }
8743 else
8744 {
8745 DPRINTF (("YABA!"));
8746 if (optgenerror
8747 (FLG_INCONDEFS,
8748 message ("%s %q %rdeclared with inconsistent type: %t",
8749 ekind_capName (unew->ukind),
8750 uentry_getName (unew),
8751 uentry_isDeclared (old),
8752 unew->utype),
8753 uentry_whereDeclared (unew)))
8754 {
8755 uentry_showWhereLast (old);
8756 typeError = TRUE;
8757 }
8758 }
8759 }
8760 }
8761 }
8762 else
8763 {
8764 /* no error */
8765 }
8766
8767 return typeError;
8768}
8769
8770static void
8771uentry_checkDatatypeConformance (/*@notnull@*/ uentry old,
8772 /*@notnull@*/ uentry unew,
8773 bool mustConform, bool completeConform)
8774{
8775 if (ctype_isDefined (unew->info->datatype->type))
8776 {
8777 /*
8778 ** bool is hard coded here, since it is built into LCL.
8779 ** For now, we're stuck with LCL's types.
8780 */
8781
8782 if (ctype_isDirectBool (old->utype) &&
8783 cstring_equalLit (unew->uname, "bool"))
8784 {
8785 /* if (!context_getFlag (FLG_ABSTRACTBOOL))
8786 evs 2000-07-25: removed
8787 */
8788 unew->utype = ctype_bool;
8789 }
8790
8791 if (ctype_isUnknown (old->info->datatype->type))
8792 {
8793 old->info->datatype->type = unew->info->datatype->type;
8794 }
8795 else
8796 {
8797 DPRINTF (("Old: %s / New: %s",
8798 uentry_unparseFull (old),
8799 uentry_unparseFull (unew)));
8800 DPRINTF (("Types: %s / %s",
8801 ctype_unparse (old->info->datatype->type),
8802 ctype_unparse (unew->info->datatype->type)));
8803
8804 if (ctype_matchDef (old->info->datatype->type,
8805 unew->info->datatype->type))
8806 {
8807 ;
8808 }
8809 else
8810 {
8811 if (optgenerror
8812 (FLG_INCONDEFS,
8813 message
8814 ("Type %q %s with inconsistent type: %t",
8815 uentry_getName (unew),
8816 uentry_reDefDecl (old, unew),
8817 unew->info->datatype->type),
8818 uentry_whereDeclared (unew)))
8819 {
8820 uentry_showWhereLastExtra
8821 (old, cstring_copy (ctype_unparse (old->info->datatype->type)));
8822 }
8823
8824 old->info->datatype->type = unew->info->datatype->type;
8825 }
8826 }
8827 }
8828
8829 if (unew->info->datatype->abs != MAYBE)
8830 {
8831 if (ynm_isOff (old->info->datatype->abs)
8832 && ynm_isOn (unew->info->datatype->abs))
8833 {
8834 if (!ctype_isDirectBool (old->utype))
8835 {
8836 if (optgenerror
8837 (FLG_INCONDEFS,
8838 message
8839 ("Datatype %q inconsistently %rdeclared as abstract type",
8840 uentry_getName (unew),
8841 uentry_isDeclared (old)),
8842 uentry_whereDeclared (unew)))
8843 {
8844 uentry_showWhereLastPlain (old);
8845 }
8846 }
8847 }
8848 else if (ynm_isOn (old->info->datatype->abs)
8849 && ynm_isOff (unew->info->datatype->abs))
8850 {
8851 if (!ctype_isDirectBool (old->utype))
8852 {
8853 if (optgenerror
8854 (FLG_INCONDEFS,
8855 message
8856 ("Datatype %q inconsistently %rdeclared as concrete type",
8857 uentry_getName (unew),
8858 uentry_isDeclared (old)),
8859 uentry_whereDeclared (unew)))
8860 {
8861 uentry_showWhereLastPlain (old);
8862 }
8863 }
8864 }
8865 else
8866 {
8867 ;
8868 }
8869 }
8870 else
8871 {
8872 if (ynm_isOn (old->info->datatype->abs))
8873 {
8874 old->sref = unew->sref;
8875 unew->info->datatype->mut = old->info->datatype->mut;
8876
8877 if (completeConform
8878 && uentry_isReallySpecified (old))
8879 {
8880 if (optgenerror
8881 (FLG_NEEDSPEC,
8882 message
8883 ("Datatype %q specified as abstract, "
8884 "but abstract annotation not used in declaration",
8885 uentry_getName (unew)),
8886 uentry_whereDeclared (unew)))
8887 {
8888 uentry_showWhereLastPlain (old);
8889 }
8890 }
8891 }
8892 }
8893
8894 unew->info->datatype->abs = old->info->datatype->abs;
8895
8896 if (ynm_isMaybe (unew->info->datatype->mut))
8897 {
8898 if (completeConform && ynm_isOff (old->info->datatype->mut)
8899 && uentry_isReallySpecified (old))
8900 {
8901 if (optgenerror
8902 (FLG_NEEDSPEC,
8903 message
8904 ("Datatype %q specified as immutable, "
8905 "but immutable annotation not used in declaration",
8906 uentry_getName (unew)),
8907 uentry_whereDeclared (unew)))
8908 {
8909 uentry_showWhereLastPlain (old);
8910 }
8911 }
8912
8913 unew->info->datatype->mut = old->info->datatype->mut;
8914 }
8915 else if (ynm_isMaybe (old->info->datatype->mut))
8916 {
8917 old->info->datatype->mut = unew->info->datatype->mut;
8918 }
8919 else
8920 {
8921 if (ynm_isOn (old->info->datatype->abs))
8922 {
8923 if (ynm_isOn (old->info->datatype->mut) && ynm_isOff (unew->info->datatype->mut))
8924 {
8925 if (optgenerror
8926 (FLG_INCONDEFS,
8927 message ("Datatype %q inconsistently %rdeclared as immutable",
8928 uentry_getName (unew),
8929 uentry_isDeclared (old)),
8930 uentry_whereDeclared (unew)))
8931 {
8932 uentry_showWhereLastPlain (old);
8933 }
8934 }
8935 else
8936 {
8937 if (ynm_isOff (old->info->datatype->mut)
8938 && ynm_isOn (unew->info->datatype->mut))
8939 {
8940 if (optgenerror
8941 (FLG_INCONDEFS,
8942 message ("Datatype %q inconsistently %rdeclared as mutable",
8943 uentry_getName (unew),
8944 uentry_isDeclared (old)),
8945 uentry_whereDeclared (unew)))
8946 {
8947 uentry_showWhereLastPlain (old);
8948 }
8949 }
8950 }
8951 }
8952 old->info->datatype->mut = unew->info->datatype->mut;
8953 }
8954
8955 uentry_checkStateConformance (old, unew, mustConform, completeConform);
8956}
8957
8958static void
8959uentry_checkConstantConformance (/*@notnull@*/ uentry old,
8960 /*@notnull@*/ uentry unew,
8961 bool mustConform,
8962 /*@unused@*/ bool completeConform)
8963{
b9904f57 8964 multiVal oldval = uentry_getConstantValue (old);
8965 multiVal newval = uentry_getConstantValue (unew);
616915dd 8966
b9904f57 8967 if (multiVal_isDefined (oldval))
616915dd 8968 {
b9904f57 8969 if (multiVal_isDefined (newval))
616915dd 8970 {
b9904f57 8971 if (!multiVal_equiv (oldval, newval))
616915dd 8972 {
8973 if (mustConform
8974 && optgenerror
8975 (FLG_INCONDEFS,
8976 message ("%s %q %rdeclared with inconsistent value: %q",
8977 ekind_capName (unew->ukind),
8978 uentry_getName (unew),
8979 uentry_isDeclared (old),
b9904f57 8980 multiVal_unparse (newval)),
616915dd 8981 uentry_whereDeclared (unew)))
8982 {
b9904f57 8983 uentry_showWhereLastExtra (old, multiVal_unparse (oldval));
616915dd 8984 }
8985 }
8986
b9904f57 8987 uentry_setConstantValue (unew, multiVal_copy (oldval));
616915dd 8988 }
8989 else
8990 {
8991 ;
8992 }
8993 }
8994 else
8995 {
b9904f57 8996 uentry_setConstantValue (old, multiVal_copy (newval));
616915dd 8997 }
8998}
8999
9000static void
9001uentry_checkConformance (/*@unique@*/ /*@notnull@*/ uentry old,
9002 /*@notnull@*/ uentry unew, bool mustConform,
9003 bool completeConform)
9004{
9005 bool typeError = FALSE;
9006 bool fcnConformance = FALSE;
9007
9008 if (!ekind_equal (unew->ukind, old->ukind))
9009 {
9010 /*
9011 ** okay, only if one is a function and the other is
9012 ** a variable of type function.
9013 */
9014
9015 if (unew->ukind == KENUMCONST
9016 && old->ukind == KCONST)
9017 {
9018 old->ukind = KENUMCONST;
9019 goto nokinderror;
9020 }
9021
9022 if (unew->ukind == KFCN
9023 && old->ukind == KCONST
9024 && ctype_isUnknown (old->utype))
9025 {
9026 /*
9027 ** When a function is defined with an unparam macro
9028 */
9029
efd360a3 9030 uentry_updateInto (old, unew);
616915dd 9031 return;
9032 }
9033
9034 if (uentry_isExpandedMacro (old)
9035 && uentry_isEitherConstant (unew))
9036 {
efd360a3 9037 uentry_updateInto (old, unew);
616915dd 9038 return;
9039 }
9040
9041 if (uentry_isEndIter (unew))
9042 {
9043 if (ctype_isUnknown (old->utype))
9044 {
9045 if (!uentry_isSpecified (old)
9046 && uentry_isCodeDefined (unew))
9047 {
9048 if (!fileloc_withinLines (uentry_whereDefined (old),
9049 uentry_whereDeclared (unew), 2))
9050 { /* bogus! will give errors if there is too much whitespace */
9051 voptgenerror
9052 (FLG_SYNTAX,
9053 message
9054 ("Iterator finalized name %q does not match name in "
9055 "previous iter declaration (should be end_%q). This iter "
9056 "is declared at %q",
9057 uentry_getName (unew),
9058 uentry_getName (old),
9059 fileloc_unparse (uentry_whereDefined (old))),
9060 uentry_whereDeclared (old));
9061 }
9062 }
9063
efd360a3 9064 uentry_updateInto (old, unew);
616915dd 9065 return;
9066 }
9067 else
9068 {
9069 KindConformanceError (old, unew, mustConform);
9070 }
9071 }
9072
9073 if (uentry_isFunction (unew))
9074 {
9075 if (uentry_isVariable (old))
9076 {
9077 if (!ctype_isUnknown (old->utype))
9078 {
9079 if (ctype_isFunction (old->utype))
9080 {
9081 uentry_makeVarFunction (old);
9082 checkFunctionConformance (old, unew, mustConform,
9083 completeConform);
9084 fcnConformance = TRUE;
9085 }
9086 else
9087 {
9088 KindConformanceError (old, unew, mustConform);
9089 }
9090 }
9091 else
9092 {
9093 if (uentry_isExpandedMacro (old))
9094 {
9095 if (fileloc_isUndefined (unew->whereDefined))
9096 {
9097 unew->whereDefined = fileloc_update (unew->whereDefined,
9098 old->whereDefined);
9099 }
9100
efd360a3 9101 uentry_updateInto (old, unew);
616915dd 9102 old->used = unew->used = TRUE;
9103 return;
9104 }
9105 else
9106 {
9107 /* undeclared identifier */
9108 old->utype = unew->utype;
9109 uentry_makeVarFunction (old);
9110 checkFunctionConformance (old, unew, FALSE, FALSE);
9111 fcnConformance = TRUE;
9112 }
9113 }
9114 }
9115 else
9116 {
9117 KindConformanceError (old, unew, mustConform);
9118 }
9119 }
9120 else if (uentry_isFunction (old) && uentry_isVariable (unew))
9121 {
9122 if (!ctype_isUnknown (unew->utype))
9123 {
9124 if (ctype_isFunction (unew->utype))
9125 {
9126 uentry_makeVarFunction (unew);
9127 checkFunctionConformance (old, unew, mustConform, completeConform);
9128 fcnConformance = TRUE;
9129 }
9130 else
9131 {
9132 KindConformanceError (old, unew, mustConform);
9133 }
9134 }
9135 else
9136 {
9137 KindConformanceError (old, unew, mustConform);
9138 }
9139 }
9140 else
9141 {
9142 KindConformanceError (old, unew, mustConform);
9143 }
9144 }
9145 else
9146 {
9147 /*
9148 ** check parameter lists for functions
9149 ** (before type errors, to get better messages
9150 */
9151
9152 if (uentry_isFunction (old))
9153 {
9154 checkFunctionConformance (old, unew, mustConform, completeConform);
9155 fcnConformance = TRUE;
9156 }
9157 else
9158 {
9159 if (!ctype_isUndefined (old->utype))
9160 {
9161 typeError = checkTypeConformance (old, unew, mustConform);
9162 }
9163 }
9164 }
9165
9166 nokinderror:
9167
9168 if (uentry_isEitherConstant (old) && uentry_isEitherConstant (unew))
9169 {
9170 uentry_checkConstantConformance (old, unew, mustConform, completeConform);
9171 }
9172
9173 if (uentry_isDatatype (old) && uentry_isDatatype (unew))
9174 {
9175 DPRINTF (("Check datatype: %s / %s",
9176 uentry_unparseFull (old),
9177 uentry_unparseFull (unew)));
9178
9179 uentry_checkDatatypeConformance (old, unew, mustConform, completeConform);
9180 }
9181
9182 if (uentry_isVariable (old) && uentry_isVariable (unew))
9183 {
9184 if (!typeError &&
9185 !ctype_matchDef (old->utype, unew->utype))
9186 {
9187 if (optgenerror
9188 (FLG_INCONDEFS,
9189 message
9190 ("Variable %q %s with inconsistent type (arrays and pointers are "
9191 "not identical in variable declarations): %t",
9192 uentry_getName (unew),
9193 uentry_reDefDecl (old, unew),
9194 unew->utype),
9195 uentry_whereDeclared (unew)))
9196 {
9197 uentry_showWhereLast (old);
9198
9199 /*
9200 ** Avoid repeated errors.
9201 */
9202
9203 if (uentry_isCodeDefined (old) && uentry_isCodeDefined (unew))
9204 {
9205 old->whereDefined = fileloc_update (old->whereDefined,
9206 fileloc_undefined);
9207 }
9208
9209 typeError = TRUE;
9210 }
9211 }
9212
9213 checkVarConformance (old, unew, mustConform, completeConform);
9214 }
9215
9216 if (fcnConformance)
9217 {
9218 /* old->utype = unew->utype; */
9219 }
9220 else
9221 {
9222 if (ctype_isConj (old->utype))
9223 {
9224 if (ctype_isConj (unew->utype))
9225 {
9226 if (!ctype_sameAltTypes (old->utype, unew->utype))
9227 {
9228 if (optgenerror
9229 (FLG_INCONDEFS,
9230 message ("%s %q inconsistently %rdeclared with "
9231 "alternate types %s "
9232 "(types match, but alternates are not identical, "
9233 "so checking may not be correct)",
9234 ekind_capName (uentry_getKind (old)),
9235 uentry_getName (unew),
9236 uentry_isDeclared (old),
9237 ctype_unparse (unew->utype)),
9238 uentry_whereDeclared (unew)))
9239 {
9240 uentry_showWhereLastVal (old, ctype_unparse (old->utype));
9241 }
9242 else
9243 {
9244 old->utype = unew->utype;
9245 }
9246 }
9247 }
9248 }
9249 else
9250 {
9251 if (ctype_isUnknown (old->utype))
9252 {
9253 old->utype = unew->utype;
9254 }
9255 }
9256 }
9257
9258 if (unew->ukind == old->ukind)
9259 {
9260 sfree (unew->info);
9261 unew->info = uinfo_copy (old->info, old->ukind);
9262 }
9263
9264 sRef_storeState (old->sref);
9265 sRef_storeState (unew->sref);
9266}
9267
ba45e1e4 9268static void uentry_mergeConstraints (uentry spec, uentry def)
9269{
9270 if (uentry_isFunction (def))
9271 {
9272 DPRINTF (("Here: %s / %s",
9273 uentry_unparseFull (spec),
9274 uentry_unparseFull (def)));
efd360a3 9275 /* evans 2001-07-21 */
9276 llassert (uentry_isFunction (spec));
ba45e1e4 9277
9278 if (functionConstraint_isDefined (def->info->fcn->preconditions))
9279 {
9280 if (fileloc_isXHFile (uentry_whereLast (def)))
9281 {
9282 llassert (uentry_isFunction (spec));
9283 spec->info->fcn->preconditions = functionConstraint_conjoin (spec->info->fcn->preconditions,
9284 def->info->fcn->preconditions);
ba45e1e4 9285 }
ccf0a4a8 9286 else if (fileloc_equal (uentry_whereLast (spec), uentry_whereLast (def)))
9287 {
9288 ;
9289 }
ba45e1e4 9290 else
9291 {
ccf0a4a8 9292 /* Check if the constraints are identical */
9293
3120b462 9294 if (optgenerror
9295 (FLG_INCONDEFS,
9296 message
9297 ("Preconditions for %q redeclared. Dropping previous precondition: %q",
9298 uentry_getName (spec),
9299 functionConstraint_unparse (spec->info->fcn->preconditions)),
9300 uentry_whereLast (def)))
9301 {
9302 uentry_showWhereSpecified (spec);
9303 }
9304
9305 functionConstraint_free (spec->info->fcn->preconditions);
9306 spec->info->fcn->preconditions = def->info->fcn->preconditions;
ba45e1e4 9307 }
3120b462 9308
9309 def->info->fcn->preconditions = functionConstraint_undefined;
ba45e1e4 9310 }
9311
ba45e1e4 9312 if (functionConstraint_isDefined (def->info->fcn->postconditions))
9313 {
9314 if (fileloc_isXHFile (uentry_whereLast (def)))
9315 {
9316 llassert (uentry_isFunction (spec));
9317 DPRINTF (("Post: %s /++/ %s",
9318 functionConstraint_unparse (spec->info->fcn->postconditions),
9319 functionConstraint_unparse (def->info->fcn->postconditions)));
9320 spec->info->fcn->postconditions = functionConstraint_conjoin (spec->info->fcn->postconditions,
9321 def->info->fcn->postconditions);
9322 def->info->fcn->postconditions = functionConstraint_undefined;
9323 DPRINTF (("Conjoined post: %s", functionConstraint_unparse (spec->info->fcn->postconditions)));
9324 }
9325 else
9326 {
3120b462 9327 if (optgenerror
9328 (FLG_INCONDEFS,
9329 message
9330 ("Postconditions for %q redeclared. Dropping previous postcondition: %q",
9331 uentry_getName (spec),
9332 functionConstraint_unparse (spec->info->fcn->postconditions)),
9333 uentry_whereLast (def)))
9334 {
9335 uentry_showWhereSpecified (spec);
9336 }
9337
9338 functionConstraint_free (spec->info->fcn->postconditions);
9339 spec->info->fcn->postconditions = def->info->fcn->postconditions;
9340 def->info->fcn->postconditions = functionConstraint_undefined;
ba45e1e4 9341 }
9342 }
9343 }
9344}
9345
616915dd 9346/*
9347** modifies spec to reflect def, reports any inconsistencies
9348*/
9349
9350void
9351uentry_mergeEntries (uentry spec, /*@only@*/ uentry def)
9352{
9353 llassert (uentry_isValid (spec));
9354 llassert (uentry_isValid (def));
9355 llassert (cstring_equal (spec->uname, def->uname));
efd360a3 9356
9357 if (uentry_isFunction (def))
9358 {
9359 if (uentry_isConstant (spec))
9360 {
9361 llassert (ctype_isUnknown (spec->utype) || ctype_isFunction (spec->utype));
9362 uentry_makeConstantFunction (spec);
9363 }
9364 else
9365 {
9366 uentry_convertVarFunction (spec);
9367 }
9368
9369 llassert (uentry_isFunction (spec));
9370 }
28bf4b0b 9371
9372 DPRINTF (("Merge entries: %s / %s",
9373 uentry_unparseFull (spec),
9374 uentry_unparseFull (def)));
616915dd 9375
ba45e1e4 9376 uentry_mergeConstraints (spec, def);
9377
616915dd 9378 uentry_checkConformance (spec, def, TRUE,
9379 context_getFlag (FLG_NEEDSPEC));
9380
28bf4b0b 9381 DPRINTF (("Merge entries after conform: %s / %s",
9382 uentry_unparseFull (spec),
9383 uentry_unparseFull (def)));
9384
616915dd 9385 /* was: !(fileloc_isImport (uentry_whereSpecified (spec)))); */
9386
9387 /*
9388 ** okay, declarations conform. Propagate extra information.
9389 */
9390
9391 uentry_setDefined (spec, uentry_whereDefined (def));
9392 uentry_setDeclared (spec, uentry_whereDeclared (def));
9393
9394 if (uentry_isStatic (def))
9395 {
9396 if (optgenerror
9397 (FLG_INCONDEFS,
9398 message ("%s %q specified, but declared as static",
9399 ekind_capName (def->ukind),
9400 uentry_getName (def)),
9401 uentry_whereDeclared (def)))
9402 {
9403 uentry_showWhereSpecified (spec);
9404 }
9405 }
9406 else
9407 {
9408 spec->storageclass = def->storageclass;
9409 }
9410
9411 sRef_storeState (spec->sref);
9412
9413 spec->used = def->used || spec->used;
9414 spec->hasNameError |= def->hasNameError;
9415
9416 uentry_free (def);
9417
9418 if (!spec->hasNameError)
9419 {
9420 uentry_checkName (spec);
9421 }
9422 else
9423 {
9424 ;
9425 }
9426}
9427
9428/*
9429** Can't generate function redeclaration errors when the
9430** entries are merged, since we don't yet know if its the
9431** definition of the function.
9432*/
9433
9434void
9435uentry_clearDecl (void)
9436{
9437 posRedeclared = uentry_undefined;
9438 fileloc_free (posLoc);
9439 posLoc = fileloc_undefined;
9440}
9441
9442void
9443uentry_checkDecl (void)
9444{
f0171cff 9445 if (uentry_isValid (posRedeclared) && !fileloc_isXHFile (posLoc))
616915dd 9446 {
9447 llassert (fileloc_isDefined (posLoc));
9448
9449 if (uentry_isCodeDefined (posRedeclared))
9450 {
9451 if (optgenerror (FLG_REDECL,
9452 message ("%s %q declared after definition",
9453 ekind_capName (posRedeclared->ukind),
9454 uentry_getName (posRedeclared)),
9455 posLoc))
9456 {
9457 llgenindentmsg (message ("Definition of %q",
9458 uentry_getName (posRedeclared)),
9459 posRedeclared->whereDeclared);
9460 }
9461 }
9462 else
9463 {
9464 if (optgenerror (FLG_REDECL,
9465 message ("%s %q declared more than once",
9466 ekind_capName (posRedeclared->ukind),
9467 uentry_getName (posRedeclared)),
9468 posLoc))
9469 {
9470 llgenindentmsg (message ("Previous declaration of %q",
9471 uentry_getName (posRedeclared)),
9472 posRedeclared->whereDeclared);
9473 }
9474 }
9475 }
9476
9477 fileloc_free (posLoc);
9478 posLoc = fileloc_undefined;
9479 posRedeclared = uentry_undefined;
9480}
9481
9482/*
9483** Redefinition of old as unew.
9484** modifies old to reflect unew, reports any inconsistencies
9485*/
9486
9487void
9488uentry_mergeDefinition (uentry old, /*@only@*/ uentry unew)
9489{
d89a0c94 9490 fileloc olddef = uentry_whereDeclared (old);
616915dd 9491 fileloc unewdef = uentry_whereDeclared (unew);
9492 bool mustConform;
9493 bool wasForward;
28bf4b0b 9494
9495 DPRINTF (("uentry merge: %s / %s",
9496 uentry_unparseFull (old),
9497 uentry_unparseFull (unew)));
616915dd 9498
616915dd 9499 wasForward =
9500 fileloc_isUndefined (olddef)
efd360a3 9501 && fileloc_isDefined (uentry_whereDefined (old))
9502 && !uentry_isExpandedMacro (old);
616915dd 9503
9504 if (!context_getFlag (FLG_INCONDEFSLIB)
9505 && (fileloc_isLib (olddef) || fileloc_isImport (olddef)))
9506 {
9507 mustConform = FALSE;
9508 }
9509 else
9510 {
9511 mustConform = TRUE;
9512 }
9513
9514 llassert (uentry_isValid (old));
9515 llassert (uentry_isValid (unew));
9516 llassert (cstring_equal (old->uname, unew->uname));
9517
efd360a3 9518 if (uentry_isFunction (unew) && !uentry_isFunction (old))
9519 {
9520 if (uentry_isConstant (old))
9521 {
9522 llassert (ctype_isUnknown (old->utype) || ctype_isFunction (old->utype));
9523 uentry_makeConstantFunction (old);
9524 }
9525 else
9526 {
9527 uentry_convertVarFunction (old);
9528 }
9529
9530 llassert (uentry_isFunction (old));
9531 }
9532
9533 DPRINTF (("uentry merge: %s / %s",
9534 uentry_unparseFull (old),
9535 uentry_unparseFull (unew)));
9536
9537 if (uentry_isExtern (unew))
9538 {
9539 uentry_setUsed (old, unewdef);
9540 }
9541
616915dd 9542 /*
9543 ** should check old one was extern!
9544 */
9545
9546 if (uentry_isStatic (old))
9547 {
9548 if (!(uentry_isStatic (unew)))
9549 {
9550 if (optgenerror
9551 (FLG_SHADOW,
9552 message ("%s %q shadows static declaration",
9553 ekind_capName (unew->ukind),
9554 uentry_getName (unew)),
9555 unewdef))
9556 {
9557 uentry_showWhereLast (old);
9558 }
9559 }
9560 else
9561 {
9562 uentry_setDeclDef (old, unewdef);
9563 }
9564 }
9565 else if (uentry_isStatic (unew))
9566 {
9567 uentry_setDeclDef (old, unewdef);
9568 }
9569 else if (uentry_isExtern (old))
9570 {
9571 uentry_setDeclared (old, unewdef);
9572 }
9573 else
9574 {
d89a0c94 9575 if (!uentry_isExtern (unew)
9576 && !uentry_isForward (old)
616915dd 9577 && !fileloc_equal (olddef, unewdef)
9578 && !fileloc_isUndefined (olddef)
9579 && !fileloc_isUndefined (unewdef)
9580 && !fileloc_isBuiltin (olddef)
9581 && !fileloc_isBuiltin (unewdef)
9582 && !uentry_isYield (old)
9583 && !(fileloc_isLib (olddef) || fileloc_isImport (olddef)))
9584 {
9585 if (uentry_isVariable (old) || uentry_isVariable (unew))
9586 {
9587 ; /* will report redeclaration error later */
9588 }
9589 else
9590 {
9591 if (fileloc_isDefined (uentry_whereDefined (old)))
9592 {
9593 if (optgenerror
9594 (FLG_REDEF,
9595 message ("%s %q defined more than once",
9596 ekind_capName (unew->ukind),
9597 uentry_getName (unew)),
9598 uentry_whereLast (unew)))
9599 {
9600 llgenindentmsg
9601 (message ("Previous definition of %q",
9602 uentry_getName (old)),
9603 uentry_whereLast (old));
9604 }
9605 /*
9606 if (uentry_isDatatype (old) || uentry_isAnyTag (old))
9607 {
efd360a3 9608 uentry_updateInto (old, unew);
616915dd 9609 old->sref = sRef_saveCopy (old->sref);
9610 }
9611 */
9612 }
9613 }
9614 }
9615 else
9616 {
9617 if (fileloc_isLib (olddef)
9618 || fileloc_isUndefined (olddef)
9619 || fileloc_isImport (olddef))
9620 {
9621 if (uentry_isExtern (unew))
9622 {
9623 if (uentry_isExtern (old)
9624 || (fileloc_isDefined (uentry_whereDeclared (old))
9625 && (!fileloc_equal (uentry_whereDeclared (old),
9626 uentry_whereDefined (old)))))
9627 {
9628 if (optgenerror
9629 (FLG_REDECL,
9630 message ("%s %q declared more than once",
9631 ekind_capName (unew->ukind),
9632 uentry_getName (unew)),
9633 unew->whereDeclared))
9634 {
9635 llgenindentmsg
9636 (message ("Previous declaration of %q",
9637 uentry_getName (old)),
9638 old->whereDeclared);
9639 }
9640 }
9641
9642 uentry_setExtern (old);
9643 }
9644 else
9645 {
d89a0c94 9646 uentry_setDeclared (old, unewdef); /* evans 2001-07-23 was setDefined */
616915dd 9647 }
9648 }
9649 }
9650 }
9651
efd360a3 9652 DPRINTF (("uentry merge: %s / %s",
9653 uentry_unparseFull (old),
9654 uentry_unparseFull (unew)));
ba45e1e4 9655
efd360a3 9656 uentry_mergeConstraints (old, unew);
d89a0c94 9657 DPRINTF (("uentry merge: %s / %s",
9658 uentry_unparseFull (old),
9659 uentry_unparseFull (unew)));
9660
616915dd 9661 uentry_checkConformance (old, unew, mustConform, FALSE);
d89a0c94 9662 DPRINTF (("uentry merge: %s / %s",
9663 uentry_unparseFull (old),
9664 uentry_unparseFull (unew)));
616915dd 9665
9666 old->used = old->used || unew->used;
9667 old->uses = filelocList_append (old->uses, unew->uses);
9668 unew->uses = filelocList_undefined;
9669
9670 sRef_storeState (old->sref);
9671 sRef_storeState (unew->sref);
9672
9673 if (wasForward)
9674 {
9675 old->whereDefined = fileloc_update (old->whereDefined,
9676 fileloc_undefined);
9677 }
9678
d89a0c94 9679 DPRINTF (("here: %s", uentry_unparseFull (old)));
9680
616915dd 9681 /*
9682 ** No redeclaration errors for functions here, since we
9683 ** don't know if this is the definition of the function.
9684 */
9685
9686 if (fileloc_isUser (old->whereDeclared)
9687 && fileloc_isUser (unew->whereDeclared)
9688 && !fileloc_equal (old->whereDeclared, unew->whereDeclared)
9689 && !fileloc_isDefined (unew->whereDefined))
9690 {
9691 if (uentry_isFunction (old))
9692 {
9693 /*@-temptrans@*/ posRedeclared = old; /*@=temptrans@*/
9694 posLoc = fileloc_update (posLoc, unew->whereDeclared);
9695 }
9696 else
9697 {
9698 if (optgenerror (FLG_REDECL,
9699 message ("%s %q declared more than once",
9700 ekind_capName (unew->ukind),
9701 uentry_getName (unew)),
9702 unew->whereDeclared))
9703 {
9704 llgenindentmsg (message ("Previous declaration of %q",
9705 uentry_getName (old)),
9706 old->whereDeclared);
9707 }
9708 }
9709 }
9710
9711 if (fileloc_isUndefined (old->whereDefined))
9712 {
9713 old->whereDefined = fileloc_update (old->whereDefined, unew->whereDefined);
9714 }
9715 else
9716 {
9717 if (!context_processingMacros ()
9718 && fileloc_isUser (old->whereDefined)
9719 && fileloc_isUser (unew->whereDefined)
9720 && !fileloc_equal (old->whereDefined, unew->whereDefined))
9721 {
9722 if (uentry_isVariable (unew) || uentry_isFunction (unew))
9723 {
9724 if (uentry_isVariable (unew)
9725 && uentry_isExtern (unew))
9726 {
9727 if (optgenerror (FLG_REDECL,
9728 message ("%s %q declared after definition",
9729 ekind_capName (unew->ukind),
9730 uentry_getName (unew)),
9731 unew->whereDeclared))
9732 {
9733 llgenindentmsg (message ("Definition of %q",
9734 uentry_getName (old)),
9735 old->whereDefined);
9736 }
9737 }
9738 else
9739 {
9740 if (optgenerror (FLG_REDEF,
9741 message ("%s %q redefined",
9742 ekind_capName (unew->ukind),
9743 uentry_getName (unew)),
9744 unew->whereDefined))
9745 {
9746 llgenindentmsg (message ("Previous definition of %q",
9747 uentry_getName (old)),
9748 old->whereDefined);
9749 }
9750 }
9751 }
9752 }
9753 }
9754
9755 if (uentry_isExternal (unew))
9756 {
9757 old->whereDefined = fileloc_createExternal ();
9758 }
9759
9760 if (unew->hasNameError)
9761 {
9762 old->hasNameError = TRUE;
9763 }
9764
9765 uentry_free (unew);
9766
9767 if (!old->hasNameError)
9768 {
9769 uentry_checkName (old);
9770 }
9771
d89a0c94 9772 DPRINTF (("After: %s", uentry_unparseFull (old)));
616915dd 9773 llassert (!ctype_isUndefined (old->utype));
9774}
9775
9776void
9777uentry_copyState (uentry res, uentry other)
9778{
9779 llassert (uentry_isValid (res));
9780 llassert (uentry_isValid (other));
9781
9782 res->used = other->used;
9783
9784 res->info->var->kind = other->info->var->kind;
9785 res->info->var->defstate = other->info->var->defstate;
9786 res->info->var->nullstate = other->info->var->nullstate;
9787 res->info->var->checked = other->info->var->checked;
9788
9789 sRef_copyState (res->sref, other->sref);
9790}
9791
9792bool
9793uentry_sameKind (uentry u1, uentry u2)
9794{
9795 if (uentry_isValid (u1) && uentry_isValid (u2))
9796 {
9797 if (uentry_isVar (u1) && uentry_isVar (u2))
9798 {
9799 ctype c1 = u1->utype;
9800 ctype c2 = u2->utype;
9801
9802 if (ctype_isUnknown (c1) || ctype_isUnknown (c2)) return FALSE;
9803
9804 /*
9805 ** both functions, or both not functions
9806 */
9807
9808 return (bool_equal (ctype_isFunction (c1), ctype_isFunction (c2)));
9809 }
9810 else
9811 {
9812 return ((u1->ukind == u2->ukind));
9813 }
9814 }
9815
9816 return FALSE;
9817}
9818
efd360a3 9819static void uentry_updateInto (/*@unique@*/ uentry unew, uentry old)
616915dd 9820{
efd360a3 9821 ekind okind = unew->ukind;
616915dd 9822 llassert (uentry_isValid (unew));
9823 llassert (uentry_isValid (old));
9824
d89a0c94 9825 DPRINTF (("Update into: %s / %s", uentry_unparseFull (unew), uentry_unparseFull (old)));
9826
616915dd 9827 unew->ukind = old->ukind;
efd360a3 9828 llassert (cstring_equal (unew->uname, old->uname));
616915dd 9829 unew->utype = old->utype;
9830
efd360a3 9831 if (fileloc_isDefined (unew->whereSpecified)
9832 && !fileloc_isDefined (old->whereSpecified))
9833 {
9834 ; /* Keep the old value */
9835 }
9836 else
9837 {
9838 fileloc_free (unew->whereSpecified); /*@i523 why no error without this? */
9839 unew->whereSpecified = fileloc_copy (old->whereSpecified);
9840 }
9841
9842 if (fileloc_isDefined (unew->whereDefined)
9843 && !fileloc_isDefined (old->whereDefined))
9844 {
9845 ; /* Keep the old value */
9846 }
9847 else
9848 {
9849 fileloc_free (unew->whereDefined); /*@i523 why no error without this? */
9850 unew->whereDefined = fileloc_copy (old->whereDefined);
9851 }
9852
9853 if (fileloc_isDefined (unew->whereDeclared)
9854 && !fileloc_isDefined (old->whereDeclared))
9855 {
9856 ; /* Keep the old value */
9857 }
9858 else
9859 {
9860 fileloc_free (unew->whereDeclared); /*@i523 why no error without this? */
9861 unew->whereDeclared = fileloc_copy (old->whereDeclared);
9862 }
616915dd 9863
d89a0c94 9864 DPRINTF (("Update into: %s / %s", uentry_unparseFull (unew), uentry_unparseFull (old)));
9865
616915dd 9866 unew->sref = sRef_saveCopy (old->sref); /* Memory leak! */
9867 unew->used = old->used;
9868 unew->lset = FALSE;
9869 unew->isPrivate = old->isPrivate;
9870 unew->hasNameError = old->hasNameError;
efd360a3 9871 unew->uses = filelocList_append (unew->uses, old->uses);
9872 old->uses = filelocList_undefined;
616915dd 9873
9874 unew->storageclass = old->storageclass;
efd360a3 9875 uinfo_free (unew->info, okind);
616915dd 9876 unew->info = uinfo_copy (old->info, old->ukind);
9877}
9878
9879
9880uentry
9881uentry_copy (uentry e)
9882{
9883 if (uentry_isValid (e))
9884 {
9885 uentry enew = uentry_alloc ();
9886 DPRINTF (("copy: %s", uentry_unparseFull (e)));
efd360a3 9887 enew->ukind = e->ukind;
9888 enew->uname = cstring_copy (e->uname);
9889 enew->utype = e->utype;
9890
9891 enew->whereSpecified = fileloc_copy (e->whereSpecified);
9892 enew->whereDefined = fileloc_copy (e->whereDefined);
9893 enew->whereDeclared = fileloc_copy (e->whereDeclared);
9894
9895 enew->sref = sRef_saveCopy (e->sref); /* Memory leak! */
9896 enew->used = e->used;
9897 enew->lset = FALSE;
9898 enew->isPrivate = e->isPrivate;
9899 enew->hasNameError = e->hasNameError;
9900 enew->uses = filelocList_undefined;
9901
9902 enew->storageclass = e->storageclass;
9903 enew->info = uinfo_copy (e->info, e->ukind);
9904 enew->warn = warnClause_copy (e->warn);
9905
616915dd 9906 DPRINTF (("Here we are..."));
9907 DPRINTF (("original: %s", uentry_unparseFull (e)));
9908 DPRINTF (("copy: %s", uentry_unparse (enew)));
9909 DPRINTF (("copy: %s", uentry_unparseFull (enew)));
9910 return enew;
9911 }
9912 else
9913 {
9914 return uentry_undefined;
9915 }
9916}
9917
9918void
9919uentry_setState (uentry res, uentry other)
9920{
9921 llassert (uentry_isValid (res));
9922 llassert (uentry_isValid (other));
9923
9924 llassert (res->ukind == other->ukind);
9925 llassert (res->ukind == KVAR);
9926
9927 res->sref = sRef_saveCopy (other->sref);
9928 res->used = other->used;
9929 filelocList_free (res->uses);
9930 res->uses = other->uses;
9931 other->uses = filelocList_undefined;
9932 res->lset = other->lset;
9933}
9934
9935void
9936uentry_mergeUses (uentry res, uentry other)
9937{
9938 llassert (uentry_isValid (res));
9939 llassert (uentry_isValid (other));
9940
9941 res->used = other->used || res->used;
9942 res->lset = other->lset || res->lset;
9943 res->uses = filelocList_append (res->uses, other->uses);
9944 other->uses = filelocList_undefined;
9945}
9946
9947
9948/*
9949** This is a really ugly routine.
9950**
9951** gack...fix this one day.
9952*/
9953
9954/*
9955** flip == TRUE
9956** >> res is the false branch, other is the true branch (or continuation)
9957** flip == FALSE
9958** >> res is the true branch, other is the false branch (or continutation)
9959**
9960** opt == TRUE if,
9961**
9962** <other>
9963** if <res> ;
9964**
9965** References not effected by res are propagated from other.
9966*/
9967
9968static void
9969 branchStateError (/*@notnull@*/ uentry res, /*@notnull@*/ uentry other,
9970 bool flip, clause cl, fileloc loc)
9971{
9972 if (optgenerror
9973 (FLG_BRANCHSTATE,
9974 message ("%s %q is %s %s, but %s %s.",
9975 ekind_capName (res->ukind), uentry_getName (res),
9976 sRef_stateVerb (res->sref), clause_nameFlip (cl, flip),
9977 sRef_stateAltVerb (res->sref), clause_nameFlip (cl, !flip)),
9978 loc))
9979 {
9980 if (sRef_isDead (res->sref))
9981 {
9982 sRef_showStateInfo (res->sref);
9983 }
9984 else if (sRef_isKept (res->sref))
9985 {
9986 sRef_showAliasInfo (res->sref);
9987 }
9988 else /* dependent */
9989 {
9990 sRef_showAliasInfo (res->sref);
9991 sRef_showAliasInfo (other->sref);
9992 }
9993
9994 sRef_setAliasKind (res->sref, AK_ERROR, fileloc_undefined);
9995 }
9996}
9997
60868d40 9998static bool uentry_incompatibleMemoryStates (sRef rs, sRef os)
616915dd 9999{
10000 alkind rk = sRef_getAliasKind (rs);
10001 alkind ok = sRef_getAliasKind (os);
10002
10003 if (alkind_isError (rk) || alkind_isError (ok))
10004 {
10005 return FALSE;
10006 }
10007 else
10008 {
10009 return ((sRef_isDead (rs)
10010 || (alkind_isKept (rk) && !alkind_isKept (ok))
10011 || (alkind_isDependent (rk)
10012 && !alkind_isDependent (ok) && !alkind_isTemp (ok)))
10013 && (sRef_isAllocated (os) || sRef_isStateDefined (os)));
10014 }
10015}
10016
10017static void
10018 branchStateAltError (/*@notnull@*/ uentry res,
10019 /*@notnull@*/ uentry other, bool flip,
10020 clause cl, fileloc loc)
10021{
10022 if (optgenerror
10023 (FLG_BRANCHSTATE,
10024 message ("%s %q is %s %s, but %s %s.",
10025 ekind_capName (res->ukind), uentry_getName (res),
10026 sRef_stateVerb (other->sref), clause_nameFlip (cl, flip),
10027 sRef_stateAltVerb (other->sref), clause_nameFlip (cl, !flip)),
10028 loc))
10029 {
10030 if (sRef_isDead (other->sref))
10031 {
10032 sRef_showStateInfo (other->sref);
10033 }
10034 else /* kept */
10035 {
10036 sRef_showAliasInfo (other->sref);
10037 }
10038
10039 sRef_setAliasKind (res->sref, AK_ERROR, fileloc_undefined);
10040 sRef_setDefinedComplete (res->sref, fileloc_undefined);
10041
10042 sRef_setAliasKind (other->sref, AK_ERROR, fileloc_undefined);
10043 sRef_setDefinedComplete (other->sref, fileloc_undefined);
10044 }
10045}
10046
28bf4b0b 10047/*
10048** A reference is relevant for certain checks, only if it
10049** is not definitely null on this path (but not declared
10050** to always be null.)
10051*/
10052
10053static bool uentry_relevantReference (sRef sr, bool flip)
616915dd 10054{
28bf4b0b 10055 if (sRef_isKept (sr) || sRef_isDependent (sr))
10056 {
10057 return FALSE;
10058 }
10059 else
10060 {
10061 if (flip)
10062 {
10063 return !sRef_definitelyNullContext (sr);
10064 }
10065 else
10066 {
10067 return !sRef_definitelyNullAltContext (sr);
10068 }
10069 }
616915dd 10070}
616915dd 10071
28bf4b0b 10072static void
10073uentry_mergeAliasStates (uentry res, uentry other, fileloc loc,
10074 bool mustReturn, bool flip, bool opt,
10075 clause cl)
10076{
60868d40 10077 sRef rs = res->sref;
10078 sRef os = other->sref;
10079
28bf4b0b 10080 DPRINTF (("Merge alias states: %s / %s",
10081 uentry_unparseFull (res),
10082 uentry_unparseFull (other)));
616915dd 10083
60868d40 10084 if (sRef_isValid (rs))
616915dd 10085 {
10086 if (!mustReturn)
10087 {
60868d40 10088 if (uentry_incompatibleMemoryStates (rs, os))
616915dd 10089 {
60868d40 10090 DPRINTF (("Incompatible: \n\t%s / \n\t%s",
10091 sRef_unparseFull (rs), sRef_unparseFull (os)));
28bf4b0b 10092
60868d40 10093 if (sRef_isThroughArrayFetch (rs)
616915dd 10094 && !context_getFlag (FLG_STRICTBRANCHSTATE))
10095 {
60868d40 10096 if (sRef_isKept (rs) || sRef_isKept (os))
616915dd 10097 {
60868d40 10098 sRef_maybeKill (rs, loc);
616915dd 10099 }
60868d40 10100 else if (sRef_isPossiblyDead (os))
616915dd 10101 {
60868d40 10102 sRef_maybeKill (rs, loc);
616915dd 10103 }
10104 else
10105 {
10106 ;
10107 }
10108 }
10109 else
10110 {
60868d40 10111 if (uentry_relevantReference (os, flip))
616915dd 10112 {
60868d40 10113 if (sRef_isLocalParamVar (rs)
10114 && (sRef_isLocalState (os)
10115 || sRef_isDependent (os)))
616915dd 10116 {
60868d40 10117 if (sRef_isDependent (rs))
616915dd 10118 {
60868d40 10119 sRef_setDependent (os, loc);
616915dd 10120 }
10121 else
10122 {
60868d40 10123 sRef_setDefState (rs, SS_UNUSEABLE, loc);
616915dd 10124 }
10125 }
10126 else
10127 {
10128 branchStateError (res, other, flip, cl, loc);
10129 }
10130 }
10131 }
10132
60868d40 10133 if (sRef_isKept (rs))
616915dd 10134 {
60868d40 10135 DPRINTF (("Setting kept: %s", sRef_unparseFull (os)));
10136 sRef_setKept (os, loc);
616915dd 10137 }
10138 }
10139 else
10140 {
60868d40 10141 if (uentry_incompatibleMemoryStates (os, rs))
616915dd 10142 {
60868d40 10143 if (uentry_relevantReference (rs, !flip))
616915dd 10144 {
60868d40 10145 if (sRef_isLocalParamVar (rs)
10146 && (sRef_isDependent (rs)
10147 || sRef_isLocalState (rs)))
616915dd 10148 {
60868d40 10149 if (sRef_isDependent (os))
616915dd 10150 {
60868d40 10151 sRef_setDependent (rs, loc);
616915dd 10152 }
10153 else
10154 {
60868d40 10155 sRef_setDefState (rs, SS_UNUSEABLE, loc);
616915dd 10156 }
10157 }
10158 else
10159 {
60868d40 10160 if (sRef_isParam (os))
616915dd 10161 {
10162 /*
10163 ** If the local variable associated
10164 ** with the param has the correct state,
10165 ** its okay.
10166 ** (e.g., free (s); s = new(); ...
10167 */
28bf4b0b 10168
616915dd 10169 uentry uvar = usymtab_lookupSafe (other->uname);
28bf4b0b 10170
616915dd 10171 if (uentry_isValid (uvar)
60868d40 10172 && ((sRef_isDead (os)
616915dd 10173 && sRef_isOnly (uvar->sref))
60868d40 10174 || (sRef_isDependent (os)
616915dd 10175 && sRef_isOwned (uvar->sref))))
10176 {
10177 /* no error */
10178 }
10179 else
10180 {
10181 branchStateAltError (res, other,
10182 flip, cl, loc);
10183 }
10184 }
10185 else
10186 {
28bf4b0b 10187 DPRINTF (("Here: %s / %s",
10188 uentry_unparseFull (res),
10189 uentry_unparseFull (other)));
10190
616915dd 10191 branchStateAltError (res, other,
10192 flip, cl, loc);
10193 }
10194 }
10195 }
10196 }
28bf4b0b 10197
60868d40 10198 if (sRef_isKept (os))
616915dd 10199 {
60868d40 10200 sRef_setKept (rs, loc);
616915dd 10201 }
10202 }
10203
10204 if (opt)
10205 {
10206 DPRINTF (("Merge opt..."));
60868d40 10207 sRef_mergeOptState (rs, os, cl, loc);
616915dd 10208 DPRINTF (("Done!"));
10209 }
10210 else
10211 {
60868d40 10212 DPRINTF (("Merging states: \n\t%s / \n\t%s", sRef_unparseFull (rs), sRef_unparseFull (os)));
10213 sRef_mergeState (rs, os, cl, loc);
10214 DPRINTF (("After merging : \n\t%s / \n\t%s", sRef_unparseFull (rs), sRef_unparseFull (os)));
616915dd 10215 }
10216 }
10217 else
10218 {
60868d40 10219 if (sRef_isModified (os))
616915dd 10220 {
60868d40 10221 sRef_setModified (rs);
616915dd 10222 }
10223 }
28bf4b0b 10224 }
60868d40 10225
10226 DPRINTF (("After merge: %s", sRef_unparseFull (res->sref)));
28bf4b0b 10227}
616915dd 10228
28bf4b0b 10229static void
b7e84605 10230uentry_mergeValueStates (uentry res, uentry other, fileloc loc, bool mustReturn, /*@unused@*/ bool flip)
28bf4b0b 10231{
10232 valueTable rvalues;
10233 valueTable ovalues;
10234
10235 DPRINTF (("Merge values: %s / %s", sRef_unparseFull (res->sref), sRef_unparseFull (other->sref)));
10236
b7e84605 10237 if (mustReturn)
10238 {
10239 return;
10240 }
10241 /* flip? */
10242
28bf4b0b 10243 rvalues = sRef_getValueTable (res->sref);
10244 ovalues = sRef_getValueTable (other->sref);
10245
10246 if (valueTable_isUndefined (ovalues))
10247 {
10248 DPRINTF (("No value table: %s", sRef_unparseFull (other->sref)));
10249 ;
10250 }
10251 else if (valueTable_isUndefined (rvalues))
10252 {
10253 /*
10254 ** Copy values from other
10255 */
10256
10257 /*@i$@#@*/
10258 DPRINTF (("Has value table: %s", sRef_unparseFull (other->sref)));
10259 DPRINTF (("No value table: %s", sRef_unparseFull (res->sref)));
10260 ;
10261 }
10262 else
10263 {
10264 valueTable_elements (ovalues, fkey, fval) {
10265 stateValue tval;
10266 metaStateInfo minfo;
10267 stateCombinationTable sctable;
10268 cstring msg;
10269 int nval;
10270
10271 tval = valueTable_lookup (rvalues, fkey);
10272
10273 DPRINTF (("Merge value: %s / %s X %s", fkey,
10274 stateValue_unparse (fval), stateValue_unparse (tval)));
10275
10276 minfo = context_lookupMetaStateInfo (fkey);
10277 llassert (stateValue_isDefined (tval));
10278
10279 if (metaStateInfo_isUndefined (minfo) || !stateValue_isDefined (tval))
10280 {
10281 DPRINTF (("Cannot find meta state for: %s", fkey));
10282 BADBRANCH;
10283 }
10284 else
10285 {
10286 llassert (metaStateInfo_isDefined (minfo));
10287
10288 if (stateValue_isError (fval)
10289 || sRef_definitelyNullContext (res->sref))
10290 {
10291 sRef_setMetaStateValueComplete (res->sref,
10292 fkey, stateValue_getValue (fval),
b7e84605 10293 stateValue_getLoc (fval));
28bf4b0b 10294 DPRINTF (("Setting res: %s", sRef_unparseFull (res->sref)));
10295 }
10296 else if (stateValue_isError (tval)
10297 || sRef_definitelyNullAltContext (other->sref))
10298 {
10299 DPRINTF (("Other branch is definitely null!"));
10300 }
b7e84605 10301 else if (sRef_isStateUndefined (res->sref)
10302 || sRef_isDead (res->sref))
10303 {
10304 ; /* Combination state doesn't matter if it is undefined or dead */
10305 }
28bf4b0b 10306 else
10307 {
10308 DPRINTF (("Check: %s / %s / %s / %s", fkey,
10309 metaStateInfo_unparse (minfo),
10310 stateValue_unparse (fval),
10311 stateValue_unparse (tval)));
10312
10313 DPRINTF (("state values: %d / %d",
10314 stateValue_getValue (fval), stateValue_getValue (tval)));
10315
10316 sctable = metaStateInfo_getMergeTable (minfo);
10317
10318 DPRINTF (("Merge table: %s",
10319 stateCombinationTable_unparse (sctable)));
10320
10321 msg = cstring_undefined;
10322
10323 nval = stateCombinationTable_lookup (sctable,
10324 stateValue_getValue (fval),
10325 stateValue_getValue (tval),
10326 &msg);
10327
10328 DPRINTF (("nval: %d / %d / %d", nval,
10329 stateValue_getValue (fval), stateValue_getValue (tval)));
10330
b7e84605 10331 if (nval == stateValue_error)
28bf4b0b 10332 {
10333 /*@i32 print extra info for assignments@*/
10334
10335 if (uentry_isGlobalMarker (res))
10336 {
10337 if (optgenerror
10338 (FLG_STATEMERGE,
10339 message
b7e84605 10340 ("Control branches merge with incompatible global states (%s and %s)%q",
28bf4b0b 10341 metaStateInfo_unparseValue (minfo, stateValue_getValue (fval)),
10342 metaStateInfo_unparseValue (minfo, stateValue_getValue (tval)),
b7e84605 10343 cstring_isDefined (msg)
10344 ? message (": %s", msg) : cstring_undefined),
28bf4b0b 10345 loc))
10346 {
10347 sRef_showMetaStateInfo (res->sref, fkey);
10348 sRef_showMetaStateInfo (other->sref, fkey);
10349 }
10350 }
10351 else
10352 {
10353 if (optgenerror
10354 (FLG_STATEMERGE,
10355 message
b7e84605 10356 ("Control branches merge with incompatible states for %q (%s and %s)%q",
28bf4b0b 10357 uentry_getName (res),
10358 metaStateInfo_unparseValue (minfo, stateValue_getValue (fval)),
10359 metaStateInfo_unparseValue (minfo, stateValue_getValue (tval)),
b7e84605 10360 cstring_isDefined (msg)
10361 ? message (": %s", msg) : cstring_undefined),
28bf4b0b 10362 loc))
10363 {
10364 sRef_showMetaStateInfo (res->sref, fkey);
10365 sRef_showMetaStateInfo (other->sref, fkey);
10366 DPRINTF (("Res: %s", sRef_unparseFull (res->sref)));
10367 DPRINTF (("Other: %s", sRef_unparseFull (other->sref)));
10368 DPRINTF (("Null: %s / %s",
10369 bool_unparse (usymtab_isDefinitelyNull (res->sref)),
10370 bool_unparse (usymtab_isDefinitelyNull (other->sref))));
10371
10372 }
10373 }
10374 }
10375
10376 if (nval == stateValue_getValue (fval)
10377 && nval != stateValue_getValue (tval))
10378 {
10379 loc = stateValue_getLoc (fval);
10380 }
10381 else if (nval == stateValue_getValue (tval)
10382 && nval != stateValue_getValue (fval))
10383 {
10384 loc = stateValue_getLoc (tval);
10385 }
10386 else
10387 {
10388 ;
10389 }
10390
10391 if (stateValue_getValue (sRef_getMetaStateValue (res->sref, fkey)) == nval
10392 && nval == stateValue_getValue (fval)
10393 && nval == stateValue_getValue (tval))
10394 {
10395 ;
10396 }
10397 else
10398 {
10399 sRef_setMetaStateValueComplete (res->sref, fkey, nval, loc);
10400 }
10401 }
10402 }
10403 } end_valueTable_elements ;
10404 }
10405}
10406
10407
10408static void
10409uentry_mergeSetStates (uentry res, uentry other, /*@unused@*/ fileloc loc,
10410 bool flip, clause cl)
10411{
10412 if (cl == DOWHILECLAUSE)
10413 {
10414 res->used = other->used || res->used;
10415 res->lset = other->lset || res->lset;
10416 res->uses = filelocList_append (res->uses, other->uses);
10417 other->uses = filelocList_undefined;
10418 }
10419 else
10420 {
10421 if (sRef_isMacroParamRef (res->sref)
10422 && !uentry_isSefParam (other)
10423 && !uentry_isSefParam (res))
616915dd 10424 {
28bf4b0b 10425 bool hasError = FALSE;
10426
10427 if (bool_equal (res->used, other->used))
616915dd 10428 {
28bf4b0b 10429 res->used = other->used;
10430 }
10431 else
10432 {
10433 if (other->used && !flip)
616915dd 10434 {
28bf4b0b 10435 hasError =
10436 optgenerror
10437 (FLG_MACROPARAMS,
10438 message ("Macro parameter %q used in true clause, "
10439 "but not in false clause",
10440 uentry_getName (res)),
10441 uentry_whereDeclared (res));
616915dd 10442 }
10443 else
28bf4b0b 10444 {
10445 hasError =
10446 optgenerror
10447 (FLG_MACROPARAMS,
10448 message ("Macro parameter %q used in false clause, "
10449 "but not in true clause",
10450 uentry_getName (res)),
10451 uentry_whereDeclared (res));
10452 }
10453 res->used = TRUE;
10454
10455 if (hasError)
616915dd 10456 {
28bf4b0b 10457 /* make it sef now, prevent more errors */
10458 res->info->var->kind = VKREFSEFPARAM;
616915dd 10459 }
10460 }
28bf4b0b 10461 }
10462 else
10463 {
10464 res->used = other->used || res->used;
10465 res->lset = other->lset || res->lset;
10466 res->uses = filelocList_append (res->uses, other->uses);
10467 other->uses = filelocList_undefined;
616915dd 10468 }
10469 }
10470}
10471
28bf4b0b 10472void
10473uentry_mergeState (uentry res, uentry other, fileloc loc,
10474 bool mustReturn, bool flip, bool opt,
10475 clause cl)
10476{
10477 llassert (uentry_isValid (res));
10478 llassert (uentry_isValid (other));
10479
10480 llassert (res->ukind == other->ukind);
10481 llassert (res->ukind == KVAR);
10482
10483 DPRINTF (("Merge state: %s / %s", uentry_unparseFull (res),
10484 uentry_unparseFull (other)));
10485
10486 uentry_mergeAliasStates (res, other, loc, mustReturn, flip, opt, cl);
b7e84605 10487 uentry_mergeValueStates (res, other, loc, mustReturn, flip);
28bf4b0b 10488 uentry_mergeSetStates (res, other, loc, flip, cl);
3e3ec469 10489
10490 DPRINTF (("Merge ==> %s", uentry_unparseFull (res)));
28bf4b0b 10491}
10492
616915dd 10493void uentry_setUsed (uentry e, fileloc loc)
10494{
10495 static bool firstTime = TRUE;
10496 static bool showUses = FALSE;
10497 static bool exportLocal = FALSE;
10498
28bf4b0b 10499 DPRINTF (("Used: %s / %s", uentry_unparse (e), fileloc_unparse (loc)));
10500
616915dd 10501 if (firstTime)
10502 {
10503 /* need to track uses is FLG_SHOWUSES or FLG_EXPORTLOCAL is true */
10504
10505 showUses = context_getFlag (FLG_SHOWUSES);
10506 exportLocal = context_maybeSet (FLG_EXPORTLOCAL);
10507
10508 firstTime = FALSE;
10509 }
10510
10511 if (uentry_isValid (e))
10512 {
10513 int dp;
28bf4b0b 10514
10515 if (warnClause_isDefined (e->warn))
10516 {
10517 flagSpec flg = warnClause_getFlag (e->warn);
10518 cstring msg;
10519
10520 if (warnClause_hasMessage (e->warn))
10521 {
10522 msg = cstring_copy (warnClause_getMessage (e->warn));
10523 }
10524 else
10525 {
10526 msg = message ("Use of possibly dangerous %s",
10527 uentry_ekindNameLC (e));
10528 }
10529
10530 vfsgenerror (flg,
10531 message ("%q: %q", msg, uentry_getName (e)),
10532 loc);
10533 }
10534
616915dd 10535 if (sRef_isMacroParamRef (e->sref))
10536 {
10537 if (uentry_isYield (e) || uentry_isSefParam (e))
10538 {
10539 ;
10540 }
10541 else
10542 {
10543 if (context_inConditional ())
10544 {
10545 if (optgenerror
10546 (FLG_MACROPARAMS,
10547 message ("Macro parameter %q used in conditionally "
10548 "executed code (may or may not be "
10549 "evaluated exactly once)",
10550 uentry_getName (e)),
10551 loc))
10552 {
10553 e->info->var->kind = VKREFSEFPARAM;
10554 }
10555 }
10556 else
10557 {
10558 if ((e)->used)
10559 {
10560 if (optgenerror
10561 (FLG_MACROPARAMS,
10562 message ("Macro parameter %q used more than once",
10563 uentry_getName (e)),
10564 uentry_whereDeclared (e)))
10565 {
10566 e->info->var->kind = VKREFSEFPARAM;
10567 }
10568 }
10569 }
10570 }
10571 }
10572
10573 if ((dp = uentry_directParamNo (e)) >= 0)
10574 {
10575 uentry_setUsed (usymtab_getParam (dp), loc);
10576 }
10577
10578 e->used = TRUE;
28bf4b0b 10579
616915dd 10580 if (!sRef_isLocalVar (e->sref))
10581 {
10582 if (showUses)
10583 {
10584 e->uses = filelocList_add (e->uses, fileloc_copy (loc));
10585 }
10586 else
10587 {
10588 if (exportLocal)
10589 {
10590 if (context_inMacro ())
10591 {
10592 e->uses = filelocList_addUndefined (e->uses);
10593 }
10594 else
10595 {
10596 e->uses = filelocList_addDifferentFile
10597 (e->uses,
10598 uentry_whereDeclared (e),
10599 loc);
10600 }
10601 }
10602 }
10603 }
10604 }
10605}
10606
10607bool uentry_isReturned (uentry u)
10608{
10609 return (uentry_isValid (u) && uentry_isVar (u)
10610 && (u->info->var->kind == VKRETPARAM
10611 || u->info->var->kind == VKSEFRETPARAM));
10612}
10613
10614/*@exposed@*/ sRef uentry_returnedRef (uentry u, exprNodeList args)
10615{
10616 llassert (uentry_isRealFunction (u));
10617
28bf4b0b 10618 if (ctype_isFunction (u->utype) && sRef_isStateSpecial (uentry_getSref (u)))
616915dd 10619 {
28bf4b0b 10620 stateClauseList clauses = uentry_getStateClauseList (u);
10621 sRef res = sRef_makeNew (ctype_getReturnType (u->utype), u->sref, u->uname);
616915dd 10622
28bf4b0b 10623 DPRINTF (("Returned: %s", sRef_unparseFull (res)));
616915dd 10624 sRef_setAllocated (res, g_currentloc);
10625
28bf4b0b 10626 DPRINTF (("ensures clause: %s / %s", uentry_unparse (u),
10627 stateClauseList_unparse (clauses)));
616915dd 10628
ccf0a4a8 10629 /*
10630 ** This should be in exprNode_reflectEnsuresClause
10631 */
10632
28bf4b0b 10633 stateClauseList_postElements (clauses, cl)
10634 {
10635 if (!stateClause_isGlobal (cl))
616915dd 10636 {
28bf4b0b 10637 sRefSet refs = stateClause_getRefs (cl);
10638 sRefMod modf = stateClause_getEffectFunction (cl);
10639
10640 sRefSet_elements (refs, el)
616915dd 10641 {
28bf4b0b 10642 sRef base = sRef_getRootBase (el);
10643
10644 if (sRef_isResult (base))
616915dd 10645 {
28bf4b0b 10646 if (modf != NULL)
10647 {
10648 sRef sr = sRef_fixBase (el, res);
10649 modf (sr, g_currentloc);
10650 }
616915dd 10651 }
28bf4b0b 10652 else
10653 {
10654 ;
10655 }
10656 } end_sRefSet_elements ;
10657 }
10658 } end_stateClauseList_postElements ;
ccf0a4a8 10659
616915dd 10660 return res;
10661 }
10662 else
10663 {
10664 uentryList params;
10665 alkind ak;
10666 sRefSet prefs = sRefSet_new ();
10667 sRef res = sRef_undefined;
10668 int paramno = 0;
10669
10670 params = uentry_getParams (u);
10671
10672 uentryList_elements (params, current)
10673 {
10674 if (uentry_isReturned (current))
10675 {
10676 if (exprNodeList_size (args) >= paramno)
10677 {
10678 exprNode ecur = exprNodeList_nth (args, paramno);
10679 sRef tref = exprNode_getSref (ecur);
10680
28bf4b0b 10681 DPRINTF (("Returned reference: %s", sRef_unparseFull (tref)));
10682
616915dd 10683 if (sRef_isValid (tref))
10684 {
10685 sRef tcref = sRef_copy (tref);
10686
28bf4b0b 10687 usymtab_addForceMustAlias (tcref, tref); /* evans 2001-05-27 */
10688
616915dd 10689 if (sRef_isDead (tcref))
10690 {
10691 sRef_setDefined (tcref, g_currentloc);
10692 sRef_setOnly (tcref, g_currentloc);
10693 }
10694
10695 if (sRef_isRefCounted (tcref))
10696 {
10697 /* could be a new ref now (but only if its returned) */
10698 sRef_setAliasKindComplete (tcref, AK_ERROR, g_currentloc);
10699 }
10700
10701 sRef_makeSafe (tcref);
616915dd 10702 prefs = sRefSet_insert (prefs, tcref);
10703 }
10704 }
10705 }
10706
10707 paramno++;
10708 } end_uentryList_elements ;
10709
10710 if (sRefSet_size (prefs) > 0)
10711 {
10712 nstate n = sRef_getNullState (u->sref);
10713
10714 if (sRefSet_size (prefs) == 1)
10715 {
10716 res = sRefSet_choose (prefs);
10717 }
10718 else
10719 {
28bf4b0b 10720 /* should this ever happen? */ /*@i534 evans 2001-05-27 */
616915dd 10721 res = sRefSet_mergeIntoOne (prefs);
10722 }
10723
10724 if (nstate_isKnown (n))
10725 {
10726 sRef_setNullState (res, n, g_currentloc);
10727 }
10728 }
10729 else
10730 {
10731 if (ctype_isFunction (u->utype))
10732 {
28bf4b0b 10733 DPRINTF (("Making new from %s -->", uentry_unparseFull (u)));
10734 res = sRef_makeNew (ctype_getReturnType (u->utype), u->sref, u->uname);
616915dd 10735 }
10736 else
10737 {
10738 res = sRef_makeNew (ctype_unknown, u->sref, u->uname);
10739 }
10740
10741 if (sRef_isRefCounted (res))
10742 {
10743 sRef_setAliasKind (res, AK_NEWREF, g_currentloc);
10744 }
10745 }
10746
28bf4b0b 10747
616915dd 10748 if (sRef_getNullState (res) == NS_ABSNULL)
10749 {
10750 ctype ct = ctype_realType (u->utype);
10751
10752 if (ctype_isAbstract (ct))
10753 {
10754 sRef_setNotNull (res, g_currentloc);
10755 }
10756 else
10757 {
10758 if (ctype_isUser (ct))
10759 {
10760 sRef_setStateFromUentry (res, usymtab_getTypeEntry (ctype_typeId (ct)));
10761 }
10762 else
10763 {
10764 sRef_setNotNull (res, g_currentloc);
10765 }
10766 }
10767 }
10768
10769 if (sRef_isRefCounted (res))
10770 {
10771 sRef_setAliasKind (res, AK_NEWREF, g_currentloc);
10772 }
10773 else if (sRef_isKillRef (res))
10774 {
10775 sRef_setAliasKind (res, AK_REFCOUNTED, g_currentloc);
10776 }
10777 else
10778 {
10779 ;
10780 }
10781
10782 ak = sRef_getAliasKind (res);
10783
10784 if (alkind_isImplicit (ak))
10785 {
10786 sRef_setAliasKind (res,
10787 alkind_fixImplicit (ak),
10788 g_currentloc);
10789 }
10790
10791 sRefSet_free (prefs);
10792
28bf4b0b 10793 DPRINTF (("Returns ref: %s", sRef_unparseFull (res)));
616915dd 10794 return res;
10795 }
10796}
10797
10798static bool uentry_isRefCounted (uentry ue)
10799{
10800 ctype ct = uentry_getType (ue);
10801
10802 if (ctype_isFunction (ct))
10803 {
28bf4b0b 10804 return (ctype_isRefCounted (ctype_getReturnType (ct)));
616915dd 10805 }
10806 else
10807 {
10808 return (ctype_isRefCounted (ct));
10809 }
10810}
10811
10812/*
10813** old was declared yield in the specification.
10814** new is declared in the iter implementation.
10815*/
10816
10817void uentry_checkYieldParam (uentry old, uentry unew)
10818{
10819 cstring name;
10820
10821 llassert (uentry_isVariable (old));
10822 llassert (uentry_isVariable (unew));
10823
10824 unew->info->var->kind = VKYIELDPARAM;
10825 (void) checkTypeConformance (old, unew, TRUE);
10826 checkVarConformance (old, unew, TRUE, FALSE);
10827
10828 /* get rid of param marker */
10829
10830 name = uentry_getName (unew);
10831 cstring_free (unew->uname);
10832 unew->uname = name;
10833 unew->info->var->kind = VKREFYIELDPARAM;
10834
10835 uentry_setUsed (old, fileloc_undefined);
10836 uentry_setUsed (unew, fileloc_undefined);
10837}
10838
10839/*@observer@*/ cstring
10840uentry_ekindName (uentry ue)
10841{
10842 if (uentry_isValid (ue))
10843 {
10844 switch (ue->ukind)
10845 {
10846 case KINVALID:
10847 return cstring_makeLiteralTemp ("<Error: invalid uentry>");
10848 case KDATATYPE:
10849 return cstring_makeLiteralTemp ("Datatype");
10850 case KENUMCONST:
10851 return cstring_makeLiteralTemp ("Enum member");
10852 case KCONST:
10853 return cstring_makeLiteralTemp ("Constant");
10854 case KVAR:
10855 if (uentry_isParam (ue))
10856 {
10857 return cstring_makeLiteralTemp ("Parameter");
10858 }
10859 else if (uentry_isExpandedMacro (ue))
10860 {
10861 return cstring_makeLiteralTemp ("Expanded macro");
10862 }
10863 else
10864 {
10865 return cstring_makeLiteralTemp ("Variable");
10866 }
10867 case KFCN:
10868 return cstring_makeLiteralTemp ("Function");
10869 case KITER:
10870 return cstring_makeLiteralTemp ("Iterator");
10871 case KENDITER:
10872 return cstring_makeLiteralTemp ("Iterator finalizer");
10873 case KSTRUCTTAG:
10874 return cstring_makeLiteralTemp ("Struct tag");
10875 case KUNIONTAG:
10876 return cstring_makeLiteralTemp ("Union tag");
10877 case KENUMTAG:
10878 return cstring_makeLiteralTemp ("Enum tag");
10879 case KELIPSMARKER:
10880 return cstring_makeLiteralTemp ("Optional parameters");
10881 }
10882 }
10883 else
10884 {
10885 return cstring_makeLiteralTemp ("<Undefined>");
10886 }
10887
10888 BADEXIT;
10889}
10890
28bf4b0b 10891/*@observer@*/ cstring
10892uentry_ekindNameLC (uentry ue)
10893{
10894 if (uentry_isValid (ue))
10895 {
10896 switch (ue->ukind)
10897 {
10898 case KINVALID:
10899 return cstring_makeLiteralTemp ("<error: invalid uentry>");
10900 case KDATATYPE:
10901 return cstring_makeLiteralTemp ("datatype");
10902 case KENUMCONST:
10903 return cstring_makeLiteralTemp ("enum member");
10904 case KCONST:
10905 return cstring_makeLiteralTemp ("constant");
10906 case KVAR:
10907 if (uentry_isParam (ue))
10908 {
10909 return cstring_makeLiteralTemp ("parameter");
10910 }
10911 else if (uentry_isExpandedMacro (ue))
10912 {
10913 return cstring_makeLiteralTemp ("expanded macro");
10914 }
10915 else
10916 {
10917 return cstring_makeLiteralTemp ("variable");
10918 }
10919 case KFCN:
10920 return cstring_makeLiteralTemp ("function");
10921 case KITER:
10922 return cstring_makeLiteralTemp ("iterator");
10923 case KENDITER:
10924 return cstring_makeLiteralTemp ("iterator finalizer");
10925 case KSTRUCTTAG:
10926 return cstring_makeLiteralTemp ("struct tag");
10927 case KUNIONTAG:
10928 return cstring_makeLiteralTemp ("union tag");
10929 case KENUMTAG:
10930 return cstring_makeLiteralTemp ("enum tag");
10931 case KELIPSMARKER:
10932 return cstring_makeLiteralTemp ("optional parameters");
10933 }
10934 }
10935 else
10936 {
10937 return cstring_makeLiteralTemp ("<Undefined>");
10938 }
10939
10940 BADEXIT;
10941}
10942
616915dd 10943void uentry_setHasNameError (uentry ue)
10944{
10945 llassert (uentry_isValid (ue));
10946
10947 ue->hasNameError = TRUE;
10948}
10949
10950void uentry_checkName (uentry ue)
10951{
28bf4b0b 10952 DPRINTF (("Checking name: %s / %s / %s", uentry_unparse (ue),
10953 uentry_observeRealName (ue),
10954 bool_unparse (uentry_isVisibleExternally (ue))));
10955
616915dd 10956 if (uentry_isValid (ue)
28bf4b0b 10957 && !context_inXHFile ()
10958 && uentry_hasName (ue)
616915dd 10959 && !uentry_isElipsisMarker (ue)
10960 && context_getFlag (FLG_NAMECHECKS)
10961 && !ue->hasNameError
10962 && !uentry_isEndIter (ue)
10963 && !fileloc_isBuiltin (uentry_whereLast (ue))
10964 && (uentry_isExpandedMacro (ue) || !uentry_isForward (ue)))
28bf4b0b 10965 {
10966 DPRINTF (("Here..."));
10967
616915dd 10968 if (uentry_isPriv (ue))
10969 {
10970 ; /* any checks here? */
10971 }
10972 else if (fileloc_isExternal (uentry_whereDefined (ue)))
10973 {
10974 ; /* no errors for externals */
10975 }
10976 else
10977 {
10978 int scope;
10979
10980 if (uentry_isExpandedMacro (ue))
10981 {
10982 scope = globScope;
10983 }
10984 else
10985 {
10986 if (uentry_isExpandedMacro (ue))
10987 {
10988 scope = fileScope;
10989 }
10990 else if (uentry_isVariable (ue))
10991 {
10992 sRef sr = uentry_getSref (ue);
10993
10994 if (sRef_isValid (sr))
10995 {
10996 scope = sRef_getScope (sr);
10997 }
10998 else
10999 {
11000 scope = fileScope;
11001 }
11002 }
11003 else if (uentry_isFunction (ue)
11004 || uentry_isIter (ue)
11005 || uentry_isEndIter (ue)
11006 || uentry_isConstant (ue))
11007 {
11008 scope = uentry_isStatic (ue) ? fileScope : globScope;
11009 }
11010 else /* datatypes, etc. must be global */
11011 {
11012 scope = globScope;
11013 }
11014
11015 usymtab_checkDistinctName (ue, scope);
11016 }
28bf4b0b 11017
616915dd 11018 if (context_getFlag (FLG_CPPNAMES))
11019 {
28bf4b0b 11020 checkCppName (ue);
616915dd 11021 }
11022
11023 if (scope == globScope)
11024 {
28bf4b0b 11025 checkExternalName (ue);
616915dd 11026 }
28bf4b0b 11027 else if (scope == fileScope)
11028 {
11029 checkFileScopeName (ue);
11030 }
11031 else
616915dd 11032 {
11033 checkLocalName (ue);
616915dd 11034 }
11035
616915dd 11036 checkPrefix (ue);
28bf4b0b 11037 checkAnsiName (ue);
616915dd 11038 }
11039 }
11040}
11041
7ebcc5bb 11042/*@exposed@*/ uentry uentry_makeUnrecognized (cstring c, /*@only@*/ fileloc loc)
616915dd 11043{
11044 uentry ue;
11045 fileloc tloc;
11046
11047 /*
7ebcc5bb 11048 ** Can't but unrecognized ids in macros in global scope, because srefs will break!
11049 */
11050
616915dd 11051 if (!context_inMacro ())
11052 {
11053 sRef_setGlobalScopeSafe ();
11054 }
11055
11056 ue = uentry_makeVariable (c, ctype_unknown, loc, FALSE);
11057 uentry_setUsed (ue, loc);
11058
11059 tloc = fileloc_createExternal ();
11060 uentry_setDefined (ue, tloc);
11061 fileloc_free (tloc);
11062 uentry_setHasNameError (ue);
11063
11064 if (context_getFlag (FLG_REPEATUNRECOG))
11065 {
11066 uentry_markOwned (ue);
11067 }
11068 else
11069 {
11070 ue = usymtab_supReturnFileEntry (ue);
11071 }
11072
11073 if (!context_inMacro ())
11074 {
11075 sRef_clearGlobalScopeSafe ();
11076 }
11077
11078 return ue;
11079}
11080
28bf4b0b 11081uentry uentry_makeGlobalMarker ()
11082{
11083 uentry ue;
11084 fileloc tloc;
11085
11086 llassert (sRef_inGlobalScope ());
11087
11088 ue = uentry_makeVariableAux
11089 (GLOBAL_MARKER_NAME, ctype_unknown, fileloc_undefined,
11090 sRef_makeGlobalMarker (),
11091 FALSE, VKNORMAL);
11092
11093 tloc = fileloc_createExternal ();
11094 uentry_setUsed (ue, tloc);
11095 uentry_setDefined (ue, tloc);
11096 fileloc_free (tloc);
11097 uentry_setHasNameError (ue);
11098
11099 return ue;
11100}
11101
11102
11103bool uentry_isGlobalMarker (uentry ue)
11104{
11105 return (uentry_isValid (ue)
11106 && (cstring_equal (uentry_rawName (ue), GLOBAL_MARKER_NAME)));
11107}
11108
616915dd 11109/* new start modifications */
28bf4b0b 11110
616915dd 11111/* start modifications */
11112/*
11113requires: p_e is defined, is a ptr/array variable
11114modifies: p_e
11115effects: sets the state of the variable
11116*/
11117
28bf4b0b 11118
616915dd 11119void uentry_setPossiblyNullTerminatedState (uentry p_e) {
b7b694d6 11120 /*@access sRef@*/ /*i523 shouldn't do this! */
616915dd 11121 if( uentry_isValid(p_e) ) {
11122 if( p_e->info != NULL) {
11123 if( p_e->info->var != NULL) {
11124 p_e->info->var->bufinfo->bufstate = BB_POSSIBLYNULLTERMINATED;
11125 p_e->sref->bufinfo.bufstate = BB_POSSIBLYNULLTERMINATED;
11126 return;
b7b694d6 11127 }
11128 }
11129 }
11130 /*@noaccess sRef@*/
616915dd 11131
11132 fprintf(stderr, "uentry:Error in setPossiblyNullTerminatedState\n");
11133}
11134
11135/*
11136requires: p_e is defined, is a ptr/array variable
11137modifies: p_e
11138effects: sets the size of the buffer
11139*/
11140
11141void uentry_setNullTerminatedState (uentry p_e) {
11142 if( uentry_isValid(p_e) ) {
11143 if( p_e->info != NULL) {
11144 if( p_e->info->var != NULL) {
11145 p_e->info->var->bufinfo->bufstate = BB_NULLTERMINATED;
b7b694d6 11146 /*@access sRef@*/ /*@i523 bad!*/
616915dd 11147 p_e->sref->bufinfo.bufstate = BB_NULLTERMINATED;
b7b694d6 11148 /*@noaccess sRef@*/
616915dd 11149 return;
b7b694d6 11150 }
11151 }
11152 }
616915dd 11153
11154 fprintf(stderr, "uentry:Error in setNullTerminatedState\n");
11155}
11156
616915dd 11157/*
11158requires: p_e is defined, is a ptr/array variable
11159modifies: p_e
11160effects: sets the size of the buffer
11161*/
11162
11163void uentry_setSize (uentry p_e, int size) {
11164 if( uentry_isValid(p_e) ) {
11165 if( p_e->info != NULL) {
11166 if( p_e->info->var != NULL) {
11167 p_e->info->var->bufinfo->size = size;
b7b694d6 11168 /*@access sRef@*/ /*@i523 bad!*/
616915dd 11169 p_e->sref->bufinfo.size = size;
b7b694d6 11170 /*@noaccess sRef@*/
616915dd 11171 return;
b7b694d6 11172 }
11173 }
11174 }
616915dd 11175
11176 fprintf(stderr, "uentry:Error in setSize\n");
11177}
11178
11179
11180/*
11181requires: p_e is defined, is a ptr/array variable
11182modifies: p_e
11183effects: sets the length of the buffer
11184*/
11185
b7b694d6 11186void uentry_setLen (uentry p_e, int len) {
616915dd 11187 if( uentry_isValid(p_e) ) {
11188 if( p_e->info != NULL) {
11189 if( p_e->info->var != NULL) {
11190 p_e->info->var->bufinfo->len = len;
b7b694d6 11191 /*@access sRef@*/ /*@i523 bad!*/
616915dd 11192 p_e->sref->bufinfo.len = len;
b7b694d6 11193 /*@noaccess sRef@*/
616915dd 11194 return;
b7b694d6 11195 }
11196 }
11197 }
11198
616915dd 11199 fprintf(stderr, "uentry:Error in setLen\n");
11200}
b7b694d6 11201
616915dd 11202/*@=type*/
ba45e1e4 11203
11204bool uentry_hasMetaStateEnsures (uentry e)
11205{
11206 if (uentry_isValid (e) && uentry_isFunction (e))
11207 {
11208 return functionConstraint_hasMetaStateConstraint (e->info->fcn->postconditions);
11209 }
11210 else
11211 {
11212 return FALSE;
11213 }
11214}
11215
ccf0a4a8 11216metaStateConstraintList uentry_getMetaStateEnsures (uentry e)
ba45e1e4 11217{
ccf0a4a8 11218 llassert (uentry_isValid (e) && uentry_isFunction (e));
11219 return functionConstraint_getMetaStateConstraints (e->info->fcn->postconditions);
ba45e1e4 11220}
This page took 1.741526 seconds and 5 git commands to generate.