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